From ecbd693ad110ff2acdec2a21b6cb6048c2008ee6 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 14 Mar 2026 20:42:33 +1100 Subject: [PATCH] Replace query `erase_and_anonymize_regions_ty` with a helper function --- compiler/rustc_middle/src/queries.rs | 14 ------------- compiler/rustc_middle/src/ty/context.rs | 4 ++++ compiler/rustc_middle/src/ty/erase_regions.rs | 20 +++++++++++-------- compiler/rustc_middle/src/ty/mod.rs | 1 - .../rustc_query_impl/src/from_cycle_error.rs | 5 ----- 5 files changed, 16 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index 6c30762725b77..790562f4b4eed 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -752,20 +752,6 @@ rustc_queries! { separate_provide_extern } - /// Erases regions from `ty` to yield a new type. - /// Normally you would just use `tcx.erase_and_anonymize_regions(value)`, - /// however, which uses this query as a kind of cache. - query erase_and_anonymize_regions_ty(ty: Ty<'tcx>) -> Ty<'tcx> { - // This query is not expected to have input -- as a result, it - // is not a good candidates for "replay" because it is essentially a - // pure function of its input (and hence the expectation is that - // no caller would be green **apart** from just these - // queries). Making it anonymous avoids hashing the result, which - // may save a bit of time. - anon - desc { "erasing regions from `{}`", ty } - } - query wasm_import_module_map(_: CrateNum) -> &'tcx DefIdMap { arena_cache desc { "getting wasm import module map" } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 91105f416c8f8..93172cd0251d0 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -823,6 +823,9 @@ pub struct GlobalCtxt<'tcx> { pub clauses_cache: Lock, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>, + /// Internal cache of erased types, used by [`TyCtxt::erase_and_anonymize_regions`]. + pub(crate) erase_and_anonymize_regions_ty_cache: ShardedHashMap, Ty<'tcx>>, + /// Data layout specification for the current target. pub data_layout: TargetDataLayout, @@ -1058,6 +1061,7 @@ impl<'tcx> TyCtxt<'tcx> { canonical_param_env_cache: Default::default(), highest_var_in_clauses_cache: Default::default(), clauses_cache: Default::default(), + erase_and_anonymize_regions_ty_cache: Default::default(), data_layout, alloc_map: interpret::AllocMap::new(), current_gcx, diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs index 74b4adda7fdd4..9f02eda533e09 100644 --- a/compiler/rustc_middle/src/ty/erase_regions.rs +++ b/compiler/rustc_middle/src/ty/erase_regions.rs @@ -1,18 +1,22 @@ use tracing::debug; -use crate::query::Providers; use crate::ty::{ self, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; -pub(super) fn provide(providers: &mut Providers) { - *providers = Providers { erase_and_anonymize_regions_ty, ..*providers }; -} - +/// Erases regions from `ty` to yield a new type. fn erase_and_anonymize_regions_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { + if let Some(erased_ty) = tcx.erase_and_anonymize_regions_ty_cache.get(&ty) { + return erased_ty; + } + // N.B., use `super_fold_with` here. If we used `fold_with`, it - // could invoke the `erase_and_anonymize_regions_ty` query recursively. - ty.super_fold_with(&mut RegionEraserAndAnonymizerVisitor { tcx }) + // could invoke `erase_and_anonymize_regions_ty` recursively. + let erased_ty = ty.super_fold_with(&mut RegionEraserAndAnonymizerVisitor { tcx }); + let old_ty = tcx.erase_and_anonymize_regions_ty_cache.insert(ty, erased_ty); + // If two threads raced to erase the same type, they should agree. + try { debug_assert_eq!(old_ty?, erased_ty) }; + erased_ty } impl<'tcx> TyCtxt<'tcx> { @@ -49,7 +53,7 @@ impl<'tcx> TypeFolder> for RegionEraserAndAnonymizerVisitor<'tcx> { } else if ty.has_infer() { ty.super_fold_with(self) } else { - self.tcx.erase_and_anonymize_regions_ty(ty) + erase_and_anonymize_regions_ty(self.tcx, ty) } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 6abe7d1466990..66c909646f594 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2202,7 +2202,6 @@ impl<'tcx> TyCtxt<'tcx> { pub fn provide(providers: &mut Providers) { closure::provide(providers); context::provide(providers); - erase_regions::provide(providers); inhabitedness::provide(providers); util::provide(providers); print::provide(providers); diff --git a/compiler/rustc_query_impl/src/from_cycle_error.rs b/compiler/rustc_query_impl/src/from_cycle_error.rs index 6a3155c02949e..6077e2f1c34f1 100644 --- a/compiler/rustc_query_impl/src/from_cycle_error.rs +++ b/compiler/rustc_query_impl/src/from_cycle_error.rs @@ -31,11 +31,6 @@ pub(crate) fn specialize_query_vtables<'tcx>(vtables: &mut QueryVTables<'tcx>) { erase_val(ty::EarlyBinder::bind(Ty::new_error(tcx, guar))) }; - vtables.erase_and_anonymize_regions_ty.value_from_cycle_error = |tcx, _, _, err| { - let guar = err.emit(); - erase_val(Ty::new_error(tcx, guar)) - }; - vtables.fn_sig.value_from_cycle_error = |tcx, key, _, err| { let guar = err.delay_as_bug(); erase_val(fn_sig(tcx, key, guar))