diff options
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 32 |
1 files changed, 15 insertions, 17 deletions
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 259feecf1..93cd54f0d 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -3,7 +3,8 @@ | |||
3 | use std::{borrow::Cow, fmt, sync::Arc}; | 3 | use std::{borrow::Cow, fmt, sync::Arc}; |
4 | 4 | ||
5 | use chalk_ir::{ | 5 | use chalk_ir::{ |
6 | cast::Cast, fold::Fold, interner::HasInterner, FloatTy, IntTy, TyVariableKind, UniverseIndex, | 6 | cast::Cast, fold::Fold, interner::HasInterner, zip::Zip, FloatTy, IntTy, TyVariableKind, |
7 | UniverseIndex, | ||
7 | }; | 8 | }; |
8 | use chalk_solve::infer::ParameterEnaVariableExt; | 9 | use chalk_solve::infer::ParameterEnaVariableExt; |
9 | use ena::unify::UnifyKey; | 10 | use ena::unify::UnifyKey; |
@@ -43,10 +44,7 @@ where | |||
43 | 44 | ||
44 | impl<T: HasInterner<Interner = Interner>> Canonicalized<T> { | 45 | impl<T: HasInterner<Interner = Interner>> Canonicalized<T> { |
45 | pub(super) fn decanonicalize_ty(&self, ty: Ty) -> Ty { | 46 | pub(super) fn decanonicalize_ty(&self, ty: Ty) -> Ty { |
46 | crate::fold_free_vars(ty, |bound, _binders| { | 47 | chalk_ir::Substitute::apply(&self.free_vars, ty, &Interner) |
47 | let var = self.free_vars[bound.index].clone(); | ||
48 | var.assert_ty_ref(&Interner).clone() | ||
49 | }) | ||
50 | } | 48 | } |
51 | 49 | ||
52 | pub(super) fn apply_solution( | 50 | pub(super) fn apply_solution( |
@@ -72,16 +70,16 @@ impl<T: HasInterner<Interner = Interner>> Canonicalized<T> { | |||
72 | _ => panic!("const variable in solution"), | 70 | _ => panic!("const variable in solution"), |
73 | }), | 71 | }), |
74 | ); | 72 | ); |
75 | for (i, ty) in solution.value.iter(&Interner).enumerate() { | 73 | for (i, v) in solution.value.iter(&Interner).enumerate() { |
76 | // FIXME: deal with non-type vars here -- the only problematic part is the normalization | ||
77 | // and maybe we don't need that with lazy normalization? | ||
78 | let var = self.free_vars[i].clone(); | 74 | let var = self.free_vars[i].clone(); |
79 | // eagerly replace projections in the type; we may be getting types | 75 | if let Some(ty) = v.ty(&Interner) { |
80 | // e.g. from where clauses where this hasn't happened yet | 76 | // eagerly replace projections in the type; we may be getting types |
81 | let ty = ctx.normalize_associated_types_in( | 77 | // e.g. from where clauses where this hasn't happened yet |
82 | new_vars.apply(ty.assert_ty_ref(&Interner).clone(), &Interner), | 78 | let ty = ctx.normalize_associated_types_in(new_vars.apply(ty.clone(), &Interner)); |
83 | ); | 79 | ctx.table.unify(var.assert_ty_ref(&Interner), &ty); |
84 | ctx.table.unify(var.assert_ty_ref(&Interner), &ty); | 80 | } else { |
81 | let _ = ctx.table.unify_inner(&var, &new_vars.apply(v.clone(), &Interner)); | ||
82 | } | ||
85 | } | 83 | } |
86 | } | 84 | } |
87 | } | 85 | } |
@@ -288,14 +286,14 @@ impl<'a> InferenceTable<'a> { | |||
288 | 286 | ||
289 | /// Unify two types and return new trait goals arising from it, so the | 287 | /// Unify two types and return new trait goals arising from it, so the |
290 | /// caller needs to deal with them. | 288 | /// caller needs to deal with them. |
291 | pub(crate) fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty) -> InferResult { | 289 | pub(crate) fn unify_inner<T: Zip<Interner>>(&mut self, t1: &T, t2: &T) -> InferResult { |
292 | match self.var_unification_table.relate( | 290 | match self.var_unification_table.relate( |
293 | &Interner, | 291 | &Interner, |
294 | &self.db, | 292 | &self.db, |
295 | &self.trait_env.env, | 293 | &self.trait_env.env, |
296 | chalk_ir::Variance::Invariant, | 294 | chalk_ir::Variance::Invariant, |
297 | ty1, | 295 | t1, |
298 | ty2, | 296 | t2, |
299 | ) { | 297 | ) { |
300 | Ok(_result) => { | 298 | Ok(_result) => { |
301 | // TODO deal with new goals | 299 | // TODO deal with new goals |