diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 99fe8e60ae52b..4086e3cf071d4 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -918,6 +918,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)"), + skip_end_regions: bool = (false, parse_bool, [UNTRACKED], + "skip EndRegion emission in MIR, skip 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_mir/build/cfg.rs b/src/librustc_mir/build/cfg.rs index b390e2888f26c..e92d8507f7613 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::CodeExtent; 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, - extent: CodeExtent) { - self.push(block, Statement { - source_info, - kind: StatementKind::EndRegion(extent), - }); + pub fn push_end_region<'a, 'gcx:'a+'tcx>(&mut self, + tcx: ty::TyCtxt<'a, 'gcx, 'tcx>, + block: BasicBlock, + source_info: SourceInfo, + extent: CodeExtent) { + if !tcx.sess.opts.debugging_opts.skip_end_regions { + self.push(block, Statement { + source_info, + kind: StatementKind::EndRegion(extent), + }); + } } pub fn push_assign(&mut self, diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 90f9c1c0d5f56..4b77cab443a38 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::CodeExtent; -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, extent.1, scope.extent); + self.cfg.push_end_region(self.hir.tcx(), block, extent.1, scope.extent); block.unit() } @@ -412,7 +412,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, extent.1, scope.extent); + self.cfg.push_end_region(self.hir.tcx(), block, extent.1, scope.extent); } } let scope = &self.scopes[len - scope_count]; @@ -461,7 +461,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.extent); + self.cfg.push_end_region(self.hir.tcx(), block, src_info, scope.extent); } self.cfg.terminate(block, src_info, TerminatorKind::GeneratorDrop); @@ -692,7 +692,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { }; for scope in scopes.iter_mut() { - target = build_diverge_scope(cfg, scope.extent_span, scope, target, generator_drop); + target = build_diverge_scope( + self.hir.tcx(), cfg, scope.extent_span, scope, target, generator_drop); } Some(target) } @@ -828,7 +829,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, @@ -890,7 +892,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.extent); + cfg.push_end_region(tcx, block, source_info(span), scope.extent); 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 f06b88551d11d..a50acd84876ff 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.opts.debugging_opts.skip_end_regions { return; } + let mut gather = GatherBorrowedRegions { seen_regions: FxHashSet() };