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