mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-30 02:33:55 +00:00
Introduce separate hir::BinaryOp
Unlike ast::BinOp, it has significantly more structure to it, so it's easier to, say, handle all assignment-like operations in the same way.
This commit is contained in:
parent
8919aa8065
commit
7e5a186c1f
@ -257,7 +257,44 @@ pub enum Expr {
|
||||
Literal(Literal),
|
||||
}
|
||||
|
||||
pub use ra_syntax::ast::BinOp as BinaryOp;
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum BinaryOp {
|
||||
LogicOp(LogicOp),
|
||||
ArithOp(ArithOp),
|
||||
CmpOp(CmpOp),
|
||||
Assignment { op: Option<ArithOp> },
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum LogicOp {
|
||||
And,
|
||||
Or,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum CmpOp {
|
||||
Equal,
|
||||
NotEqual,
|
||||
Less,
|
||||
LessOrEqual,
|
||||
Greater,
|
||||
GreaterOrEqual,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum ArithOp {
|
||||
Add,
|
||||
Mul,
|
||||
Sub,
|
||||
Div,
|
||||
Rem,
|
||||
Shl,
|
||||
Shr,
|
||||
BitXor,
|
||||
BitOr,
|
||||
BitAnd,
|
||||
}
|
||||
|
||||
pub use ra_syntax::ast::PrefixOp as UnaryOp;
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub enum Array {
|
||||
@ -791,7 +828,7 @@ where
|
||||
ast::ExprKind::BinExpr(e) => {
|
||||
let lhs = self.collect_expr_opt(e.lhs());
|
||||
let rhs = self.collect_expr_opt(e.rhs());
|
||||
let op = e.op_kind();
|
||||
let op = e.op_kind().map(BinaryOp::from);
|
||||
self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr)
|
||||
}
|
||||
ast::ExprKind::TupleExpr(e) => {
|
||||
@ -1038,6 +1075,42 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ast::BinOp> for BinaryOp {
|
||||
fn from(ast_op: ast::BinOp) -> Self {
|
||||
match ast_op {
|
||||
ast::BinOp::BooleanOr => BinaryOp::LogicOp(LogicOp::Or),
|
||||
ast::BinOp::BooleanAnd => BinaryOp::LogicOp(LogicOp::And),
|
||||
ast::BinOp::EqualityTest => BinaryOp::CmpOp(CmpOp::Equal),
|
||||
ast::BinOp::NegatedEqualityTest => BinaryOp::CmpOp(CmpOp::NotEqual),
|
||||
ast::BinOp::LesserEqualTest => BinaryOp::CmpOp(CmpOp::LessOrEqual),
|
||||
ast::BinOp::GreaterEqualTest => BinaryOp::CmpOp(CmpOp::GreaterOrEqual),
|
||||
ast::BinOp::LesserTest => BinaryOp::CmpOp(CmpOp::Less),
|
||||
ast::BinOp::GreaterTest => BinaryOp::CmpOp(CmpOp::Greater),
|
||||
ast::BinOp::Addition => BinaryOp::ArithOp(ArithOp::Add),
|
||||
ast::BinOp::Multiplication => BinaryOp::ArithOp(ArithOp::Mul),
|
||||
ast::BinOp::Subtraction => BinaryOp::ArithOp(ArithOp::Sub),
|
||||
ast::BinOp::Division => BinaryOp::ArithOp(ArithOp::Div),
|
||||
ast::BinOp::Remainder => BinaryOp::ArithOp(ArithOp::Rem),
|
||||
ast::BinOp::LeftShift => BinaryOp::ArithOp(ArithOp::Shl),
|
||||
ast::BinOp::RightShift => BinaryOp::ArithOp(ArithOp::Shr),
|
||||
ast::BinOp::BitwiseXor => BinaryOp::ArithOp(ArithOp::BitXor),
|
||||
ast::BinOp::BitwiseOr => BinaryOp::ArithOp(ArithOp::BitOr),
|
||||
ast::BinOp::BitwiseAnd => BinaryOp::ArithOp(ArithOp::BitAnd),
|
||||
ast::BinOp::Assignment => BinaryOp::Assignment { op: None },
|
||||
ast::BinOp::AddAssign => BinaryOp::Assignment { op: Some(ArithOp::Add) },
|
||||
ast::BinOp::DivAssign => BinaryOp::Assignment { op: Some(ArithOp::Div) },
|
||||
ast::BinOp::MulAssign => BinaryOp::Assignment { op: Some(ArithOp::Mul) },
|
||||
ast::BinOp::RemAssign => BinaryOp::Assignment { op: Some(ArithOp::Rem) },
|
||||
ast::BinOp::ShlAssign => BinaryOp::Assignment { op: Some(ArithOp::Shl) },
|
||||
ast::BinOp::ShrAssign => BinaryOp::Assignment { op: Some(ArithOp::Shr) },
|
||||
ast::BinOp::SubAssign => BinaryOp::Assignment { op: Some(ArithOp::Sub) },
|
||||
ast::BinOp::BitOrAssign => BinaryOp::Assignment { op: Some(ArithOp::BitOr) },
|
||||
ast::BinOp::BitAndAssign => BinaryOp::Assignment { op: Some(ArithOp::BitAnd) },
|
||||
ast::BinOp::BitXorAssign => BinaryOp::Assignment { op: Some(ArithOp::BitXor) },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn body_with_source_map_query(
|
||||
db: &impl HirDatabase,
|
||||
def: DefWithBody,
|
||||
|
@ -1265,9 +1265,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||
Expr::BinaryOp { lhs, rhs, op } => match op {
|
||||
Some(op) => {
|
||||
let lhs_expectation = match op {
|
||||
BinaryOp::BooleanAnd | BinaryOp::BooleanOr => {
|
||||
Expectation::has_type(Ty::simple(TypeCtor::Bool))
|
||||
}
|
||||
BinaryOp::LogicOp(..) => Expectation::has_type(Ty::simple(TypeCtor::Bool)),
|
||||
_ => Expectation::none(),
|
||||
};
|
||||
let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
|
||||
|
@ -1,37 +1,14 @@
|
||||
use super::{InferTy, Ty, TypeCtor};
|
||||
use crate::{expr::BinaryOp, ty::ApplicationTy};
|
||||
use crate::{
|
||||
expr::{BinaryOp, CmpOp},
|
||||
ty::ApplicationTy,
|
||||
};
|
||||
|
||||
pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty {
|
||||
match op {
|
||||
BinaryOp::BooleanOr
|
||||
| BinaryOp::BooleanAnd
|
||||
| BinaryOp::EqualityTest
|
||||
| BinaryOp::NegatedEqualityTest
|
||||
| BinaryOp::LesserEqualTest
|
||||
| BinaryOp::GreaterEqualTest
|
||||
| BinaryOp::LesserTest
|
||||
| BinaryOp::GreaterTest => Ty::simple(TypeCtor::Bool),
|
||||
BinaryOp::Assignment
|
||||
| BinaryOp::AddAssign
|
||||
| BinaryOp::SubAssign
|
||||
| BinaryOp::DivAssign
|
||||
| BinaryOp::MulAssign
|
||||
| BinaryOp::RemAssign
|
||||
| BinaryOp::ShrAssign
|
||||
| BinaryOp::ShlAssign
|
||||
| BinaryOp::BitAndAssign
|
||||
| BinaryOp::BitOrAssign
|
||||
| BinaryOp::BitXorAssign => Ty::unit(),
|
||||
BinaryOp::Addition
|
||||
| BinaryOp::Subtraction
|
||||
| BinaryOp::Multiplication
|
||||
| BinaryOp::Division
|
||||
| BinaryOp::Remainder
|
||||
| BinaryOp::LeftShift
|
||||
| BinaryOp::RightShift
|
||||
| BinaryOp::BitwiseAnd
|
||||
| BinaryOp::BitwiseOr
|
||||
| BinaryOp::BitwiseXor => match rhs_ty {
|
||||
BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::simple(TypeCtor::Bool),
|
||||
BinaryOp::Assignment { .. } => Ty::unit(),
|
||||
BinaryOp::ArithOp(_) => match rhs_ty {
|
||||
Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
|
||||
TypeCtor::Int(..) | TypeCtor::Float(..) => rhs_ty,
|
||||
_ => Ty::Unknown,
|
||||
@ -39,14 +16,15 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty {
|
||||
Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => rhs_ty,
|
||||
_ => Ty::Unknown,
|
||||
},
|
||||
BinaryOp::RangeRightOpen | BinaryOp::RangeRightClosed => Ty::Unknown,
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
|
||||
match op {
|
||||
BinaryOp::BooleanAnd | BinaryOp::BooleanOr => Ty::simple(TypeCtor::Bool),
|
||||
BinaryOp::Assignment | BinaryOp::EqualityTest => match lhs_ty {
|
||||
BinaryOp::LogicOp(..) => Ty::simple(TypeCtor::Bool),
|
||||
BinaryOp::Assignment { op: None }
|
||||
| BinaryOp::CmpOp(CmpOp::Equal)
|
||||
| BinaryOp::CmpOp(CmpOp::NotEqual) => match lhs_ty {
|
||||
Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
|
||||
TypeCtor::Int(..)
|
||||
| TypeCtor::Float(..)
|
||||
@ -58,37 +36,15 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
|
||||
Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty,
|
||||
_ => Ty::Unknown,
|
||||
},
|
||||
BinaryOp::LesserEqualTest
|
||||
| BinaryOp::GreaterEqualTest
|
||||
| BinaryOp::LesserTest
|
||||
| BinaryOp::GreaterTest
|
||||
| BinaryOp::AddAssign
|
||||
| BinaryOp::SubAssign
|
||||
| BinaryOp::DivAssign
|
||||
| BinaryOp::MulAssign
|
||||
| BinaryOp::RemAssign
|
||||
| BinaryOp::ShrAssign
|
||||
| BinaryOp::ShlAssign
|
||||
| BinaryOp::BitAndAssign
|
||||
| BinaryOp::BitOrAssign
|
||||
| BinaryOp::BitXorAssign
|
||||
| BinaryOp::Addition
|
||||
| BinaryOp::Subtraction
|
||||
| BinaryOp::Multiplication
|
||||
| BinaryOp::Division
|
||||
| BinaryOp::Remainder
|
||||
| BinaryOp::LeftShift
|
||||
| BinaryOp::RightShift
|
||||
| BinaryOp::BitwiseAnd
|
||||
| BinaryOp::BitwiseOr
|
||||
| BinaryOp::BitwiseXor => match lhs_ty {
|
||||
Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
|
||||
TypeCtor::Int(..) | TypeCtor::Float(..) => lhs_ty,
|
||||
BinaryOp::CmpOp(_) | BinaryOp::Assignment { op: Some(_) } | BinaryOp::ArithOp(_) => {
|
||||
match lhs_ty {
|
||||
Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
|
||||
TypeCtor::Int(..) | TypeCtor::Float(..) => lhs_ty,
|
||||
_ => Ty::Unknown,
|
||||
},
|
||||
Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty,
|
||||
_ => Ty::Unknown,
|
||||
},
|
||||
Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty,
|
||||
_ => Ty::Unknown,
|
||||
},
|
||||
_ => Ty::Unknown,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -102,10 +102,6 @@ pub enum BinOp {
|
||||
BitwiseOr,
|
||||
/// The `&` operator for bitwise AND
|
||||
BitwiseAnd,
|
||||
/// The `..` operator for right-open ranges
|
||||
RangeRightOpen,
|
||||
/// The `..=` operator for right-closed ranges
|
||||
RangeRightClosed,
|
||||
/// The `=` operator for assignment
|
||||
Assignment,
|
||||
/// The `+=` operator for assignment after addition
|
||||
@ -152,8 +148,6 @@ impl ast::BinExpr {
|
||||
T![^] => BinOp::BitwiseXor,
|
||||
T![|] => BinOp::BitwiseOr,
|
||||
T![&] => BinOp::BitwiseAnd,
|
||||
T![..] => BinOp::RangeRightOpen,
|
||||
T![..=] => BinOp::RangeRightClosed,
|
||||
T![=] => BinOp::Assignment,
|
||||
T![+=] => BinOp::AddAssign,
|
||||
T![/=] => BinOp::DivAssign,
|
||||
|
Loading…
Reference in New Issue
Block a user