aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/infer
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-03-01 13:31:35 +0000
committerFlorian Diebold <[email protected]>2020-03-01 13:31:35 +0000
commit336a3c6121edf54a19728dbbd880f62bc835d7c8 (patch)
tree7cfbf56ccaf53e8e008798a3569c70e21516c5c9 /crates/ra_hir_ty/src/infer
parent6db2da4993d3956fc7c8ebf152963a132611426a (diff)
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.
Diffstat (limited to 'crates/ra_hir_ty/src/infer')
-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())))