aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r--crates/hir_ty/src/infer/unify.rs44
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
3use std::borrow::Cow; 3use std::borrow::Cow;
4 4
5use chalk_ir::{FloatTy, IntTy, TyVariableKind}; 5use chalk_ir::{FloatTy, IntTy, TyVariableKind, UniverseIndex, VariableKind};
6use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; 6use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
7 7
8use super::{DomainGoal, InferenceContext}; 8use super::{DomainGoal, InferenceContext};
9use crate::{ 9use 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
14impl<'a> InferenceContext<'a> { 14impl<'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> {
147pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { 163pub(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 )