diff options
author | Florian Diebold <[email protected]> | 2021-05-16 16:56:38 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2021-05-21 16:49:07 +0100 |
commit | 4bd446f5b3f8035d5db1fde1c6c50073e3f4fb2b (patch) | |
tree | fee7c98d53e93b9a1d743450d290fa1cb2ae0df4 /crates/hir_ty | |
parent | a78f0076abbbf61f7b68ce5c323639037c8a72de (diff) |
Get rid of resolve_ty_as_possible
Instead use shallow resolving where necessary.
Diffstat (limited to 'crates/hir_ty')
-rw-r--r-- | crates/hir_ty/src/infer.rs | 34 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 4 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 28 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 19 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/path.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 39 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/regression.rs | 16 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/traits.rs | 2 |
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::{ | |||
35 | impl<'a> InferenceContext<'a> { | 35 | impl<'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 | } |