diff options
Diffstat (limited to 'crates/ra_hir_ty/src/infer')
-rw-r--r-- | crates/ra_hir_ty/src/infer/pat.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/unify.rs | 15 |
2 files changed, 25 insertions, 3 deletions
diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs index bf8ea192b..7a84e47f8 100644 --- a/crates/ra_hir_ty/src/infer/pat.rs +++ b/crates/ra_hir_ty/src/infer/pat.rs | |||
@@ -185,6 +185,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
185 | self.write_pat_ty(pat, bound_ty); | 185 | self.write_pat_ty(pat, bound_ty); |
186 | return inner_ty; | 186 | return inner_ty; |
187 | } | 187 | } |
188 | Pat::Slice { prefix, slice: _slice, suffix } => { | ||
189 | let (container_ty, elem_ty) = match &expected { | ||
190 | ty_app!(TypeCtor::Array, st) => (TypeCtor::Array, st.as_single().clone()), | ||
191 | ty_app!(TypeCtor::Slice, st) => (TypeCtor::Slice, st.as_single().clone()), | ||
192 | _ => (TypeCtor::Slice, Ty::Unknown), | ||
193 | }; | ||
194 | |||
195 | for pat_id in prefix.iter().chain(suffix) { | ||
196 | self.infer_pat(*pat_id, &elem_ty, default_bm); | ||
197 | } | ||
198 | |||
199 | Ty::apply_one(container_ty, elem_ty) | ||
200 | } | ||
188 | _ => Ty::Unknown, | 201 | _ => Ty::Unknown, |
189 | }; | 202 | }; |
190 | // use a new type variable if we got Ty::Unknown here | 203 | // use a new type variable if we got Ty::Unknown here |
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()))) |