aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/infer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty/infer.rs')
-rw-r--r--crates/ra_hir/src/ty/infer.rs105
1 files changed, 82 insertions, 23 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index d94e8154b..812990426 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -280,8 +280,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
280 let ty1 = self.resolve_ty_shallow(ty1); 280 let ty1 = self.resolve_ty_shallow(ty1);
281 let ty2 = self.resolve_ty_shallow(ty2); 281 let ty2 = self.resolve_ty_shallow(ty2);
282 match (&*ty1, &*ty2) { 282 match (&*ty1, &*ty2) {
283 (Ty::Unknown, ..) => true, 283 (Ty::Unknown, _) | (_, Ty::Unknown) => true,
284 (.., Ty::Unknown) => true,
285 (Ty::Apply(a_ty1), Ty::Apply(a_ty2)) if a_ty1.ctor == a_ty2.ctor => { 284 (Ty::Apply(a_ty1), Ty::Apply(a_ty2)) if a_ty1.ctor == a_ty2.ctor => {
286 self.unify_substs(&a_ty1.parameters, &a_ty2.parameters, depth + 1) 285 self.unify_substs(&a_ty1.parameters, &a_ty2.parameters, depth + 1)
287 } 286 }
@@ -976,24 +975,48 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
976 ret_ty 975 ret_ty
977 } 976 }
978 977
978 /// This is similar to unify, but it makes the first type coerce to the
979 /// second one.
980 fn coerce(&mut self, from_ty: &Ty, to_ty: &Ty) -> bool {
981 if is_never(from_ty) {
982 // ! coerces to any type
983 true
984 } else {
985 self.unify(from_ty, to_ty)
986 }
987 }
988
979 fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { 989 fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
990 let ty = self.infer_expr_inner(tgt_expr, expected);
991 let could_unify = self.unify(&ty, &expected.ty);
992 if !could_unify {
993 self.result.type_mismatches.insert(
994 tgt_expr,
995 TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() },
996 );
997 }
998 let ty = self.resolve_ty_as_possible(&mut vec![], ty);
999 ty
1000 }
1001
1002 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
980 let body = Arc::clone(&self.body); // avoid borrow checker problem 1003 let body = Arc::clone(&self.body); // avoid borrow checker problem
981 let ty = match &body[tgt_expr] { 1004 let ty = match &body[tgt_expr] {
982 Expr::Missing => Ty::Unknown, 1005 Expr::Missing => Ty::Unknown,
983 Expr::If { condition, then_branch, else_branch } => { 1006 Expr::If { condition, then_branch, else_branch } => {
984 // if let is desugared to match, so this is always simple if 1007 // if let is desugared to match, so this is always simple if
985 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); 1008 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool)));
986 let then_ty = self.infer_expr(*then_branch, expected); 1009
987 match else_branch { 1010 let then_ty = self.infer_expr_inner(*then_branch, &expected);
988 Some(else_branch) => { 1011 self.coerce(&then_ty, &expected.ty);
989 self.infer_expr(*else_branch, expected); 1012
990 } 1013 let else_ty = match else_branch {
991 None => { 1014 Some(else_branch) => self.infer_expr_inner(*else_branch, &expected),
992 // no else branch -> unit 1015 None => Ty::unit(),
993 self.unify(&then_ty, &Ty::unit()); // actually coerce
994 }
995 }; 1016 };
996 then_ty 1017 self.coerce(&else_ty, &expected.ty);
1018
1019 expected.ty.clone()
997 } 1020 }
998 Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected), 1021 Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected),
999 Expr::TryBlock { body } => { 1022 Expr::TryBlock { body } => {
@@ -1073,12 +1096,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1073 Expr::MethodCall { receiver, args, method_name, generic_args } => self 1096 Expr::MethodCall { receiver, args, method_name, generic_args } => self
1074 .infer_method_call(tgt_expr, *receiver, &args, &method_name, generic_args.as_ref()), 1097 .infer_method_call(tgt_expr, *receiver, &args, &method_name, generic_args.as_ref()),
1075 Expr::Match { expr, arms } => { 1098 Expr::Match { expr, arms } => {
1099 let input_ty = self.infer_expr(*expr, &Expectation::none());
1076 let expected = if expected.ty == Ty::Unknown { 1100 let expected = if expected.ty == Ty::Unknown {
1077 Expectation::has_type(self.new_type_var()) 1101 Expectation::has_type(self.new_type_var())
1078 } else { 1102 } else {
1079 expected.clone() 1103 expected.clone()
1080 }; 1104 };
1081 let input_ty = self.infer_expr(*expr, &Expectation::none()); 1105
1106 let mut arm_tys = Vec::with_capacity(arms.len());
1082 1107
1083 for arm in arms { 1108 for arm in arms {
1084 for &pat in &arm.pats { 1109 for &pat in &arm.pats {
@@ -1090,10 +1115,16 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1090 &Expectation::has_type(Ty::simple(TypeCtor::Bool)), 1115 &Expectation::has_type(Ty::simple(TypeCtor::Bool)),
1091 ); 1116 );
1092 } 1117 }
1093 self.infer_expr(arm.expr, &expected); 1118 arm_tys.push(self.infer_expr_inner(arm.expr, &expected));
1119 }
1120
1121 let lub_ty = calculate_least_upper_bound(expected.ty.clone(), &arm_tys);
1122
1123 for arm_ty in &arm_tys {
1124 self.coerce(arm_ty, &lub_ty);
1094 } 1125 }
1095 1126
1096 expected.ty 1127 lub_ty
1097 } 1128 }
1098 Expr::Path(p) => { 1129 Expr::Path(p) => {
1099 // FIXME this could be more efficient... 1130 // FIXME this could be more efficient...
@@ -1356,15 +1387,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1356 }; 1387 };
1357 // use a new type variable if we got Ty::Unknown here 1388 // use a new type variable if we got Ty::Unknown here
1358 let ty = self.insert_type_vars_shallow(ty); 1389 let ty = self.insert_type_vars_shallow(ty);
1359 let could_unify = self.unify(&ty, &expected.ty);
1360 let ty = self.resolve_ty_as_possible(&mut vec![], ty); 1390 let ty = self.resolve_ty_as_possible(&mut vec![], ty);
1361 self.write_expr_ty(tgt_expr, ty.clone()); 1391 self.write_expr_ty(tgt_expr, ty.clone());
1362 if !could_unify {
1363 self.result.type_mismatches.insert(
1364 tgt_expr,
1365 TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() },
1366 );
1367 }
1368 ty 1392 ty
1369 } 1393 }
1370 1394
@@ -1394,7 +1418,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1394 } 1418 }
1395 } 1419 }
1396 } 1420 }
1397 let ty = if let Some(expr) = tail { self.infer_expr(expr, expected) } else { Ty::unit() }; 1421 let ty =
1422 if let Some(expr) = tail { self.infer_expr_inner(expr, expected) } else { Ty::unit() };
1398 ty 1423 ty
1399 } 1424 }
1400 1425
@@ -1616,3 +1641,37 @@ mod diagnostics {
1616 } 1641 }
1617 } 1642 }
1618} 1643}
1644
1645fn is_never(ty: &Ty) -> bool {
1646 if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. }) = ty {
1647 true
1648 } else {
1649 false
1650 }
1651}
1652
1653fn calculate_least_upper_bound(expected_ty: Ty, actual_tys: &[Ty]) -> Ty {
1654 let mut all_never = true;
1655 let mut last_never_ty = None;
1656 let mut least_upper_bound = expected_ty;
1657
1658 for actual_ty in actual_tys {
1659 if is_never(actual_ty) {
1660 last_never_ty = Some(actual_ty.clone());
1661 } else {
1662 all_never = false;
1663 least_upper_bound = match (actual_ty, &least_upper_bound) {
1664 (_, Ty::Unknown)
1665 | (Ty::Infer(_), Ty::Infer(InferTy::TypeVar(_)))
1666 | (Ty::Apply(_), _) => actual_ty.clone(),
1667 _ => least_upper_bound,
1668 }
1669 }
1670 }
1671
1672 if all_never && last_never_ty.is_some() {
1673 last_never_ty.unwrap()
1674 } else {
1675 least_upper_bound
1676 }
1677}