diff options
Diffstat (limited to 'crates/hir_ty/src/infer/unify.rs')
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 9b28c76d6..3a4258e86 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -9,7 +9,7 @@ use chalk_ir::{ | |||
9 | use chalk_solve::infer::ParameterEnaVariableExt; | 9 | use chalk_solve::infer::ParameterEnaVariableExt; |
10 | use ena::unify::UnifyKey; | 10 | use ena::unify::UnifyKey; |
11 | 11 | ||
12 | use super::InferenceContext; | 12 | use super::{InferOk, InferResult, InferenceContext, TypeError}; |
13 | use crate::{ | 13 | use crate::{ |
14 | db::HirDatabase, fold_tys, static_lifetime, BoundVar, Canonical, DebruijnIndex, GenericArg, | 14 | db::HirDatabase, fold_tys, static_lifetime, BoundVar, Canonical, DebruijnIndex, GenericArg, |
15 | InferenceVar, Interner, Scalar, Substitution, TraitEnvironment, Ty, TyKind, | 15 | InferenceVar, Interner, Scalar, Substitution, TraitEnvironment, Ty, TyKind, |
@@ -45,7 +45,7 @@ where | |||
45 | impl<T: HasInterner<Interner = Interner>> Canonicalized<T> { | 45 | impl<T: HasInterner<Interner = Interner>> Canonicalized<T> { |
46 | pub(super) fn decanonicalize_ty(&self, ty: Ty) -> Ty { | 46 | pub(super) fn decanonicalize_ty(&self, ty: Ty) -> Ty { |
47 | crate::fold_free_vars(ty, |bound, _binders| { | 47 | crate::fold_free_vars(ty, |bound, _binders| { |
48 | let var = self.free_vars[bound.index]; | 48 | let var = self.free_vars[bound.index].clone(); |
49 | var.assert_ty_ref(&Interner).clone() | 49 | var.assert_ty_ref(&Interner).clone() |
50 | }) | 50 | }) |
51 | } | 51 | } |
@@ -76,7 +76,7 @@ impl<T: HasInterner<Interner = Interner>> Canonicalized<T> { | |||
76 | for (i, ty) in solution.value.iter(&Interner).enumerate() { | 76 | for (i, ty) in solution.value.iter(&Interner).enumerate() { |
77 | // FIXME: deal with non-type vars here -- the only problematic part is the normalization | 77 | // FIXME: deal with non-type vars here -- the only problematic part is the normalization |
78 | // and maybe we don't need that with lazy normalization? | 78 | // and maybe we don't need that with lazy normalization? |
79 | let var = self.free_vars[i]; | 79 | let var = self.free_vars[i].clone(); |
80 | // eagerly replace projections in the type; we may be getting types | 80 | // eagerly replace projections in the type; we may be getting types |
81 | // e.g. from where clauses where this hasn't happened yet | 81 | // e.g. from where clauses where this hasn't happened yet |
82 | let ty = ctx.normalize_associated_types_in( | 82 | let ty = ctx.normalize_associated_types_in( |
@@ -218,16 +218,10 @@ impl<'a> InferenceTable<'a> { | |||
218 | self.resolve_ty_as_possible_inner(&mut Vec::new(), ty) | 218 | self.resolve_ty_as_possible_inner(&mut Vec::new(), ty) |
219 | } | 219 | } |
220 | 220 | ||
221 | /// Unify two types and register new trait goals that arise from that. | ||
222 | // TODO give these two functions better names | ||
221 | pub(crate) fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { | 223 | pub(crate) fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { |
222 | let result = self.var_unification_table.relate( | 224 | let result = if let Ok(r) = self.unify_inner(ty1, ty2) { |
223 | &Interner, | ||
224 | &self.db, | ||
225 | &self.trait_env.env, | ||
226 | chalk_ir::Variance::Invariant, | ||
227 | ty1, | ||
228 | ty2, | ||
229 | ); | ||
230 | let result = if let Ok(r) = result { | ||
231 | r | 225 | r |
232 | } else { | 226 | } else { |
233 | return false; | 227 | return false; |
@@ -236,6 +230,25 @@ impl<'a> InferenceTable<'a> { | |||
236 | true | 230 | true |
237 | } | 231 | } |
238 | 232 | ||
233 | /// Unify two types and return new trait goals arising from it, so the | ||
234 | /// caller needs to deal with them. | ||
235 | pub(crate) fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty) -> InferResult { | ||
236 | match self.var_unification_table.relate( | ||
237 | &Interner, | ||
238 | &self.db, | ||
239 | &self.trait_env.env, | ||
240 | chalk_ir::Variance::Invariant, | ||
241 | ty1, | ||
242 | ty2, | ||
243 | ) { | ||
244 | Ok(result) => { | ||
245 | // TODO deal with new goals | ||
246 | Ok(InferOk {}) | ||
247 | } | ||
248 | Err(NoSolution) => Err(TypeError), | ||
249 | } | ||
250 | } | ||
251 | |||
239 | /// If `ty` is a type variable with known type, returns that type; | 252 | /// If `ty` is a type variable with known type, returns that type; |
240 | /// otherwise, return ty. | 253 | /// otherwise, return ty. |
241 | // FIXME this could probably just return Ty | 254 | // FIXME this could probably just return Ty |