Skip to content

Commit 0f058d6

Browse files
committed
Replace remaining fold calls
1 parent caee3b6 commit 0f058d6

File tree

3 files changed

+104
-59
lines changed

3 files changed

+104
-59
lines changed

crates/hir_ty/src/infer.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::mem;
1818
use std::ops::Index;
1919
use std::sync::Arc;
2020

21-
use chalk_ir::{cast::Cast, Mutability};
21+
use chalk_ir::{cast::Cast, DebruijnIndex, Mutability};
2222
use hir_def::{
2323
body::Body,
2424
data::{ConstData, FunctionData, StaticData},
@@ -41,8 +41,9 @@ use super::{
4141
TypeWalk,
4242
};
4343
use crate::{
44-
db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode,
45-
to_assoc_type_id, AliasEq, AliasTy, Canonical, Interner, TyBuilder, TyExt, TyKind,
44+
db::HirDatabase, fold_tys, infer::diagnostics::InferenceDiagnostic,
45+
lower::ImplTraitLoweringMode, to_assoc_type_id, AliasEq, AliasTy, Canonical, Interner,
46+
TyBuilder, TyExt, TyKind,
4647
};
4748

4849
// This lint has a false positive here. See the link below for details.
@@ -323,7 +324,7 @@ impl<'a> InferenceContext<'a> {
323324
}
324325

325326
fn insert_type_vars(&mut self, ty: Ty) -> Ty {
326-
ty.fold(&mut |ty| self.insert_type_vars_shallow(ty))
327+
fold_tys(ty, |ty, _| self.insert_type_vars_shallow(ty), DebruijnIndex::INNERMOST)
327328
}
328329

329330
fn resolve_obligations_as_possible(&mut self) {
@@ -434,12 +435,16 @@ impl<'a> InferenceContext<'a> {
434435
/// to do it as well.
435436
fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
436437
let ty = self.resolve_ty_as_possible(ty);
437-
ty.fold(&mut |ty| match ty.kind(&Interner) {
438-
TyKind::Alias(AliasTy::Projection(proj_ty)) => {
439-
self.normalize_projection_ty(proj_ty.clone())
440-
}
441-
_ => ty,
442-
})
438+
fold_tys(
439+
ty,
440+
|ty, _| match ty.kind(&Interner) {
441+
TyKind::Alias(AliasTy::Projection(proj_ty)) => {
442+
self.normalize_projection_ty(proj_ty.clone())
443+
}
444+
_ => ty,
445+
},
446+
DebruijnIndex::INNERMOST,
447+
)
443448
}
444449

445450
fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty {

crates/hir_ty/src/infer/unify.rs

Lines changed: 62 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
use std::borrow::Cow;
44

55
use chalk_ir::{
6-
interner::HasInterner, FloatTy, IntTy, TyVariableKind, UniverseIndex, VariableKind,
6+
fold::Fold, interner::HasInterner, FloatTy, IntTy, TyVariableKind, UniverseIndex, VariableKind,
77
};
88
use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
99

1010
use super::{DomainGoal, InferenceContext};
1111
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,
1515
};
1616

1717
impl<'a> InferenceContext<'a> {
@@ -53,9 +53,14 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
5353
})
5454
}
5555

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) {
5964
&TyKind::InferenceVar(var, kind) => {
6065
let inner = from_inference_var(var);
6166
if self.var_stack.contains(&inner) {
@@ -485,55 +490,63 @@ impl InferenceTable {
485490
/// be resolved as far as possible, i.e. contain no type variables with
486491
/// known type.
487492
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+
}
506514
}
507-
}
508-
_ => ty,
509-
})
515+
_ => ty,
516+
},
517+
DebruijnIndex::INNERMOST,
518+
)
510519
}
511520

512521
/// Resolves the type completely; type variables without known type are
513522
/// replaced by TyKind::Unknown.
514523
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+
}
533545
}
534-
}
535-
_ => ty,
536-
})
546+
_ => ty,
547+
},
548+
DebruijnIndex::INNERMOST,
549+
)
537550
}
538551
}
539552

crates/hir_ty/src/lib.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,3 +328,30 @@ pub(crate) fn fold_free_vars<T: HasInterner<Interner = Interner> + Fold<Interner
328328
}
329329
t.fold_with(&mut FreeVarFolder(f), DebruijnIndex::INNERMOST).expect("fold failed unexpectedly")
330330
}
331+
332+
pub(crate) fn fold_tys<T: HasInterner<Interner = Interner> + Fold<Interner>>(
333+
t: T,
334+
f: impl FnMut(Ty, DebruijnIndex) -> Ty,
335+
binders: DebruijnIndex,
336+
) -> T::Result {
337+
use chalk_ir::{
338+
fold::{Folder, SuperFold},
339+
Fallible,
340+
};
341+
struct TyFolder<F>(F);
342+
impl<'i, F: FnMut(Ty, DebruijnIndex) -> Ty + 'i> Folder<'i, Interner> for TyFolder<F> {
343+
fn as_dyn(&mut self) -> &mut dyn Folder<'i, Interner> {
344+
self
345+
}
346+
347+
fn interner(&self) -> &'i Interner {
348+
&Interner
349+
}
350+
351+
fn fold_ty(&mut self, ty: Ty, outer_binder: DebruijnIndex) -> Fallible<Ty> {
352+
let ty = ty.super_fold_with(self.as_dyn(), outer_binder)?;
353+
Ok(self.0(ty, outer_binder))
354+
}
355+
}
356+
t.fold_with(&mut TyFolder(f), binders).expect("fold failed unexpectedly")
357+
}

0 commit comments

Comments
 (0)