From 336a3c6121edf54a19728dbbd880f62bc835d7c8 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 1 Mar 2020 14:31:35 +0100 Subject: Fix #3373 Basically, we need to allow variables in the caller self type to unify with the impl's declared self type. That requires some more contortions in the variable handling. I'm looking forward to (hopefully) handling this in a cleaner way when we switch to Chalk's types and unification code. --- crates/ra_hir_ty/src/infer/unify.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir_ty/src/infer') diff --git a/crates/ra_hir_ty/src/infer/unify.rs b/crates/ra_hir_ty/src/infer/unify.rs index aed527fe5..82b85d570 100644 --- a/crates/ra_hir_ty/src/infer/unify.rs +++ b/crates/ra_hir_ty/src/infer/unify.rs @@ -142,12 +142,21 @@ impl Canonicalized { pub fn unify(ty1: &Canonical, ty2: &Canonical) -> Option { let mut table = InferenceTable::new(); + let num_vars = ty1.num_vars.max(ty2.num_vars); let vars = - Substs::builder(ty1.num_vars).fill(std::iter::repeat_with(|| table.new_type_var())).build(); - let ty_with_vars = ty1.value.clone().subst_bound_vars(&vars); - if !table.unify(&ty_with_vars, &ty2.value) { + Substs::builder(num_vars).fill(std::iter::repeat_with(|| table.new_type_var())).build(); + let ty1_with_vars = ty1.value.clone().subst_bound_vars(&vars); + let ty2_with_vars = ty2.value.clone().subst_bound_vars(&vars); + if !table.unify(&ty1_with_vars, &ty2_with_vars) { return None; } + // default any type vars that weren't unified back to their original bound vars + // (kind of hacky) + for (i, var) in vars.iter().enumerate() { + if &*table.resolve_ty_shallow(var) == var { + table.unify(var, &Ty::Bound(i as u32)); + } + } Some( Substs::builder(ty1.num_vars) .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone()))) -- cgit v1.2.3