diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 5bfc3e810d9fd..c044c4f7c37de 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -490,11 +490,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { && let Some(from_trait) = fcx.tcx.get_diagnostic_item(sym::From) { let ty = fcx.resolve_vars_if_possible(self.cast_ty); - // Erase regions to avoid panic in `prove_value` when calling - // `type_implements_trait`. - let ty = fcx.tcx.erase_regions(ty); let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); - let expr_ty = fcx.tcx.erase_regions(expr_ty); if fcx .infcx .type_implements_trait(from_trait, [ty, expr_ty], fcx.param_env) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index b2133fea08cc3..22eef79d7df4a 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -678,20 +678,6 @@ rustc_queries! { separate_provide_extern } - /// Erases regions from `ty` to yield a new type. - /// Normally you would just use `tcx.erase_regions(value)`, - /// however, which uses this query as a kind of cache. - query erase_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 0759fa3da428a..59b6e27b835d0 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1454,6 +1454,8 @@ pub struct GlobalCtxt<'tcx> { /// A jobserver reference used to release then acquire a token while waiting on a query. pub jobserver_proxy: Arc, + + pub erased_ty_cache: Lock, Ty<'tcx>>>, } impl<'tcx> GlobalCtxt<'tcx> { @@ -1694,6 +1696,7 @@ impl<'tcx> TyCtxt<'tcx> { alloc_map: interpret::AllocMap::new(), current_gcx, jobserver_proxy, + erased_ty_cache: Default::default(), }); // This is a separate function to work around a crash with parallel rustc (#135870) diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs index 45a0b1288db87..0730ff373381a 100644 --- a/compiler/rustc_middle/src/ty/erase_regions.rs +++ b/compiler/rustc_middle/src/ty/erase_regions.rs @@ -1,18 +1,17 @@ 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_regions_ty, ..*providers }; -} - fn erase_regions_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { - // N.B., use `super_fold_with` here. If we used `fold_with`, it - // could invoke the `erase_regions_ty` query recursively. - ty.super_fold_with(&mut RegionEraserVisitor { tcx }) + if let Some(erased) = tcx.erased_ty_cache.lock().get(&ty) { + *erased + } else { + let erased = ty.super_fold_with(&mut RegionEraserVisitor { tcx }); + tcx.erased_ty_cache.lock().insert(ty, erased); + erased + } } impl<'tcx> TyCtxt<'tcx> { @@ -46,10 +45,8 @@ impl<'tcx> TypeFolder> for RegionEraserVisitor<'tcx> { fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { if !ty.has_type_flags(TypeFlags::HAS_BINDER_VARS | TypeFlags::HAS_FREE_REGIONS) { ty - } else if ty.has_infer() { - ty.super_fold_with(self) } else { - self.tcx.erase_regions_ty(ty) + erase_regions_ty(self.tcx, ty) } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 2d69a1c2b553e..c4cc9c22d3a59 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2242,7 +2242,6 @@ pub fn ast_uint_ty(uty: UintTy) -> ast::UintTy { 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_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 0250c777faf79..6fd6aff0e2b23 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1453,9 +1453,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { // contain named regions. So we erase and anonymize everything // here to compare the types modulo regions below. let proj = cx.tcx().erase_regions(proj); - let proj = cx.tcx().anonymize_bound_vars(proj); let super_proj = cx.tcx().erase_regions(super_proj); - let super_proj = cx.tcx().anonymize_bound_vars(super_proj); proj == super_proj }); diff --git a/compiler/rustc_mir_transform/src/add_subtyping_projections.rs b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs index b5cd41334598b..92ee80eaa353e 100644 --- a/compiler/rustc_mir_transform/src/add_subtyping_projections.rs +++ b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs @@ -32,7 +32,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeChecker<'a, 'tcx> { let mut rval_ty = rvalue.ty(self.local_decls, self.tcx); // Not erasing this causes `Free Regions` errors in validator, // when rval is `ReStatic`. - rval_ty = self.tcx.erase_regions_ty(rval_ty); + rval_ty = self.tcx.erase_regions(rval_ty); place_ty = self.tcx.erase_regions(place_ty); if place_ty != rval_ty { let temp = self