replace unnecessary folder impls with fold_region

This commit is contained in:
lcnr 2023-11-15 17:40:54 +00:00
parent 00bfd6b273
commit 41cfb20abb
4 changed files with 15 additions and 51 deletions

View File

@ -864,6 +864,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
};
// Use the underlying local for this (necessarily interior) borrow.
debug_assert!(region.is_erased());
let ty = local_decls[place.local].ty;
let span = statement.source_info.span;
@ -873,8 +874,6 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
ty::TypeAndMut { ty, mutbl: borrow_kind.to_mutbl_lossy() },
);
*region = tcx.lifetimes.re_erased;
let mut projection = vec![PlaceElem::Deref];
projection.extend(place.projection);
place.projection = tcx.mk_place_elems(&projection);

View File

@ -5,7 +5,7 @@ use rustc_hir::{ForeignItem, ForeignItemKind};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{ObligationCause, WellFormedLoc};
use rustc_middle::query::Providers;
use rustc_middle::ty::{self, Region, TyCtxt, TypeFoldable, TypeFolder};
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::def_id::LocalDefId;
use rustc_trait_selection::traits::{self, ObligationCtxt};
@ -68,7 +68,13 @@ fn diagnostic_hir_wf_check<'tcx>(
let infcx = self.tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx);
let tcx_ty = self.icx.to_ty(ty).fold_with(&mut EraseAllBoundRegions { tcx: self.tcx });
let tcx_ty = self.icx.to_ty(ty);
// This visitor can walk into binders, resulting in the `tcx_ty` to
// potentially reference escaping bound variables. We simply erase
// those here.
let tcx_ty = self.tcx.fold_regions(tcx_ty, |r, _| {
if r.is_bound() { self.tcx.lifetimes.re_erased } else { r }
});
let cause = traits::ObligationCause::new(
ty.span,
self.def_id,
@ -178,25 +184,3 @@ fn diagnostic_hir_wf_check<'tcx>(
}
visitor.cause
}
struct EraseAllBoundRegions<'tcx> {
tcx: TyCtxt<'tcx>,
}
// Higher ranked regions are complicated.
// To make matters worse, the HIR WF check can instantiate them
// outside of a `Binder`, due to the way we (ab)use
// `ItemCtxt::to_ty`. To make things simpler, we just erase all
// of them, regardless of depth. At worse, this will give
// us an inaccurate span for an error message, but cannot
// lead to unsoundness (we call `delay_span_bug` at the start
// of `diagnostic_hir_wf_check`).
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EraseAllBoundRegions<'tcx> {
fn interner(&self) -> TyCtxt<'tcx> {
self.tcx
}
fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
// FIXME(@lcnr): only erase escaping bound regions!
if r.is_bound() { self.tcx.lifetimes.re_erased } else { r }
}
}

View File

@ -9,7 +9,7 @@ use rustc_hir as hir;
use rustc_hir::intravisit::{self, Visitor};
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::symbol::sym;
@ -768,41 +768,22 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
}
}
struct EraseEarlyRegions<'tcx> {
tcx: TyCtxt<'tcx>,
}
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EraseEarlyRegions<'tcx> {
fn interner(&self) -> TyCtxt<'tcx> {
self.tcx
}
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
if ty.has_type_flags(ty::TypeFlags::HAS_FREE_REGIONS) {
ty.super_fold_with(self)
} else {
ty
}
}
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
if r.is_bound() { r } else { self.tcx.lifetimes.re_erased }
}
}
impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> {
fn interner(&self) -> TyCtxt<'tcx> {
self.fcx.tcx
}
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
let tcx = self.fcx.tcx;
match self.fcx.fully_resolve(t) {
Ok(t) if self.fcx.next_trait_solver() => {
// We must normalize erasing regions here, since later lints
// expect that types that show up in the typeck are fully
// normalized.
if let Ok(t) = self.fcx.tcx.try_normalize_erasing_regions(self.fcx.param_env, t) {
if let Ok(t) = tcx.try_normalize_erasing_regions(self.fcx.param_env, t) {
t
} else {
EraseEarlyRegions { tcx: self.fcx.tcx }.fold_ty(t)
tcx.fold_regions(t, |_, _| tcx.lifetimes.re_erased)
}
}
Ok(t) => {
@ -810,7 +791,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> {
// (e.g. keep `for<'a>` named `for<'a>`).
// This allows NLL to generate error messages that
// refer to the higher-ranked lifetime names written by the user.
EraseEarlyRegions { tcx: self.fcx.tcx }.fold_ty(t)
tcx.fold_regions(t, |_, _| tcx.lifetimes.re_erased)
}
Err(_) => {
debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);

View File

@ -75,7 +75,7 @@ impl<'a> DescriptionCtx<'a> {
// We shouldn't really be having unification failures with ReVar
// and ReBound though.
//
// FIXME(@lcnr): figure out why we `ReBound` have to handle `ReBound`
// FIXME(@lcnr): figure out why we have to handle `ReBound`
// here, this feels somewhat off.
ty::ReVar(_) | ty::ReBound(..) | ty::ReErased => {
(alt_span, "revar", format!("{region:?}"))