From caee3b6c2d9a7dbcf678cc06d0c1832a4bf19be4 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Wed, 7 Apr 2021 21:26:37 +0200 Subject: Replace some `fold` calls --- crates/hir_ty/src/infer/unify.rs | 19 ++++--------------- crates/hir_ty/src/lib.rs | 26 ++++++++++++++++++++++++++ crates/hir_ty/src/lower.rs | 26 ++++++++++---------------- crates/hir_ty/src/method_resolution.rs | 29 +++++++++++++---------------- 4 files changed, 53 insertions(+), 47 deletions(-) (limited to 'crates') diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 3732d8ebd..c3d9e81c3 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs @@ -118,21 +118,10 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { impl> Canonicalized { pub(super) fn decanonicalize_ty(&self, ty: Ty) -> Ty { - ty.fold_binders( - &mut |ty, binders| { - if let TyKind::BoundVar(bound) = ty.kind(&Interner) { - if bound.debruijn >= binders { - let (v, k) = self.free_vars[bound.index]; - TyKind::InferenceVar(v, k).intern(&Interner) - } else { - ty - } - } else { - ty - } - }, - DebruijnIndex::INNERMOST, - ) + crate::fold_free_vars(ty, |bound, _binders| { + let (v, k) = self.free_vars[bound.index]; + TyKind::InferenceVar(v, k).intern(&Interner) + }) } pub(super) fn apply_solution( diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 7d4793c2f..60680ec86 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs @@ -302,3 +302,29 @@ pub fn dummy_usize_const() -> Const { } .intern(&Interner) } + +pub(crate) fn fold_free_vars + Fold>( + t: T, + f: impl FnMut(BoundVar, DebruijnIndex) -> Ty, +) -> T::Result { + use chalk_ir::{fold::Folder, Fallible}; + struct FreeVarFolder(F); + impl<'i, F: FnMut(BoundVar, DebruijnIndex) -> Ty + 'i> Folder<'i, Interner> for FreeVarFolder { + fn as_dyn(&mut self) -> &mut dyn Folder<'i, Interner> { + self + } + + fn interner(&self) -> &'i Interner { + &Interner + } + + fn fold_free_var_ty( + &mut self, + bound_var: BoundVar, + outer_binder: DebruijnIndex, + ) -> Fallible { + Ok(self.0(bound_var, outer_binder)) + } + } + t.fold_with(&mut FreeVarFolder(f), DebruijnIndex::INNERMOST).expect("fold failed unexpectedly") +} diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index b45e811fa..109157a5e 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs @@ -1016,22 +1016,16 @@ pub(crate) fn generic_defaults_query( p.default.as_ref().map_or(TyKind::Error.intern(&Interner), |t| ctx.lower_ty(t)); // Each default can only refer to previous parameters. - ty = ty.fold_binders( - &mut |ty, binders| match ty.kind(&Interner) { - TyKind::BoundVar(BoundVar { debruijn, index }) if *debruijn == binders => { - if *index >= idx { - // type variable default referring to parameter coming - // after it. This is forbidden (FIXME: report - // diagnostic) - TyKind::Error.intern(&Interner) - } else { - ty - } - } - _ => ty, - }, - DebruijnIndex::INNERMOST, - ); + ty = crate::fold_free_vars(ty, |bound, binders| { + if bound.index >= idx && bound.debruijn == DebruijnIndex::INNERMOST { + // type variable default referring to parameter coming + // after it. This is forbidden (FIXME: report + // diagnostic) + TyKind::Error.intern(&Interner) + } else { + bound.shifted_in_from(binders).to_ty(&Interner) + } + }); crate::make_only_type_binders(idx, ty) }) diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index 7e09a1539..766880b14 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs @@ -6,7 +6,11 @@ use std::{iter, sync::Arc}; use arrayvec::ArrayVec; use base_db::CrateId; -use chalk_ir::{cast::Cast, Mutability, UniverseIndex}; +use chalk_ir::{ + cast::Cast, + fold::{Fold, Folder}, + Fallible, Mutability, UniverseIndex, +}; use hir_def::{ lang_item::LangItemTarget, nameres::DefMap, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule, ImplId, Lookup, ModuleId, TraitId, @@ -21,7 +25,7 @@ use crate::{ primitive::{self, FloatTy, IntTy, UintTy}, static_lifetime, utils::all_super_traits, - AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId, + AdtId, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId, InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, TypeWalk, }; @@ -757,20 +761,13 @@ pub(crate) fn inherent_impl_substs( /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past /// num_vars_to_keep) by `TyKind::Unknown`. fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution { - s.fold_binders( - &mut |ty, binders| { - if let TyKind::BoundVar(bound) = ty.kind(&Interner) { - if bound.index >= num_vars_to_keep && bound.debruijn >= binders { - TyKind::Error.intern(&Interner) - } else { - ty - } - } else { - ty - } - }, - DebruijnIndex::INNERMOST, - ) + crate::fold_free_vars(s, |bound, binders| { + if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST { + TyKind::Error.intern(&Interner) + } else { + bound.shifted_in_from(binders).to_ty(&Interner) + } + }) } fn transform_receiver_ty( -- cgit v1.2.3