1
Fork 0

Paired source_info with extent; thread both through to pts where EndRegion will need construction.

This commit is contained in:
Felix S. Klock II 2017-05-26 18:21:03 +02:00
parent cbed41a174
commit a658bb21e4
9 changed files with 40 additions and 32 deletions

View file

@ -23,8 +23,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
-> BlockAnd<()> { -> BlockAnd<()> {
let Block { extent, opt_destruction_extent, span, stmts, expr, targeted_by_break } = let Block { extent, opt_destruction_extent, span, stmts, expr, targeted_by_break } =
self.hir.mirror(ast_block); self.hir.mirror(ast_block);
self.in_opt_scope(opt_destruction_extent, block, move |this| { self.in_opt_scope(opt_destruction_extent.map(|de|(de, source_info)), block, move |this| {
this.in_scope(extent, block, move |this| { this.in_scope((extent, source_info), block, move |this| {
if targeted_by_break { if targeted_by_break {
// This is a `break`-able block (currently only `catch { ... }`) // This is a `break`-able block (currently only `catch { ... }`)
let exit_block = this.cfg.start_new_block(); 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. // First we build all the statements in the block.
let mut let_extent_stack = Vec::with_capacity(8); let mut let_extent_stack = Vec::with_capacity(8);
let outer_visibility_scope = this.visibility_scope; let outer_visibility_scope = this.visibility_scope;
let source_info = this.source_info(span);
for stmt in stmts { for stmt in stmts {
let Stmt { span: _, kind, opt_destruction_extent } = this.hir.mirror(stmt); let Stmt { span: _, kind, opt_destruction_extent } = this.hir.mirror(stmt);
match kind { match kind {
StmtKind::Expr { scope, expr } => { StmtKind::Expr { scope, expr } => {
unpack!(block = this.in_opt_scope(opt_destruction_extent, block, |this| { unpack!(block = this.in_opt_scope(
this.in_scope(scope, block, |this| { opt_destruction_extent.map(|de|(de, source_info)), block, |this| {
let expr = this.hir.mirror(expr); this.in_scope((scope, source_info), block, |this| {
this.stmt_expr(block, expr) let expr = this.hir.mirror(expr);
}) this.stmt_expr(block, expr)
})); })
}));
} }
StmtKind::Let { remainder_scope, init_scope, pattern, initializer } => { StmtKind::Let { remainder_scope, init_scope, pattern, initializer } => {
let tcx = this.hir.tcx(); let tcx = this.hir.tcx();
@ -95,9 +97,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
// Evaluate the initializer, if present. // Evaluate the initializer, if present.
if let Some(init) = initializer { if let Some(init) = initializer {
unpack!(block = this.in_opt_scope( unpack!(block = this.in_opt_scope(
opt_destruction_extent, block, move |this| { opt_destruction_extent.map(|de|(de, source_info)), block, move |this| {
this.in_scope(init_scope, block, move |this| { this.in_scope((init_scope, source_info), block, move |this| {
// FIXME #30046 ^~~~ // FIXME #30046 ^~~~
this.expr_into_pattern(block, pattern, init) 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 // Finally, we pop all the let scopes before exiting out from the scope of block
// itself. // itself.
for extent in let_extent_stack.into_iter().rev() { 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. // Restore the original visibility scope.
this.visibility_scope = outer_visibility_scope; this.visibility_scope = outer_visibility_scope;

View file

@ -40,7 +40,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let source_info = this.source_info(expr_span); let source_info = this.source_info(expr_span);
match expr.kind { match expr.kind {
ExprKind::Scope { extent, value } => { 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 } => { ExprKind::Field { lhs, name } => {
let lvalue = unpack!(block = this.as_lvalue(block, lhs)); let lvalue = unpack!(block = this.as_lvalue(block, lhs));

View file

@ -56,6 +56,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let this = self; let this = self;
if let ExprKind::Scope { extent, value } = expr.kind { 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| { return this.in_scope(extent, block, |this| {
this.as_operand(block, scope, value) this.as_operand(block, scope, value)
}); });

View file

@ -59,6 +59,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
match expr.kind { match expr.kind {
ExprKind::Scope { extent, value } => { ExprKind::Scope { extent, value } => {
let extent = (extent, source_info);
this.in_scope(extent, block, |this| this.as_rvalue(block, scope, value)) this.in_scope(extent, block, |this| this.as_rvalue(block, scope, value))
} }
ExprKind::Repeat { value, count } => { 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): // to start, malloc some memory of suitable type (thus far, uninitialized):
let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty); let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
this.cfg.push_assign(block, source_info, &result, box_); 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: // schedule a shallow free of that memory, lest we unwind:
this.schedule_box_free(expr_span, value_extents, &result, value.ty); this.schedule_box_free(expr_span, value_extents, &result, value.ty);
// initialize the box contents: // initialize the box contents:

View file

@ -39,14 +39,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
block, temp_lifetime, expr); block, temp_lifetime, expr);
let this = self; let this = self;
let expr_span = expr.span;
let source_info = this.source_info(expr_span);
if let ExprKind::Scope { extent, value } = expr.kind { 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) this.as_temp(block, temp_lifetime, value)
}); });
} }
let expr_ty = expr.ty.clone(); let expr_ty = expr.ty.clone();
let expr_span = expr.span;
let temp = this.temp(expr_ty.clone(), expr_span); let temp = this.temp(expr_ty.clone(), expr_span);
let source_info = this.source_info(expr_span); let source_info = this.source_info(expr_span);

View file

@ -39,6 +39,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
match expr.kind { match expr.kind {
ExprKind::Scope { extent, value } => { ExprKind::Scope { extent, value } => {
let extent = (extent, source_info);
this.in_scope(extent, block, |this| this.into(destination, block, value)) this.in_scope(extent, block, |this| this.into(destination, block, value))
} }
ExprKind::Block { body: ast_block } => { ExprKind::Block { body: ast_block } => {

View file

@ -24,7 +24,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
match expr.kind { match expr.kind {
ExprKind::Scope { extent, value } => { ExprKind::Scope { extent, value } => {
let value = this.hir.mirror(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 } => { ExprKind::Assign { lhs, rhs } => {
let lhs = this.hir.mirror(lhs); 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); *this.find_breakable_scope(expr_span, label);
let continue_block = continue_block.expect( let continue_block = continue_block.expect(
"Attempted to continue in non-continuable breakable block"); "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() this.cfg.start_new_block().unit()
} }
ExprKind::Break { label, value } => { ExprKind::Break { label, value } => {
@ -99,7 +99,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
} else { } else {
this.cfg.push_assign_unit(block, source_info, &destination) 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() this.cfg.start_new_block().unit()
} }
ExprKind::Return { value } => { ExprKind::Return { value } => {
@ -116,7 +116,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
}; };
let extent = this.extent_of_return_scope(); let extent = this.extent_of_return_scope();
let return_block = this.return_block(); 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() this.cfg.start_new_block().unit()
} }
ExprKind::InlineAsm { asm, outputs, inputs } => { ExprKind::InlineAsm { asm, outputs, inputs } => {

View file

@ -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 call_site_extent = CodeExtent::CallSiteScope(body.id());
let arg_extent = CodeExtent::ParameterScope(body.id()); let arg_extent = CodeExtent::ParameterScope(body.id());
let mut block = START_BLOCK; let mut block = START_BLOCK;
unpack!(block = builder.in_scope(call_site_extent, block, |builder| { let source_info = builder.source_info(span);
unpack!(block = builder.in_scope(arg_extent, block, |builder| { 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) builder.args_and_body(block, &arguments, arg_extent, &body.value)
})); }));
// Attribute epilogue to function's closing brace // Attribute epilogue to function's closing brace

View file

@ -270,14 +270,14 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
} }
pub fn in_opt_scope<F, R>(&mut self, pub fn in_opt_scope<F, R>(&mut self,
opt_extent: Option<CodeExtent>, opt_extent: Option<(CodeExtent, SourceInfo)>,
mut block: BasicBlock, mut block: BasicBlock,
f: F) f: F)
-> BlockAnd<R> -> BlockAnd<R>
where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> BlockAnd<R> where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> BlockAnd<R>
{ {
debug!("in_opt_scope(opt_extent={:?}, block={:?})", opt_extent, block); 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)); let rv = unpack!(block = f(self));
if let Some(extent) = opt_extent { if let Some(extent) = opt_extent {
unpack!(block = self.pop_scope(extent, block)); 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` /// Convenience wrapper that pushes a scope and then executes `f`
/// to build its contents, popping the scope afterwards. /// to build its contents, popping the scope afterwards.
pub fn in_scope<F, R>(&mut self, pub fn in_scope<F, R>(&mut self,
extent: CodeExtent, extent: (CodeExtent, SourceInfo),
mut block: BasicBlock, mut block: BasicBlock,
f: F) f: F)
-> BlockAnd<R> -> BlockAnd<R>
where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> BlockAnd<R> where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> BlockAnd<R>
{ {
debug!("in_scope(extent={:?}, block={:?})", extent, block); debug!("in_scope(extent={:?}, block={:?})", extent, block);
self.push_scope(extent); self.push_scope(extent.0);
let rv = unpack!(block = f(self)); let rv = unpack!(block = f(self));
unpack!(block = self.pop_scope(extent, block)); unpack!(block = self.pop_scope(extent, block));
debug!("in_scope: exiting extent={:?} block={:?}", 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 /// drops onto the end of `block` that are needed. This must
/// match 1-to-1 with `push_scope`. /// match 1-to-1 with `push_scope`.
pub fn pop_scope(&mut self, pub fn pop_scope(&mut self,
extent: CodeExtent, extent: (CodeExtent, SourceInfo),
mut block: BasicBlock) mut block: BasicBlock)
-> BlockAnd<()> { -> BlockAnd<()> {
debug!("pop_scope({:?}, {:?})", extent, block); 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. // to make sure all the `cached_block`s are filled in.
self.diverge_cleanup(); self.diverge_cleanup();
let scope = self.scopes.pop().unwrap(); 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, unpack!(block = build_scope_drops(&mut self.cfg,
&scope, &scope,
&self.scopes, &self.scopes,
@ -348,11 +348,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
/// module comment for details. /// module comment for details.
pub fn exit_scope(&mut self, pub fn exit_scope(&mut self,
span: Span, span: Span,
extent: CodeExtent, extent: (CodeExtent, SourceInfo),
mut block: BasicBlock, mut block: BasicBlock,
target: BasicBlock) { target: BasicBlock) {
debug!("exit_scope(extent={:?}, block={:?}, target={:?})", extent, block, target); 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(||{ .unwrap_or_else(||{
span_bug!(span, "extent {:?} does not enclose", extent) 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)..]; let mut rest = &mut self.scopes[(len - scope_count)..];
while let Some((scope, rest_)) = {rest}.split_last_mut() { while let Some((scope, rest_)) = {rest}.split_last_mut() {
rest = rest_; 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), self.cfg.terminate(block, scope.source_info(span),
TerminatorKind::Goto { target: e }); TerminatorKind::Goto { target: e });
return; return;
@ -371,7 +371,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let b = self.cfg.start_new_block(); let b = self.cfg.start_new_block();
self.cfg.terminate(block, scope.source_info(span), self.cfg.terminate(block, scope.source_info(span),
TerminatorKind::Goto { target: b }); TerminatorKind::Goto { target: b });
scope.cached_exits.insert((target, extent), b); scope.cached_exits.insert((target, extent.0), b);
b b
}; };
unpack!(block = build_scope_drops(&mut self.cfg, unpack!(block = build_scope_drops(&mut self.cfg,