aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer/unify.rs
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2021-05-01 20:53:10 +0100
committerFlorian Diebold <[email protected]>2021-05-21 16:48:33 +0100
commit693582946fae1813627ad59f60a31c9237e98744 (patch)
tree7c546542a5e76b8e1a958f867faddd1c04b05d07 /crates/hir_ty/src/infer/unify.rs
parent84074cb1852aa702e1307e9533e1fa3448e3e04f (diff)
Rewrite coercion using the new unification
Diffstat (limited to 'crates/hir_ty/src/infer/unify.rs')
-rw-r--r--crates/hir_ty/src/infer/unify.rs37
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::{
9use chalk_solve::infer::ParameterEnaVariableExt; 9use chalk_solve::infer::ParameterEnaVariableExt;
10use ena::unify::UnifyKey; 10use ena::unify::UnifyKey;
11 11
12use super::InferenceContext; 12use super::{InferOk, InferResult, InferenceContext, TypeError};
13use crate::{ 13use 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
45impl<T: HasInterner<Interner = Interner>> Canonicalized<T> { 45impl<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