Paired source_info with extent; thread both through to pts where EndRegion will need construction.
This commit is contained in:
parent
cbed41a174
commit
a658bb21e4
9 changed files with 40 additions and 32 deletions
|
@ -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;
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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)
|
||||||
});
|
});
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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 } => {
|
||||||
|
|
|
@ -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 } => {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue