8000 Clean up MIR drop generation by matthewjasper · Pull Request #61872 · rust-lang/rust · GitHub
[go: up one dir, main page]

Skip to content

Clean up MIR drop generation #61872

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 26, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Use as_temp to evaluate statement expressions
  • Loading branch information
matthewjasper committed Jun 25, 2019
commit 101a2f59b490650c12c5f9e4561a7390bfce78d3
4 changes: 2 additions & 2 deletions src/librustc_mir/build/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {

let source_info = this.source_info(span);
for stmt in stmts {
let Stmt { kind, opt_destruction_scope, span: stmt_span } = this.hir.mirror(stmt);
let Stmt { kind, opt_destruction_scope } = this.hir.mirror(stmt);
match kind {
StmtKind::Expr { scope, expr } => {
this.block_context.push(BlockFrame::Statement { ignores_expr_result: true });
Expand All @@ -87,7 +87,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let si = (scope, source_info);
this.in_scope(si, LintLevel::Inherited, |this| {
let expr = this.hir.mirror(expr);
this.stmt_expr(block, expr, Some(stmt_span))
this.stmt_expr(block, expr, Some(scope))
})
}));
}
Expand Down
80 changes: 35 additions & 45 deletions src/librustc_mir/build/expr/stmt.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
use crate::build::scope::BreakableScope;
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
use crate::hair::*;
use rustc::middle::region;
use rustc::mir::*;

impl<'a, 'tcx> Builder<'a, 'tcx> {
/// Builds a block of MIR statements to evaluate the HAIR `expr`.
/// If the original expression was an AST statement,
/// (e.g., `some().code(&here());`) then `opt_stmt_span` is the
/// span of that statement (including its semicolon, if any).
/// Diagnostics use this span (which may be larger than that of
/// `expr`) to identify when statement temporaries are dropped.
pub fn stmt_expr(&mut self,
mut block: BasicBlock,
expr: Expr<'tcx>,
opt_stmt_span: Option<StatementSpan>)
-> BlockAnd<()>
{
/// The scope is used if a statement temporary must be dropped.
pub fn stmt_expr(
&mut self,
mut block: BasicBlock,
expr: Expr<'tcx>,
statement_scope: Option<region::Scope>,
) -> BlockAnd<()> {
let this = self;
let expr_span = expr.span;
let source_info = this.source_info(expr.span);
Expand All @@ -30,7 +30,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} => {
let value = this.hir.mirror(value);
this.in_scope((region_scope, source_info), lint_level, |this| {
this.stmt_expr(block, value, opt_stmt_span)
this.stmt_expr(block, value, statement_scope)
})
}
ExprKind::Assign { lhs, rhs } => {
Expand Down Expand Up @@ -199,7 +199,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block.unit()
}
_ => {
let expr_ty = expr.ty;
assert!(
statement_scope.is_some(),
"Should not be calling `stmt_expr` on a general expression \
without a statement scope",
);

// Issue #54382: When creating temp for the value of
// expression like:
Expand All @@ -208,48 +212,34 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
//
// it is usually better to focus on `the_value` rather
// than the entirety of block(s) surrounding it.
let mut temp_span = expr_span;
let mut temp_in_tail_of_block = false;
if let ExprKind::Block { body } = expr.kind {
if let Some(tail_expr) = &body.expr {
let mut expr = tail_expr;
while let rustc::hir::ExprKind::Block(subblock, _label) = &expr.node {
if let Some(subtail_expr) = &subblock.expr {
expr = subtail_expr
} else {
break;
let adjusted_span = (|| {
if let ExprKind::Block { body } = expr.kind {
if let Some(tail_expr) = &body.expr {
let mut expr = tail_expr;
while let rustc::hir::ExprKind::Block(subblock, _label) = &expr.node {
if let Some(subtail_expr) = &subblock.expr {
expr = subtail_expr
} else {
break;
}
}
}
temp_span = expr.span;
temp_in_tail_of_block = true;
}
}

let temp = {
let mut local_decl = LocalDecl::new_temp(expr.ty.clone(), temp_span);
if temp_in_tail_of_block {
if this.block_context.currently_ignores_tail_results() {
local_decl = local_decl.block_tail(BlockTailInfo {
this.block_context.push(BlockFrame::TailExpr {
tail_result_is_ignored: true
});
return Some(expr.span);
}
}
let temp = this.local_decls.push(local_decl);
let place = Place::from(temp);
debug!("created temp {:?} for expr {:?} in block_context: {:?}",
temp, expr, this.block_context);
place
};
unpack!(block = this.into(&temp, block, expr));
None
})();

let temp = unpack!(block =
this.as_temp(block, statement_scope, expr, Mutability::Not));

// Attribute drops of the statement's temps to the
// semicolon at the statement's end.
let drop_point = this.hir.tcx().sess.source_map().end_point(match opt_stmt_span {
None => expr_span,
Some(StatementSpan(span)) => span,
});
if let Some(span) = adjusted_span {
this.local_decls[temp].source_info.span = span;
this.block_context.pop();
}

unpack!(block = this.build_drop(block, drop_point, temp, expr_ty));
block.unit()
}
}
Expand Down
21 changes: 0 additions & 21 deletions src/librustc_mir/build/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -805,27 +805,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
target
}

/// Utility function for *non*-scope code to build their own drops
pub fn build_drop(&mut self,
block: BasicBlock,
span: Span,
location: Place<'tcx>,
ty: Ty<'tcx>) -> BlockAnd<()> {
if !self.hir.needs_drop(ty) {
return block.unit();
}
let source_info = self.source_info(span);
let next_target = self.cfg.start_new_block();
let diverge_target = self.diverge_cleanup();
self.cfg.terminate(block, source_info,
TerminatorKind::Drop {
location,
target: next_target,
unwind: Some(diverge_target),
});
next_target.unit()
}

/// Utility function for *non*-scope code to build their own drops
pub fn build_drop_and_replace(&mut self,
block: BasicBlock,
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_mir/hair/cx/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ fn mirror_stmts<'a, 'tcx>(
for (index, stmt) in stmts.iter().enumerate() {
let hir_id = stmt.hir_id;
let opt_dxn_ext = cx.region_scope_tree.opt_destruction_scope(hir_id.local_id);
let stmt_span = StatementSpan(cx.tcx.hir().span(hir_id));
match stmt.node {
hir::StmtKind::Expr(ref expr) |
hir::StmtKind::Semi(ref expr) => {
Expand All @@ -62,7 +61,6 @@ fn mirror_stmts<'a, 'tcx>(
expr: expr.to_ref(),
},
opt_destruction_scope: opt_dxn_ext,
span: stmt_span,
})))
}
hir::StmtKind::Item(..) => {
Expand Down Expand Up @@ -107,7 +105,6 @@ fn mirror_stmts<'a, 'tcx>(
lint_level: LintLevel::Explicit(local.hir_id),
},
opt_destruction_scope: opt_dxn_ext,
span: stmt_span,
})));
}
}
Expand Down
4 changes: 0 additions & 4 deletions src/librustc_mir/hair/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,10 @@ pub enum StmtRef<'tcx> {
Mirror(Box<Stmt<'tcx>>),
}

