Skip to content

Commit 101a2f5

Browse files
committed
Use as_temp to evaluate statement expressions
1 parent 62bec71 commit 101a2f5

17 files changed

+96
-81
lines changed

src/librustc_mir/build/block.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
7878

7979
let source_info = this.source_info(span);
8080
for stmt in stmts {
81-
let Stmt { kind, opt_destruction_scope, span: stmt_span } = this.hir.mirror(stmt);
81+
let Stmt { kind, opt_destruction_scope } = this.hir.mirror(stmt);
8282
match kind {
8383
StmtKind::Expr { scope, expr } => {
8484
this.block_context.push(BlockFrame::Statement { ignores_expr_result: true });
@@ -87,7 +87,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
8787
let si = (scope, source_info);
8888
this.in_scope(si, LintLevel::Inherited, |this| {
8989
let expr = this.hir.mirror(expr);
90-
this.stmt_expr(block, expr, Some(stmt_span))
90+
this.stmt_expr(block, expr, Some(scope))
9191
})
9292
}));
9393
}

src/librustc_mir/build/expr/stmt.rs

+35-45
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
use crate::build::scope::BreakableScope;
22
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
33
use crate::hair::*;
4+
use rustc::middle::region;
45
use rustc::mir::*;
56

67
impl<'a, 'tcx> Builder<'a, 'tcx> {
78
/// Builds a block of MIR statements to evaluate the HAIR `expr`.
89
/// If the original expression was an AST statement,
910
/// (e.g., `some().code(&here());`) then `opt_stmt_span` is the
1011
/// span of that statement (including its semicolon, if any).
11-
/// Diagnostics use this span (which may be larger than that of
12-
/// `expr`) to identify when statement temporaries are dropped.
13-
pub fn stmt_expr(&mut self,
14-
mut block: BasicBlock,
15-
expr: Expr<'tcx>,
16-
opt_stmt_span: Option<StatementSpan>)
17-
-> BlockAnd<()>
18-
{
12+
/// The scope is used if a statement temporary must be dropped.
13+
pub fn stmt_expr(
14+
&mut self,
15+
mut block: BasicBlock,
16+
expr: Expr<'tcx>,
17+
statement_scope: Option<region::Scope>,
18+
) -> BlockAnd<()> {
1919
let this = self;
2020
let expr_span = expr.span;
2121
let source_info = this.source_info(expr.span);
@@ -30,7 +30,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
3030
} => {
3131
let value = this.hir.mirror(value);
3232
this.in_scope((region_scope, source_info), lint_level, |this| {
33-
this.stmt_expr(block, value, opt_stmt_span)
33+
this.stmt_expr(block, value, statement_scope)
3434
})
3535
}
3636
ExprKind::Assign { lhs, rhs } => {
@@ -199,7 +199,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
199199
block.unit()
200200
}
201201
_ => {
202-
let expr_ty = expr.ty;
202+
assert!(
203+
statement_scope.is_some(),
204+
"Should not be calling `stmt_expr` on a general expression \
205+
without a statement scope",
206+
);
203207

204208
// Issue #54382: When creating temp for the value of
205209
// expression like:
@@ -208,48 +212,34 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
208212
//
209213
// it is usually better to focus on `the_value` rather
210214
// than the entirety of block(s) surrounding it.
211-
let mut temp_span = expr_span;
212-
let mut temp_in_tail_of_block = false;
213-
if let ExprKind::Block { body } = expr.kind {
214-
if let Some(tail_expr) = &body.expr {
215-
let mut expr = tail_expr;
216-
while let rustc::hir::ExprKind::Block(subblock, _label) = &expr.node {
217-
if let Some(subtail_expr) = &subblock.expr {
218-
expr = subtail_expr
219-
} else {
220-
break;
215+
let adjusted_span = (|| {
216+
if let ExprKind::Block { body } = expr.kind {
217+
if let Some(tail_expr) = &body.expr {
218+
let mut expr = tail_expr;
219+
while let rustc::hir::ExprKind::Block(subblock, _label) = &expr.node {
220+
if let Some(subtail_expr) = &subblock.expr {
221+
expr = subtail_expr
222+
} else {
223+
break;
224+
}
221225
}
222-
}
223-
temp_span = expr.span;
224-
temp_in_tail_of_block = true;
225-
}
226-
}
227-
228-
let temp = {
229-
let mut local_decl = LocalDecl::new_temp(expr.ty.clone(), temp_span);
230-
if temp_in_tail_of_block {
231-
if this.block_context.currently_ignores_tail_results() {
232-
local_decl = local_decl.block_tail(BlockTailInfo {
226+
this.block_context.push(BlockFrame::TailExpr {
233227
tail_result_is_ignored: true
234228
});
229+
return Some(expr.span);
235230
}
236231
}
237-
let temp = this.local_decls.push(local_decl);
238-
let place = Place::from(temp);
239-
debug!("created temp {:?} for expr {:?} in block_context: {:?}",
240-
temp, expr, this.block_context);
241-
place
242-
};
243-
unpack!(block = this.into(&temp, block, expr));
232+
None
233+
})();
234+
235+
let temp = unpack!(block =
236+
this.as_temp(block, statement_scope, expr, Mutability::Not));
244237

245-
// Attribute drops of the statement's temps to the
246-
// semicolon at the statement's end.
247-
let drop_point = this.hir.tcx().sess.source_map().end_point(match opt_stmt_span {
248-
None => expr_span,
249-
Some(StatementSpan(span)) => span,
250-
});
238+
if let Some(span) = adjusted_span {
239+
this.local_decls[temp].source_info.span = span;
240+
this.block_context.pop();
241+
}
251242

252-
unpack!(block = this.build_drop(block, drop_point, temp, expr_ty));
253243
block.unit()
254244
}
255245
}

src/librustc_mir/build/scope.rs

-21
Original file line numberDiff line numberDiff line change
@@ -805,27 +805,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
805805
target
806806
}
807807

808-
/// Utility function for *non*-scope code to build their own drops
809-
pub fn build_drop(&mut self,
810-
block: BasicBlock,
811-
span: Span,
812-
location: Place<'tcx>,
813-
ty: Ty<'tcx>) -> BlockAnd<()> {
814-
if !self.hir.needs_drop(ty) {
815-
return block.unit();
816-
}
817-
let source_info = self.source_info(span);
818-
let next_target = self.cfg.start_new_block();
819-
let diverge_target = self.diverge_cleanup();
820-
self.cfg.terminate(block, source_info,
821-
TerminatorKind::Drop {
822-
location,
823-
target: next_target,
824-
unwind: Some(diverge_target),
825-
});
826-
next_target.unit()
827-
}
828-
829808
/// Utility function for *non*-scope code to build their own drops
830809
pub fn build_drop_and_replace(&mut self,
831810
block: BasicBlock,

src/librustc_mir/hair/cx/block.rs

-3
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ fn mirror_stmts<'a, 'tcx>(
4949
for (index, stmt) in stmts.iter().enumerate() {
5050
let hir_id = stmt.hir_id;
5151
let opt_dxn_ext = cx.region_scope_tree.opt_destruction_scope(hir_id.local_id);
52-
let stmt_span = StatementSpan(cx.tcx.hir().span(hir_id));
5352
match stmt.node {
5453
hir::StmtKind::Expr(ref expr) |
5554
hir::StmtKind::Semi(ref expr) => {
@@ -62,7 +61,6 @@ fn mirror_stmts<'a, 'tcx>(
6261
expr: expr.to_ref(),
6362
},
6463
opt_destruction_scope: opt_dxn_ext,
65-
span: stmt_span,
6664
})))
6765
}
6866
hir::StmtKind::Item(..) => {
@@ -107,7 +105,6 @@ fn mirror_stmts<'a, 'tcx>(
107105
lint_level: LintLevel::Explicit(local.hir_id),
108106
},
109107
opt_destruction_scope: opt_dxn_ext,
110-
span: stmt_span,
111108
})));
112109
}
113110
}

