diff options
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 35b0a2059..7595b46cf 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -2,13 +2,13 @@ | |||
2 | 2 | ||
3 | use std::borrow::Cow; | 3 | use std::borrow::Cow; |
4 | 4 | ||
5 | use chalk_ir::{FloatTy, IntTy, TyVariableKind}; | 5 | use chalk_ir::{FloatTy, IntTy, TyVariableKind, UniverseIndex, VariableKind}; |
6 | use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; | 6 | use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; |
7 | 7 | ||
8 | use super::{DomainGoal, InferenceContext}; | 8 | use super::{DomainGoal, InferenceContext}; |
9 | use crate::{ | 9 | use crate::{ |
10 | AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, FnPointer, InEnvironment, InferenceVar, | 10 | AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, |
11 | Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause, | 11 | InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause, |
12 | }; | 12 | }; |
13 | 13 | ||
14 | impl<'a> InferenceContext<'a> { | 14 | impl<'a> InferenceContext<'a> { |
@@ -76,8 +76,17 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { | |||
76 | } | 76 | } |
77 | 77 | ||
78 | fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> { | 78 | fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> { |
79 | let kinds = self.free_vars.iter().map(|&(_, k)| k).collect(); | 79 | let kinds = self |
80 | Canonicalized { value: Canonical { value: result, kinds }, free_vars: self.free_vars } | 80 | .free_vars |
81 | .iter() | ||
82 | .map(|&(_, k)| chalk_ir::WithKind::new(VariableKind::Ty(k), UniverseIndex::ROOT)); | ||
83 | Canonicalized { | ||
84 | value: Canonical { | ||
85 | value: result, | ||
86 | binders: CanonicalVarKinds::from_iter(&Interner, kinds), | ||
87 | }, | ||
88 | free_vars: self.free_vars, | ||
89 | } | ||
81 | } | 90 | } |
82 | 91 | ||
83 | pub(crate) fn canonicalize_ty(mut self, ty: Ty) -> Canonicalized<Ty> { | 92 | pub(crate) fn canonicalize_ty(mut self, ty: Ty) -> Canonicalized<Ty> { |
@@ -125,12 +134,19 @@ impl<T> Canonicalized<T> { | |||
125 | // the solution may contain new variables, which we need to convert to new inference vars | 134 | // the solution may contain new variables, which we need to convert to new inference vars |
126 | let new_vars = Substitution( | 135 | let new_vars = Substitution( |
127 | solution | 136 | solution |
128 | .kinds | 137 | .binders |
129 | .iter() | 138 | .iter(&Interner) |
130 | .map(|k| match k { | 139 | .map(|k| match k.kind { |
131 | TyVariableKind::General => ctx.table.new_type_var(), | 140 | VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(), |
132 | TyVariableKind::Integer => ctx.table.new_integer_var(), | 141 | VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(), |
133 | TyVariableKind::Float => ctx.table.new_float_var(), | 142 | VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(), |
143 | // HACK: Chalk can sometimes return new lifetime variables. We | ||
144 | // want to just skip them, but to not mess up the indices of | ||
145 | // other variables, we'll just create a new type variable in | ||
146 | // their place instead. This should not matter (we never see the | ||
147 | // actual *uses* of the lifetime variable). | ||
148 | VariableKind::Lifetime => ctx.table.new_type_var(), | ||
149 | _ => panic!("const variable in solution"), | ||
134 | }) | 150 | }) |
135 | .collect(), | 151 | .collect(), |
136 | ); | 152 | ); |
@@ -147,8 +163,8 @@ impl<T> Canonicalized<T> { | |||
147 | pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { | 163 | pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { |
148 | let mut table = InferenceTable::new(); | 164 | let mut table = InferenceTable::new(); |
149 | let vars = Substitution( | 165 | let vars = Substitution( |
150 | tys.kinds | 166 | tys.binders |
151 | .iter() | 167 | .iter(&Interner) |
152 | // we always use type vars here because we want everything to | 168 | // we always use type vars here because we want everything to |
153 | // fallback to Unknown in the end (kind of hacky, as below) | 169 | // fallback to Unknown in the end (kind of hacky, as below) |
154 | .map(|_| table.new_type_var()) | 170 | .map(|_| table.new_type_var()) |
@@ -170,7 +186,7 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { | |||
170 | } | 186 | } |
171 | } | 187 | } |
172 | Some( | 188 | Some( |
173 | Substitution::builder(tys.kinds.len()) | 189 | Substitution::builder(tys.binders.len(&Interner)) |
174 | .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone()))) | 190 | .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone()))) |
175 | .build(), | 191 | .build(), |
176 | ) | 192 | ) |