Skip to content

Commit cbed41a

Browse files
committed
Add destruction extents around blocks and statements in HAIR.
1 parent 609813b commit cbed41a

File tree

4 files changed

+60
-22
lines changed

4 files changed

+60
-22
lines changed

src/librustc_mir/build/block.rs

+30-22
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,24 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
2121
ast_block: &'tcx hir::Block,
2222
source_info: SourceInfo)
2323
-> BlockAnd<()> {
24-
let Block { extent, span, stmts, expr, targeted_by_break } = self.hir.mirror(ast_block);
25-
self.in_scope(extent, block, move |this| {
26-
if targeted_by_break {
27-
// This is a `break`-able block (currently only `catch { ... }`)
28-
let exit_block = this.cfg.start_new_block();
29-
let block_exit = this.in_breakable_scope(None, exit_block,
30-
destination.clone(), |this| {
24+
let Block { extent, opt_destruction_extent, span, stmts, expr, targeted_by_break } =
25+
self.hir.mirror(ast_block);
26+
self.in_opt_scope(opt_destruction_extent, block, move |this| {
27+
this.in_scope(extent, block, move |this| {
28+
if targeted_by_break {
29+
// This is a `break`-able block (currently only `catch { ... }`)
30+
let exit_block = this.cfg.start_new_block();
31+
let block_exit = this.in_breakable_scope(
32+
None, exit_block, destination.clone(), |this| {
33+
this.ast_block_stmts(destination, block, span, stmts, expr)
34+
});
35+
this.cfg.terminate(unpack!(block_exit), source_info,
36+
TerminatorKind::Goto { target: exit_block });
37+
exit_block.unit()
38+
} else {
3139
this.ast_block_stmts(destination, block, span, stmts, expr)
32-
});
33-
this.cfg.terminate(unpack!(block_exit), source_info,
34-
TerminatorKind::Goto { target: exit_block });
35-
exit_block.unit()
36-
} else {
37-
this.ast_block_stmts(destination, block, span, stmts, expr)
38-
}
40+
}
41+
})
3942
})
4043
}
4144

@@ -67,12 +70,14 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
6770
let mut let_extent_stack = Vec::with_capacity(8);
6871
let outer_visibility_scope = this.visibility_scope;
6972
for stmt in stmts {
70-
let Stmt { span: _, kind } = this.hir.mirror(stmt);
73+
let Stmt { span: _, kind, opt_destruction_extent } = this.hir.mirror(stmt);
7174
match kind {
7275
StmtKind::Expr { scope, expr } => {
73-
unpack!(block = this.in_scope(scope, block, |this| {
74-
let expr = this.hir.mirror(expr);
75-
this.stmt_expr(block, expr)
76+
unpack!(block = this.in_opt_scope(opt_destruction_extent, block, |this| {
77+
this.in_scope(scope, block, |this| {
78+
let expr = this.hir.mirror(expr);
79+
this.stmt_expr(block, expr)
80+
})
7681
}));
7782
}
7883
StmtKind::Let { remainder_scope, init_scope, pattern, initializer } => {
@@ -89,10 +94,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
8994

9095
// Evaluate the initializer, if present.
9196
if let Some(init) = initializer {
92-
unpack!(block = this.in_scope(init_scope, block, move |this| {
93-
// FIXME #30046 ^~~~
94-
this.expr_into_pattern(block, pattern, init)
95-
}));
97+
unpack!(block = this.in_opt_scope(
98+
opt_destruction_extent, block, move |this| {
99+
this.in_scope(init_scope, block, move |this| {
100+
// FIXME #30046 ^~~~
101+
this.expr_into_pattern(block, pattern, init)
102+
})
103+
}));
96104
} else {
97105
this.visit_bindings(&pattern, &mut |this, _, _, node, span, _| {
98106
this.storage_live_binding(block, node, span);

src/librustc_mir/build/scope.rs

+17
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,23 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
269269
res
270270
}
271271

272+
pub fn in_opt_scope<F, R>(&mut self,
273+
opt_extent: Option<CodeExtent>,
274+
mut block: BasicBlock,
275+
f: F)
276+
-> BlockAnd<R>
277+
where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> BlockAnd<R>
278+
{
279+
debug!("in_opt_scope(opt_extent={:?}, block={:?})", opt_extent, block);
280+
if let Some(extent) = opt_extent { self.push_scope(extent); }
281+
let rv = unpack!(block = f(self));
282+
if let Some(extent) = opt_extent {
283+
unpack!(block = self.pop_scope(extent, block));
284+
}
285+
debug!("in_scope: exiting opt_extent={:?} block={:?}", opt_extent, block);
286+
block.and(rv)
287+
}
288+
272289
/// Convenience wrapper that pushes a scope and then executes `f`
273290
/// to build its contents, popping the scope afterwards.
274291
pub fn in_scope<F, R>(&mut self,

src/librustc_mir/hair/cx/block.rs

+11
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,14 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Block {
2222
// We have to eagerly translate the "spine" of the statements
2323
// in order to get the lexical scoping correctly.
2424
let stmts = mirror_stmts(cx, self.id, &*self.stmts);
25+
let opt_def_id = cx.tcx.hir.opt_local_def_id(self.id);
26+
let opt_destruction_extent = opt_def_id.and_then(|def_id| {
27+
cx.tcx.region_maps(def_id).opt_destruction_extent(self.id)
28+
});
2529
Block {
2630
targeted_by_break: self.targeted_by_break,
2731
extent: CodeExtent::Misc(self.id),
32+
opt_destruction_extent: opt_destruction_extent,
2833
span: self.span,
2934
stmts: stmts,
3035
expr: self.expr.to_ref(),
@@ -37,7 +42,11 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
3742
stmts: &'tcx [hir::Stmt])
3843
-> Vec<StmtRef<'tcx>> {
3944
let mut result = vec![];
45+
let opt_def_id = cx.tcx.hir.opt_local_def_id(block_id);
4046
for (index, stmt) in stmts.iter().enumerate() {
47+
let opt_dxn_ext = opt_def_id.and_then(|def_id| {
48+
cx.tcx.region_maps(def_id).opt_destruction_extent(stmt.node.id())
49+
});
4150
match stmt.node {
4251
hir::StmtExpr(ref expr, id) |
4352
hir::StmtSemi(ref expr, id) => {
@@ -47,6 +56,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
4756
scope: CodeExtent::Misc(id),
4857
expr: expr.to_ref(),
4958
},
59+
opt_destruction_extent: opt_dxn_ext,
5060
})))
5161
}
5262
hir::StmtDecl(ref decl, id) => {
@@ -69,6 +79,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
6979
pattern: pattern,
7080
initializer: local.init.to_ref(),
7181
},
82+
opt_destruction_extent: opt_dxn_ext,
7283
})));
7384
}
7485
}

src/librustc_mir/hair/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub use rustc_const_eval::pattern::{BindingMode, Pattern, PatternKind, FieldPatt
3333
pub struct Block<'tcx> {
3434
pub targeted_by_break: bool,
3535
pub extent: CodeExtent,
36+
pub opt_destruction_extent: Option<CodeExtent>,
3637
pub span: Span,
3738
pub stmts: Vec<StmtRef<'tcx>>,
3839
pub expr: Option<ExprRef<'tcx>>,
@@ -47,6 +48,7 @@ pub enum StmtRef<'tcx> {
4748
pub struct Stmt<'tcx> {
4849
pub span: Span,
4950
pub kind: StmtKind<'tcx>,
51+
pub opt_destruction_extent: Option<CodeExtent>,
5052
}
5153

5254
#[derive(Clone, Debug)]

0 commit comments

Comments
 (0)