#[derive(Clone, Debug)]
pub struct StatementSpan(pub Span);

#[derive(Clone, Debug)]
pub struct Stmt<'tcx> {
pub kind: StmtKind<'tcx>,
pub opt_destruction_scope: Option<region::Scope>,
pub span: StatementSpan,
}

#[derive(Clone, Debug)]
Expand Down
4 changes: 3 additions & 1 deletion src/test/mir-opt/box_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ impl Drop for S {
// let mut _0: ();
// let _1: std::boxed::Box<S>;
// let mut _2: std::boxed::Box<S>;
// let mut _3: ();
// let _3: ();
// let mut _4: std::boxed::Box<S>;
// scope 1 {
// }
Expand All @@ -50,6 +50,7 @@ impl Drop for S {
//
// bb4: {
// StorageDead(_2);
// StorageLive(_3);
// StorageLive(_4);
// _4 = move _1;
// _3 = const std::mem::drop::<std::boxed::Box<S>>(move _4) -> [return: bb5, unwind: bb7];
Expand All @@ -69,6 +70,7 @@ impl Drop for S {
//
// bb8: {
// StorageDead(_4);
// StorageDead(_3);
// _0 = ();
// drop(_1) -> bb9;
// }
Expand Down
2 changes: 2 additions & 0 deletions src/test/mir-opt/copy_propagation_arg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,14 @@ fn main() {
// END rustc.foo.CopyPropagation.after.mir
// START rustc.bar.CopyPropagation.before.mir
// bb0: {
// StorageLive(_2);
// StorageLive(_3);
// _3 = _1;
// _2 = const dummy(move _3) -> bb1;
// }
// bb1: {
// StorageDead(_3);
// StorageDead(_2);
// _1 = const 5u8;
// ...
// return;
Expand Down
2 changes: 2 additions & 0 deletions src/test/mir-opt/generator-drop-cleanup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ fn main() {
// }
// bb1: {
// StorageDead(_3);
// StorageDead(_2);
// goto -> bb5;
// }
// bb2: {
Expand All @@ -36,6 +37,7 @@ fn main() {
// goto -> bb3;
// }
// bb7: {
// StorageLive(_2);
// StorageLive(_3);
// goto -> bb1;
// }
Expand Down
6 changes: 6 additions & 0 deletions src/test/mir-opt/generator-storage-dead-unwind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ fn main() {
// }
// bb2: {
// ...
// StorageLive(_6);
// StorageLive(_7);
// _7 = move _2;
// _6 = const take::<Foo>(move _7) -> [return: bb9, unwind: bb8];
Expand Down Expand Up @@ -81,23 +82,28 @@ fn main() {
// }
// bb8 (cleanup): {
// StorageDead(_7);
// StorageDead(_6);
// goto -> bb7;
// }
// bb9: {
// StorageDead(_7);
// StorageDead(_6);
// StorageLive(_8);
// StorageLive(_9);
// _9 = move _3;
// _8 = const take::<Bar>(move _9) -> [return: bb10, unwind: bb11];
// }
// bb10: {
// StorageDead(_9);
// StorageDead(_8);
// ...
// StorageDead(_3);
// StorageDead(_2);
// drop(_1) -> [return: bb12, unwind: bb1];
// }
// bb11 (cleanup): {
// StorageDead(_9);
// StorageDead(_8);
// goto -> bb7;
// }
// bb12: {
Expand Down
3 changes: 3 additions & 0 deletions src/test/mir-opt/issue-38669.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ fn main() {
// falseUnwind -> [real: bb3, cleanup: bb1];
// }
// bb3: {
// StorageLive(_3);
// StorageLive(_4);
// _4 = _1;
// FakeRead(ForMatchedPlace, _4);
Expand All @@ -34,13 +35,15 @@ fn main() {
// bb5: {
// _3 = ();
// StorageDead(_4);
// StorageDead(_3);
// _1 = const true;
// _2 = ();
// goto -> bb2;
// }
// bb6: {
// _0 = ();
// StorageDead(_4);
// StorageDead(_3);
// StorageDead(_1);
// return;
// }
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/issue-41110.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl S {
// START rustc.test.ElaborateDrops.after.mir
// let mut _0: ();
// let _1: S;
// let mut _3: ();
// let _3: ();
// let mut _4: S;
// let mut _5: S;
// let mut _6: bool;
Expand Down
4 changes: 3 additions & 1 deletion src/test/mir-opt/issue-49232.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn main() {
// let _2: i32;
// let mut _3: bool;
// let mut _4: !;
// let mut _5: ();
// let _5: ();
// let mut _6: &i32;
// scope 1 {
// }
Expand Down Expand Up @@ -73,12 +73,14 @@ fn main() {
// bb12: {
// FakeRead(ForLet, _2);
// StorageDead(_3);
// StorageLive(_5);
// StorageLive(_6);
// _6 = &_2;
// _5 = const std::mem::drop::<&i32>(move _6) -> [return: bb13, unwind: bb4];
// }
// bb13: {
// StorageDead(_6);
// StorageDead(_5);
// _1 = ();
// StorageDead(_2);
// goto -> bb1;
Expand Down
1 change: 1 addition & 0 deletions src/test/mir-opt/loop_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ fn main() {
// bb3: { // Entry into the loop
// _1 = ();
// StorageDead(_2);
// StorageDead(_1);
// goto -> bb5;
// }
// ...
Expand Down
1 change: 1 addition & 0 deletions src/test/mir-opt/match_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ fn main() {
// goto -> bb14;
// }
// bb14: {
// StorageDead(_3);
// _0 = ();
// StorageDead(_2);
// StorageDead(_1);
Expand Down
6 changes: 3 additions & 3 deletions src/test/mir-opt/nll/region-subtyping-basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ fn main() {

// END RUST SOURCE
// START rustc.main.nll.0.mir
// | '_#2r | U0 | {bb2[0..=8], bb3[0], bb5[0..=1]}
// | '_#3r | U0 | {bb2[1..=8], bb3[0], bb5[0..=1]}
// | '_#4r | U0 | {bb2[4..=8], bb3[0], bb5[0..=1]}
// | '_#2r | U0 | {bb2[0..=8], bb3[0], bb5[0..=2]}
// | '_#3r | U0 | {bb2[1..=8], bb3[0], bb5[0..=2]}
// | '_#4r | U0 | {bb2[4..=8], bb3[0], bb5[0..=2]}
// END rustc.main.nll.0.mir
// START rustc.main.nll.0.mir
// let _2: &'_#3r usize;
Expand Down
Loading
0