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.rs72
1 files changed, 50 insertions, 22 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 453520bbe..7203a8a10 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -879,11 +879,22 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
879 ty 879 ty
880 } 880 }
881 881
882 fn unify_substs(&mut self, substs1: &Substs, substs2: &Substs) -> bool { 882 fn unify_substs(&mut self, substs1: &Substs, substs2: &Substs, depth: usize) -> bool {
883 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify(t1, t2)) 883 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth))
884 } 884 }
885 885
886 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { 886 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
887 self.unify_inner(ty1, ty2, 0)
888 }
889
890 fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool {
891 if depth > 1000 {
892 // prevent stackoverflows
893 panic!("infinite recursion in unification");
894 }
895 if ty1 == ty2 {
896 return true;
897 }
887 // try to resolve type vars first 898 // try to resolve type vars first
888 let ty1 = self.resolve_ty_shallow(ty1); 899 let ty1 = self.resolve_ty_shallow(ty1);
889 let ty2 = self.resolve_ty_shallow(ty2); 900 let ty2 = self.resolve_ty_shallow(ty2);
@@ -904,13 +915,15 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
904 ( 915 (
905 Ty::Adt { def_id: def_id1, substs: substs1, .. }, 916 Ty::Adt { def_id: def_id1, substs: substs1, .. },
906 Ty::Adt { def_id: def_id2, substs: substs2, .. }, 917 Ty::Adt { def_id: def_id2, substs: substs2, .. },
907 ) if def_id1 == def_id2 => self.unify_substs(substs1, substs2), 918 ) if def_id1 == def_id2 => self.unify_substs(substs1, substs2, depth + 1),
908 (Ty::Slice(t1), Ty::Slice(t2)) => self.unify(t1, t2), 919 (Ty::Slice(t1), Ty::Slice(t2)) => self.unify_inner(t1, t2, depth + 1),
909 (Ty::RawPtr(t1, m1), Ty::RawPtr(t2, m2)) if m1 == m2 => self.unify(t1, t2), 920 (Ty::RawPtr(t1, m1), Ty::RawPtr(t2, m2)) if m1 == m2 => {
910 (Ty::Ref(t1, m1), Ty::Ref(t2, m2)) if m1 == m2 => self.unify(t1, t2), 921 self.unify_inner(t1, t2, depth + 1)
922 }
923 (Ty::Ref(t1, m1), Ty::Ref(t2, m2)) if m1 == m2 => self.unify_inner(t1, t2, depth + 1),
911 (Ty::FnPtr(sig1), Ty::FnPtr(sig2)) if sig1 == sig2 => true, 924 (Ty::FnPtr(sig1), Ty::FnPtr(sig2)) if sig1 == sig2 => true,
912 (Ty::Tuple(ts1), Ty::Tuple(ts2)) if ts1.len() == ts2.len() => { 925 (Ty::Tuple(ts1), Ty::Tuple(ts2)) if ts1.len() == ts2.len() => {
913 ts1.iter().zip(ts2.iter()).all(|(t1, t2)| self.unify(t1, t2)) 926 ts1.iter().zip(ts2.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth + 1))
914 } 927 }
915 (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) 928 (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2)))
916 | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) 929 | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2)))
@@ -989,19 +1002,30 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
989 /// If `ty` is a type variable with known type, returns that type; 1002 /// If `ty` is a type variable with known type, returns that type;
990 /// otherwise, return ty. 1003 /// otherwise, return ty.
991 fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> { 1004 fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> {
992 match ty { 1005 let mut ty = Cow::Borrowed(ty);
993 Ty::Infer(tv) => { 1006 // The type variable could resolve to a int/float variable. Hence try
994 let inner = tv.to_inner(); 1007 // resolving up to three times; each type of variable shouldn't occur
995 match self.var_unification_table.probe_value(inner).known() { 1008 // more than once
996 Some(known_ty) => { 1009 for i in 0..3 {
997 // The known_ty can't be a type var itself 1010 if i > 0 {
998 Cow::Owned(known_ty.clone()) 1011 tested_by!(type_var_resolves_to_int_var);
1012 }
1013 match &*ty {
1014 Ty::Infer(tv) => {
1015 let inner = tv.to_inner();
1016 match self.var_unification_table.probe_value(inner).known() {
1017 Some(known_ty) => {
1018 // The known_ty can't be a type var itself
1019 ty = Cow::Owned(known_ty.clone());
1020 }
1021 _ => return ty,
999 } 1022 }
1000 _ => Cow::Borrowed(ty),
1001 } 1023 }
1024 _ => return ty,
1002 } 1025 }
1003 _ => Cow::Borrowed(ty),
1004 } 1026 }
1027 log::error!("Inference variable still not resolved: {:?}", ty);
1028 ty
1005 } 1029 }
1006 1030
1007 /// Resolves the type completely; type variables without known type are 1031 /// Resolves the type completely; type variables without known type are
@@ -1185,17 +1209,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1185 self.infer_path_expr(&resolver, &path).unwrap_or(Ty::Unknown) 1209 self.infer_path_expr(&resolver, &path).unwrap_or(Ty::Unknown)
1186 } 1210 }
1187 Pat::Bind { mode, name: _name, subpat } => { 1211 Pat::Bind { mode, name: _name, subpat } => {
1188 let subty = if let Some(subpat) = subpat { 1212 let inner_ty = if let Some(subpat) = subpat {
1189 self.infer_pat(*subpat, expected) 1213 self.infer_pat(*subpat, expected)
1190 } else { 1214 } else {
1191 expected.clone() 1215 expected.clone()
1192 }; 1216 };
1217 let inner_ty = self.insert_type_vars_shallow(inner_ty);
1193 1218
1194 match mode { 1219 let bound_ty = match mode {
1195 BindingAnnotation::Ref => Ty::Ref(subty.into(), Mutability::Shared), 1220 BindingAnnotation::Ref => Ty::Ref(inner_ty.clone().into(), Mutability::Shared),
1196 BindingAnnotation::RefMut => Ty::Ref(subty.into(), Mutability::Mut), 1221 BindingAnnotation::RefMut => Ty::Ref(inner_ty.clone().into(), Mutability::Mut),
1197 BindingAnnotation::Mutable | BindingAnnotation::Unannotated => subty, 1222 BindingAnnotation::Mutable | BindingAnnotation::Unannotated => inner_ty.clone(),
1198 } 1223 };
1224 let bound_ty = self.resolve_ty_as_possible(&mut vec![], bound_ty);
1225 self.write_pat_ty(pat, bound_ty);
1226 return inner_ty;
1199 } 1227 }
1200 _ => Ty::Unknown, 1228 _ => Ty::Unknown,
1201 }; 1229 };