src/librustc_mir/hair/mod.rs

-4
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,10 @@ pub enum StmtRef<'tcx> {
5555
Mirror(Box<Stmt<'tcx>>),
5656
}
5757

58-
#[derive(Clone, Debug)]
59-
pub struct StatementSpan(pub Span);
60-
6158
#[derive(Clone, Debug)]
6259
pub struct Stmt<'tcx> {
6360
pub kind: StmtKind<'tcx>,
6461
pub opt_destruction_scope: Option<region::Scope>,
65-
pub span: StatementSpan,
6662
}
6763

6864
#[derive(Clone, Debug)]

src/test/mir-opt/box_expr.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ impl Drop for S {
2424
// let mut _0: ();
2525
// let _1: std::boxed::Box<S>;
2626
// let mut _2: std::boxed::Box<S>;
27-
// let mut _3: ();
27+
// let _3: ();
2828
// let mut _4: std::boxed::Box<S>;
2929
// scope 1 {
3030
// }
@@ -50,6 +50,7 @@ impl Drop for S {
5050
//
5151
// bb4: {
5252
// StorageDead(_2);
53+
// StorageLive(_3);
5354
// StorageLive(_4);
5455
// _4 = move _1;
5556
// _3 = const std::mem::drop::<std::boxed::Box<S>>(move _4) -> [return: bb5, unwind: bb7];
@@ -69,6 +70,7 @@ impl Drop for S {
6970
//
7071
// bb8: {
7172
// StorageDead(_4);
73+
// StorageDead(_3);
7274
// _0 = ();
7375
// drop(_1) -> bb9;
7476
// }

src/test/mir-opt/copy_propagation_arg.rs

+2
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,14 @@ fn main() {
6161
// END rustc.foo.CopyPropagation.after.mir
6262
// START rustc.bar.CopyPropagation.before.mir
6363
// bb0: {
64+
// StorageLive(_2);
6465
// StorageLive(_3);
6566
// _3 = _1;
6667
// _2 = const dummy(move _3) -> bb1;
6768
// }
6869
// bb1: {
6970
// StorageDead(_3);
71+
// StorageDead(_2);
7072
// _1 = const 5u8;
7173
// ...
7274
// return;

src/test/mir-opt/generator-drop-cleanup.rs

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ fn main() {
1818
// }
1919
// bb1: {
2020
// StorageDead(_3);
21+
// StorageDead(_2);
2122
// goto -> bb5;
2223
// }
2324
// bb2: {
@@ -36,6 +37,7 @@ fn main() {
3637
// goto -> bb3;
3738
// }
3839
// bb7: {
40+
// StorageLive(_2);
3941
// StorageLive(_3);
4042
// goto -> bb1;
4143
// }

src/test/mir-opt/generator-storage-dead-unwind.rs

+6
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ fn main() {
5454
// }
5555
// bb2: {
5656
// ...
57+
// StorageLive(_6);
5758
// StorageLive(_7);
5859
// _7 = move _2;
5960
// _6 = const take::<Foo>(move _7) -> [return: bb9, unwind: bb8];
@@ -81,23 +82,28 @@ fn main() {
8182
// }
8283
// bb8 (cleanup): {
8384
// StorageDead(_7);
85+
// StorageDead(_6);
8486
// goto -> bb7;
8587
// }
8688
// bb9: {
8789
// StorageDead(_7);
90+
// StorageDead(_6);
91+
// StorageLive(_8);
8892
// StorageLive(_9);
8993
// _9 = move _3;
9094
// _8 = const take::<Bar>(move _9) -> [return: bb10, unwind: bb11];
9195
// }
9296
// bb10: {
9397
// StorageDead(_9);
98+
// StorageDead(_8);
9499
// ...
95100
// StorageDead(_3);
96101
// StorageDead(_2);
97102
// drop(_1) -> [return: bb12, unwind: bb1];
98103
// }
99104
// bb11 (cleanup): {
100105
// StorageDead(_9);
106+
// StorageDead(_8);
101107
// goto -> bb7;
102108
// }
103109
// bb12: {

src/test/mir-opt/issue-38669.rs

+3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ fn main() {
2525
// falseUnwind -> [real: bb3, cleanup: bb1];
2626
// }
2727
// bb3: {
28+
// StorageLive(_3);
2829
// StorageLive(_4);
2930
// _4 = _1;
3031
// FakeRead(ForMatchedPlace, _4);
@@ -34,13 +35,15 @@ fn main() {
3435
// bb5: {
3536
// _3 = ();
3637
// StorageDead(_4);
38+
// StorageDead(_3);
3739
// _1 = const true;
3840
// _2 = ();
3941
// goto -> bb2;
4042
// }
4143
// bb6: {
4244
// _0 = ();
4345
// StorageDead(_4);
46+
// StorageDead(_3);
4447
// StorageDead(_1);
4548
// return;
4649
// }

src/test/mir-opt/issue-41110.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl S {
4242
// START rustc.test.ElaborateDrops.after.mir
4343
// let mut _0: ();
4444
// let _1: S;
45-
// let mut _3: ();
45+
// let _3: ();
4646
// let mut _4: S;
4747
// let mut _5: S;
4848
// let mut _6: bool;

src/test/mir-opt/issue-49232.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ fn main() {
2121
// let _2: i32;
2222
// let mut _3: bool;
2323
// let mut _4: !;
24-
// let mut _5: ();
24+
// let _5: ();
2525
// let mut _6: &i32;
2626
// scope 1 {
2727
// }
@@ -73,12 +73,14 @@ fn main() {
7373
// bb12: {
7474
// FakeRead(ForLet, _2);
7575
// StorageDead(_3);
76+
// StorageLive(_5);
7677
// StorageLive(_6);
7778
// _6 = &_2;
7879
// _5 = const std::mem::drop::<&i32>(move _6) -> [return: bb13, unwind: bb4];
7980
// }
8081
// bb13: {
8182
// StorageDead(_6);
83+
// StorageDead(_5);
8284
// _1 = ();
8385
// StorageDead(_2);
8486
// goto -> bb1;

src/test/mir-opt/loop_test.rs

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ fn main() {
2525
// bb3: { // Entry into the loop
2626
// _1 = ();
2727
// StorageDead(_2);
28+
// StorageDead(_1);
2829
// goto -> bb5;
2930
// }
3031
// ...

src/test/mir-opt/match_test.rs

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ fn main() {
7575
// goto -> bb14;
7676
// }
7777
// bb14: {
78+
// StorageDead(_3);
7879
// _0 = ();
7980
// StorageDead(_2);
8081
// StorageDead(_1);

src/test/mir-opt/nll/region-subtyping-basic.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ fn main() {
2222

2323
// END RUST SOURCE
2424
// START rustc.main.nll.0.mir
25-
// | '_#2r | U0 | {bb2[0..=8], bb3[0], bb5[0..=1]}
26-
// | '_#3r | U0 | {bb2[1..=8], bb3[0], bb5[0..=1]}
27-
// | '_#4r | U0 | {bb2[4..=8], bb3[0], bb5[0..=1]}
25+
// | '_#2r | U0 | {bb2[0..=8], bb3[0], bb5[0..=2]}
26+
// | '_#3r | U0 | {bb2[1..=8], bb3[0], bb5[0..=2]}
27+
// | '_#4r | U0 | {bb2[4..=8], bb3[0], bb5[0..=2]}
2828
// END rustc.main.nll.0.mir
2929
// START rustc.main.nll.0.mir
3030
// let _2: &'_#3r usize;

0 commit comments

Comments
 (0)