mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 09:14:20 +00:00
Rollup merge of #70165 - matthewjasper:erase-more, r=nikomatsakis
Remove the erase regions MIR transform We now ensure that MIR never contains unerased regions in the first place.
This commit is contained in:
commit
b24d168e10
@ -39,7 +39,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
let loc_ty = self
|
||||
.tcx
|
||||
.type_of(self.tcx.require_lang_item(PanicLocationLangItem, None))
|
||||
.subst(*self.tcx, self.tcx.mk_substs([self.tcx.lifetimes.re_static.into()].iter()));
|
||||
.subst(*self.tcx, self.tcx.mk_substs([self.tcx.lifetimes.re_erased.into()].iter()));
|
||||
let loc_layout = self.layout_of(loc_ty).unwrap();
|
||||
let location = self.allocate(loc_layout, MemoryKind::CallerLocation);
|
||||
|
||||
|
@ -32,6 +32,7 @@ impl<'tcx> MirPass<'tcx> for CleanupNonCodegenStatements {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) {
|
||||
let mut delete = DeleteNonCodegenStatements { tcx };
|
||||
delete.visit_body(body);
|
||||
body.user_type_annotations.raw.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,63 +0,0 @@
|
||||
//! This pass erases all early-bound regions from the types occurring in the MIR.
|
||||
//! We want to do this once just before codegen, so codegen does not have to take
|
||||
//! care erasing regions all over the place.
|
||||
//! N.B., we do _not_ erase regions of statements that are relevant for
|
||||
//! "types-as-contracts"-validation, namely, `AcquireValid` and `ReleaseValid`.
|
||||
|
||||
use crate::transform::{MirPass, MirSource};
|
||||
use rustc::mir::visit::{MutVisitor, TyContext};
|
||||
use rustc::mir::*;
|
||||
use rustc::ty::subst::SubstsRef;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
|
||||
struct EraseRegionsVisitor<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
}
|
||||
|
||||
impl EraseRegionsVisitor<'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'tcx>) -> Self {
|
||||
EraseRegionsVisitor { tcx }
|
||||
}
|
||||
}
|
||||
|
||||
impl MutVisitor<'tcx> for EraseRegionsVisitor<'tcx> {
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) {
|
||||
*ty = self.tcx.erase_regions(ty);
|
||||
}
|
||||
|
||||
fn visit_region(&mut self, region: &mut ty::Region<'tcx>, _: Location) {
|
||||
*region = self.tcx.lifetimes.re_erased;
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, constant: &mut &'tcx ty::Const<'tcx>, _: Location) {
|
||||
*constant = self.tcx.erase_regions(constant);
|
||||
}
|
||||
|
||||
fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, _: Location) {
|
||||
*substs = self.tcx.erase_regions(substs);
|
||||
}
|
||||
|
||||
fn process_projection_elem(&mut self, elem: &PlaceElem<'tcx>) -> Option<PlaceElem<'tcx>> {
|
||||
if let PlaceElem::Field(field, ty) = elem {
|
||||
let new_ty = self.tcx.erase_regions(ty);
|
||||
|
||||
if new_ty != *ty {
|
||||
return Some(PlaceElem::Field(*field, new_ty));
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EraseRegions;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for EraseRegions {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) {
|
||||
EraseRegionsVisitor::new(tcx).visit_body(body);
|
||||
}
|
||||
}
|
@ -357,18 +357,11 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn make_generator_state_argument_indirect<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: DefId,
|
||||
body: &mut BodyAndCache<'tcx>,
|
||||
) {
|
||||
fn make_generator_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut BodyAndCache<'tcx>) {
|
||||
let gen_ty = body.local_decls.raw[1].ty;
|
||||
|
||||
let region = ty::ReFree(ty::FreeRegion { scope: def_id, bound_region: ty::BoundRegion::BrEnv });
|
||||
|
||||
let region = tcx.mk_region(region);
|
||||
|
||||
let ref_gen_ty = tcx.mk_ref(region, ty::TypeAndMut { ty: gen_ty, mutbl: hir::Mutability::Mut });
|
||||
let ref_gen_ty =
|
||||
tcx.mk_ref(tcx.lifetimes.re_erased, ty::TypeAndMut { ty: gen_ty, mutbl: Mutability::Mut });
|
||||
|
||||
// Replace the by value generator argument
|
||||
body.local_decls.raw[1].ty = ref_gen_ty;
|
||||
@ -874,7 +867,6 @@ fn elaborate_generator_drops<'tcx>(
|
||||
fn create_generator_drop_shim<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
transform: &TransformVisitor<'tcx>,
|
||||
def_id: DefId,
|
||||
source: MirSource<'tcx>,
|
||||
gen_ty: Ty<'tcx>,
|
||||
body: &mut BodyAndCache<'tcx>,
|
||||
@ -912,7 +904,7 @@ fn create_generator_drop_shim<'tcx>(
|
||||
local_info: LocalInfo::Other,
|
||||
};
|
||||
|
||||
make_generator_state_argument_indirect(tcx, def_id, &mut body);
|
||||
make_generator_state_argument_indirect(tcx, &mut body);
|
||||
|
||||
// Change the generator argument from &mut to *mut
|
||||
body.local_decls[SELF_ARG] = LocalDecl {
|
||||
@ -1047,7 +1039,6 @@ fn can_unwind<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool {
|
||||
fn create_generator_resume_function<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
transform: TransformVisitor<'tcx>,
|
||||
def_id: DefId,
|
||||
source: MirSource<'tcx>,
|
||||
body: &mut BodyAndCache<'tcx>,
|
||||
can_return: bool,
|
||||
@ -1112,7 +1103,7 @@ fn create_generator_resume_function<'tcx>(
|
||||
|
||||
insert_switch(body, cases, &transform, TerminatorKind::Unreachable);
|
||||
|
||||
make_generator_state_argument_indirect(tcx, def_id, body);
|
||||
make_generator_state_argument_indirect(tcx, body);
|
||||
make_generator_state_argument_pinned(tcx, body);
|
||||
|
||||
no_landing_pads(tcx, body);
|
||||
@ -1332,11 +1323,11 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
|
||||
|
||||
// Create a copy of our MIR and use it to create the drop shim for the generator
|
||||
let drop_shim =
|
||||
create_generator_drop_shim(tcx, &transform, def_id, source, gen_ty, body, drop_clean);
|
||||
create_generator_drop_shim(tcx, &transform, source, gen_ty, body, drop_clean);
|
||||
|
||||
body.generator_drop = Some(box drop_shim);
|
||||
|
||||
// Create the Generator::resume function
|
||||
create_generator_resume_function(tcx, transform, def_id, source, body, can_return);
|
||||
create_generator_resume_function(tcx, transform, source, body, can_return);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ pub mod copy_prop;
|
||||
pub mod deaggregator;
|
||||
pub mod dump_mir;
|
||||
pub mod elaborate_drops;
|
||||
pub mod erase_regions;
|
||||
pub mod generator;
|
||||
pub mod inline;
|
||||
pub mod instcombine;
|
||||
@ -296,8 +295,6 @@ fn run_optimization_passes<'tcx>(
|
||||
&simplify::SimplifyCfg::new("elaborate-drops"),
|
||||
// No lifetime analysis based on borrowing can be done from here on out.
|
||||
|
||||
// From here on out, regions are gone.
|
||||
&erase_regions::EraseRegions,
|
||||
// Optimizations begin.
|
||||
&unreachable_prop::UnreachablePropagation,
|
||||
&uninhabited_enum_branching::UninhabitedEnumBranching,
|
||||
@ -341,6 +338,9 @@ fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &BodyAndCache<'_> {
|
||||
let mut body = body.steal();
|
||||
run_optimization_passes(tcx, &mut body, def_id, None);
|
||||
body.ensure_predecessors();
|
||||
|
||||
debug_assert!(!body.has_free_regions(), "Free regions in optimized MIR");
|
||||
|
||||
tcx.arena.alloc(body)
|
||||
}
|
||||
|
||||
@ -358,5 +358,7 @@ fn promoted_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &IndexVec<Promoted, BodyAndCa
|
||||
body.ensure_predecessors();
|
||||
}
|
||||
|
||||
debug_assert!(!promoted.has_free_regions(), "Free regions in promoted MIR");
|
||||
|
||||
tcx.intern_promoted(promoted)
|
||||
}
|
||||
|
@ -913,7 +913,13 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
||||
ty,
|
||||
val: ty::ConstKind::Unevaluated(
|
||||
def_id,
|
||||
InternalSubsts::identity_for_item(tcx, def_id),
|
||||
InternalSubsts::for_item(tcx, def_id, |param, _| {
|
||||
if let ty::GenericParamDefKind::Lifetime = param.kind {
|
||||
tcx.lifetimes.re_erased.into()
|
||||
} else {
|
||||
tcx.mk_param_from_def(param)
|
||||
}
|
||||
}),
|
||||
Some(promoted_id),
|
||||
),
|
||||
}),
|
||||
|
@ -6,7 +6,7 @@ use rustc::middle::lang_items;
|
||||
use rustc::middle::region;
|
||||
use rustc::mir::*;
|
||||
use rustc::ty::subst::Subst;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_attr::{self as attr, UnwindAttr};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
@ -43,8 +43,7 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> {
|
||||
..
|
||||
})
|
||||
| Node::TraitItem(hir::TraitItem {
|
||||
kind:
|
||||
hir::TraitItemKind::Fn(hir::FnSig { decl, .. }, hir::TraitFn::Provided(body_id)),
|
||||
kind: hir::TraitItemKind::Fn(hir::FnSig { decl, .. }, hir::TraitFn::Provided(body_id)),
|
||||
..
|
||||
}) => (*body_id, decl.output.span()),
|
||||
Node::Item(hir::Item { kind: hir::ItemKind::Static(ty, _, body_id), .. })
|
||||
@ -128,12 +127,8 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> {
|
||||
let ty = if fn_sig.c_variadic && index == fn_sig.inputs().len() {
|
||||
let va_list_did =
|
||||
tcx.require_lang_item(lang_items::VaListTypeLangItem, Some(arg.span));
|
||||
let region = tcx.mk_region(ty::ReScope(region::Scope {
|
||||
id: body.value.hir_id.local_id,
|
||||
data: region::ScopeData::CallSite,
|
||||
}));
|
||||
|
||||
tcx.type_of(va_list_did).subst(tcx, &[region.into()])
|
||||
tcx.type_of(va_list_did).subst(tcx, &[tcx.lifetimes.re_erased.into()])
|
||||
} else {
|
||||
fn_sig.inputs()[index]
|
||||
};
|
||||
@ -189,6 +184,20 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> {
|
||||
|
||||
let mut body = BodyAndCache::new(body);
|
||||
body.ensure_predecessors();
|
||||
|
||||
// The borrow checker will replace all the regions here with its own
|
||||
// inference variables. There's no point having non-erased regions here.
|
||||
// The exception is `body.user_type_annotations`, which is used unmodified
|
||||
// by borrow checking.
|
||||
debug_assert!(
|
||||
!(body.local_decls.has_free_regions()
|
||||
|| body.basic_blocks().has_free_regions()
|
||||
|| body.var_debug_info.has_free_regions()
|
||||
|| body.yield_ty.has_free_regions()),
|
||||
"Unexpected free regions in MIR: {:?}",
|
||||
body,
|
||||
);
|
||||
|
||||
body
|
||||
})
|
||||
}
|
||||
@ -209,7 +218,7 @@ fn liberated_closure_env_ty(
|
||||
};
|
||||
|
||||
let closure_env_ty = tcx.closure_env_ty(closure_def_id, closure_substs).unwrap();
|
||||
tcx.liberate_late_bound_regions(closure_def_id, &closure_env_ty)
|
||||
tcx.erase_late_bound_regions(&closure_env_ty)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
|
@ -15,7 +15,7 @@ fn main() {
|
||||
}
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.main.EraseRegions.after.mir
|
||||
// START rustc.main.SimplifyCfg-elaborate-drops.after.mir
|
||||
// bb0: {
|
||||
// ...
|
||||
// _4 = &mut _2;
|
||||
@ -38,4 +38,4 @@ fn main() {
|
||||
// ...
|
||||
// return;
|
||||
// }
|
||||
// END rustc.main.EraseRegions.after.mir
|
||||
// END rustc.main.SimplifyCfg-elaborate-drops.after.mir
|
||||
|
@ -6,10 +6,10 @@ fn main() {
|
||||
}
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.main.EraseRegions.after.mir
|
||||
// START rustc.main.SimplifyCfg-elaborate-drops.after.mir
|
||||
// ...
|
||||
// _1 = const b"foo";
|
||||
// ...
|
||||
// _2 = [const 5u8, const 120u8];
|
||||
// ...
|
||||
// END rustc.main.EraseRegions.after.mir
|
||||
// END rustc.main.SimplifyCfg-elaborate-drops.after.mir
|
||||
|
@ -15,7 +15,7 @@ impl Drop for Droppy {
|
||||
}
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.main.EraseRegions.before.mir
|
||||
// START rustc.main.SimplifyCfg-elaborate-drops.after.mir
|
||||
// fn main() -> () {
|
||||
// let mut _0: ();
|
||||
// let mut _1: Packed;
|
||||
@ -56,4 +56,4 @@ impl Drop for Droppy {
|
||||
// drop(_1) -> [return: bb2, unwind: bb1];
|
||||
// }
|
||||
// }
|
||||
// END rustc.main.EraseRegions.before.mir
|
||||
// END rustc.main.SimplifyCfg-elaborate-drops.after.mir
|
||||
|
@ -8,8 +8,12 @@ struct Test(i32);
|
||||
|
||||
impl Test {
|
||||
// Make sure we run the pass on a method, not just on bare functions.
|
||||
fn foo<'x>(&self, x: &'x mut i32) -> &'x mut i32 { x }
|
||||
fn foo_shr<'x>(&self, x: &'x i32) -> &'x i32 { x }
|
||||
fn foo<'x>(&self, x: &'x mut i32) -> &'x mut i32 {
|
||||
x
|
||||
}
|
||||
fn foo_shr<'x>(&self, x: &'x i32) -> &'x i32 {
|
||||
x
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Test {
|
||||
@ -27,7 +31,10 @@ fn main() {
|
||||
}
|
||||
|
||||
// Also test closures
|
||||
let c: fn(&i32) -> &i32 = |x: &i32| -> &i32 { let _y = x; x };
|
||||
let c: fn(&i32) -> &i32 = |x: &i32| -> &i32 {
|
||||
let _y = x;
|
||||
x
|
||||
};
|
||||
let _w = c(&x);
|
||||
|
||||
// need to call `foo_shr` or it doesn't even get generated
|
||||
@ -38,7 +45,7 @@ fn main() {
|
||||
}
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.{{impl}}-foo.EraseRegions.after.mir
|
||||
// START rustc.{{impl}}-foo.SimplifyCfg-elaborate-drops.after.mir
|
||||
// bb0: {
|
||||
// Retag([fn entry] _1);
|
||||
// Retag([fn entry] _2);
|
||||
@ -48,8 +55,8 @@ fn main() {
|
||||
// ...
|
||||
// return;
|
||||
// }
|
||||
// END rustc.{{impl}}-foo.EraseRegions.after.mir
|
||||
// START rustc.{{impl}}-foo_shr.EraseRegions.after.mir
|
||||
// END rustc.{{impl}}-foo.SimplifyCfg-elaborate-drops.after.mir
|
||||
// START rustc.{{impl}}-foo_shr.SimplifyCfg-elaborate-drops.after.mir
|
||||
// bb0: {
|
||||
// Retag([fn entry] _1);
|
||||
// Retag([fn entry] _2);
|
||||
@ -59,8 +66,8 @@ fn main() {
|
||||
// ...
|
||||
// return;
|
||||
// }
|
||||
// END rustc.{{impl}}-foo_shr.EraseRegions.after.mir
|
||||
// START rustc.main.EraseRegions.after.mir
|
||||
// END rustc.{{impl}}-foo_shr.SimplifyCfg-elaborate-drops.after.mir
|
||||
// START rustc.main.SimplifyCfg-elaborate-drops.after.mir
|
||||
// fn main() -> () {
|
||||
// ...
|
||||
// bb0: {
|
||||
@ -96,8 +103,8 @@ fn main() {
|
||||
//
|
||||
// ...
|
||||
// }
|
||||
// END rustc.main.EraseRegions.after.mir
|
||||
// START rustc.main-{{closure}}.EraseRegions.after.mir
|
||||
// END rustc.main.SimplifyCfg-elaborate-drops.after.mir
|
||||
// START rustc.main-{{closure}}.SimplifyCfg-elaborate-drops.after.mir
|
||||
// fn main::{{closure}}#0(_1: &[closure@main::{{closure}}#0], _2: &i32) -> &i32 {
|
||||
// ...
|
||||
// bb0: {
|
||||
@ -112,7 +119,7 @@ fn main() {
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// END rustc.main-{{closure}}.EraseRegions.after.mir
|
||||
// END rustc.main-{{closure}}.SimplifyCfg-elaborate-drops.after.mir
|
||||
// START rustc.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir
|
||||
// fn std::intrinsics::drop_in_place(_1: *mut Test) -> () {
|
||||
// ...
|
||||
|
Loading…
Reference in New Issue
Block a user