diff options
Diffstat (limited to 'crates/hir_ty/src/infer/unify.rs')
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 39 |
1 files changed, 3 insertions, 36 deletions
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) |