diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 307110d9fbc2c..2dbe9f2dcc5f5 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -515,6 +515,10 @@ impl<'cx, 'tcx> TypeFolder> for Canonicalizer<'cx, 'tcx> { ct } } + + fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { + if p.flags().intersects(self.needs_canonical_flags) { p.super_fold_with(self) } else { p } + } } impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 4a99c2209755d..496931a94c5d4 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -56,6 +56,10 @@ impl<'a, 'tcx> TypeFolder> for OpportunisticVarResolver<'a, 'tcx> { ct.super_fold_with(self) } } + + fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { + if !p.has_non_region_infer() { p } else { p.super_fold_with(self) } + } } /// The opportunistic region resolver opportunistically resolves regions diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs index c9b9ec771b324..79ee9bd328d93 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -63,7 +63,12 @@ impl<'tcx> TyCtxt<'tcx> { }, _ => c, }; - ct.super_fold_with(self) + + if ct.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) { + ct.super_fold_with(self) + } else { + ct + } } } ac.fold_with(&mut Expander { tcx: self }) diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs index f25c48cf42ab7..efa4b07752407 100644 --- a/compiler/rustc_middle/src/ty/erase_regions.rs +++ b/compiler/rustc_middle/src/ty/erase_regions.rs @@ -64,4 +64,20 @@ impl<'tcx> TypeFolder> for RegionEraserVisitor<'tcx> { _ => self.tcx.lifetimes.re_erased, } } + + fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { + if ct.has_type_flags(TypeFlags::HAS_BINDER_VARS | TypeFlags::HAS_FREE_REGIONS) { + ct.super_fold_with(self) + } else { + ct + } + } + + fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { + if p.has_type_flags(TypeFlags::HAS_BINDER_VARS | TypeFlags::HAS_FREE_REGIONS) { + p.super_fold_with(self) + } else { + p + } + } } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index de337710b5ef7..a8ac5f01e7ba5 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -376,6 +376,22 @@ pub fn normalize_param_env_or_error<'tcx>( c } + + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { + if t.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) { + t.super_fold_with(self) + } else { + t + } + } + + fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { + if p.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) { + p.super_fold_with(self) + } else { + p + } + } } // This whole normalization step is a hack to work around the fact that diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index e9055940310d0..7512e032fe73a 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -697,12 +697,24 @@ impl<'a, I: Interner> TypeFolder for ArgFolder<'a, I> { } fn fold_const(&mut self, c: I::Const) -> I::Const { + if !c.has_param() { + return c; + } + if let ty::ConstKind::Param(p) = c.kind() { self.const_for_param(p, c) } else { c.super_fold_with(self) } } + + fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate { + if !p.has_param() { + return p; + } + + p.super_fold_with(self) + } } impl<'a, I: Interner> ArgFolder<'a, I> { diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index 0bc8b94bbf4cc..034ca7bfa127b 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -54,7 +54,7 @@ use tracing::{debug, instrument}; use crate::inherent::*; use crate::visit::{TypeVisitable, TypeVisitableExt as _}; -use crate::{self as ty, Interner}; +use crate::{self as ty, Interner, TypeFlags}; #[cfg(feature = "nightly")] type Never = !; @@ -502,4 +502,34 @@ impl<'a, I: Interner> TypeFolder for RegionFolder<'a, I> { } } } + + fn fold_ty(&mut self, t: I::Ty) -> I::Ty { + if t.has_type_flags( + TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_BOUND | TypeFlags::HAS_RE_ERASED, + ) { + t.super_fold_with(self) + } else { + t + } + } + + fn fold_const(&mut self, ct: I::Const) -> I::Const { + if ct.has_type_flags( + TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_BOUND | TypeFlags::HAS_RE_ERASED, + ) { + ct.super_fold_with(self) + } else { + ct + } + } + + fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate { + if p.has_type_flags( + TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_BOUND | TypeFlags::HAS_RE_ERASED, + ) { + p.super_fold_with(self) + } else { + p + } + } }