aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/infer.rs
diff options
context:
space:
mode:
authorKirill Bulatov <[email protected]>2019-08-21 22:34:50 +0100
committerKirill Bulatov <[email protected]>2019-08-26 20:44:50 +0100
commit44386d5373114ffc88ef6bd182fb3b58a7c27e69 (patch)
tree19a1d277377ecf2ea9c5ca9232f019d20b53137d /crates/ra_hir/src/ty/infer.rs
parent89f3cc587d07a3cdcebf84cc4b99fe42636e66f0 (diff)
An attempt to add the coercion logic for Never
Diffstat (limited to 'crates/ra_hir/src/ty/infer.rs')
-rw-r--r--crates/ra_hir/src/ty/infer.rs91
1 files changed, 40 insertions, 51 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 3911695df..074baa8ef 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -296,9 +296,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
296 | (Ty::Infer(InferTy::IntVar(tv)), other) 296 | (Ty::Infer(InferTy::IntVar(tv)), other)
297 | (other, Ty::Infer(InferTy::IntVar(tv))) 297 | (other, Ty::Infer(InferTy::IntVar(tv)))
298 | (Ty::Infer(InferTy::FloatVar(tv)), other) 298 | (Ty::Infer(InferTy::FloatVar(tv)), other)
299 | (other, Ty::Infer(InferTy::FloatVar(tv))) 299 | (other, Ty::Infer(InferTy::FloatVar(tv))) => {
300 if !is_never(other) =>
301 {
302 // the type var is unknown since we tried to resolve it 300 // the type var is unknown since we tried to resolve it
303 self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); 301 self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone()));
304 true 302 true
@@ -977,27 +975,56 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
977 ret_ty 975 ret_ty
978 } 976 }
979 977
978 fn coerce(&mut self, tgt_expr: ExprId, ty1: Ty, ty2: Ty) -> Ty {
979 if is_never(&ty1) {
980 ty2
981 } else {
982 self.unify(&ty1, &ty2);
983 // TODO Fugly and looks like we need more, `infer_adt_pattern` and other fails
984 let ty = self.resolve_ty_as_possible(&mut vec![], ty1);
985 self.write_expr_ty(tgt_expr, ty.clone());
986 ty
987 }
988 }
989
980 fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { 990 fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
991 let ty = self.infer_expr_inner(tgt_expr, expected);
992 // use a new type variable if we got Ty::Unknown here
993 let ty = self.insert_type_vars_shallow(ty);
994 let could_unify = self.unify(&ty, &expected.ty);
995 let ty = self.resolve_ty_as_possible(&mut vec![], ty);
996 self.write_expr_ty(tgt_expr, ty.clone());
997 if !could_unify {
998 self.result.type_mismatches.insert(
999 tgt_expr,
1000 TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() },
1001 );
1002 }
1003 ty
1004 }
1005
1006 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
981 let body = Arc::clone(&self.body); // avoid borrow checker problem 1007 let body = Arc::clone(&self.body); // avoid borrow checker problem
982 let ty = match &body[tgt_expr] { 1008 match &body[tgt_expr] {
983 Expr::Missing => Ty::Unknown, 1009 Expr::Missing => Ty::Unknown,
984 Expr::If { condition, then_branch, else_branch } => { 1010 Expr::If { condition, then_branch, else_branch } => {
985 // if let is desugared to match, so this is always simple if 1011 // if let is desugared to match, so this is always simple if
986 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); 1012 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool)));
987 1013
988 let mut branch_tys = Vec::with_capacity(2); 1014 let then_ty = self.infer_expr_inner(*then_branch, &expected);
989 let then_ty = self.infer_expr(*then_branch, &expected); 1015 self.coerce(*then_branch, then_ty.clone(), expected.ty.clone());
990 match else_branch { 1016 match else_branch {
991 Some(else_branch) => { 1017 Some(else_branch) => {
992 branch_tys.push(self.infer_expr(*else_branch, &expected)); 1018 let else_ty = self.infer_expr_inner(*else_branch, &expected);
1019 self.coerce(*else_branch, else_ty, expected.ty.clone());
993 } 1020 }
994 None => { 1021 None => {
995 // no else branch -> unit 1022 // no else branch -> unit
996 self.unify(&then_ty, &Ty::unit()); // actually coerce 1023 self.unify(&then_ty, &Ty::unit()); // actually coerce
997 } 1024 }
998 }; 1025 };
999 branch_tys.push(then_ty); 1026
1000 calculate_least_upper_bound(expected.ty.clone(), branch_tys) 1027 expected.ty.clone()
1001 } 1028 }
1002 Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected), 1029 Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected),
1003 Expr::TryBlock { body } => { 1030 Expr::TryBlock { body } => {
@@ -1084,8 +1111,6 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1084 expected.clone() 1111 expected.clone()
1085 }; 1112 };
1086 1113
1087 let mut arm_tys = Vec::with_capacity(arms.len());
1088
1089 for arm in arms { 1114 for arm in arms {
1090 for &pat in &arm.pats { 1115 for &pat in &arm.pats {
1091 let _pat_ty = self.infer_pat(pat, &input_ty, BindingMode::default()); 1116 let _pat_ty = self.infer_pat(pat, &input_ty, BindingMode::default());
@@ -1096,9 +1121,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1096 &Expectation::has_type(Ty::simple(TypeCtor::Bool)), 1121 &Expectation::has_type(Ty::simple(TypeCtor::Bool)),
1097 ); 1122 );
1098 } 1123 }
1099 arm_tys.push(self.infer_expr(arm.expr, &expected)); 1124 let match_arm_ty = self.infer_expr_inner(arm.expr, &expected);
1125 self.coerce(arm.expr, match_arm_ty, expected.ty.clone());
1100 } 1126 }
1101 calculate_least_upper_bound(expected.ty.clone(), arm_tys) 1127
1128 expected.ty
1102 } 1129 }
1103 Expr::Path(p) => { 1130 Expr::Path(p) => {
1104 // FIXME this could be more efficient... 1131 // FIXME this could be more efficient...
@@ -1358,19 +1385,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1358 Literal::Int(_v, ty) => Ty::simple(TypeCtor::Int(*ty)), 1385 Literal::Int(_v, ty) => Ty::simple(TypeCtor::Int(*ty)),
1359 Literal::Float(_v, ty) => Ty::simple(TypeCtor::Float(*ty)), 1386 Literal::Float(_v, ty) => Ty::simple(TypeCtor::Float(*ty)),
1360 }, 1387 },
1361 };
1362 // use a new type variable if we got Ty::Unknown here
1363 let ty = self.insert_type_vars_shallow(ty);
1364 let could_unify = self.unify(&ty, &expected.ty);
1365 let ty = self.resolve_ty_as_possible(&mut vec![], ty);
1366 self.write_expr_ty(tgt_expr, ty.clone());
1367 if !could_unify {
1368 self.result.type_mismatches.insert(
1369 tgt_expr,
1370 TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() },
1371 );
1372 } 1388 }
1373 ty
1374 } 1389 }
1375 1390
1376 fn infer_block( 1391 fn infer_block(
@@ -1629,29 +1644,3 @@ fn is_never(ty: &Ty) -> bool {
1629 false 1644 false
1630 } 1645 }
1631} 1646}
1632
1633fn calculate_least_upper_bound(expected_ty: Ty, actual_tys: Vec<Ty>) -> Ty {
1634 let mut all_never = true;
1635 let mut last_never_ty = None;
1636 let mut least_upper_bound = expected_ty;
1637
1638 for actual_ty in actual_tys {
1639 if is_never(&actual_ty) {
1640 last_never_ty = Some(actual_ty);
1641 } else {
1642 all_never = false;
1643 least_upper_bound = match (&actual_ty, &least_upper_bound) {
1644 (_, Ty::Unknown)
1645 | (Ty::Infer(_), Ty::Infer(InferTy::TypeVar(_)))
1646 | (Ty::Apply(_), _) => actual_ty,
1647 _ => least_upper_bound,
1648 }
1649 }
1650 }
1651
1652 if all_never && last_never_ty.is_some() {
1653 last_never_ty.unwrap()
1654 } else {
1655 least_upper_bound
1656 }
1657}