Auto merge of #145717 - BoxyUwU:erase_regions_rename, r=lcnr

rename erase_regions to erase_and_anonymize_regions

I find it consistently confusing that `erase_regions` does more than replacing regions with `'erased`. it also makes some code look real goofy to be writing manual folders to erase regions with a comment saying "we cant use erase regions" :> or code that re-calls erase_regions on types with regions already erased just to anonymize all the bound regions.

r? lcnr

idk how i feel about the name being almost twice as long now
This commit is contained in:
bors 2025-09-09 15:04:44 +00:00
commit 364da5d88d
60 changed files with 162 additions and 137 deletions

View file

@ -615,7 +615,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}
// Type-test failed. Report the error.
let erased_generic_kind = infcx.tcx.erase_regions(type_test.generic_kind);
let erased_generic_kind = infcx.tcx.erase_and_anonymize_regions(type_test.generic_kind);
// Skip duplicate-ish errors.
if deduplicate_errors.insert((

View file

@ -341,7 +341,7 @@ fn compute_concrete_types_from_defining_uses<'tcx>(
//
// FIXME(-Znext-solver): This isn't necessary after all. We can remove this check again.
if let Some((prev_decl_key, prev_span)) = decls_modulo_regions.insert(
rcx.infcx.tcx.erase_regions(opaque_type_key),
rcx.infcx.tcx.erase_and_anonymize_regions(opaque_type_key),
(opaque_type_key, hidden_type.span),
) && let Some((arg1, arg2)) = std::iter::zip(
prev_decl_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg),

View file

@ -1892,7 +1892,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
if is_diverging {
// The signature in this call can reference region variables,
// so erase them before calling a query.
let output_ty = self.tcx().erase_regions(sig.output());
let output_ty = self.tcx().erase_and_anonymize_regions(sig.output());
if !output_ty
.is_privately_uninhabited(self.tcx(), self.infcx.typing_env(self.infcx.param_env))
{
@ -1986,7 +1986,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let op_arg_ty = self.normalize(op_arg_ty, term_location);
let category = if call_source.from_hir_call() {
ConstraintCategory::CallArgument(Some(self.infcx.tcx.erase_regions(func_ty)))
ConstraintCategory::CallArgument(Some(
self.infcx.tcx.erase_and_anonymize_regions(func_ty),
))
} else {
ConstraintCategory::Boring
};
@ -2120,7 +2122,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// Erase the regions from `ty` to get a global type. The
// `Sized` bound in no way depends on precise regions, so this
// shouldn't affect `is_sized`.
let erased_ty = tcx.erase_regions(ty);
let erased_ty = tcx.erase_and_anonymize_regions(ty);
// FIXME(#132279): Using `Ty::is_sized` causes us to incorrectly handle opaques here.
if !erased_ty.is_sized(tcx, self.infcx.typing_env(self.infcx.param_env)) {
// in current MIR construction, all non-control-flow rvalue

View file

@ -240,7 +240,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
// Make sure lifetimes are erased, to avoid generating distinct LLVM
// types for Rust types that only differ in the choice of lifetimes.
let normal_ty = cx.tcx.erase_regions(self.ty);
let normal_ty = cx.tcx.erase_and_anonymize_regions(self.ty);
let mut defer = None;
let ty = if self.ty != normal_ty {

View file

@ -1436,7 +1436,7 @@ fn build_vtable_type_di_node<'ll, 'tcx>(
let vtable_entries = if let Some(poly_trait_ref) = poly_trait_ref {
let trait_ref = poly_trait_ref.with_self_ty(tcx, ty);
let trait_ref = tcx.erase_regions(trait_ref);
let trait_ref = tcx.erase_and_anonymize_regions(trait_ref);
tcx.vtable_entries(trait_ref)
} else {
@ -1563,7 +1563,7 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>(
// Unwrap potential addrspacecast
let vtable = find_vtable_behind_cast(vtable);
let trait_ref_self = trait_ref.with_self_ty(cx.tcx, ty);
let trait_ref_self = cx.tcx.erase_regions(trait_ref_self);
let trait_ref_self = cx.tcx.erase_and_anonymize_regions(trait_ref_self);
let trait_def_id = trait_ref_self.def_id;
let trait_vis = cx.tcx.visibility(trait_def_id);

View file

@ -231,7 +231,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
// Make sure lifetimes are erased, to avoid generating distinct LLVM
// types for Rust types that only differ in the choice of lifetimes.
let normal_ty = cx.tcx.erase_regions(self.ty);
let normal_ty = cx.tcx.erase_and_anonymize_regions(self.ty);
let mut defer = None;
let llty = if self.ty != normal_ty {

View file

@ -23,7 +23,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
) -> InterpResult<'tcx, Pointer<Option<M::Provenance>>> {
trace!("get_vtable(ty={ty:?}, dyn_ty={dyn_ty:?})");
let (ty, dyn_ty) = self.tcx.erase_regions((ty, dyn_ty));
let (ty, dyn_ty) = self.tcx.erase_and_anonymize_regions((ty, dyn_ty));
// All vtables must be monomorphic, bail out otherwise.
ensure_monomorphic_enough(*self.tcx, ty)?;
@ -53,8 +53,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
) -> &'tcx [VtblEntry<'tcx>] {
if let Some(trait_) = trait_ {
let trait_ref = trait_.with_self_ty(*self.tcx, dyn_ty);
let trait_ref =
self.tcx.erase_regions(self.tcx.instantiate_bound_regions_with_erased(trait_ref));
let trait_ref = self.tcx.erase_and_anonymize_regions(
self.tcx.instantiate_bound_regions_with_erased(trait_ref),
);
self.tcx.vtable_entries(trait_ref)
} else {
TyCtxt::COMMON_VTABLE_ENTRIES

View file

@ -1047,7 +1047,7 @@ fn check_type_defn<'tcx>(
let needs_drop_copy = || {
packed && {
let ty = tcx.type_of(variant.tail().did).instantiate_identity();
let ty = tcx.erase_regions(ty);
let ty = tcx.erase_and_anonymize_regions(ty);
assert!(!ty.has_infer());
ty.needs_drop(tcx, wfcx.infcx.typing_env(wfcx.param_env))
}

View file

@ -404,7 +404,7 @@ fn emit_orphan_check_error<'tcx>(
of_trait.trait_ref.path.span
};
ty = tcx.erase_regions(ty);
ty = tcx.erase_and_anonymize_regions(ty);
let is_foreign =
!trait_ref.def_id.is_local() && matches!(is_target_ty, IsFirstInputType::No);

View file

@ -482,7 +482,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
.map(|header| header.trait_ref.instantiate_identity().self_ty())
// We don't care about blanket impls.
.filter(|self_ty| !self_ty.has_non_region_param())
.map(|self_ty| tcx.erase_regions(self_ty).to_string())
.map(|self_ty| tcx.erase_and_anonymize_regions(self_ty).to_string())
.collect()
};
// FIXME: also look at `tcx.generics_of(self.item_def_id()).params` any that

View file

@ -851,8 +851,8 @@ impl<'a, 'tcx> CastCheck<'tcx> {
debug!("check_ptr_ptr_cast m_src={m_src:?} m_dst={m_dst:?}");
// ptr-ptr cast. metadata must match.
let src_kind = fcx.tcx.erase_regions(fcx.pointer_kind(m_src.ty, self.span)?);
let dst_kind = fcx.tcx.erase_regions(fcx.pointer_kind(m_dst.ty, self.span)?);
let src_kind = fcx.tcx.erase_and_anonymize_regions(fcx.pointer_kind(m_src.ty, self.span)?);
let dst_kind = fcx.tcx.erase_and_anonymize_regions(fcx.pointer_kind(m_dst.ty, self.span)?);
// We can't cast if target pointer kind is unknown
let Some(dst_kind) = dst_kind else {

View file

@ -1358,7 +1358,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.infcx
.type_implements_trait(
clone_trait_def,
[self.tcx.erase_regions(expected_ty)],
[self.tcx.erase_and_anonymize_regions(expected_ty)],
self.param_env,
)
.must_apply_modulo_regions()

View file

@ -44,7 +44,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
if ty.has_non_region_infer() {
Ty::new_misc_error(self.tcx())
} else {
self.tcx().erase_regions(ty)
self.tcx().erase_and_anonymize_regions(ty)
}
}

View file

@ -802,7 +802,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
format!("unexpected inference variable after writeback: {predicate:?}"),
);
} else {
let predicate = self.tcx().erase_regions(predicate);
let predicate = self.tcx().erase_and_anonymize_regions(predicate);
if cause.has_infer() || cause.has_placeholders() {
// We can't use the the obligation cause as it references
// information local to this query.
@ -984,8 +984,8 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
// borrowck, and specifically region constraints will be populated during
// MIR typeck which is run on the new body.
//
// We're not using `tcx.erase_regions` as that also anonymizes bound variables,
// regressing borrowck diagnostics.
// We're not using `tcx.erase_and_anonymize_regions` as that also
// anonymizes bound variables, regressing borrowck diagnostics.
value = fold_regions(tcx, value, |_, _| tcx.lifetimes.re_erased);
// Normalize consts in writeback, because GCE doesn't normalize eagerly.

View file

@ -76,7 +76,7 @@ pub(super) fn can_match_erased_ty<'tcx>(
erased_ty: Ty<'tcx>,
) -> bool {
assert!(!outlives_predicate.has_escaping_bound_vars());
let erased_outlives_predicate = tcx.erase_regions(outlives_predicate);
let erased_outlives_predicate = tcx.erase_and_anonymize_regions(outlives_predicate);
let outlives_ty = erased_outlives_predicate.skip_binder().0;
if outlives_ty == erased_ty {
// pointless micro-optimization

View file

@ -96,7 +96,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
&self,
alias_ty: ty::AliasTy<'tcx>,
) -> Vec<ty::PolyTypeOutlivesPredicate<'tcx>> {
let erased_alias_ty = self.tcx.erase_regions(alias_ty.to_ty(self.tcx));
let erased_alias_ty = self.tcx.erase_and_anonymize_regions(alias_ty.to_ty(self.tcx));
self.declared_generic_bounds_from_env_for_erased_ty(erased_alias_ty)
}
@ -241,7 +241,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
}
let p_ty = p.to_ty(tcx);
let erased_p_ty = self.tcx.erase_regions(p_ty);
let erased_p_ty = self.tcx.erase_and_anonymize_regions(p_ty);
(erased_p_ty == erased_ty).then_some(ty::Binder::dummy(ty::OutlivesPredicate(p_ty, r)))
}));

View file

@ -78,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
{
// erase regions in self type for better diagnostic presentation
let (self_ty, target_principal, supertrait_principal) =
tcx.erase_regions((self_ty, target_principal, supertrait_principal));
tcx.erase_and_anonymize_regions((self_ty, target_principal, supertrait_principal));
let label2 = tcx
.associated_items(item.owner_id)
.find_by_ident_and_kind(

View file

@ -176,7 +176,7 @@ fn suggest_question_mark<'tcx>(
cause,
param_env,
// Erase any region vids from the type, which may not be resolved
infcx.tcx.erase_regions(ty),
infcx.tcx.erase_and_anonymize_regions(ty),
into_iterator_did,
);

View file

@ -935,7 +935,7 @@ impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences {
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
if let hir::ItemKind::Enum(_, _, ref enum_definition) = it.kind {
let t = cx.tcx.type_of(it.owner_id).instantiate_identity();
let ty = cx.tcx.erase_regions(t);
let ty = cx.tcx.erase_and_anonymize_regions(t);
let Ok(layout) = cx.layout_of(ty) else { return };
let Variants::Multiple { tag_encoding: TagEncoding::Direct, tag, variants, .. } =
&layout.variants

View file

@ -41,7 +41,7 @@ impl<'tcx> TyCtxt<'tcx> {
let instance = ty::Instance::new_raw(def_id, args);
let cid = GlobalId { instance, promoted: None };
let typing_env = ty::TypingEnv::post_analysis(self, def_id);
let inputs = self.erase_regions(typing_env.as_query_input(cid));
let inputs = self.erase_and_anonymize_regions(typing_env.as_query_input(cid));
self.eval_to_allocation_raw(inputs)
}
@ -172,8 +172,9 @@ impl<'tcx> TyCtxt<'tcx> {
) -> EvalToConstValueResult<'tcx> {
// Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
// improve caching of queries.
let inputs =
self.erase_regions(typing_env.with_post_analysis_normalized(self).as_query_input(cid));
let inputs = self.erase_and_anonymize_regions(
typing_env.with_post_analysis_normalized(self).as_query_input(cid),
);
if !span.is_dummy() {
// The query doesn't know where it is being invoked, so we need to fix the span.
self.at(span).eval_to_const_value_raw(inputs).map_err(|e| e.with_span(span))
@ -192,8 +193,9 @@ impl<'tcx> TyCtxt<'tcx> {
) -> ConstToValTreeResult<'tcx> {
// Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
// improve caching of queries.
let inputs =
self.erase_regions(typing_env.with_post_analysis_normalized(self).as_query_input(cid));
let inputs = self.erase_and_anonymize_regions(
typing_env.with_post_analysis_normalized(self).as_query_input(cid),
);
debug!(?inputs);
let res = if !span.is_dummy() {
// The query doesn't know where it is being invoked, so we need to fix the span.

View file

@ -761,9 +761,9 @@ rustc_queries! {
}
/// Erases regions from `ty` to yield a new type.
/// Normally you would just use `tcx.erase_regions(value)`,
/// Normally you would just use `tcx.erase_and_anonymize_regions(value)`,
/// however, which uses this query as a kind of cache.
query erase_regions_ty(ty: Ty<'tcx>) -> Ty<'tcx> {
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

View file

@ -55,7 +55,7 @@ impl<'tcx> TyCtxt<'tcx> {
ty::ConstKind::Unevaluated(uv) => match self.tcx.thir_abstract_const(uv.def) {
Err(e) => ty::Const::new_error(self.tcx, e),
Ok(Some(bac)) => {
let args = self.tcx.erase_regions(uv.args);
let args = self.tcx.erase_and_anonymize_regions(uv.args);
let bac = bac.instantiate(self.tcx, args);
return bac.fold_with(self);
}

View file

@ -6,20 +6,20 @@ use crate::ty::{
};
pub(super) fn provide(providers: &mut Providers) {
*providers = Providers { erase_regions_ty, ..*providers };
*providers = Providers { erase_and_anonymize_regions_ty, ..*providers };
}
fn erase_regions_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
fn erase_and_anonymize_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 })
// could invoke the `erase_and_anonymize_regions_ty` query recursively.
ty.super_fold_with(&mut RegionEraserAndAnonymizerVisitor { tcx })
}
impl<'tcx> TyCtxt<'tcx> {
/// Returns an equivalent value with all free regions removed (note
/// that late-bound regions remain, because they are important for
/// subtyping, but they are anonymized and normalized as well)..
pub fn erase_regions<T>(self, value: T) -> T
/// Returns an equivalent value with all free regions removed and
/// bound regions anonymized. (note that bound regions are important
/// for subtyping and generally type equality so *cannot* be removed)
pub fn erase_and_anonymize_regions<T>(self, value: T) -> T
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
@ -27,18 +27,18 @@ impl<'tcx> TyCtxt<'tcx> {
if !value.has_type_flags(TypeFlags::HAS_BINDER_VARS | TypeFlags::HAS_FREE_REGIONS) {
return value;
}
debug!("erase_regions({:?})", value);
let value1 = value.fold_with(&mut RegionEraserVisitor { tcx: self });
debug!("erase_regions = {:?}", value1);
debug!("erase_and_anonymize_regions({:?})", value);
let value1 = value.fold_with(&mut RegionEraserAndAnonymizerVisitor { tcx: self });
debug!("erase_and_anonymize_regions = {:?}", value1);
value1
}
}
struct RegionEraserVisitor<'tcx> {
struct RegionEraserAndAnonymizerVisitor<'tcx> {
tcx: TyCtxt<'tcx>,
}
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RegionEraserVisitor<'tcx> {
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RegionEraserAndAnonymizerVisitor<'tcx> {
fn cx(&self) -> TyCtxt<'tcx> {
self.tcx
}
@ -49,7 +49,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RegionEraserVisitor<'tcx> {
} else if ty.has_infer() {
ty.super_fold_with(self)
} else {
self.tcx.erase_regions_ty(ty)
self.tcx.erase_and_anonymize_regions_ty(ty)
}
}

View file

@ -544,7 +544,9 @@ impl<'tcx> Instance<'tcx> {
// All regions in the result of this query are erased, so it's
// fine to erase all of the input regions.
tcx.resolve_instance_raw(tcx.erase_regions(typing_env.as_query_input((def_id, args))))
tcx.resolve_instance_raw(
tcx.erase_and_anonymize_regions(typing_env.as_query_input((def_id, args))),
)
}
pub fn expect_resolve(

View file

@ -401,7 +401,10 @@ impl<'tcx> SizeSkeleton<'tcx> {
match tail.kind() {
ty::Param(_) | ty::Alias(ty::Projection | ty::Inherent, _) => {
debug_assert!(tail.has_non_region_param());
Ok(SizeSkeleton::Pointer { non_zero, tail: tcx.erase_regions(tail) })
Ok(SizeSkeleton::Pointer {
non_zero,
tail: tcx.erase_and_anonymize_regions(tail),
})
}
ty::Error(guar) => {
// Fixes ICE #124031

View file

@ -51,7 +51,7 @@ impl<'tcx> TyCtxt<'tcx> {
// Erase first before we do the real query -- this keeps the
// cache from being too polluted.
let value = self.erase_regions(value);
let value = self.erase_and_anonymize_regions(value);
debug!(?value);
if !value.has_aliases() {
@ -83,7 +83,7 @@ impl<'tcx> TyCtxt<'tcx> {
// Erase first before we do the real query -- this keeps the
// cache from being too polluted.
let value = self.erase_regions(value);
let value = self.erase_and_anonymize_regions(value);
debug!(?value);
if !value.has_aliases() {

View file

@ -1436,8 +1436,8 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
// anonymized regions, but the super projections can still
// contain named regions. So we erase and anonymize everything
// here to compare the types modulo regions below.
let proj = p.tcx().erase_regions(proj);
let super_proj = p.tcx().erase_regions(super_proj);
let proj = p.tcx().erase_and_anonymize_regions(proj);
let super_proj = p.tcx().erase_and_anonymize_regions(super_proj);
proj == super_proj
});

View file

@ -131,10 +131,9 @@ impl<'tcx> TyCtxt<'tcx> {
/// Creates a hash of the type `Ty` which will be the same no matter what crate
/// context it's calculated within. This is used by the `type_id` intrinsic.
pub fn type_id_hash(self, ty: Ty<'tcx>) -> Hash128 {
// We want the type_id be independent of the types free regions, so we
// erase them. The erase_regions() call will also anonymize bound
// regions, which is desirable too.
let ty = self.erase_regions(ty);
// We don't have region information, so we erase all free regions. Equal types
// must have the same `TypeId`, so we must anonymize all bound regions as well.
let ty = self.erase_and_anonymize_regions(ty);
self.with_stable_hashing_context(|mut hcx| {
let mut hasher = StableHasher::new();
@ -1309,7 +1308,7 @@ impl<'tcx> Ty<'tcx> {
debug_assert!(!typing_env.param_env.has_infer());
let query_ty = tcx
.try_normalize_erasing_regions(typing_env, query_ty)
.unwrap_or_else(|_| tcx.erase_regions(query_ty));
.unwrap_or_else(|_| tcx.erase_and_anonymize_regions(query_ty));
tcx.needs_drop_raw(typing_env.as_query_input(query_ty))
}
@ -1346,7 +1345,7 @@ impl<'tcx> Ty<'tcx> {
debug_assert!(!typing_env.has_infer());
let query_ty = tcx
.try_normalize_erasing_regions(typing_env, query_ty)
.unwrap_or_else(|_| tcx.erase_regions(query_ty));
.unwrap_or_else(|_| tcx.erase_and_anonymize_regions(query_ty));
tcx.needs_async_drop_raw(typing_env.as_query_input(query_ty))
}

View file

@ -89,7 +89,7 @@ pub(super) fn vtable_allocation_provider<'tcx>(
let vtable_entries = if let Some(poly_trait_ref) = poly_trait_ref {
let trait_ref = poly_trait_ref.with_self_ty(tcx, ty);
let trait_ref = tcx.erase_regions(trait_ref);
let trait_ref = tcx.erase_and_anonymize_regions(trait_ref);
tcx.vtable_entries(trait_ref)
} else {

View file

@ -64,10 +64,10 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> {
"`become` outside of functions should have been disallowed by hir_typeck"
)
};
// While the `caller_sig` does have its regions erased, it does not have its
// binders anonymized. We call `erase_regions` once again to anonymize any binders
// While the `caller_sig` does have its free regions erased, it does not have its
// binders anonymized. We call `erase_and_anonymize_regions` once again to anonymize any binders
// within the signature, such as in function pointer or `dyn Trait` args.
let caller_sig = self.tcx.erase_regions(caller_sig);
let caller_sig = self.tcx.erase_and_anonymize_regions(caller_sig);
let ExprKind::Scope { value, .. } = call.kind else {
span_bug!(call.span, "expected scope, found: {call:?}")

View file

@ -792,10 +792,9 @@ impl<'tcx> ThirBuildCx<'tcx> {
let ty = self.typeck_results.node_type(anon_const.hir_id);
let did = anon_const.def_id.to_def_id();
let typeck_root_def_id = tcx.typeck_root_def_id(did);
let parent_args = tcx.erase_regions(GenericArgs::identity_for_item(
tcx,
typeck_root_def_id,
));
let parent_args = tcx.erase_and_anonymize_regions(
GenericArgs::identity_for_item(tcx, typeck_root_def_id),
);
let args =
InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty })
.args;
@ -831,8 +830,10 @@ impl<'tcx> ThirBuildCx<'tcx> {
let ty = self.typeck_results.node_type(anon_const.hir_id);
let did = anon_const.def_id.to_def_id();
let typeck_root_def_id = tcx.typeck_root_def_id(did);
let parent_args =
tcx.erase_regions(GenericArgs::identity_for_item(tcx, typeck_root_def_id));
let parent_args = tcx.erase_and_anonymize_regions(GenericArgs::identity_for_item(
tcx,
typeck_root_def_id,
));
let args = InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty }).args;
ExprKind::ConstBlock { did, args }

View file

@ -105,9 +105,11 @@ impl<'tcx> ConstToPat<'tcx> {
//
// FIXME: `const_eval_resolve_for_typeck` should probably just modify the env itself
// instead of having this logic here
let typing_env =
self.tcx.erase_regions(self.typing_env).with_post_analysis_normalized(self.tcx);
let uv = self.tcx.erase_regions(uv);
let typing_env = self
.tcx
.erase_and_anonymize_regions(self.typing_env)
.with_post_analysis_normalized(self.tcx);
let uv = self.tcx.erase_and_anonymize_regions(uv);
// try to resolve e.g. associated constants to their definition on an impl, and then
// evaluate the const.

View file

@ -891,7 +891,7 @@ pub fn iter_fields<'tcx>(
let field_ty = f_def.ty(tcx, args);
let field_ty = tcx
.try_normalize_erasing_regions(typing_env, field_ty)
.unwrap_or_else(|_| tcx.erase_regions(field_ty));
.unwrap_or_else(|_| tcx.erase_and_anonymize_regions(field_ty));
f(variant, f_index.into(), field_ty);
}
}

View file

@ -32,8 +32,8 @@ 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(rval_ty);
place_ty = self.tcx.erase_regions(place_ty);
rval_ty = self.tcx.erase_and_anonymize_regions(rval_ty);
place_ty = self.tcx.erase_and_anonymize_regions(place_ty);
if place_ty != rval_ty {
let temp = self
.patcher

View file

@ -875,7 +875,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
let mut promoted_operand = |ty, span| {
promoted.span = span;
promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span);
let args = tcx.erase_regions(GenericArgs::identity_for_item(tcx, def));
let args =
tcx.erase_and_anonymize_regions(GenericArgs::identity_for_item(tcx, def));
let uneval =
mir::UnevaluatedConst { def, args, promoted: Some(next_promoted_index) };

View file

@ -1558,7 +1558,7 @@ impl<'v> RootCollector<'_, 'v> {
ty::Closure(def_id, args)
| ty::Coroutine(def_id, args)
| ty::CoroutineClosure(def_id, args) => {
Instance::new_raw(def_id, self.tcx.erase_regions(args))
Instance::new_raw(def_id, self.tcx.erase_and_anonymize_regions(args))
}
_ => unreachable!(),
};

View file

@ -54,7 +54,7 @@ pub(super) fn mangle<'tcx>(
// Erase regions because they may not be deterministic when hashed
// and should not matter anyhow.
let instance_ty = tcx.erase_regions(instance_ty);
let instance_ty = tcx.erase_and_anonymize_regions(instance_ty);
let hash = get_symbol_hash(tcx, instance, instance_ty, instantiating_crate);
@ -422,7 +422,10 @@ impl<'tcx> Printer<'tcx> for LegacySymbolMangler<'tcx> {
|| &args[..generics.count()]
== self
.tcx
.erase_regions(ty::GenericArgs::identity_for_item(self.tcx, impl_def_id))
.erase_and_anonymize_regions(ty::GenericArgs::identity_for_item(
self.tcx,
impl_def_id,
))
.as_slice()
{
(

View file

@ -58,7 +58,7 @@ impl SymbolNamesTest<'_> {
let def_id = def_id.to_def_id();
let instance = Instance::new_raw(
def_id,
tcx.erase_regions(GenericArgs::identity_for_item(tcx, def_id)),
tcx.erase_and_anonymize_regions(GenericArgs::identity_for_item(tcx, def_id)),
);
let mangled = tcx.symbol_name(instance);
tcx.dcx().emit_err(TestOutput {

View file

@ -329,7 +329,10 @@ impl<'tcx> Printer<'tcx> for V0SymbolMangler<'tcx> {
|| &args[..generics.count()]
== self
.tcx
.erase_regions(ty::GenericArgs::identity_for_item(self.tcx, impl_def_id))
.erase_and_anonymize_regions(ty::GenericArgs::identity_for_item(
self.tcx,
impl_def_id,
))
.as_slice()
{
(
@ -339,7 +342,7 @@ impl<'tcx> Printer<'tcx> for V0SymbolMangler<'tcx> {
)
} else {
assert!(
!args.has_non_region_param(),
!args.has_non_region_param() && !args.has_free_regions(),
"should not be mangling partially substituted \
polymorphic instance: {impl_def_id:?} {args:?}"
);

View file

@ -1616,8 +1616,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
&& let Some((e, f)) = values.ty()
&& let TypeError::ArgumentSorts(..) | TypeError::Sorts(_) = terr
{
let e = self.tcx.erase_regions(e);
let f = self.tcx.erase_regions(f);
let e = self.tcx.erase_and_anonymize_regions(e);
let f = self.tcx.erase_and_anonymize_regions(f);
let mut expected = with_forced_trimmed_paths!(e.sort_string(self.tcx));
let mut found = with_forced_trimmed_paths!(f.sort_string(self.tcx));
if let ObligationCauseCode::Pattern { span, .. } = cause.code()

View file

@ -629,7 +629,11 @@ impl<T> Trait<T> for X {
let tcx = self.tcx;
// Don't suggest constraining a projection to something containing itself
if self.tcx.erase_regions(values.found).contains(self.tcx.erase_regions(values.expected)) {
if self
.tcx
.erase_and_anonymize_regions(values.found)
.contains(self.tcx.erase_and_anonymize_regions(values.expected))
{
return;
}

View file

@ -75,7 +75,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
{
if let Some(cause) = self
.tcx
.diagnostic_hir_wf_check((tcx.erase_regions(obligation.predicate), *wf_loc))
.diagnostic_hir_wf_check((tcx.erase_and_anonymize_regions(obligation.predicate), *wf_loc))
{
obligation.cause = cause.clone();
span = obligation.cause.span;
@ -2612,8 +2612,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}
// Erase regions because layout code doesn't particularly care about regions.
let trait_pred =
self.tcx.erase_regions(self.tcx.instantiate_bound_regions_with_erased(trait_pred));
let trait_pred = self.tcx.erase_and_anonymize_regions(
self.tcx.instantiate_bound_regions_with_erased(trait_pred),
);
let src_and_dst = rustc_transmute::Types {
dst: trait_pred.trait_ref.args.type_at(0),

View file

@ -2442,7 +2442,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
// Look for a type inside the coroutine interior that matches the target type to get
// a span.
let target_ty_erased = self.tcx.erase_regions(target_ty);
let target_ty_erased = self.tcx.erase_and_anonymize_regions(target_ty);
let ty_matches = |ty| -> bool {
// Careful: the regions for types that appear in the
// coroutine interior are not generally known, so we
@ -2454,10 +2454,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
// interior generally contain "bound regions" to
// represent regions that are part of the suspended
// coroutine frame. Bound regions are preserved by
// `erase_regions` and so we must also call
// `erase_and_anonymize_regions` and so we must also call
// `instantiate_bound_regions_with_erased`.
let ty_erased = self.tcx.instantiate_bound_regions_with_erased(ty);
let ty_erased = self.tcx.erase_regions(ty_erased);
let ty_erased = self.tcx.erase_and_anonymize_regions(ty_erased);
let eq = ty_erased == target_ty_erased;
debug!(?ty_erased, ?target_ty_erased, ?eq);
eq

View file

@ -300,7 +300,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
) -> Result<Certainty, NoSolution> {
// Erase regions because we compute layouts in `rustc_transmute`,
// which will ICE for region vars.
let (dst, src) = self.tcx.erase_regions((dst, src));
let (dst, src) = self.tcx.erase_and_anonymize_regions((dst, src));
let Some(assume) = rustc_transmute::Assume::from_const(self.tcx, assume) else {
return Err(NoSolution);

View file

@ -759,7 +759,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IllegalSelfTypeVisitor<'tcx> {
)),
)
.map(|trait_ref| {
self.tcx.erase_regions(
self.tcx.erase_and_anonymize_regions(
self.tcx.instantiate_bound_regions_with_erased(trait_ref),
)
})

View file

@ -576,7 +576,7 @@ pub fn try_evaluate_const<'tcx>(
let args =
replace_param_and_infer_args_with_placeholder(tcx, uv.args);
let typing_env = infcx
.typing_env(tcx.erase_regions(param_env))
.typing_env(tcx.erase_and_anonymize_regions(param_env))
.with_post_analysis_normalized(tcx);
(args, typing_env)
}
@ -589,7 +589,7 @@ pub fn try_evaluate_const<'tcx>(
}
} else {
let typing_env = infcx
.typing_env(tcx.erase_regions(param_env))
.typing_env(tcx.erase_and_anonymize_regions(param_env))
.with_post_analysis_normalized(tcx);
(uv.args, typing_env)
}
@ -634,14 +634,14 @@ pub fn try_evaluate_const<'tcx>(
}
let typing_env = infcx
.typing_env(tcx.erase_regions(param_env))
.typing_env(tcx.erase_and_anonymize_regions(param_env))
.with_post_analysis_normalized(tcx);
(uv.args, typing_env)
}
};
let uv = ty::UnevaluatedConst::new(uv.def, args);
let erased_uv = tcx.erase_regions(uv);
let erased_uv = tcx.erase_and_anonymize_regions(uv);
use rustc_middle::mir::interpret::ErrorHandled;
// FIXME: `def_span` will point at the definition of this const; ideally, we'd point at

View file

@ -350,7 +350,9 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
// Note that we don't care about whether the resume type has any drops since this is
// redundant; there is no storage for the resume type, so if it is actually stored
// in the interior, we'll already detect the need for a drop by checking the interior.
let typing_env = tcx.erase_regions(typing_env);
//
// FIXME(@lcnr): Why do we erase regions in the env here? Seems odd
let typing_env = tcx.erase_and_anonymize_regions(typing_env);
let needs_drop = tcx.mir_coroutine_witnesses(def_id).is_some_and(|witness| {
witness.field_tys.iter().any(|field| field.ty.needs_drop(tcx, typing_env))
});

View file

@ -73,7 +73,7 @@ pub(crate) fn codegen_select_candidate<'tcx>(
}
let impl_source = infcx.resolve_vars_if_possible(impl_source);
let impl_source = tcx.erase_regions(impl_source);
let impl_source = tcx.erase_and_anonymize_regions(impl_source);
if impl_source.has_non_region_infer() {
// Unused generic types or consts on an impl get replaced with inference vars,
// but never resolved, causing the return value of a query to contain inference

View file

@ -41,7 +41,7 @@ fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<TyCtxt<'tcx>> + Par
// fresh `InferCtxt`. If this assert does trigger, it will give
// us a test case.
debug_assert_eq!(normalized_value, resolved_value);
let erased = infcx.tcx.erase_regions(resolved_value);
let erased = infcx.tcx.erase_and_anonymize_regions(resolved_value);
debug_assert!(!erased.has_infer(), "{erased:?}");
Ok(erased)
}

View file

@ -163,7 +163,7 @@ pub mod rustc {
ty: Ty<'tcx>,
) -> Result<Layout<'tcx>, &'tcx LayoutError<'tcx>> {
use rustc_middle::ty::layout::LayoutOf;
let ty = cx.tcx().erase_regions(ty);
let ty = cx.tcx().erase_and_anonymize_regions(ty);
cx.layout_of(ty).map(|tl| tl.layout)
}
}

View file

@ -426,24 +426,23 @@ pub(crate) mod rustc {
assert!(def.is_enum());
// Computes the layout of a variant.
let layout_of_variant =
|index, encoding: Option<TagEncoding<VariantIdx>>| -> Result<Self, Err> {
let variant_layout = ty_variant(cx, (ty, layout), index);
if variant_layout.is_uninhabited() {
return Ok(Self::uninhabited());
}
let tag = cx.tcx().tag_for_variant(
cx.typing_env.as_query_input((cx.tcx().erase_regions(ty), index)),
);
let variant_def = Def::Variant(def.variant(index));
Self::from_variant(
variant_def,
tag.map(|tag| (tag, index, encoding.unwrap())),
(ty, variant_layout),
layout.size,
cx,
)
};
let layout_of_variant = |index, encoding: Option<_>| -> Result<Self, Err> {
let variant_layout = ty_variant(cx, (ty, layout), index);
if variant_layout.is_uninhabited() {
return Ok(Self::uninhabited());
}
let tag = cx.tcx().tag_for_variant(
cx.typing_env.as_query_input((cx.tcx().erase_and_anonymize_regions(ty), index)),
);
let variant_def = Def::Variant(def.variant(index));
Self::from_variant(
variant_def,
tag.map(|tag| (tag, index, encoding.unwrap())),
(ty, variant_layout),
layout.size,
cx,
)
};
match layout.variants() {
Variants::Empty => Ok(Self::uninhabited()),
@ -634,7 +633,7 @@ pub(crate) mod rustc {
(ty, layout): (Ty<'tcx>, Layout<'tcx>),
i: VariantIdx,
) -> Layout<'tcx> {
let ty = cx.tcx().erase_regions(ty);
let ty = cx.tcx().erase_and_anonymize_regions(ty);
TyAndLayout { ty, layout }.for_variant(&cx, i).layout
}
}

View file

@ -176,7 +176,7 @@ fn resolve_associated_item<'tcx>(
args,
leaf_def.defining_node,
);
let args = infcx.tcx.erase_regions(args);
let args = infcx.tcx.erase_and_anonymize_regions(args);
// HACK: We may have overlapping `dyn Trait` built-in impls and
// user-provided blanket impls. Detect that case here, and return
@ -222,7 +222,7 @@ fn resolve_associated_item<'tcx>(
return Err(guar);
}
let args = tcx.erase_regions(args);
let args = tcx.erase_and_anonymize_regions(args);
// We check that the impl item is compatible with the trait item
// because otherwise we may ICE in const eval due to type mismatches,
@ -279,7 +279,7 @@ fn resolve_associated_item<'tcx>(
assert_eq!(name, sym::clone_from);
// Use the default `fn clone_from` from `trait Clone`.
let args = tcx.erase_regions(rcvr_args);
let args = tcx.erase_and_anonymize_regions(rcvr_args);
Some(ty::Instance::new_raw(trait_item_id, args))
}
} else if tcx.is_lang_item(trait_ref.def_id, LangItem::FnPtrTrait) {
@ -380,7 +380,7 @@ fn resolve_associated_item<'tcx>(
} else if tcx.is_lang_item(trait_ref.def_id, LangItem::TransmuteTrait) {
let name = tcx.item_name(trait_item_id);
assert_eq!(name, sym::transmute);
let args = tcx.erase_regions(rcvr_args);
let args = tcx.erase_and_anonymize_regions(rcvr_args);
Some(ty::Instance::new_raw(trait_item_id, args))
} else {
Instance::try_resolve_item_for_coroutine(tcx, trait_item_id, trait_id, rcvr_args)

View file

@ -398,9 +398,9 @@ impl std::fmt::Debug for HasTypeFlagsVisitor {
// looks, particular for `Ty`/`Predicate` where it's just a field access.
//
// N.B. The only case where this isn't totally true is binders, which also
// add `HAS_{RE,TY,CT}_LATE_BOUND` flag depending on the *bound variables* that
// add `HAS_BINDER_VARS` flag depending on the *bound variables* that
// are present, regardless of whether those bound variables are used. This
// is important for anonymization of binders in `TyCtxt::erase_regions`. We
// is important for anonymization of binders in `TyCtxt::erase_and_anonymize_regions`. We
// specifically detect this case in `visit_binder`.
impl<I: Interner> TypeVisitor<I> for HasTypeFlagsVisitor {
type Result = ControlFlow<FoundFlags>;

View file

@ -364,7 +364,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
// priority.
if let Some(fn_id) = typeck.type_dependent_def_id(hir_id)
&& let Some(trait_id) = cx.tcx.trait_of_assoc(fn_id)
&& let arg_ty = cx.tcx.erase_regions(adjusted_ty)
&& let arg_ty = cx.tcx.erase_and_anonymize_regions(adjusted_ty)
&& let ty::Ref(_, sub_ty, _) = *arg_ty.kind()
&& let args =
typeck.node_args_opt(hir_id).map(|args| &args[1..]).unwrap_or_default()

View file

@ -140,7 +140,7 @@ fn is_ref_iterable<'tcx>(
let res_ty = cx
.tcx
.erase_regions(EarlyBinder::bind(req_res_ty).instantiate(cx.tcx, typeck.node_args(call_expr.hir_id)));
.erase_and_anonymize_regions(EarlyBinder::bind(req_res_ty).instantiate(cx.tcx, typeck.node_args(call_expr.hir_id)));
let mutbl = if let ty::Ref(_, _, mutbl) = *req_self_ty.kind() {
Some(mutbl)
} else {

View file

@ -252,7 +252,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
{
(
trait_item_id,
FnKind::ImplTraitFn(std::ptr::from_ref(cx.tcx.erase_regions(trait_ref.args)) as usize),
FnKind::ImplTraitFn(std::ptr::from_ref(cx.tcx.erase_and_anonymize_regions(trait_ref.args)) as usize),
usize::from(sig.decl.implicit_self.has_implicit_self()),
)
} else {

View file

@ -45,7 +45,7 @@ pub(super) fn check<'tcx>(
Applicability::MaybeIncorrect,
);
triggered = true;
} else if (cx.tcx.erase_regions(from_ty) != cx.tcx.erase_regions(to_ty)) && !const_context {
} else if (cx.tcx.erase_and_anonymize_regions(from_ty) != cx.tcx.erase_and_anonymize_regions(to_ty)) && !const_context {
span_lint_and_then(
cx,
TRANSMUTE_PTR_TO_PTR,

View file

@ -12,8 +12,8 @@ pub(super) fn check<'tcx>(
from_ty_orig: Ty<'tcx>,
to_ty_orig: Ty<'tcx>,
) -> bool {
let mut from_ty = cx.tcx.erase_regions(from_ty_orig);
let mut to_ty = cx.tcx.erase_regions(to_ty_orig);
let mut from_ty = cx.tcx.erase_and_anonymize_regions(from_ty_orig);
let mut to_ty = cx.tcx.erase_and_anonymize_regions(to_ty_orig);
while from_ty != to_ty {
let reduced_tys = reduce_refs(cx, from_ty, to_ty);

View file

@ -98,7 +98,7 @@ fn into_iter_bound<'tcx>(
if tr.def_id() == into_iter_did {
into_iter_span = Some(*span);
} else {
let tr = cx.tcx.erase_regions(tr);
let tr = cx.tcx.erase_and_anonymize_regions(tr);
if tr.has_escaping_bound_vars() {
return None;
}

View file

@ -285,7 +285,7 @@ pub fn implements_trait_with_env_from_iter<'tcx>(
let _ = tcx.hir_body_owner_kind(callee_id);
}
let ty = tcx.erase_regions(ty);
let ty = tcx.erase_and_anonymize_regions(ty);
if ty.has_escaping_bound_vars() {
return false;
}