aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer/unify.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/infer/unify.rs')
-rw-r--r--crates/hir_ty/src/infer/unify.rs105
1 files changed, 61 insertions, 44 deletions
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 54fcfed10..16d89ed1b 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -7,8 +7,8 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
7 7
8use super::{InferenceContext, Obligation}; 8use super::{InferenceContext, Obligation};
9use crate::{ 9use crate::{
10 BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferenceVar, Scalar, 10 BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferenceVar, Interner,
11 Substs, Ty, TypeWalk, 11 Scalar, Substs, Ty, TyKind, TypeWalk,
12}; 12};
13 13
14impl<'a> InferenceContext<'a> { 14impl<'a> InferenceContext<'a> {
@@ -49,8 +49,8 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
49 49
50 fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { 50 fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T {
51 t.fold_binders( 51 t.fold_binders(
52 &mut |ty, binders| match ty { 52 &mut |ty, binders| match ty.interned(&Interner) {
53 Ty::InferenceVar(var, kind) => { 53 &TyKind::InferenceVar(var, kind) => {
54 let inner = var.to_inner(); 54 let inner = var.to_inner();
55 if self.var_stack.contains(&inner) { 55 if self.var_stack.contains(&inner) {
56 // recursive type 56 // recursive type
@@ -66,7 +66,7 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
66 } else { 66 } else {
67 let root = self.ctx.table.var_unification_table.find(inner); 67 let root = self.ctx.table.var_unification_table.find(inner);
68 let position = self.add(InferenceVar::from_inner(root), kind); 68 let position = self.add(InferenceVar::from_inner(root), kind);
69 Ty::BoundVar(BoundVar::new(binders, position)) 69 TyKind::BoundVar(BoundVar::new(binders, position)).intern(&Interner)
70 } 70 }
71 } 71 }
72 _ => ty, 72 _ => ty,
@@ -108,10 +108,10 @@ impl<T> Canonicalized<T> {
108 pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { 108 pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty {
109 ty.walk_mut_binders( 109 ty.walk_mut_binders(
110 &mut |ty, binders| { 110 &mut |ty, binders| {
111 if let &mut Ty::BoundVar(bound) = ty { 111 if let &mut TyKind::BoundVar(bound) = &mut ty.0 {
112 if bound.debruijn >= binders { 112 if bound.debruijn >= binders {
113 let (v, k) = self.free_vars[bound.index]; 113 let (v, k) = self.free_vars[bound.index];
114 *ty = Ty::InferenceVar(v, k); 114 *ty = TyKind::InferenceVar(v, k).intern(&Interner);
115 } 115 }
116 } 116 }
117 }, 117 },
@@ -142,7 +142,7 @@ impl<T> Canonicalized<T> {
142 // eagerly replace projections in the type; we may be getting types 142 // eagerly replace projections in the type; we may be getting types
143 // e.g. from where clauses where this hasn't happened yet 143 // e.g. from where clauses where this hasn't happened yet
144 let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars)); 144 let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars));
145 ctx.table.unify(&Ty::InferenceVar(v, k), &ty); 145 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty);
146 } 146 }
147 } 147 }
148} 148}
@@ -166,7 +166,10 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> {
166 // (kind of hacky) 166 // (kind of hacky)
167 for (i, var) in vars.iter().enumerate() { 167 for (i, var) in vars.iter().enumerate() {
168 if &*table.resolve_ty_shallow(var) == var { 168 if &*table.resolve_ty_shallow(var) == var {
169 table.unify(var, &Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i))); 169 table.unify(
170 var,
171 &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i)).intern(&Interner),
172 );
170 } 173 }
171 } 174 }
172 Some( 175 Some(
@@ -196,11 +199,12 @@ impl TypeVariableTable {
196 199
197 fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { 200 fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty {
198 match kind { 201 match kind {
199 _ if self.inner[iv.to_inner().0 as usize].diverging => Ty::Never, 202 _ if self.inner[iv.to_inner().0 as usize].diverging => TyKind::Never,
200 TyVariableKind::General => Ty::Unknown, 203 TyVariableKind::General => TyKind::Unknown,
201 TyVariableKind::Integer => Ty::Scalar(Scalar::Int(IntTy::I32)), 204 TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)),
202 TyVariableKind::Float => Ty::Scalar(Scalar::Float(FloatTy::F64)), 205 TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)),
203 } 206 }
207 .intern(&Interner)
204 } 208 }
205} 209}
206 210
@@ -227,7 +231,7 @@ impl InferenceTable {
227 self.type_variable_table.push(TypeVariableData { diverging }); 231 self.type_variable_table.push(TypeVariableData { diverging });
228 let key = self.var_unification_table.new_key(TypeVarValue::Unknown); 232 let key = self.var_unification_table.new_key(TypeVarValue::Unknown);
229 assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1); 233 assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1);
230 Ty::InferenceVar(InferenceVar::from_inner(key), kind) 234 TyKind::InferenceVar(InferenceVar::from_inner(key), kind).intern(&Interner)
231 } 235 }
232 236
233 pub(crate) fn new_type_var(&mut self) -> Ty { 237 pub(crate) fn new_type_var(&mut self) -> Ty {
@@ -290,12 +294,12 @@ impl InferenceTable {
290 } 294 }
291 295
292 pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { 296 pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool {
293 match (ty1, ty2) { 297 match (ty1.interned(&Interner), ty2.interned(&Interner)) {
294 (Ty::Unknown, _) | (_, Ty::Unknown) => true, 298 (TyKind::Unknown, _) | (_, TyKind::Unknown) => true,
295 299
296 (Ty::Placeholder(p1), Ty::Placeholder(p2)) if *p1 == *p2 => true, 300 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true,
297 301
298 (Ty::Dyn(dyn1), Ty::Dyn(dyn2)) if dyn1.len() == dyn2.len() => { 302 (TyKind::Dyn(dyn1), TyKind::Dyn(dyn2)) if dyn1.len() == dyn2.len() => {
299 for (pred1, pred2) in dyn1.iter().zip(dyn2.iter()) { 303 for (pred1, pred2) in dyn1.iter().zip(dyn2.iter()) {
300 if !self.unify_preds(pred1, pred2, depth + 1) { 304 if !self.unify_preds(pred1, pred2, depth + 1) {
301 return false; 305 return false;
@@ -305,16 +309,16 @@ impl InferenceTable {
305 } 309 }
306 310
307 ( 311 (
308 Ty::InferenceVar(tv1, TyVariableKind::General), 312 TyKind::InferenceVar(tv1, TyVariableKind::General),
309 Ty::InferenceVar(tv2, TyVariableKind::General), 313 TyKind::InferenceVar(tv2, TyVariableKind::General),
310 ) 314 )
311 | ( 315 | (
312 Ty::InferenceVar(tv1, TyVariableKind::Integer), 316 TyKind::InferenceVar(tv1, TyVariableKind::Integer),
313 Ty::InferenceVar(tv2, TyVariableKind::Integer), 317 TyKind::InferenceVar(tv2, TyVariableKind::Integer),
314 ) 318 )
315 | ( 319 | (
316 Ty::InferenceVar(tv1, TyVariableKind::Float), 320 TyKind::InferenceVar(tv1, TyVariableKind::Float),
317 Ty::InferenceVar(tv2, TyVariableKind::Float), 321 TyKind::InferenceVar(tv2, TyVariableKind::Float),
318 ) if self.type_variable_table.is_diverging(*tv1) 322 ) if self.type_variable_table.is_diverging(*tv1)
319 == self.type_variable_table.is_diverging(*tv2) => 323 == self.type_variable_table.is_diverging(*tv2) =>
320 { 324 {
@@ -326,24 +330,37 @@ impl InferenceTable {
326 // The order of MaybeNeverTypeVar matters here. 330 // The order of MaybeNeverTypeVar matters here.
327 // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. 331 // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar.
328 // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. 332 // Unifying MaybeNeverTypeVar and other concrete type will let the former become it.
329 (Ty::InferenceVar(tv, TyVariableKind::General), other) 333 (TyKind::InferenceVar(tv, TyVariableKind::General), other)
330 | (other, Ty::InferenceVar(tv, TyVariableKind::General)) 334 | (other, TyKind::InferenceVar(tv, TyVariableKind::General))
331 | (Ty::InferenceVar(tv, TyVariableKind::Integer), other @ Ty::Scalar(Scalar::Int(_)))
332 | (other @ Ty::Scalar(Scalar::Int(_)), Ty::InferenceVar(tv, TyVariableKind::Integer))
333 | ( 335 | (
334 Ty::InferenceVar(tv, TyVariableKind::Integer), 336 TyKind::InferenceVar(tv, TyVariableKind::Integer),
335 other @ Ty::Scalar(Scalar::Uint(_)), 337 other @ TyKind::Scalar(Scalar::Int(_)),
336 ) 338 )
337 | ( 339 | (
338 other @ Ty::Scalar(Scalar::Uint(_)), 340 other @ TyKind::Scalar(Scalar::Int(_)),
339 Ty::InferenceVar(tv, TyVariableKind::Integer), 341 TyKind::InferenceVar(tv, TyVariableKind::Integer),
340 ) 342 )
341 | (Ty::InferenceVar(tv, TyVariableKind::Float), other @ Ty::Scalar(Scalar::Float(_))) 343 | (
342 | (other @ Ty::Scalar(Scalar::Float(_)), Ty::InferenceVar(tv, TyVariableKind::Float)) => 344 TyKind::InferenceVar(tv, TyVariableKind::Integer),
343 { 345 other @ TyKind::Scalar(Scalar::Uint(_)),
346 )
347 | (
348 other @ TyKind::Scalar(Scalar::Uint(_)),
349 TyKind::InferenceVar(tv, TyVariableKind::Integer),
350 )
351 | (
352 TyKind::InferenceVar(tv, TyVariableKind::Float),
353 other @ TyKind::Scalar(Scalar::Float(_)),
354 )
355 | (
356 other @ TyKind::Scalar(Scalar::Float(_)),
357 TyKind::InferenceVar(tv, TyVariableKind::Float),
358 ) => {
344 // the type var is unknown since we tried to resolve it 359 // the type var is unknown since we tried to resolve it
345 self.var_unification_table 360 self.var_unification_table.union_value(
346 .union_value(tv.to_inner(), TypeVarValue::Known(other.clone())); 361 tv.to_inner(),
362 TypeVarValue::Known(other.clone().intern(&Interner)),
363 );
347 true 364 true
348 } 365 }
349 366
@@ -387,8 +404,8 @@ impl InferenceTable {
387 if i > 0 { 404 if i > 0 {
388 cov_mark::hit!(type_var_resolves_to_int_var); 405 cov_mark::hit!(type_var_resolves_to_int_var);
389 } 406 }
390 match &*ty { 407 match &ty.0 {
391 Ty::InferenceVar(tv, _) => { 408 TyKind::InferenceVar(tv, _) => {
392 let inner = tv.to_inner(); 409 let inner = tv.to_inner();
393 match self.var_unification_table.inlined_probe_value(inner).known() { 410 match self.var_unification_table.inlined_probe_value(inner).known() {
394 Some(known_ty) => { 411 Some(known_ty) => {
@@ -410,8 +427,8 @@ impl InferenceTable {
410 /// be resolved as far as possible, i.e. contain no type variables with 427 /// be resolved as far as possible, i.e. contain no type variables with
411 /// known type. 428 /// known type.
412 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 429 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
413 ty.fold(&mut |ty| match ty { 430 ty.fold(&mut |ty| match ty.interned(&Interner) {
414 Ty::InferenceVar(tv, kind) => { 431 &TyKind::InferenceVar(tv, kind) => {
415 let inner = tv.to_inner(); 432 let inner = tv.to_inner();
416 if tv_stack.contains(&inner) { 433 if tv_stack.contains(&inner) {
417 cov_mark::hit!(type_var_cycles_resolve_as_possible); 434 cov_mark::hit!(type_var_cycles_resolve_as_possible);
@@ -435,10 +452,10 @@ impl InferenceTable {
435 } 452 }
436 453
437 /// Resolves the type completely; type variables without known type are 454 /// Resolves the type completely; type variables without known type are
438 /// replaced by Ty::Unknown. 455 /// replaced by TyKind::Unknown.
439 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 456 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
440 ty.fold(&mut |ty| match ty { 457 ty.fold(&mut |ty| match ty.interned(&Interner) {
441 Ty::InferenceVar(tv, kind) => { 458 &TyKind::InferenceVar(tv, kind) => {
442 let inner = tv.to_inner(); 459 let inner = tv.to_inner();
443 if tv_stack.contains(&inner) { 460 if tv_stack.contains(&inner) {
444 cov_mark::hit!(type_var_cycles_resolve_completely); 461 cov_mark::hit!(type_var_cycles_resolve_completely);