aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-08-17 15:42:41 +0100
committerAleksey Kladov <[email protected]>2019-08-17 15:42:41 +0100
commit7e5a186c1fe585aac95019addc963bf74cb112ae (patch)
tree3ece58abec006c824f38e8470f67229bc7c6acdd /crates/ra_hir/src
parent8919aa8065c31d55050a6bfe10b574fc71bcec09 (diff)
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.
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/expr.rs77
-rw-r--r--crates/ra_hir/src/ty/infer.rs4
-rw-r--r--crates/ra_hir/src/ty/op.rs84
3 files changed, 96 insertions, 69 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index f33676655..ea3fa4417 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -257,7 +257,44 @@ pub enum Expr {
257 Literal(Literal), 257 Literal(Literal),
258} 258}
259 259
260pub use ra_syntax::ast::BinOp as BinaryOp; 260#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
261pub enum BinaryOp {
262 LogicOp(LogicOp),
263 ArithOp(ArithOp),
264 CmpOp(CmpOp),
265 Assignment { op: Option<ArithOp> },
266}
267
268#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
269pub enum LogicOp {
270 And,
271 Or,
272}
273
274#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
275pub enum CmpOp {
276 Equal,
277 NotEqual,
278 Less,
279 LessOrEqual,
280 Greater,
281 GreaterOrEqual,
282}
283
284#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
285pub enum ArithOp {
286 Add,
287 Mul,
288 Sub,
289 Div,
290 Rem,
291 Shl,
292 Shr,
293 BitXor,
294 BitOr,
295 BitAnd,
296}
297
261pub use ra_syntax::ast::PrefixOp as UnaryOp; 298pub use ra_syntax::ast::PrefixOp as UnaryOp;
262#[derive(Debug, Clone, Eq, PartialEq)] 299#[derive(Debug, Clone, Eq, PartialEq)]
263pub enum Array { 300pub enum Array {
@@ -791,7 +828,7 @@ where
791 ast::ExprKind::BinExpr(e) => { 828 ast::ExprKind::BinExpr(e) => {
792 let lhs = self.collect_expr_opt(e.lhs()); 829 let lhs = self.collect_expr_opt(e.lhs());
793 let rhs = self.collect_expr_opt(e.rhs()); 830 let rhs = self.collect_expr_opt(e.rhs());
794 let op = e.op_kind(); 831 let op = e.op_kind().map(BinaryOp::from);
795 self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr) 832 self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr)
796 } 833 }
797 ast::ExprKind::TupleExpr(e) => { 834 ast::ExprKind::TupleExpr(e) => {
@@ -1038,6 +1075,42 @@ where
1038 } 1075 }
1039} 1076}
1040 1077
1078impl From<ast::BinOp> for BinaryOp {
1079 fn from(ast_op: ast::BinOp) -> Self {
1080 match ast_op {
1081 ast::BinOp::BooleanOr => BinaryOp::LogicOp(LogicOp::Or),
1082 ast::BinOp::BooleanAnd => BinaryOp::LogicOp(LogicOp::And),
1083 ast::BinOp::EqualityTest => BinaryOp::CmpOp(CmpOp::Equal),
1084 ast::BinOp::NegatedEqualityTest => BinaryOp::CmpOp(CmpOp::NotEqual),
1085 ast::BinOp::LesserEqualTest => BinaryOp::CmpOp(CmpOp::LessOrEqual),
1086 ast::BinOp::GreaterEqualTest => BinaryOp::CmpOp(CmpOp::GreaterOrEqual),
1087 ast::BinOp::LesserTest => BinaryOp::CmpOp(CmpOp::Less),
1088 ast::BinOp::GreaterTest => BinaryOp::CmpOp(CmpOp::Greater),
1089 ast::BinOp::Addition => BinaryOp::ArithOp(ArithOp::Add),
1090 ast::BinOp::Multiplication => BinaryOp::ArithOp(ArithOp::Mul),
1091 ast::BinOp::Subtraction => BinaryOp::ArithOp(ArithOp::Sub),
1092 ast::BinOp::Division => BinaryOp::ArithOp(ArithOp::Div),
1093 ast::BinOp::Remainder => BinaryOp::ArithOp(ArithOp::Rem),
1094 ast::BinOp::LeftShift => BinaryOp::ArithOp(ArithOp::Shl),
1095 ast::BinOp::RightShift => BinaryOp::ArithOp(ArithOp::Shr),
1096 ast::BinOp::BitwiseXor => BinaryOp::ArithOp(ArithOp::BitXor),
1097 ast::BinOp::BitwiseOr => BinaryOp::ArithOp(ArithOp::BitOr),
1098 ast::BinOp::BitwiseAnd => BinaryOp::ArithOp(ArithOp::BitAnd),
1099 ast::BinOp::Assignment => BinaryOp::Assignment { op: None },
1100 ast::BinOp::AddAssign => BinaryOp::Assignment { op: Some(ArithOp::Add) },
1101 ast::BinOp::DivAssign => BinaryOp::Assignment { op: Some(ArithOp::Div) },
1102 ast::BinOp::MulAssign => BinaryOp::Assignment { op: Some(ArithOp::Mul) },
1103 ast::BinOp::RemAssign => BinaryOp::Assignment { op: Some(ArithOp::Rem) },
1104 ast::BinOp::ShlAssign => BinaryOp::Assignment { op: Some(ArithOp::Shl) },
1105 ast::BinOp::ShrAssign => BinaryOp::Assignment { op: Some(ArithOp::Shr) },
1106 ast::BinOp::SubAssign => BinaryOp::Assignment { op: Some(ArithOp::Sub) },
1107 ast::BinOp::BitOrAssign => BinaryOp::Assignment { op: Some(ArithOp::BitOr) },
1108 ast::BinOp::BitAndAssign => BinaryOp::Assignment { op: Some(ArithOp::BitAnd) },
1109 ast::BinOp::BitXorAssign => BinaryOp::Assignment { op: Some(ArithOp::BitXor) },
1110 }
1111 }
1112}
1113
1041pub(crate) fn body_with_source_map_query( 1114pub(crate) fn body_with_source_map_query(
1042 db: &impl HirDatabase, 1115 db: &impl HirDatabase,
1043 def: DefWithBody, 1116 def: DefWithBody,
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 675df4a22..33bfd0952 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -1265,9 +1265,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1265 Expr::BinaryOp { lhs, rhs, op } => match op { 1265 Expr::BinaryOp { lhs, rhs, op } => match op {
1266 Some(op) => { 1266 Some(op) => {
1267 let lhs_expectation = match op { 1267 let lhs_expectation = match op {
1268 BinaryOp::BooleanAnd | BinaryOp::BooleanOr => { 1268 BinaryOp::LogicOp(..) => Expectation::has_type(Ty::simple(TypeCtor::Bool)),
1269 Expectation::has_type(Ty::simple(TypeCtor::Bool))
1270 }
1271 _ => Expectation::none(), 1269 _ => Expectation::none(),
1272 }; 1270 };
1273 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); 1271 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
diff --git a/crates/ra_hir/src/ty/op.rs b/crates/ra_hir/src/ty/op.rs
index 9ba868298..1d089f1b0 100644
--- a/crates/ra_hir/src/ty/op.rs
+++ b/crates/ra_hir/src/ty/op.rs
@@ -1,37 +1,14 @@
1use super::{InferTy, Ty, TypeCtor}; 1use super::{InferTy, Ty, TypeCtor};
2use crate::{expr::BinaryOp, ty::ApplicationTy}; 2use crate::{
3 expr::{BinaryOp, CmpOp},
4 ty::ApplicationTy,
5};
3 6
4pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty { 7pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty {
5 match op { 8 match op {
6 BinaryOp::BooleanOr 9 BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::simple(TypeCtor::Bool),
7 | BinaryOp::BooleanAnd 10 BinaryOp::Assignment { .. } => Ty::unit(),
8 | BinaryOp::EqualityTest 11 BinaryOp::ArithOp(_) => match rhs_ty {
9 | BinaryOp::NegatedEqualityTest
10 | BinaryOp::LesserEqualTest
11 | BinaryOp::GreaterEqualTest
12 | BinaryOp::LesserTest
13 | BinaryOp::GreaterTest => Ty::simple(TypeCtor::Bool),
14 BinaryOp::Assignment
15 | BinaryOp::AddAssign
16 | BinaryOp::SubAssign
17 | BinaryOp::DivAssign
18 | BinaryOp::MulAssign
19 | BinaryOp::RemAssign
20 | BinaryOp::ShrAssign
21 | BinaryOp::ShlAssign
22 | BinaryOp::BitAndAssign
23 | BinaryOp::BitOrAssign
24 | BinaryOp::BitXorAssign => Ty::unit(),
25 BinaryOp::Addition
26 | BinaryOp::Subtraction
27 | BinaryOp::Multiplication
28 | BinaryOp::Division
29 | BinaryOp::Remainder
30 | BinaryOp::LeftShift
31 | BinaryOp::RightShift
32 | BinaryOp::BitwiseAnd
33 | BinaryOp::BitwiseOr
34 | BinaryOp::BitwiseXor => match rhs_ty {
35 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { 12 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
36 TypeCtor::Int(..) | TypeCtor::Float(..) => rhs_ty, 13 TypeCtor::Int(..) | TypeCtor::Float(..) => rhs_ty,
37 _ => Ty::Unknown, 14 _ => Ty::Unknown,
@@ -39,14 +16,15 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty {
39 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => rhs_ty, 16 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => rhs_ty,
40 _ => Ty::Unknown, 17 _ => Ty::Unknown,
41 }, 18 },
42 BinaryOp::RangeRightOpen | BinaryOp::RangeRightClosed => Ty::Unknown,
43 } 19 }
44} 20}
45 21
46pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { 22pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
47 match op { 23 match op {
48 BinaryOp::BooleanAnd | BinaryOp::BooleanOr => Ty::simple(TypeCtor::Bool), 24 BinaryOp::LogicOp(..) => Ty::simple(TypeCtor::Bool),
49 BinaryOp::Assignment | BinaryOp::EqualityTest => match lhs_ty { 25 BinaryOp::Assignment { op: None }
26 | BinaryOp::CmpOp(CmpOp::Equal)
27 | BinaryOp::CmpOp(CmpOp::NotEqual) => match lhs_ty {
50 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { 28 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
51 TypeCtor::Int(..) 29 TypeCtor::Int(..)
52 | TypeCtor::Float(..) 30 | TypeCtor::Float(..)
@@ -58,37 +36,15 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
58 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, 36 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty,
59 _ => Ty::Unknown, 37 _ => Ty::Unknown,
60 }, 38 },
61 BinaryOp::LesserEqualTest 39 BinaryOp::CmpOp(_) | BinaryOp::Assignment { op: Some(_) } | BinaryOp::ArithOp(_) => {
62 | BinaryOp::GreaterEqualTest 40 match lhs_ty {
63 | BinaryOp::LesserTest 41 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
64 | BinaryOp::GreaterTest 42 TypeCtor::Int(..) | TypeCtor::Float(..) => lhs_ty,
65 | BinaryOp::AddAssign 43 _ => Ty::Unknown,
66 | BinaryOp::SubAssign 44 },
67 | BinaryOp::DivAssign 45 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty,
68 | BinaryOp::MulAssign
69 | BinaryOp::RemAssign
70 | BinaryOp::ShrAssign
71 | BinaryOp::ShlAssign
72 | BinaryOp::BitAndAssign
73 | BinaryOp::BitOrAssign
74 | BinaryOp::BitXorAssign
75 | BinaryOp::Addition
76 | BinaryOp::Subtraction
77 | BinaryOp::Multiplication
78 | BinaryOp::Division
79 | BinaryOp::Remainder
80 | BinaryOp::LeftShift
81 | BinaryOp::RightShift
82 | BinaryOp::BitwiseAnd
83 | BinaryOp::BitwiseOr
84 | BinaryOp::BitwiseXor => match lhs_ty {
85 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
86 TypeCtor::Int(..) | TypeCtor::Float(..) => lhs_ty,
87 _ => Ty::Unknown, 46 _ => Ty::Unknown,
88 }, 47 }
89 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, 48 }
90 _ => Ty::Unknown,
91 },
92 _ => Ty::Unknown,
93 } 49 }
94} 50}