diff options
author | Marcus Klaas de Vries <[email protected]> | 2019-01-07 19:39:23 +0000 |
---|---|---|
committer | Marcus Klaas de Vries <[email protected]> | 2019-01-07 19:39:23 +0000 |
commit | 5d15dd70b037b3d1623ebd83d8ef0f66ad6950af (patch) | |
tree | f4e1936de76bee89502613ce038f4ecaef19ec4b /crates/ra_hir/src/ty.rs | |
parent | 7b0eaef58072acc087d23faca5a9f9879f1765d5 (diff) |
Tidy up binary operator type inference; add test file
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 85 |
1 files changed, 41 insertions, 44 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index e09279a68..7827e82c4 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -527,9 +527,7 @@ struct InferenceContext<'a, D: HirDatabase> { | |||
527 | return_ty: Ty, | 527 | return_ty: Ty, |
528 | } | 528 | } |
529 | 529 | ||
530 | // helper function that determines whether a binary operator | 530 | fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty { |
531 | // always returns a boolean | ||
532 | fn boolean_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty { | ||
533 | match op { | 531 | match op { |
534 | BinaryOp::BooleanOr | 532 | BinaryOp::BooleanOr |
535 | | BinaryOp::BooleanAnd | 533 | | BinaryOp::BooleanAnd |
@@ -566,6 +564,44 @@ fn boolean_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty { | |||
566 | } | 564 | } |
567 | } | 565 | } |
568 | 566 | ||
567 | fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { | ||
568 | match op { | ||
569 | BinaryOp::BooleanAnd | BinaryOp::BooleanOr => Ty::Bool, | ||
570 | BinaryOp::Assignment | BinaryOp::EqualityTest => match lhs_ty { | ||
571 | Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) | Ty::Str | Ty::Char | Ty::Bool => lhs_ty, | ||
572 | _ => Ty::Unknown, | ||
573 | }, | ||
574 | BinaryOp::LesserEqualTest | ||
575 | | BinaryOp::GreaterEqualTest | ||
576 | | BinaryOp::LesserTest | ||
577 | | BinaryOp::GreaterTest | ||
578 | | BinaryOp::AddAssign | ||
579 | | BinaryOp::SubAssign | ||
580 | | BinaryOp::DivAssign | ||
581 | | BinaryOp::MulAssign | ||
582 | | BinaryOp::RemAssign | ||
583 | | BinaryOp::ShrAssign | ||
584 | | BinaryOp::ShlAssign | ||
585 | | BinaryOp::BitAndAssign | ||
586 | | BinaryOp::BitOrAssign | ||
587 | | BinaryOp::BitXorAssign | ||
588 | | BinaryOp::Addition | ||
589 | | BinaryOp::Subtraction | ||
590 | | BinaryOp::Multiplication | ||
591 | | BinaryOp::Division | ||
592 | | BinaryOp::Remainder | ||
593 | | BinaryOp::LeftShift | ||
594 | | BinaryOp::RightShift | ||
595 | | BinaryOp::BitwiseAnd | ||
596 | | BinaryOp::BitwiseOr | ||
597 | | BinaryOp::BitwiseXor => match lhs_ty { | ||
598 | Ty::Uint(..) | Ty::Int(..) | Ty::Float(..) => lhs_ty, | ||
599 | _ => Ty::Unknown, | ||
600 | }, | ||
601 | _ => Ty::Unknown, | ||
602 | } | ||
603 | } | ||
604 | |||
569 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 605 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { |
570 | fn new( | 606 | fn new( |
571 | db: &'a D, | 607 | db: &'a D, |
@@ -923,50 +959,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
923 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation)?; | 959 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation)?; |
924 | // TODO: find implementation of trait corresponding to operation | 960 | // TODO: find implementation of trait corresponding to operation |
925 | // symbol and resolve associated `Output` type | 961 | // symbol and resolve associated `Output` type |
926 | let rhs_expectation = match op { | 962 | let rhs_expectation = binary_op_rhs_expectation(*op, lhs_ty); |
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))?; | 963 | let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation))?; |
967 | 964 | ||
968 | // TODO: similar as above, return ty is often associated trait type | 965 | // TODO: similar as above, return ty is often associated trait type |
969 | boolean_op_return_ty(*op, rhs_ty) | 966 | binary_op_return_ty(*op, rhs_ty) |
970 | } | 967 | } |
971 | _ => Ty::Unknown, | 968 | _ => Ty::Unknown, |
972 | }, | 969 | }, |