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.rs39
1 files changed, 24 insertions, 15 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 453520bbe..28cb32ac5 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -989,19 +989,24 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
989 /// If `ty` is a type variable with known type, returns that type; 989 /// If `ty` is a type variable with known type, returns that type;
990 /// otherwise, return ty. 990 /// otherwise, return ty.
991 fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> { 991 fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> {
992 match ty { 992 let mut ty = Cow::Borrowed(ty);
993 Ty::Infer(tv) => { 993 for _ in 0..3 {
994 let inner = tv.to_inner(); 994 // the type variable could resolve to a int/float variable
995 match self.var_unification_table.probe_value(inner).known() { 995 match &*ty {
996 Some(known_ty) => { 996 Ty::Infer(tv) => {
997 // The known_ty can't be a type var itself 997 let inner = tv.to_inner();
998 Cow::Owned(known_ty.clone()) 998 match self.var_unification_table.probe_value(inner).known() {
999 Some(known_ty) => {
1000 // The known_ty can't be a type var itself
1001 ty = Cow::Owned(known_ty.clone());
1002 }
1003 _ => return ty,
999 } 1004 }
1000 _ => Cow::Borrowed(ty),
1001 } 1005 }
1006 _ => return ty,
1002 } 1007 }
1003 _ => Cow::Borrowed(ty),
1004 } 1008 }
1009 ty
1005 } 1010 }
1006 1011
1007 /// Resolves the type completely; type variables without known type are 1012 /// Resolves the type completely; type variables without known type are
@@ -1185,17 +1190,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1185 self.infer_path_expr(&resolver, &path).unwrap_or(Ty::Unknown) 1190 self.infer_path_expr(&resolver, &path).unwrap_or(Ty::Unknown)
1186 } 1191 }
1187 Pat::Bind { mode, name: _name, subpat } => { 1192 Pat::Bind { mode, name: _name, subpat } => {
1188 let subty = if let Some(subpat) = subpat { 1193 let inner_ty = if let Some(subpat) = subpat {
1189 self.infer_pat(*subpat, expected) 1194 self.infer_pat(*subpat, expected)
1190 } else { 1195 } else {
1191 expected.clone() 1196 expected.clone()
1192 }; 1197 };
1198 let inner_ty = self.insert_type_vars_shallow(inner_ty);
1193 1199
1194 match mode { 1200 let bound_ty = match mode {
1195 BindingAnnotation::Ref => Ty::Ref(subty.into(), Mutability::Shared), 1201 BindingAnnotation::Ref => Ty::Ref(inner_ty.clone().into(), Mutability::Shared),
1196 BindingAnnotation::RefMut => Ty::Ref(subty.into(), Mutability::Mut), 1202 BindingAnnotation::RefMut => Ty::Ref(inner_ty.clone().into(), Mutability::Mut),
1197 BindingAnnotation::Mutable | BindingAnnotation::Unannotated => subty, 1203 BindingAnnotation::Mutable | BindingAnnotation::Unannotated => inner_ty.clone(),
1198 } 1204 };
1205 let bound_ty = self.resolve_ty_as_possible(&mut vec![], bound_ty);
1206 self.write_pat_ty(pat, bound_ty);
1207 return inner_ty;
1199 } 1208 }
1200 _ => Ty::Unknown, 1209 _ => Ty::Unknown,
1201 }; 1210 };