diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs index 1933ef29b53..f3f366bb792 100644 --- a/src/librustc_mir/build/block.rs +++ b/src/librustc_mir/build/block.rs @@ -23,8 +23,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { -> BlockAnd<()> { let Block { extent, opt_destruction_extent, span, stmts, expr, targeted_by_break } = self.hir.mirror(ast_block); - self.in_opt_scope(opt_destruction_extent, block, move |this| { - this.in_scope(extent, block, move |this| { + self.in_opt_scope(opt_destruction_extent.map(|de|(de, source_info)), block, move |this| { + this.in_scope((extent, source_info), block, move |this| { if targeted_by_break { // This is a `break`-able block (currently only `catch { ... }`) let exit_block = this.cfg.start_new_block(); @@ -69,16 +69,18 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // First we build all the statements in the block. let mut let_extent_stack = Vec::with_capacity(8); let outer_visibility_scope = this.visibility_scope; + let source_info = this.source_info(span); for stmt in stmts { let Stmt { span: _, kind, opt_destruction_extent } = this.hir.mirror(stmt); match kind { StmtKind::Expr { scope, expr } => { - unpack!(block = this.in_opt_scope(opt_destruction_extent, block, |this| { - this.in_scope(scope, block, |this| { - let expr = this.hir.mirror(expr); - this.stmt_expr(block, expr) - }) - })); + unpack!(block = this.in_opt_scope( + opt_destruction_extent.map(|de|(de, source_info)), block, |this| { + this.in_scope((scope, source_info), block, |this| { + let expr = this.hir.mirror(expr); + this.stmt_expr(block, expr) + }) + })); } StmtKind::Let { remainder_scope, init_scope, pattern, initializer } => { let tcx = this.hir.tcx(); @@ -95,9 +97,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // Evaluate the initializer, if present. if let Some(init) = initializer { unpack!(block = this.in_opt_scope( - opt_destruction_extent, block, move |this| { - this.in_scope(init_scope, block, move |this| { - // FIXME #30046 ^~~~ + opt_destruction_extent.map(|de|(de, source_info)), block, move |this| { + this.in_scope((init_scope, source_info), block, move |this| { + // FIXME #30046 ^~~~ this.expr_into_pattern(block, pattern, init) }) })); @@ -126,7 +128,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // Finally, we pop all the let scopes before exiting out from the scope of block // itself. for extent in let_extent_stack.into_iter().rev() { - unpack!(block = this.pop_scope(extent, block)); + unpack!(block = this.pop_scope((extent, source_info), block)); } // Restore the original visibility scope. this.visibility_scope = outer_visibility_scope; diff --git a/src/librustc_mir/build/expr/as_lvalue.rs b/src/librustc_mir/build/expr/as_lvalue.rs index df2841a6682..04c23215463 100644 --- a/src/librustc_mir/build/expr/as_lvalue.rs +++ b/src/librustc_mir/build/expr/as_lvalue.rs @@ -40,7 +40,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let source_info = this.source_info(expr_span); match expr.kind { ExprKind::Scope { extent, value } => { - this.in_scope(extent, block, |this| this.as_lvalue(block, value)) + this.in_scope((extent, source_info), block, |this| this.as_lvalue(block, value)) } ExprKind::Field { lhs, name } => { let lvalue = unpack!(block = this.as_lvalue(block, lhs)); diff --git a/src/librustc_mir/build/expr/as_operand.rs b/src/librustc_mir/build/expr/as_operand.rs index 5178963179d..4679e0bb0a5 100644 --- a/src/librustc_mir/build/expr/as_operand.rs +++ b/src/librustc_mir/build/expr/as_operand.rs @@ -56,6 +56,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let this = self; if let ExprKind::Scope { extent, value } = expr.kind { + let source_info = this.source_info(expr.span); + let extent = (extent, source_info); return this.in_scope(extent, block, |this| { this.as_operand(block, scope, value) }); diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 2884b60fdd8..2512291f1a4 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -59,6 +59,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { match expr.kind { ExprKind::Scope { extent, value } => { + let extent = (extent, source_info); this.in_scope(extent, block, |this| this.as_rvalue(block, scope, value)) } ExprKind::Repeat { value, count } => { @@ -99,7 +100,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // to start, malloc some memory of suitable type (thus far, uninitialized): let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty); this.cfg.push_assign(block, source_info, &result, box_); - this.in_scope(value_extents, block, |this| { + this.in_scope((value_extents, source_info), block, |this| { // schedule a shallow free of that memory, lest we unwind: this.schedule_box_free(expr_span, value_extents, &result, value.ty); // initialize the box contents: diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs index 17d74571ce4..faaa46a4a8f 100644 --- a/src/librustc_mir/build/expr/as_temp.rs +++ b/src/librustc_mir/build/expr/as_temp.rs @@ -39,14 +39,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { block, temp_lifetime, expr); let this = self; + let expr_span = expr.span; + let source_info = this.source_info(expr_span); if let ExprKind::Scope { extent, value } = expr.kind { - return this.in_scope(extent, block, |this| { + return this.in_scope((extent, source_info), block, |this| { this.as_temp(block, temp_lifetime, value) }); } let expr_ty = expr.ty.clone(); - let expr_span = expr.span; let temp = this.temp(expr_ty.clone(), expr_span); let source_info = this.source_info(expr_span); diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index d456bc3ded3..97d63ac6d19 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -39,6 +39,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { match expr.kind { ExprKind::Scope { extent, value } => { + let extent = (extent, source_info); this.in_scope(extent, block, |this| this.into(destination, block, value)) } ExprKind::Block { body: ast_block } => { diff --git a/src/librustc_mir/build/expr/stmt.rs b/src/librustc_mir/build/expr/stmt.rs index 3c7ab373651..3120ac21908 100644 --- a/src/librustc_mir/build/expr/stmt.rs +++ b/src/librustc_mir/build/expr/stmt.rs @@ -24,7 +24,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { match expr.kind { ExprKind::Scope { extent, value } => { let value = this.hir.mirror(value); - this.in_scope(extent, block, |this| this.stmt_expr(block, value)) + this.in_scope((extent, source_info), block, |this| this.stmt_expr(block, value)) } ExprKind::Assign { lhs, rhs } => { let lhs = this.hir.mirror(lhs); @@ -81,7 +81,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { *this.find_breakable_scope(expr_span, label); let continue_block = continue_block.expect( "Attempted to continue in non-continuable breakable block"); - this.exit_scope(expr_span, extent, block, continue_block); + this.exit_scope(expr_span, (extent, source_info), block, continue_block); this.cfg.start_new_block().unit() } ExprKind::Break { label, value } => { @@ -99,7 +99,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } else { this.cfg.push_assign_unit(block, source_info, &destination) } - this.exit_scope(expr_span, extent, block, break_block); + this.exit_scope(expr_span, (extent, source_info), block, break_block); this.cfg.start_new_block().unit() } ExprKind::Return { value } => { @@ -116,7 +116,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { }; let extent = this.extent_of_return_scope(); let return_block = this.return_block(); - this.exit_scope(expr_span, extent, block, return_block); + this.exit_scope(expr_span, (extent, source_info), block, return_block); this.cfg.start_new_block().unit() } ExprKind::InlineAsm { asm, outputs, inputs } => { diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 56c0e18d6f9..eb1414d42e1 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -339,8 +339,9 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, let call_site_extent = CodeExtent::CallSiteScope(body.id()); let arg_extent = CodeExtent::ParameterScope(body.id()); let mut block = START_BLOCK; - unpack!(block = builder.in_scope(call_site_extent, block, |builder| { - unpack!(block = builder.in_scope(arg_extent, block, |builder| { + let source_info = builder.source_info(span); + unpack!(block = builder.in_scope((call_site_extent, source_info), block, |builder| { + unpack!(block = builder.in_scope((arg_extent, source_info), block, |builder| { builder.args_and_body(block, &arguments, arg_extent, &body.value) })); // Attribute epilogue to function's closing brace diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index d9c303369cc..84b69bbf610 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -270,14 +270,14 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } pub fn in_opt_scope(&mut self, - opt_extent: Option, + opt_extent: Option<(CodeExtent, SourceInfo)>, mut block: BasicBlock, f: F) -> BlockAnd where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> BlockAnd { debug!("in_opt_scope(opt_extent={:?}, block={:?})", opt_extent, block); - if let Some(extent) = opt_extent { self.push_scope(extent); } + if let Some(extent) = opt_extent { self.push_scope(extent.0); } let rv = unpack!(block = f(self)); if let Some(extent) = opt_extent { unpack!(block = self.pop_scope(extent, block)); @@ -289,14 +289,14 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// Convenience wrapper that pushes a scope and then executes `f` /// to build its contents, popping the scope afterwards. pub fn in_scope(&mut self, - extent: CodeExtent, + extent: (CodeExtent, SourceInfo), mut block: BasicBlock, f: F) -> BlockAnd where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> BlockAnd { debug!("in_scope(extent={:?}, block={:?})", extent, block); - self.push_scope(extent); + self.push_scope(extent.0); let rv = unpack!(block = f(self)); unpack!(block = self.pop_scope(extent, block)); debug!("in_scope: exiting extent={:?} block={:?}", extent, block); @@ -324,7 +324,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// drops onto the end of `block` that are needed. This must /// match 1-to-1 with `push_scope`. pub fn pop_scope(&mut self, - extent: CodeExtent, + extent: (CodeExtent, SourceInfo), mut block: BasicBlock) -> BlockAnd<()> { debug!("pop_scope({:?}, {:?})", extent, block); @@ -332,7 +332,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // to make sure all the `cached_block`s are filled in. self.diverge_cleanup(); let scope = self.scopes.pop().unwrap(); - assert_eq!(scope.extent, extent); + assert_eq!(scope.extent, extent.0); unpack!(block = build_scope_drops(&mut self.cfg, &scope, &self.scopes, @@ -348,11 +348,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// module comment for details. pub fn exit_scope(&mut self, span: Span, - extent: CodeExtent, + extent: (CodeExtent, SourceInfo), mut block: BasicBlock, target: BasicBlock) { debug!("exit_scope(extent={:?}, block={:?}, target={:?})", extent, block, target); - let scope_count = 1 + self.scopes.iter().rev().position(|scope| scope.extent == extent) + let scope_count = 1 + self.scopes.iter().rev().position(|scope| scope.extent == extent.0) .unwrap_or_else(||{ span_bug!(span, "extent {:?} does not enclose", extent) }); @@ -363,7 +363,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let mut rest = &mut self.scopes[(len - scope_count)..]; while let Some((scope, rest_)) = {rest}.split_last_mut() { rest = rest_; - block = if let Some(&e) = scope.cached_exits.get(&(target, extent)) { + block = if let Some(&e) = scope.cached_exits.get(&(target, extent.0)) { self.cfg.terminate(block, scope.source_info(span), TerminatorKind::Goto { target: e }); return; @@ -371,7 +371,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let b = self.cfg.start_new_block(); self.cfg.terminate(block, scope.source_info(span), TerminatorKind::Goto { target: b }); - scope.cached_exits.insert((target, extent), b); + scope.cached_exits.insert((target, extent.0), b); b }; unpack!(block = build_scope_drops(&mut self.cfg,