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.rs111
1 files changed, 62 insertions, 49 deletions
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index c3d9e81c3..ffa324b6d 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -3,15 +3,15 @@
3use std::borrow::Cow; 3use std::borrow::Cow;
4 4
5use chalk_ir::{ 5use chalk_ir::{
6 interner::HasInterner, FloatTy, IntTy, TyVariableKind, UniverseIndex, VariableKind, 6 fold::Fold, interner::HasInterner, FloatTy, IntTy, TyVariableKind, UniverseIndex, VariableKind,
7}; 7};
8use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; 8use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
9 9
10use super::{DomainGoal, InferenceContext}; 10use super::{DomainGoal, InferenceContext};
11use crate::{ 11use crate::{
12 AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSubst, 12 fold_tys, AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer,
13 InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyExt, TyKind, TypeWalk, 13 FnSubst, InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyExt, TyKind,
14 WhereClause, 14 TypeWalk, WhereClause,
15}; 15};
16 16
17impl<'a> InferenceContext<'a> { 17impl<'a> InferenceContext<'a> {
@@ -53,9 +53,14 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
53 }) 53 })
54 } 54 }
55 55
56 fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { 56 fn do_canonicalize<T: Fold<Interner, Result = T> + HasInterner<Interner = Interner>>(
57 t.fold_binders( 57 &mut self,
58 &mut |ty, binders| match ty.kind(&Interner) { 58 t: T,
59 binders: DebruijnIndex,
60 ) -> T {
61 fold_tys(
62 t,
63 |ty, binders| match ty.kind(&Interner) {
59 &TyKind::InferenceVar(var, kind) => { 64 &TyKind::InferenceVar(var, kind) => {
60 let inner = from_inference_var(var); 65 let inner = from_inference_var(var);
61 if self.var_stack.contains(&inner) { 66 if self.var_stack.contains(&inner) {
@@ -485,55 +490,63 @@ impl InferenceTable {
485 /// be resolved as far as possible, i.e. contain no type variables with 490 /// be resolved as far as possible, i.e. contain no type variables with
486 /// known type. 491 /// known type.
487 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 492 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
488 ty.fold(&mut |ty| match ty.kind(&Interner) { 493 fold_tys(
489 &TyKind::InferenceVar(tv, kind) => { 494 ty,
490 let inner = from_inference_var(tv); 495 |ty, _| match ty.kind(&Interner) {
491 if tv_stack.contains(&inner) { 496 &TyKind::InferenceVar(tv, kind) => {
492 cov_mark::hit!(type_var_cycles_resolve_as_possible); 497 let inner = from_inference_var(tv);
493 // recursive type 498 if tv_stack.contains(&inner) {
494 return self.type_variable_table.fallback_value(tv, kind); 499 cov_mark::hit!(type_var_cycles_resolve_as_possible);
495 } 500 // recursive type
496 if let Some(known_ty) = 501 return self.type_variable_table.fallback_value(tv, kind);
497 self.var_unification_table.inlined_probe_value(inner).known() 502 }
498 { 503 if let Some(known_ty) =
499 // known_ty may contain other variables that are known by now 504 self.var_unification_table.inlined_probe_value(inner).known()
500 tv_stack.push(inner); 505 {
501 let result = self.resolve_ty_as_possible_inner(tv_stack, known_ty.clone()); 506 // known_ty may contain other variables that are known by now
502 tv_stack.pop(); 507 tv_stack.push(inner);
503 result 508 let result = self.resolve_ty_as_possible_inner(tv_stack, known_ty.clone());
504 } else { 509 tv_stack.pop();
505 ty 510 result
511 } else {
512 ty
513 }
506 } 514 }
507 } 515 _ => ty,
508 _ => ty, 516 },
509 }) 517 DebruijnIndex::INNERMOST,
518 )
510 } 519 }
511 520
512 /// Resolves the type completely; type variables without known type are 521 /// Resolves the type completely; type variables without known type are
513 /// replaced by TyKind::Unknown. 522 /// replaced by TyKind::Unknown.
514 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 523 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
515 ty.fold(&mut |ty| match ty.kind(&Interner) { 524 fold_tys(
516 &TyKind::InferenceVar(tv, kind) => { 525 ty,
517 let inner = from_inference_var(tv); 526 |ty, _| match ty.kind(&Interner) {
518 if tv_stack.contains(&inner) { 527 &TyKind::InferenceVar(tv, kind) => {
519 cov_mark::hit!(type_var_cycles_resolve_completely); 528 let inner = from_inference_var(tv);
520 // recursive type 529 if tv_stack.contains(&inner) {
521 return self.type_variable_table.fallback_value(tv, kind); 530 cov_mark::hit!(type_var_cycles_resolve_completely);
522 } 531 // recursive type
523 if let Some(known_ty) = 532 return self.type_variable_table.fallback_value(tv, kind);
524 self.var_unification_table.inlined_probe_value(inner).known() 533 }
525 { 534 if let Some(known_ty) =
526 // known_ty may contain other variables that are known by now 535 self.var_unification_table.inlined_probe_value(inner).known()
527 tv_stack.push(inner); 536 {
528 let result = self.resolve_ty_completely_inner(tv_stack, known_ty.clone()); 537 // known_ty may contain other variables that are known by now
529 tv_stack.pop(); 538 tv_stack.push(inner);
530 result 539 let result = self.resolve_ty_completely_inner(tv_stack, known_ty.clone());
531 } else { 540 tv_stack.pop();
532 self.type_variable_table.fallback_value(tv, kind) 541 result
542 } else {
543 self.type_variable_table.fallback_value(tv, kind)
544 }
533 } 545 }
534 } 546 _ => ty,
535 _ => ty, 547 },
536 }) 548 DebruijnIndex::INNERMOST,
549 )
537 } 550 }
538} 551}
539 552