aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/infer/unify.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/infer/unify.rs')
-rw-r--r--crates/ra_hir_ty/src/infer/unify.rs15
1 files changed, 12 insertions, 3 deletions
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<T> Canonicalized<T> {
142 142
143pub fn unify(ty1: &Canonical<Ty>, ty2: &Canonical<Ty>) -> Option<Substs> { 143pub fn unify(ty1: &Canonical<Ty>, ty2: &Canonical<Ty>) -> Option<Substs> {
144 let mut table = InferenceTable::new(); 144 let mut table = InferenceTable::new();
145 let num_vars = ty1.num_vars.max(ty2.num_vars);
145 let vars = 146 let vars =
146 Substs::builder(ty1.num_vars).fill(std::iter::repeat_with(|| table.new_type_var())).build(); 147 Substs::builder(num_vars).fill(std::iter::repeat_with(|| table.new_type_var())).build();
147 let ty_with_vars = ty1.value.clone().subst_bound_vars(&vars); 148 let ty1_with_vars = ty1.value.clone().subst_bound_vars(&vars);
148 if !table.unify(&ty_with_vars, &ty2.value) { 149 let ty2_with_vars = ty2.value.clone().subst_bound_vars(&vars);
150 if !table.unify(&ty1_with_vars, &ty2_with_vars) {
149 return None; 151 return None;
150 } 152 }
153 // default any type vars that weren't unified back to their original bound vars
154 // (kind of hacky)
155 for (i, var) in vars.iter().enumerate() {
156 if &*table.resolve_ty_shallow(var) == var {
157 table.unify(var, &Ty::Bound(i as u32));
158 }
159 }
151 Some( 160 Some(
152 Substs::builder(ty1.num_vars) 161 Substs::builder(ty1.num_vars)
153 .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone()))) 162 .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone())))