From 39a990d2f126b4751bd7821f26d166e07b073915 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 14 Jul 2022 12:35:09 +0200 Subject: [PATCH 1/2] remove `ct.has_vars_bound_at_or_above` calls `ty::Const` doesn't have precomputed type flags, so computing `has_vars_bound_at_or_above` for constants requires us to visit the const and its contained types and constants. A noop fold should be pretty much equally as fast so removing it prevents us from walking the constant twice in case it contains bound vars. --- compiler/rustc_middle/src/ty/fold.rs | 3 +-- compiler/rustc_trait_selection/src/traits/project.rs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index f8893ae29f58e..6b1ee83aff3b2 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -445,8 +445,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> { let ct = (self.fld_c)(bound_const, ct.ty()); ty::fold::shift_vars(self.tcx, ct, self.current_index.as_u32()) } - _ if ct.has_vars_bound_at_or_above(self.current_index) => ct.super_fold_with(self), - _ => ct, + _ => ct.super_fold_with(self), } } } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index b3e7fbb357828..054308e441a49 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -753,8 +753,7 @@ impl<'tcx> TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> { .tcx .mk_const(ty::ConstS { kind: ty::ConstKind::Placeholder(p), ty: ct.ty() }) } - _ if ct.has_vars_bound_at_or_above(self.current_index) => ct.super_fold_with(self), - _ => ct, + _ => ct.super_fold_with(self), } } } From 864d2f35280aadeaf63f6e7efa483e173ebd62f6 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 14 Jul 2022 12:47:38 +0200 Subject: [PATCH 2/2] eagerly check for bound vars of predicates --- compiler/rustc_middle/src/ty/fold.rs | 4 ++++ compiler/rustc_trait_selection/src/traits/project.rs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 6b1ee83aff3b2..878f31af00f07 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -448,6 +448,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> { _ => ct.super_fold_with(self), } } + + fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { + if p.has_vars_bound_at_or_above(self.current_index) { p.super_fold_with(self) } else { p } + } } impl<'tcx> TyCtxt<'tcx> { diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 054308e441a49..9de4d3a646cb3 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -756,6 +756,10 @@ impl<'tcx> TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> { _ => ct.super_fold_with(self), } } + + fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { + if p.has_vars_bound_at_or_above(self.current_index) { p.super_fold_with(self) } else { p } + } } // The inverse of `BoundVarReplacer`: replaces placeholders with the bound vars from which they came.