aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2021-05-16 16:56:38 +0100
committerFlorian Diebold <[email protected]>2021-05-21 16:49:07 +0100
commit4bd446f5b3f8035d5db1fde1c6c50073e3f4fb2b (patch)
treefee7c98d53e93b9a1d743450d290fa1cb2ae0df4 /crates
parenta78f0076abbbf61f7b68ce5c323639037c8a72de (diff)
Get rid of resolve_ty_as_possible
Instead use shallow resolving where necessary.
Diffstat (limited to 'crates')
-rw-r--r--crates/hir_ty/src/infer.rs34
-rw-r--r--crates/hir_ty/src/infer/coerce.rs4
-rw-r--r--crates/hir_ty/src/infer/expr.rs28
-rw-r--r--crates/hir_ty/src/infer/pat.rs19
-rw-r--r--crates/hir_ty/src/infer/path.rs2
-rw-r--r--crates/hir_ty/src/infer/unify.rs39
-rw-r--r--crates/hir_ty/src/tests/regression.rs16
-rw-r--r--crates/hir_ty/src/tests/traits.rs2
8 files changed, 56 insertions, 88 deletions
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 8cfc84b86..ab742e203 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -273,7 +273,7 @@ impl<'a> InferenceContext<'a> {
273 } 273 }
274 274
275 fn err_ty(&self) -> Ty { 275 fn err_ty(&self) -> Ty {
276 TyKind::Error.intern(&Interner) 276 self.result.standard_types.unknown.clone()
277 } 277 }
278 278
279 fn resolve_all(mut self) -> InferenceResult { 279 fn resolve_all(mut self) -> InferenceResult {
@@ -284,12 +284,14 @@ impl<'a> InferenceContext<'a> {
284 self.table.propagate_diverging_flag(); 284 self.table.propagate_diverging_flag();
285 let mut result = std::mem::take(&mut self.result); 285 let mut result = std::mem::take(&mut self.result);
286 for ty in result.type_of_expr.values_mut() { 286 for ty in result.type_of_expr.values_mut() {
287 let resolved = self.table.resolve_ty_completely(ty.clone()); 287 *ty = self.table.resolve_ty_completely(ty.clone());
288 *ty = resolved;
289 } 288 }
290 for ty in result.type_of_pat.values_mut() { 289 for ty in result.type_of_pat.values_mut() {
291 let resolved = self.table.resolve_ty_completely(ty.clone()); 290 *ty = self.table.resolve_ty_completely(ty.clone());
292 *ty = resolved; 291 }
292 for mismatch in result.type_mismatches.values_mut() {
293 mismatch.expected = self.table.resolve_ty_completely(mismatch.expected.clone());
294 mismatch.actual = self.table.resolve_ty_completely(mismatch.actual.clone());
293 } 295 }
294 result 296 result
295 } 297 }
@@ -343,6 +345,14 @@ impl<'a> InferenceContext<'a> {
343 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { 345 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
344 match ty.kind(&Interner) { 346 match ty.kind(&Interner) {
345 TyKind::Error => self.table.new_type_var(), 347 TyKind::Error => self.table.new_type_var(),
348 TyKind::InferenceVar(..) => {
349 let ty_resolved = self.resolve_ty_shallow(&ty);
350 if ty_resolved.is_unknown() {
351 self.table.new_type_var()
352 } else {
353 ty
354 }
355 }
346 _ => ty, 356 _ => ty,
347 } 357 }
348 } 358 }
@@ -371,18 +381,8 @@ impl<'a> InferenceContext<'a> {
371 self.table.unify_inner(ty1, ty2) 381 self.table.unify_inner(ty1, ty2)
372 } 382 }
373 383
374 // FIXME get rid of this, instead resolve shallowly where necessary
375 /// Resolves the type as far as currently possible, replacing type variables
376 /// by their known types. All types returned by the infer_* functions should
377 /// be resolved as far as possible, i.e. contain no type variables with
378 /// known type.
379 fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty {
380 self.resolve_obligations_as_possible();
381
382 self.table.resolve_ty_as_possible(ty)
383 }
384
385 fn resolve_ty_shallow(&mut self, ty: &Ty) -> Ty { 384 fn resolve_ty_shallow(&mut self, ty: &Ty) -> Ty {
385 self.resolve_obligations_as_possible();
386 self.table.resolve_ty_shallow(ty) 386 self.table.resolve_ty_shallow(ty)
387 } 387 }
388 388
@@ -416,7 +416,7 @@ impl<'a> InferenceContext<'a> {
416 }; 416 };
417 self.push_obligation(trait_ref.cast(&Interner)); 417 self.push_obligation(trait_ref.cast(&Interner));
418 self.push_obligation(alias_eq.cast(&Interner)); 418 self.push_obligation(alias_eq.cast(&Interner));
419 self.resolve_ty_as_possible(ty) 419 ty
420 } 420 }
421 None => self.err_ty(), 421 None => self.err_ty(),
422 } 422 }
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index c85c088f7..00b2b585f 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -19,12 +19,12 @@ impl<'a> InferenceContext<'a> {
19 /// Unify two types, but may coerce the first one to the second one 19 /// Unify two types, but may coerce the first one to the second one
20 /// using "implicit coercion rules" if needed. 20 /// using "implicit coercion rules" if needed.
21 pub(super) fn coerce(&mut self, from_ty: &Ty, to_ty: &Ty) -> bool { 21 pub(super) fn coerce(&mut self, from_ty: &Ty, to_ty: &Ty) -> bool {
22 let from_ty = self.resolve_ty_shallow(from_ty);
23 let to_ty = self.resolve_ty_shallow(to_ty);
22 // TODO handle expectations properly 24 // TODO handle expectations properly
23 if to_ty.is_unknown() { 25 if to_ty.is_unknown() {
24 return true; 26 return true;
25 } 27 }
26 let from_ty = self.resolve_ty_shallow(from_ty);
27 let to_ty = self.resolve_ty_shallow(to_ty);
28 match self.coerce_inner(from_ty, &to_ty) { 28 match self.coerce_inner(from_ty, &to_ty) {
29 Ok(_result) => { 29 Ok(_result) => {
30 // TODO deal with goals 30 // TODO deal with goals
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 6eaccd9b4..f5782ab24 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -35,7 +35,7 @@ use super::{
35impl<'a> InferenceContext<'a> { 35impl<'a> InferenceContext<'a> {
36 pub(super) fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { 36 pub(super) fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
37 let ty = self.infer_expr_inner(tgt_expr, expected); 37 let ty = self.infer_expr_inner(tgt_expr, expected);
38 if ty.is_never() { 38 if self.resolve_ty_shallow(&ty).is_never() {
39 // Any expression that produces a value of type `!` must have diverged 39 // Any expression that produces a value of type `!` must have diverged
40 self.diverges = Diverges::Always; 40 self.diverges = Diverges::Always;
41 } 41 }
@@ -46,7 +46,7 @@ impl<'a> InferenceContext<'a> {
46 TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() }, 46 TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() },
47 ); 47 );
48 } 48 }
49 self.resolve_ty_as_possible(ty) 49 ty
50 } 50 }
51 51
52 /// Infer type of expression with possibly implicit coerce to the expected type. 52 /// Infer type of expression with possibly implicit coerce to the expected type.
@@ -67,7 +67,7 @@ impl<'a> InferenceContext<'a> {
67 expected.ty.clone() 67 expected.ty.clone()
68 }; 68 };
69 69
70 self.resolve_ty_as_possible(ty) 70 ty
71 } 71 }
72 72
73 fn callable_sig_from_fn_trait(&mut self, ty: &Ty, num_args: usize) -> Option<(Vec<Ty>, Ty)> { 73 fn callable_sig_from_fn_trait(&mut self, ty: &Ty, num_args: usize) -> Option<(Vec<Ty>, Ty)> {
@@ -284,8 +284,7 @@ impl<'a> InferenceContext<'a> {
284 284
285 // Now go through the argument patterns 285 // Now go through the argument patterns
286 for (arg_pat, arg_ty) in args.iter().zip(sig_tys) { 286 for (arg_pat, arg_ty) in args.iter().zip(sig_tys) {
287 let resolved = self.resolve_ty_as_possible(arg_ty); 287 self.infer_pat(*arg_pat, &arg_ty, BindingMode::default());
288 self.infer_pat(*arg_pat, &resolved, BindingMode::default());
289 } 288 }
290 289
291 let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); 290 let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
@@ -525,14 +524,14 @@ impl<'a> InferenceContext<'a> {
525 Expr::Ref { expr, rawness, mutability } => { 524 Expr::Ref { expr, rawness, mutability } => {
526 let mutability = lower_to_chalk_mutability(*mutability); 525 let mutability = lower_to_chalk_mutability(*mutability);
527 let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = 526 let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) =
528 &expected.ty.as_reference_or_ptr() 527 &self.resolve_ty_shallow(&expected.ty).as_reference_or_ptr()
529 { 528 {
530 if *exp_mutability == Mutability::Mut && mutability == Mutability::Not { 529 if *exp_mutability == Mutability::Mut && mutability == Mutability::Not {
531 // FIXME: throw type error - expected mut reference but found shared ref, 530 // FIXME: record type error - expected mut reference but found shared ref,
532 // which cannot be coerced 531 // which cannot be coerced
533 } 532 }
534 if *exp_rawness == Rawness::Ref && *rawness == Rawness::RawPtr { 533 if *exp_rawness == Rawness::Ref && *rawness == Rawness::RawPtr {
535 // FIXME: throw type error - expected reference but found ptr, 534 // FIXME: record type error - expected reference but found ptr,
536 // which cannot be coerced 535 // which cannot be coerced
537 } 536 }
538 Expectation::rvalue_hint(Ty::clone(exp_inner)) 537 Expectation::rvalue_hint(Ty::clone(exp_inner))
@@ -559,6 +558,7 @@ impl<'a> InferenceContext<'a> {
559 } 558 }
560 Expr::UnaryOp { expr, op } => { 559 Expr::UnaryOp { expr, op } => {
561 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 560 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
561 let inner_ty = self.resolve_ty_shallow(&inner_ty);
562 match op { 562 match op {
563 UnaryOp::Deref => match self.resolver.krate() { 563 UnaryOp::Deref => match self.resolver.krate() {
564 Some(krate) => { 564 Some(krate) => {
@@ -615,8 +615,10 @@ impl<'a> InferenceContext<'a> {
615 _ => Expectation::none(), 615 _ => Expectation::none(),
616 }; 616 };
617 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); 617 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
618 let lhs_ty = self.resolve_ty_shallow(&lhs_ty);
618 let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty.clone()); 619 let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty.clone());
619 let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation)); 620 let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation));
621 let rhs_ty = self.resolve_ty_shallow(&rhs_ty);
620 622
621 let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone()); 623 let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone());
622 624
@@ -699,7 +701,7 @@ impl<'a> InferenceContext<'a> {
699 } 701 }
700 } 702 }
701 Expr::Tuple { exprs } => { 703 Expr::Tuple { exprs } => {
702 let mut tys = match expected.ty.kind(&Interner) { 704 let mut tys = match self.resolve_ty_shallow(&expected.ty).kind(&Interner) {
703 TyKind::Tuple(_, substs) => substs 705 TyKind::Tuple(_, substs) => substs
704 .iter(&Interner) 706 .iter(&Interner)
705 .map(|a| a.assert_ty_ref(&Interner).clone()) 707 .map(|a| a.assert_ty_ref(&Interner).clone())
@@ -716,7 +718,7 @@ impl<'a> InferenceContext<'a> {
716 TyKind::Tuple(tys.len(), Substitution::from_iter(&Interner, tys)).intern(&Interner) 718 TyKind::Tuple(tys.len(), Substitution::from_iter(&Interner, tys)).intern(&Interner)
717 } 719 }
718 Expr::Array(array) => { 720 Expr::Array(array) => {
719 let elem_ty = match expected.ty.kind(&Interner) { 721 let elem_ty = match self.resolve_ty_shallow(&expected.ty).kind(&Interner) {
720 TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(), 722 TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(),
721 _ => self.table.new_type_var(), 723 _ => self.table.new_type_var(),
722 }; 724 };
@@ -788,7 +790,6 @@ impl<'a> InferenceContext<'a> {
788 }; 790 };
789 // use a new type variable if we got unknown here 791 // use a new type variable if we got unknown here
790 let ty = self.insert_type_vars_shallow(ty); 792 let ty = self.insert_type_vars_shallow(ty);
791 let ty = self.resolve_ty_as_possible(ty);
792 self.write_expr_ty(tgt_expr, ty.clone()); 793 self.write_expr_ty(tgt_expr, ty.clone());
793 ty 794 ty
794 } 795 }
@@ -816,7 +817,6 @@ impl<'a> InferenceContext<'a> {
816 } 817 }
817 } 818 }
818 819
819 let ty = self.resolve_ty_as_possible(ty);
820 self.infer_pat(*pat, &ty, BindingMode::default()); 820 self.infer_pat(*pat, &ty, BindingMode::default());
821 } 821 }
822 Statement::Expr { expr, .. } => { 822 Statement::Expr { expr, .. } => {
@@ -894,7 +894,8 @@ impl<'a> InferenceContext<'a> {
894 }; 894 };
895 // Apply autoref so the below unification works correctly 895 // Apply autoref so the below unification works correctly
896 // FIXME: return correct autorefs from lookup_method 896 // FIXME: return correct autorefs from lookup_method
897 let actual_receiver_ty = match expected_receiver_ty.as_reference() { 897 let actual_receiver_ty = match self.resolve_ty_shallow(&expected_receiver_ty).as_reference()
898 {
898 Some((_, lifetime, mutability)) => { 899 Some((_, lifetime, mutability)) => {
899 TyKind::Ref(mutability, lifetime, derefed_receiver_ty).intern(&Interner) 900 TyKind::Ref(mutability, lifetime, derefed_receiver_ty).intern(&Interner)
900 } 901 }
@@ -974,6 +975,7 @@ impl<'a> InferenceContext<'a> {
974 } 975 }
975 976
976 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 977 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
978 let callable_ty = self.resolve_ty_shallow(&callable_ty);
977 if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind(&Interner) { 979 if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind(&Interner) {
978 let def: CallableDefId = from_chalk(self.db, *fn_def); 980 let def: CallableDefId = from_chalk(self.db, *fn_def);
979 let generic_predicates = self.db.generic_predicates(def.into()); 981 let generic_predicates = self.db.generic_predicates(def.into());
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index b15f4977d..9c8e3b6ae 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -94,14 +94,15 @@ impl<'a> InferenceContext<'a> {
94 pub(super) fn infer_pat( 94 pub(super) fn infer_pat(
95 &mut self, 95 &mut self,
96 pat: PatId, 96 pat: PatId,
97 mut expected: &Ty, 97 expected: &Ty,
98 mut default_bm: BindingMode, 98 mut default_bm: BindingMode,
99 ) -> Ty { 99 ) -> Ty {
100 let body = Arc::clone(&self.body); // avoid borrow checker problem 100 let body = Arc::clone(&self.body); // avoid borrow checker problem
101 let mut expected = self.resolve_ty_shallow(expected);
101 102
102 if is_non_ref_pat(&body, pat) { 103 if is_non_ref_pat(&body, pat) {
103 while let Some((inner, _lifetime, mutability)) = expected.as_reference() { 104 while let Some((inner, _lifetime, mutability)) = expected.as_reference() {
104 expected = inner; 105 expected = self.resolve_ty_shallow(inner);
105 default_bm = match default_bm { 106 default_bm = match default_bm {
106 BindingMode::Move => BindingMode::Ref(mutability), 107 BindingMode::Move => BindingMode::Ref(mutability),
107 BindingMode::Ref(Mutability::Not) => BindingMode::Ref(Mutability::Not), 108 BindingMode::Ref(Mutability::Not) => BindingMode::Ref(Mutability::Not),
@@ -147,9 +148,9 @@ impl<'a> InferenceContext<'a> {
147 } 148 }
148 Pat::Or(ref pats) => { 149 Pat::Or(ref pats) => {
149 if let Some((first_pat, rest)) = pats.split_first() { 150 if let Some((first_pat, rest)) = pats.split_first() {
150 let ty = self.infer_pat(*first_pat, expected, default_bm); 151 let ty = self.infer_pat(*first_pat, &expected, default_bm);
151 for pat in rest { 152 for pat in rest {
152 self.infer_pat(*pat, expected, default_bm); 153 self.infer_pat(*pat, &expected, default_bm);
153 } 154 }
154 ty 155 ty
155 } else { 156 } else {
@@ -173,13 +174,13 @@ impl<'a> InferenceContext<'a> {
173 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( 174 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat(
174 p.as_deref(), 175 p.as_deref(),
175 subpats, 176 subpats,
176 expected, 177 &expected,
177 default_bm, 178 default_bm,
178 pat, 179 pat,
179 *ellipsis, 180 *ellipsis,
180 ), 181 ),
181 Pat::Record { path: p, args: fields, ellipsis: _ } => { 182 Pat::Record { path: p, args: fields, ellipsis: _ } => {
182 self.infer_record_pat(p.as_deref(), fields, expected, default_bm, pat) 183 self.infer_record_pat(p.as_deref(), fields, &expected, default_bm, pat)
183 } 184 }
184 Pat::Path(path) => { 185 Pat::Path(path) => {
185 // FIXME use correct resolver for the surrounding expression 186 // FIXME use correct resolver for the surrounding expression
@@ -193,7 +194,7 @@ impl<'a> InferenceContext<'a> {
193 BindingMode::convert(*mode) 194 BindingMode::convert(*mode)
194 }; 195 };
195 let inner_ty = if let Some(subpat) = subpat { 196 let inner_ty = if let Some(subpat) = subpat {
196 self.infer_pat(*subpat, expected, default_bm) 197 self.infer_pat(*subpat, &expected, default_bm)
197 } else { 198 } else {
198 expected.clone() 199 expected.clone()
199 }; 200 };
@@ -206,7 +207,6 @@ impl<'a> InferenceContext<'a> {
206 } 207 }
207 BindingMode::Move => inner_ty.clone(), 208 BindingMode::Move => inner_ty.clone(),
208 }; 209 };
209 let bound_ty = self.resolve_ty_as_possible(bound_ty);
210 self.write_pat_ty(pat, bound_ty); 210 self.write_pat_ty(pat, bound_ty);
211 return inner_ty; 211 return inner_ty;
212 } 212 }
@@ -265,13 +265,12 @@ impl<'a> InferenceContext<'a> {
265 }; 265 };
266 // use a new type variable if we got error type here 266 // use a new type variable if we got error type here
267 let ty = self.insert_type_vars_shallow(ty); 267 let ty = self.insert_type_vars_shallow(ty);
268 if !self.unify(&ty, expected) { 268 if !self.unify(&ty, &expected) {
269 self.result.type_mismatches.insert( 269 self.result.type_mismatches.insert(
270 pat.into(), 270 pat.into(),
271 TypeMismatch { expected: expected.clone(), actual: ty.clone() }, 271 TypeMismatch { expected: expected.clone(), actual: ty.clone() },
272 ); 272 );
273 } 273 }
274 let ty = self.resolve_ty_as_possible(ty);
275 self.write_pat_ty(pat, ty.clone()); 274 self.write_pat_ty(pat, ty.clone());
276 ty 275 ty
277 } 276 }
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs
index fd366e121..14c99eafd 100644
--- a/crates/hir_ty/src/infer/path.rs
+++ b/crates/hir_ty/src/infer/path.rs
@@ -65,7 +65,6 @@ impl<'a> InferenceContext<'a> {
65 let typable: ValueTyDefId = match value { 65 let typable: ValueTyDefId = match value {
66 ValueNs::LocalBinding(pat) => { 66 ValueNs::LocalBinding(pat) => {
67 let ty = self.result.type_of_pat.get(pat)?.clone(); 67 let ty = self.result.type_of_pat.get(pat)?.clone();
68 let ty = self.resolve_ty_as_possible(ty);
69 return Some(ty); 68 return Some(ty);
70 } 69 }
71 ValueNs::FunctionId(it) => it.into(), 70 ValueNs::FunctionId(it) => it.into(),
@@ -275,6 +274,7 @@ impl<'a> InferenceContext<'a> {
275 name: &Name, 274 name: &Name,
276 id: ExprOrPatId, 275 id: ExprOrPatId,
277 ) -> Option<(ValueNs, Option<Substitution>)> { 276 ) -> Option<(ValueNs, Option<Substitution>)> {
277 let ty = self.resolve_ty_shallow(ty);
278 let (enum_id, subst) = match ty.as_adt() { 278 let (enum_id, subst) = match ty.as_adt() {
279 Some((AdtId::EnumId(e), subst)) => (e, subst), 279 Some((AdtId::EnumId(e), subst)) => (e, subst),
280 _ => return None, 280 _ => return None,
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 278127c69..539e12420 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -24,6 +24,9 @@ impl<'a> InferenceContext<'a> {
24 where 24 where
25 T::Result: HasInterner<Interner = Interner>, 25 T::Result: HasInterner<Interner = Interner>,
26 { 26 {
27 // try to resolve obligations before canonicalizing, since this might
28 // result in new knowledge about variables
29 self.resolve_obligations_as_possible();
27 self.table.canonicalize(t) 30 self.table.canonicalize(t)
28 } 31 }
29} 32}
@@ -216,7 +219,6 @@ impl<'a> InferenceTable<'a> {
216 /// call). `make_ty` handles this already, but e.g. for field types we need 219 /// call). `make_ty` handles this already, but e.g. for field types we need
217 /// to do it as well. 220 /// to do it as well.
218 pub(super) fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { 221 pub(super) fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
219 let ty = self.resolve_ty_as_possible(ty);
220 fold_tys( 222 fold_tys(
221 ty, 223 ty,
222 |ty, _| match ty.kind(&Interner) { 224 |ty, _| match ty.kind(&Interner) {
@@ -302,11 +304,6 @@ impl<'a> InferenceTable<'a> {
302 self.resolve_with_fallback(ty, |_, _, d, _| d) 304 self.resolve_with_fallback(ty, |_, _, d, _| d)
303 } 305 }
304 306
305 // FIXME get rid of this, instead resolve shallowly where necessary
306 pub(crate) fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty {
307 self.resolve_ty_as_possible_inner(&mut Vec::new(), ty)
308 }
309
310 /// Unify two types and register new trait goals that arise from that. 307 /// Unify two types and register new trait goals that arise from that.
311 // TODO give these two functions better names 308 // TODO give these two functions better names
312 pub(crate) fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { 309 pub(crate) fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
@@ -344,36 +341,6 @@ impl<'a> InferenceTable<'a> {
344 self.var_unification_table.normalize_ty_shallow(&Interner, ty).unwrap_or_else(|| ty.clone()) 341 self.var_unification_table.normalize_ty_shallow(&Interner, ty).unwrap_or_else(|| ty.clone())
345 } 342 }
346 343
347 /// Resolves the type as far as currently possible, replacing type variables
348 /// by their known types.
349 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<InferenceVar>, ty: Ty) -> Ty {
350 fold_tys(
351 ty,
352 |ty, _| match ty.kind(&Interner) {
353 &TyKind::InferenceVar(tv, kind) => {
354 if tv_stack.contains(&tv) {
355 // recursive type
356 return self.type_variable_table.fallback_value(tv, kind);
357 }
358 if let Some(known_ty) = self.var_unification_table.probe_var(tv) {
359 // known_ty may contain other variables that are known by now
360 tv_stack.push(tv);
361 let result = self.resolve_ty_as_possible_inner(
362 tv_stack,
363 known_ty.assert_ty_ref(&Interner).clone(),
364 );
365 tv_stack.pop();
366 result
367 } else {
368 ty
369 }
370 }
371 _ => ty,
372 },
373 DebruijnIndex::INNERMOST,
374 )
375 }
376
377 pub fn register_obligation(&mut self, goal: Goal) { 344 pub fn register_obligation(&mut self, goal: Goal) {
378 let in_env = InEnvironment::new(&self.trait_env.env, goal); 345 let in_env = InEnvironment::new(&self.trait_env.env, goal);
379 self.register_obligation_in_env(in_env) 346 self.register_obligation_in_env(in_env)
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs
index 59a16f390..baef81590 100644
--- a/crates/hir_ty/src/tests/regression.rs
+++ b/crates/hir_ty/src/tests/regression.rs
@@ -117,19 +117,19 @@ fn recursive_vars_2() {
117 "#, 117 "#,
118 expect![[r#" 118 expect![[r#"
119 10..79 '{ ...x)]; }': () 119 10..79 '{ ...x)]; }': ()
120 20..21 'x': {unknown} 120 20..21 'x': &{unknown}
121 24..31 'unknown': {unknown} 121 24..31 'unknown': &{unknown}
122 41..42 'y': {unknown} 122 41..42 'y': {unknown}
123 45..52 'unknown': {unknown} 123 45..52 'unknown': {unknown}
124 58..76 '[(x, y..., &x)]': [({unknown}, {unknown}); 2] 124 58..76 '[(x, y..., &x)]': [(&{unknown}, {unknown}); 2]
125 59..65 '(x, y)': ({unknown}, {unknown}) 125 59..65 '(x, y)': (&{unknown}, {unknown})
126 60..61 'x': {unknown} 126 60..61 'x': &{unknown}
127 63..64 'y': {unknown} 127 63..64 'y': {unknown}
128 67..75 '(&y, &x)': (&{unknown}, &{unknown}) 128 67..75 '(&y, &x)': (&{unknown}, {unknown})
129 68..70 '&y': &{unknown} 129 68..70 '&y': &{unknown}
130 69..70 'y': {unknown} 130 69..70 'y': {unknown}
131 72..74 '&x': &{unknown} 131 72..74 '&x': &&{unknown}
132 73..74 'x': {unknown} 132 73..74 'x': &{unknown}
133 "#]], 133 "#]],
134 ); 134 );
135} 135}
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index f80cf9879..a5a2df54c 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -3104,7 +3104,7 @@ fn foo() {
3104 568..573 'f(&s)': FnOnce::Output<dyn FnOnce(&Option<i32>), (&Option<i32>,)> 3104 568..573 'f(&s)': FnOnce::Output<dyn FnOnce(&Option<i32>), (&Option<i32>,)>
3105 570..572 '&s': &Option<i32> 3105 570..572 '&s': &Option<i32>
3106 571..572 's': Option<i32> 3106 571..572 's': Option<i32>
3107 549..562: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|_| -> ()> 3107 549..562: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|{unknown}| -> ()>
3108 "#]], 3108 "#]],
3109 ); 3109 );
3110} 3110}