From db547520822eaa8cde18be0788cbad144c67b636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Wed, 14 Oct 2020 00:00:00 +0000 Subject: [PATCH] Create a single source scope for promoteds A promoted inherits all scopes from the parent body. At the same time, almost all statements and terminators inside the promoted body so far refer only to one of those scopes: the outermost one. Instead of inheriting all scopes, inherit only a single scope corresponding to the location of the promoted, making sure that there are no references to other scopes. --- .../rustc_mir/src/transform/promote_consts.rs | 17 ++++++++++++++--- ...n_static.FOO-promoted[0].ConstProp.after.mir | 2 -- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_mir/src/transform/promote_consts.rs b/compiler/rustc_mir/src/transform/promote_consts.rs index 7abc998d388..7373abcc820 100644 --- a/compiler/rustc_mir/src/transform/promote_consts.rs +++ b/compiler/rustc_mir/src/transform/promote_consts.rs @@ -124,6 +124,15 @@ fn forces_explicit_promotion(&self) -> bool { Candidate::Argument { .. } | Candidate::InlineAsm { .. } => true, } } + + fn source_info(&self, body: &Body<'_>) -> SourceInfo { + match self { + Candidate::Ref(location) | Candidate::Repeat(location) => *body.source_info(*location), + Candidate::Argument { bb, .. } | Candidate::InlineAsm { bb, .. } => { + *body.source_info(body.terminator_loc(*bb)) + } + } + } } fn args_required_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { @@ -953,6 +962,7 @@ fn promote_temp(&mut self, temp: Local) -> Local { from_hir_call, fn_span, }, + source_info: SourceInfo::outermost(terminator.source_info.span), ..terminator }; } @@ -1163,12 +1173,13 @@ pub fn promote_candidates<'tcx>( // Declare return place local so that `mir::Body::new` doesn't complain. let initial_locals = iter::once(LocalDecl::new(tcx.types.never, body.span)).collect(); + let mut scope = body.source_scopes[candidate.source_info(body).scope].clone(); + scope.parent_scope = None; + let mut promoted = Body::new( body.source, // `promoted` gets filled in below IndexVec::new(), - // FIXME: maybe try to filter this to avoid blowing up - // memory usage? - body.source_scopes.clone(), + IndexVec::from_elem_n(scope, 1), initial_locals, IndexVec::new(), 0, diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir index d9c6b4f0029..0d5760b4cd5 100644 --- a/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir +++ b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir @@ -5,8 +5,6 @@ promoted[0] in FOO: &[&i32; 1] = { let mut _1: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 let mut _2: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:32: 13:45 let mut _3: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 - scope 1 { - } bb0: { _3 = const {alloc2: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43