aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty.rs
diff options
context:
space:
mode:
authorMarcus Klaas de Vries <[email protected]>2019-01-06 20:39:36 +0000
committerMarcus Klaas de Vries <[email protected]>2019-01-06 21:17:54 +0000
commit82d9a77dade454ee8d09f198fa839e7755ff7bfb (patch)
tree791b3c0ee6069a06896c815795ff7e86877887df /crates/ra_hir/src/ty.rs
parent4fc233a02e8dc07619a969400c445ec47c2b1a9d (diff)
Touch up type inference for boolean operators
Also try to infer its subexpressions and set type expectations whenever possible.
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r--crates/ra_hir/src/ty.rs36
1 files changed, 29 insertions, 7 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 718e193f7..8f56cdb15 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -526,6 +526,20 @@ struct InferenceContext<'a, D: HirDatabase> {
526 return_ty: Ty, 526 return_ty: Ty,
527} 527}
528 528
529// helper function that determines whether a binary operator
530// always returns a boolean
531fn is_boolean_operator(op: BinOp) -> bool {
532 match op {
533 BinOp::BooleanOr
534 | BinOp::BooleanAnd
535 | BinOp::EqualityTest
536 | BinOp::LesserEqualTest
537 | BinOp::GreaterEqualTest
538 | BinOp::LesserTest
539 | BinOp::GreaterTest => true,
540 }
541}
542
529impl<'a, D: HirDatabase> InferenceContext<'a, D> { 543impl<'a, D: HirDatabase> InferenceContext<'a, D> {
530 fn new( 544 fn new(
531 db: &'a D, 545 db: &'a D,
@@ -907,13 +921,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
907 } 921 }
908 ast::Expr::RangeExpr(_e) => Ty::Unknown, 922 ast::Expr::RangeExpr(_e) => Ty::Unknown,
909 ast::Expr::BinExpr(e) => match e.op() { 923 ast::Expr::BinExpr(e) => match e.op() {
910 Some(BinOp::BooleanOr) 924 Some(op) => {
911 | Some(BinOp::BooleanAnd) 925 let subtype_expectation = match op {
912 | Some(BinOp::EqualityTest) 926 BinOp::BooleanAnd | BinOp::BooleanOr => Expectation::has_type(Ty::Bool),
913 | Some(BinOp::LesserEqualTest) 927 _ => Expectation::none(),
914 | Some(BinOp::GreaterEqualTest) 928 };
915 | Some(BinOp::LesserTest) 929 let (lhs, rhs) = e.sub_exprs();
916 | Some(BinOp::GreaterTest) => Ty::Bool, 930 let _lhs_ty = self.infer_expr_opt(lhs, &subtype_expectation)?;
931 let _rhs_ty = self.infer_expr_opt(rhs, &subtype_expectation)?;
932
933 if is_boolean_operator(op) {
934 Ty::Bool
935 } else {
936 Ty::Unknown
937 }
938 }
917 _ => Ty::Unknown, 939 _ => Ty::Unknown,
918 }, 940 },
919 ast::Expr::Literal(_e) => Ty::Unknown, 941 ast::Expr::Literal(_e) => Ty::Unknown,