Skip to content

Use a full cache for erasing regions #140814

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions compiler/rustc_hir_typeck/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
14 changes: 0 additions & 14 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> {
arena_cache
desc { "getting wasm import module map" }
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Proxy>,

pub erased_ty_cache: Lock<FxHashMap<Ty<'tcx>, Ty<'tcx>>>,
}

impl<'tcx> GlobalCtxt<'tcx> {
Expand Down Expand Up @@ -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)
Expand Down
19 changes: 8 additions & 11 deletions compiler/rustc_middle/src/ty/erase_regions.rs
Original file line number Diff line number Diff line change
@@ -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> {
Expand Down Expand Up @@ -46,10 +45,8 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> 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)
}
}

Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading