diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index b538c6a6eca7b..577c905a1d5a6 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -919,6 +919,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "when debug-printing compiler state, do not include spans"), // o/w tests have closure@path identify_regions: bool = (false, parse_bool, [UNTRACKED], "make unnamed regions display as '# (where # is some non-ident unique id)"), + emit_end_regions: bool = (false, parse_bool, [UNTRACKED], + "emit EndRegion as part of MIR; enable transforms that solely process EndRegion"), borrowck_mir: bool = (false, parse_bool, [UNTRACKED], "implicitly treat functions as if they have `#[rustc_mir_borrowck]` attribute"), time_passes: bool = (false, parse_bool, [UNTRACKED], diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 823a637c7e0d4..129a9f5575008 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -410,6 +410,10 @@ impl Session { pub fn print_llvm_passes(&self) -> bool { self.opts.debugging_opts.print_llvm_passes } + pub fn emit_end_regions(&self) -> bool { + self.opts.debugging_opts.emit_end_regions || + (self.opts.debugging_opts.mir_emit_validate > 0) + } pub fn lto(&self) -> bool { self.opts.cg.lto } diff --git a/src/librustc_mir/build/cfg.rs b/src/librustc_mir/build/cfg.rs index d77fe5170e040..a6e31bcddd242 100644 --- a/src/librustc_mir/build/cfg.rs +++ b/src/librustc_mir/build/cfg.rs @@ -16,6 +16,7 @@ use build::CFG; use rustc::middle::region; use rustc::mir::*; +use rustc::ty; impl<'tcx> CFG<'tcx> { pub fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<'tcx> { @@ -44,14 +45,17 @@ impl<'tcx> CFG<'tcx> { self.block_data_mut(block).statements.push(statement); } - pub fn push_end_region(&mut self, - block: BasicBlock, - source_info: SourceInfo, - region_scope: region::Scope) { - self.push(block, Statement { - source_info, - kind: StatementKind::EndRegion(region_scope), - }); + pub fn push_end_region<'a, 'gcx:'a+'tcx>(&mut self, + tcx: ty::TyCtxt<'a, 'gcx, 'tcx>, + block: BasicBlock, + source_info: SourceInfo, + region_scope: region::Scope) { + if tcx.sess.emit_end_regions() { + self.push(block, Statement { + source_info, + kind: StatementKind::EndRegion(region_scope), + }); + } } pub fn push_assign(&mut self, diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index ed598c876f3e9..c08620c1e4104 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -89,7 +89,7 @@ should go to. use build::{BlockAnd, BlockAndExtension, Builder, CFG}; use rustc::middle::region; -use rustc::ty::Ty; +use rustc::ty::{Ty, TyCtxt}; use rustc::mir::*; use rustc::mir::transform::MirSource; use syntax_pos::{Span}; @@ -359,7 +359,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { self.arg_count, false)); - self.cfg.push_end_region(block, region_scope.1, scope.region_scope); + self.cfg.push_end_region(self.hir.tcx(), block, region_scope.1, scope.region_scope); block.unit() } @@ -414,7 +414,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { false)); // End all regions for scopes out of which we are breaking. - self.cfg.push_end_region(block, region_scope.1, scope.region_scope); + self.cfg.push_end_region(self.hir.tcx(), block, region_scope.1, scope.region_scope); } } let scope = &self.scopes[len - scope_count]; @@ -463,7 +463,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { true)); // End all regions for scopes out of which we are breaking. - self.cfg.push_end_region(block, src_info, scope.region_scope); + self.cfg.push_end_region(self.hir.tcx(), block, src_info, scope.region_scope); } self.cfg.terminate(block, src_info, TerminatorKind::GeneratorDrop); @@ -694,7 +694,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { }; for scope in scopes.iter_mut() { - target = build_diverge_scope(cfg, scope.region_scope_span, + target = build_diverge_scope(self.hir.tcx(), cfg, scope.region_scope_span, scope, target, generator_drop); } Some(target) @@ -831,7 +831,8 @@ fn build_scope_drops<'tcx>(cfg: &mut CFG<'tcx>, block.unit() } -fn build_diverge_scope<'a, 'gcx, 'tcx>(cfg: &mut CFG<'tcx>, +fn build_diverge_scope<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, + cfg: &mut CFG<'tcx>, span: Span, scope: &mut Scope<'tcx>, mut target: BasicBlock, @@ -893,7 +894,7 @@ fn build_diverge_scope<'a, 'gcx, 'tcx>(cfg: &mut CFG<'tcx>, // becomes trivial goto after pass that removes all EndRegions.) { let block = cfg.start_new_cleanup_block(); - cfg.push_end_region(block, source_info(span), scope.region_scope); + cfg.push_end_region(tcx, block, source_info(span), scope.region_scope); cfg.terminate(block, source_info(span), TerminatorKind::Goto { target: target }); target = block } diff --git a/src/librustc_mir/transform/clean_end_regions.rs b/src/librustc_mir/transform/clean_end_regions.rs index 55a16b2f39161..a6750f400ba93 100644 --- a/src/librustc_mir/transform/clean_end_regions.rs +++ b/src/librustc_mir/transform/clean_end_regions.rs @@ -39,9 +39,11 @@ struct DeleteTrivialEndRegions<'a> { impl MirPass for CleanEndRegions { fn run_pass<'a, 'tcx>(&self, - _tcx: TyCtxt<'a, 'tcx, 'tcx>, + tcx: TyCtxt<'a, 'tcx, 'tcx>, _source: MirSource, mir: &mut Mir<'tcx>) { + if !tcx.sess.emit_end_regions() { return; } + let mut gather = GatherBorrowedRegions { seen_regions: FxHashSet() }; diff --git a/src/test/mir-opt/end_region_1.rs b/src/test/mir-opt/end_region_1.rs index 54409d3543ebc..9c8cfc0ab208c 100644 --- a/src/test/mir-opt/end_region_1.rs +++ b/src/test/mir-opt/end_region_1.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z identify_regions +// compile-flags: -Z identify_regions -Z emit-end-regions // ignore-tidy-linelength // This is just about the simplest program that exhibits an EndRegion. diff --git a/src/test/mir-opt/end_region_2.rs b/src/test/mir-opt/end_region_2.rs index b37bd4188d970..6a4e209a14b7f 100644 --- a/src/test/mir-opt/end_region_2.rs +++ b/src/test/mir-opt/end_region_2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z identify_regions +// compile-flags: -Z identify_regions -Z emit-end-regions // ignore-tidy-linelength // We will EndRegion for borrows in a loop that occur before break but diff --git a/src/test/mir-opt/end_region_3.rs b/src/test/mir-opt/end_region_3.rs index be9fc579ab636..cb1d45e37c834 100644 --- a/src/test/mir-opt/end_region_3.rs +++ b/src/test/mir-opt/end_region_3.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z identify_regions +// compile-flags: -Z identify_regions -Z emit-end-regions // ignore-tidy-linelength // Binding the borrow's subject outside the loop does not increase the diff --git a/src/test/mir-opt/end_region_4.rs b/src/test/mir-opt/end_region_4.rs index 58ce1ed5b84b7..b714b6bc55b24 100644 --- a/src/test/mir-opt/end_region_4.rs +++ b/src/test/mir-opt/end_region_4.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z identify_regions +// compile-flags: -Z identify_regions -Z emit-end-regions // ignore-tidy-linelength // Unwinding should EndRegion for in-scope borrows: Direct borrows. diff --git a/src/test/mir-opt/end_region_5.rs b/src/test/mir-opt/end_region_5.rs index be62a5473a6ff..a4c53675b9c3a 100644 --- a/src/test/mir-opt/end_region_5.rs +++ b/src/test/mir-opt/end_region_5.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z identify_regions -Z span_free_formats +// compile-flags: -Z identify_regions -Z span_free_formats -Z emit-end-regions // ignore-tidy-linelength // Unwinding should EndRegion for in-scope borrows: Borrowing via by-ref closure. diff --git a/src/test/mir-opt/end_region_6.rs b/src/test/mir-opt/end_region_6.rs index 23b92583a11da..daa94769430df 100644 --- a/src/test/mir-opt/end_region_6.rs +++ b/src/test/mir-opt/end_region_6.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z identify_regions -Z span_free_formats +// compile-flags: -Z identify_regions -Z span_free_formats -Z emit-end-regions // ignore-tidy-linelength // Unwinding should EndRegion for in-scope borrows: 2nd borrow within by-ref closure. diff --git a/src/test/mir-opt/end_region_7.rs b/src/test/mir-opt/end_region_7.rs index ee0615f2bb312..9feacd04fe0fa 100644 --- a/src/test/mir-opt/end_region_7.rs +++ b/src/test/mir-opt/end_region_7.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z identify_regions -Z span_free_formats +// compile-flags: -Z identify_regions -Z span_free_formats -Z emit-end-regions // ignore-tidy-linelength // Unwinding should EndRegion for in-scope borrows: Borrow of moved data. diff --git a/src/test/mir-opt/end_region_8.rs b/src/test/mir-opt/end_region_8.rs index ef184e39c0061..30dda7a406260 100644 --- a/src/test/mir-opt/end_region_8.rs +++ b/src/test/mir-opt/end_region_8.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z identify_regions -Z span_free_formats +// compile-flags: -Z identify_regions -Z span_free_formats -Z emit-end-regions // ignore-tidy-linelength // Unwinding should EndRegion for in-scope borrows: Move of borrow into closure. diff --git a/src/test/mir-opt/end_region_9.rs b/src/test/mir-opt/end_region_9.rs index 719bc3ff9dd04..bbfdc0e77a8d6 100644 --- a/src/test/mir-opt/end_region_9.rs +++ b/src/test/mir-opt/end_region_9.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z identify_regions -Z span_free_formats +// compile-flags: -Z identify_regions -Z span_free_formats -Z emit-end-regions // ignore-tidy-linelength // This test models a scenario that arielb1 found during review. diff --git a/src/test/mir-opt/issue-43457.rs b/src/test/mir-opt/issue-43457.rs index 2a36672a45774..3f0f5068577c6 100644 --- a/src/test/mir-opt/issue-43457.rs +++ b/src/test/mir-opt/issue-43457.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z identify_regions -Z span_free_formats +// compile-flags: -Z identify_regions -Z span_free_formats -Z emit-end-regions // ignore-tidy-linelength // Regression test for #43457: an `EndRegion` was missing from output