From 0f058d61cea9805897702654bcca146fd0cdc507 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Thu, 8 Apr 2021 13:32:48 +0200 Subject: Replace remaining `fold` calls --- crates/hir_ty/src/infer/unify.rs | 111 ++++++++++++++++++++++----------------- 1 file changed, 62 insertions(+), 49 deletions(-) (limited to 'crates/hir_ty/src/infer') 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 @@ use std::borrow::Cow; use chalk_ir::{ - interner::HasInterner, FloatTy, IntTy, TyVariableKind, UniverseIndex, VariableKind, + fold::Fold, interner::HasInterner, FloatTy, IntTy, TyVariableKind, UniverseIndex, VariableKind, }; use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; use super::{DomainGoal, InferenceContext}; use crate::{ - AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSubst, - InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyExt, TyKind, TypeWalk, - WhereClause, + fold_tys, AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, + FnSubst, InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyExt, TyKind, + TypeWalk, WhereClause, }; impl<'a> InferenceContext<'a> { @@ -53,9 +53,14 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { }) } - fn do_canonicalize(&mut self, t: T, binders: DebruijnIndex) -> T { - t.fold_binders( - &mut |ty, binders| match ty.kind(&Interner) { + fn do_canonicalize + HasInterner>( + &mut self, + t: T, + binders: DebruijnIndex, + ) -> T { + fold_tys( + t, + |ty, binders| match ty.kind(&Interner) { &TyKind::InferenceVar(var, kind) => { let inner = from_inference_var(var); if self.var_stack.contains(&inner) { @@ -485,55 +490,63 @@ impl InferenceTable { /// be resolved as far as possible, i.e. contain no type variables with /// known type. fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec, ty: Ty) -> Ty { - ty.fold(&mut |ty| match ty.kind(&Interner) { - &TyKind::InferenceVar(tv, kind) => { - let inner = from_inference_var(tv); - if tv_stack.contains(&inner) { - cov_mark::hit!(type_var_cycles_resolve_as_possible); - // recursive type - return self.type_variable_table.fallback_value(tv, kind); - } - if let Some(known_ty) = - self.var_unification_table.inlined_probe_value(inner).known() - { - // known_ty may contain other variables that are known by now - tv_stack.push(inner); - let result = self.resolve_ty_as_possible_inner(tv_stack, known_ty.clone()); - tv_stack.pop(); - result - } else { - ty + fold_tys( + ty, + |ty, _| match ty.kind(&Interner) { + &TyKind::InferenceVar(tv, kind) => { + let inner = from_inference_var(tv); + if tv_stack.contains(&inner) { + cov_mark::hit!(type_var_cycles_resolve_as_possible); + // recursive type + return self.type_variable_table.fallback_value(tv, kind); + } + if let Some(known_ty) = + self.var_unification_table.inlined_probe_value(inner).known() + { + // known_ty may contain other variables that are known by now + tv_stack.push(inner); + let result = self.resolve_ty_as_possible_inner(tv_stack, known_ty.clone()); + tv_stack.pop(); + result + } else { + ty + } } - } - _ => ty, - }) + _ => ty, + }, + DebruijnIndex::INNERMOST, + ) } /// Resolves the type completely; type variables without known type are /// replaced by TyKind::Unknown. fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec, ty: Ty) -> Ty { - ty.fold(&mut |ty| match ty.kind(&Interner) { - &TyKind::InferenceVar(tv, kind) => { - let inner = from_inference_var(tv); - if tv_stack.contains(&inner) { - cov_mark::hit!(type_var_cycles_resolve_completely); - // recursive type - return self.type_variable_table.fallback_value(tv, kind); - } - if let Some(known_ty) = - self.var_unification_table.inlined_probe_value(inner).known() - { - // known_ty may contain other variables that are known by now - tv_stack.push(inner); - let result = self.resolve_ty_completely_inner(tv_stack, known_ty.clone()); - tv_stack.pop(); - result - } else { - self.type_variable_table.fallback_value(tv, kind) + fold_tys( + ty, + |ty, _| match ty.kind(&Interner) { + &TyKind::InferenceVar(tv, kind) => { + let inner = from_inference_var(tv); + if tv_stack.contains(&inner) { + cov_mark::hit!(type_var_cycles_resolve_completely); + // recursive type + return self.type_variable_table.fallback_value(tv, kind); + } + if let Some(known_ty) = + self.var_unification_table.inlined_probe_value(inner).known() + { + // known_ty may contain other variables that are known by now + tv_stack.push(inner); + let result = self.resolve_ty_completely_inner(tv_stack, known_ty.clone()); + tv_stack.pop(); + result + } else { + self.type_variable_table.fallback_value(tv, kind) + } } - } - _ => ty, - }) + _ => ty, + }, + DebruijnIndex::INNERMOST, + ) } } -- cgit v1.2.3