aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r--crates/ra_hir/src/ty.rs85
1 files changed, 74 insertions, 11 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 23ee76f4e..e09279a68 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -529,7 +529,7 @@ struct InferenceContext<'a, D: HirDatabase> {
529 529
530// helper function that determines whether a binary operator 530// helper function that determines whether a binary operator
531// always returns a boolean 531// always returns a boolean
532fn is_boolean_operator(op: BinaryOp) -> bool { 532fn boolean_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty {
533 match op { 533 match op {
534 BinaryOp::BooleanOr 534 BinaryOp::BooleanOr
535 | BinaryOp::BooleanAnd 535 | BinaryOp::BooleanAnd
@@ -537,8 +537,32 @@ fn is_boolean_operator(op: BinaryOp) -> bool {
537 | BinaryOp::LesserEqualTest 537 | BinaryOp::LesserEqualTest
538 | BinaryOp::GreaterEqualTest 538 | BinaryOp::GreaterEqualTest
539 | BinaryOp::LesserTest 539 | BinaryOp::LesserTest
540 | BinaryOp::GreaterTest => true, 540 | BinaryOp::GreaterTest => Ty::Bool,
541 _ => false, 541 BinaryOp::Assignment
542 | BinaryOp::AddAssign
543 | BinaryOp::SubAssign
544 | BinaryOp::DivAssign
545 | BinaryOp::MulAssign
546 | BinaryOp::RemAssign
547 | BinaryOp::ShrAssign
548 | BinaryOp::ShlAssign
549 | BinaryOp::BitAndAssign
550 | BinaryOp::BitOrAssign
551 | BinaryOp::BitXorAssign => Ty::unit(),
552 BinaryOp::Addition
553 | BinaryOp::Subtraction
554 | BinaryOp::Multiplication
555 | BinaryOp::Division
556 | BinaryOp::Remainder
557 | BinaryOp::LeftShift
558 | BinaryOp::RightShift
559 | BinaryOp::BitwiseAnd
560 | BinaryOp::BitwiseOr
561 | BinaryOp::BitwiseXor => match rhs_ty {
562 Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) => rhs_ty,
563 _ => Ty::Unknown,
564 },
565 BinaryOp::RangeRightOpen | BinaryOp::RangeRightClosed => Ty::Unknown,
542 } 566 }
543} 567}
544 568
@@ -890,20 +914,59 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
890 } 914 }
891 Expr::BinaryOp { lhs, rhs, op } => match op { 915 Expr::BinaryOp { lhs, rhs, op } => match op {
892 Some(op) => { 916 Some(op) => {
893 let subtype_expectation = match op { 917 let lhs_expectation = match op {
894 BinaryOp::BooleanAnd | BinaryOp::BooleanOr => { 918 BinaryOp::BooleanAnd | BinaryOp::BooleanOr => {
895 Expectation::has_type(Ty::Bool) 919 Expectation::has_type(Ty::Bool)
896 } 920 }
897 _ => Expectation::none(), 921 _ => Expectation::none(),
898 }; 922 };
899 let _lhs_ty = self.infer_expr(*lhs, &subtype_expectation)?; 923 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation)?;
900 let _rhs_ty = self.infer_expr(*rhs, &subtype_expectation)?; 924 // TODO: find implementation of trait corresponding to operation
925 // symbol and resolve associated `Output` type
926 let rhs_expectation = match op {
927 BinaryOp::BooleanAnd | BinaryOp::BooleanOr => Ty::Bool,
928 BinaryOp::Assignment | BinaryOp::EqualityTest => match lhs_ty {
929 Ty::Uint(..)
930 | Ty::Int(..)
931 | Ty::Float(..)
932 | Ty::Str
933 | Ty::Char
934 | Ty::Bool => lhs_ty,
935 _ => Ty::Unknown,
936 },
937 BinaryOp::LesserEqualTest
938 | BinaryOp::GreaterEqualTest
939 | BinaryOp::LesserTest
940 | BinaryOp::GreaterTest
941 | BinaryOp::AddAssign
942 | BinaryOp::SubAssign
943 | BinaryOp::DivAssign
944 | BinaryOp::MulAssign
945 | BinaryOp::RemAssign
946 | BinaryOp::ShrAssign
947 | BinaryOp::ShlAssign
948 | BinaryOp::BitAndAssign
949 | BinaryOp::BitOrAssign
950 | BinaryOp::BitXorAssign
951 | BinaryOp::Addition
952 | BinaryOp::Subtraction
953 | BinaryOp::Multiplication
954 | BinaryOp::Division
955 | BinaryOp::Remainder
956 | BinaryOp::LeftShift
957 | BinaryOp::RightShift
958 | BinaryOp::BitwiseAnd
959 | BinaryOp::BitwiseOr
960 | BinaryOp::BitwiseXor => match lhs_ty {
961 Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) => lhs_ty,
962 _ => Ty::Unknown,
963 },
964 _ => Ty::Unknown,
965 };
966 let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation))?;
901 967
902 if is_boolean_operator(*op) { 968 // TODO: similar as above, return ty is often associated trait type
903 Ty::Bool 969 boolean_op_return_ty(*op, rhs_ty)
904 } else {
905 Ty::Unknown
906 }
907 } 970 }
908 _ => Ty::Unknown, 971 _ => Ty::Unknown,
909 }, 972 },