diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-03-02 13:23:24 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-03-02 13:23:24 +0000 |
commit | 79c874803b7c318106c8eb129046667aa3227e3e (patch) | |
tree | 05b767f16e0a8de971b575c57ea9145d070b4c66 /crates/ra_hir_ty/src/infer/unify.rs | |
parent | cf23ca771967d473a2efd0c0b0cf9f285dc3107e (diff) | |
parent | 336a3c6121edf54a19728dbbd880f62bc835d7c8 (diff) |
Merge #3385
3385: Fix #3373 r=matklad a=flodiebold
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.
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir_ty/src/infer/unify.rs')
-rw-r--r-- | crates/ra_hir_ty/src/infer/unify.rs | 15 |
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 | ||
143 | pub fn unify(ty1: &Canonical<Ty>, ty2: &Canonical<Ty>) -> Option<Substs> { | 143 | pub 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()))) |