aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty')
-rw-r--r--crates/hir_ty/src/infer/unify.rs32
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 @@
3use std::{borrow::Cow, fmt, sync::Arc}; 3use std::{borrow::Cow, fmt, sync::Arc};
4 4
5use chalk_ir::{ 5use 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};
8use chalk_solve::infer::ParameterEnaVariableExt; 9use chalk_solve::infer::ParameterEnaVariableExt;
9use ena::unify::UnifyKey; 10use ena::unify::UnifyKey;
@@ -43,10 +44,7 @@ where
43 44
44impl<T: HasInterner<Interner = Interner>> Canonicalized<T> { 45impl<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