Skip to content

Commit f5a06a4

Browse files
committed
Revert "Avoid leaking block expression values"
This reverts commit 4fef391.
1 parent a9a396d commit f5a06a4

20 files changed

+10733
-10930
lines changed

compiler/rustc_mir_build/src/build/block.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use crate::build::ForGuard::OutsideGuard;
33
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
44
use crate::thir::*;
55
use rustc_hir as hir;
6-
use rustc_middle::middle::region;
76
use rustc_middle::mir::*;
87
use rustc_session::lint::builtin::UNSAFE_OP_IN_UNSAFE_FN;
98
use rustc_session::lint::Level;
@@ -13,7 +12,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1312
crate fn ast_block(
1413
&mut self,
1514
destination: Place<'tcx>,
16-
scope: Option<region::Scope>,
1715
block: BasicBlock,
1816
ast_block: &'tcx hir::Block<'tcx>,
1917
source_info: SourceInfo,
@@ -30,10 +28,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
3028
self.in_opt_scope(opt_destruction_scope.map(|de| (de, source_info)), move |this| {
3129
this.in_scope((region_scope, source_info), LintLevel::Inherited, move |this| {
3230
if targeted_by_break {
33-
this.in_breakable_scope(None, destination, scope, span, |this| {
31+
this.in_breakable_scope(None, destination, span, |this| {
3432
Some(this.ast_block_stmts(
3533
destination,
36-
scope,
3734
block,
3835
span,
3936
stmts,
@@ -42,7 +39,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
4239
))
4340
})
4441
} else {
45-
this.ast_block_stmts(destination, scope, block, span, stmts, expr, safety_mode)
42+
this.ast_block_stmts(destination, block, span, stmts, expr, safety_mode)
4643
}
4744
})
4845
})
@@ -51,7 +48,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
5148
fn ast_block_stmts(
5249
&mut self,
5350
destination: Place<'tcx>,
54-
scope: Option<region::Scope>,
5551
mut block: BasicBlock,
5652
span: Span,
5753
stmts: Vec<StmtRef<'tcx>>,
@@ -186,7 +182,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
186182
};
187183
this.block_context.push(BlockFrame::TailExpr { tail_result_is_ignored, span });
188184

189-
unpack!(block = this.into(destination, scope, block, expr));
185+
unpack!(block = this.into(destination, block, expr));
190186
let popped = this.block_context.pop();
191187

192188
assert!(popped.map_or(false, |bf| bf.is_tail_expr()));

compiler/rustc_mir_build/src/build/expr/as_rvalue.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
115115
let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
116116
this.cfg.push_assign(block, source_info, Place::from(result), box_);
117117

118-
// Initialize the box contents. No scope is needed since the
119-
// `Box` is already scheduled to be dropped.
118+
// initialize the box contents:
120119
unpack!(
121-
block = this.into(
122-
this.hir.tcx().mk_place_deref(Place::from(result)),
123-
None,
124-
block,
125-
value,
126-
)
120+
block =
121+
this.into(this.hir.tcx().mk_place_deref(Place::from(result)), block, value)
127122
);
128123
let result_operand = Operand::Move(Place::from(result));
129124
this.record_operands_moved(slice::from_ref(&result_operand));

compiler/rustc_mir_build/src/build/expr/as_temp.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
114114
}
115115
}
116116

117-
unpack!(block = this.into(temp_place, temp_lifetime, block, expr));
117+
unpack!(block = this.into(temp_place, block, expr));
118+
119+
if let Some(temp_lifetime) = temp_lifetime {
120+
this.schedule_drop(expr_span, temp_lifetime, temp, DropKind::Value);
121+
}
118122

119123
block.and(temp)
120124
}

compiler/rustc_mir_build/src/build/expr/into.rs

Lines changed: 27 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
//! See docs in build/expr/mod.rs
22
33
use crate::build::expr::category::{Category, RvalueFunc};
4-
use crate::build::scope::DropKind;
54
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
65
use crate::thir::*;
76
use rustc_ast::InlineAsmOptions;
87
use rustc_data_structures::fx::FxHashMap;
98
use rustc_data_structures::stack::ensure_sufficient_stack;
109
use rustc_hir as hir;
11-
use rustc_middle::middle::region;
1210
use rustc_middle::mir::*;
1311
use rustc_middle::ty::{CanonicalUserTypeAnnotation};
1412

@@ -17,19 +15,13 @@ use std::slice;
1715
impl<'a, 'tcx> Builder<'a, 'tcx> {
1816
/// Compile `expr`, storing the result into `destination`, which
1917
/// is assumed to be uninitialized.
20-
/// If a `drop_scope` is provided, `destination` is scheduled to be dropped
21-
/// in `scope` once it has been initialized.
2218
crate fn into_expr(
2319
&mut self,
2420
destination: Place<'tcx>,
25-
scope: Option<region::Scope>,
2621
mut block: BasicBlock,
2722
expr: Expr<'tcx>,
2823
) -> BlockAnd<()> {
29-
debug!(
30-
"into_expr(destination={:?}, scope={:?}, block={:?}, expr={:?})",
31-
destination, scope, block, expr
32-
);
24+
debug!("into_expr(destination={:?}, block={:?}, expr={:?})", destination, block, expr);
3325

3426
// since we frequently have to reference `self` from within a
3527
// closure, where `self` would be shadowed, it's easier to
@@ -40,14 +32,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
4032

4133
let expr_is_block_or_scope = matches!(expr.kind, ExprKind::Block { .. } | ExprKind::Scope { .. });
4234

43-
let schedule_drop = move |this: &mut Self| {
44-
if let Some(drop_scope) = scope {
45-
let local =
46-
destination.as_local().expect("cannot schedule drop of non-Local place");
47-
this.schedule_drop(expr_span, drop_scope, local, DropKind::Value);
48-
}
49-
};
50-
5135
if !expr_is_block_or_scope {
5236
this.block_context.push(BlockFrame::SubExpr);
5337
}
@@ -57,15 +41,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
5741
let region_scope = (region_scope, source_info);
5842
ensure_sufficient_stack(|| {
5943
this.in_scope(region_scope, lint_level, |this| {
60-
this.into(destination, scope, block, value)
44+
this.into(destination, block, value)
6145
})
6246
})
6347
}
6448
ExprKind::Block { body: ast_block } => {
65-
this.ast_block(destination, scope, block, ast_block, source_info)
49+
this.ast_block(destination, block, ast_block, source_info)
6650
}
6751
ExprKind::Match { scrutinee, arms } => {
68-
this.match_expr(destination, scope, expr_span, block, scrutinee, arms)
52+
this.match_expr(destination, expr_span, block, scrutinee, arms)
6953
}
7054
ExprKind::If { cond, then, else_opt } => {
7155
let place = unpack!(block = this.as_temp(block, Some(this.local_scope()), cond, Mutability::Mut));
@@ -76,9 +60,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
7660
let term = TerminatorKind::if_(this.hir.tcx(), operand, then_block, else_block);
7761
this.cfg.terminate(block, source_info, term);
7862

79-
unpack!(then_block = this.into(destination, scope, then_block, then));
63+
unpack!(then_block = this.into(destination, then_block, then));
8064
else_block = if let Some(else_opt) = else_opt {
81-
unpack!(this.into(destination, None, else_block, else_opt))
65+
unpack!(this.into(destination, else_block, else_opt))
8266
} else {
8367
// Body of the `if` expression without an `else` clause must return `()`, thus
8468
// we implicitly generate a `else {}` if it is not specified.
@@ -111,7 +95,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
11195

11296
// This is an optimization. If the expression was a call then we already have an
11397
// unreachable block. Don't bother to terminate it and create a new one.
114-
schedule_drop(this);
11598
if is_call {
11699
block.unit()
117100
} else {
@@ -187,35 +170,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
187170
// Start the loop.
188171
this.cfg.goto(block, source_info, loop_block);
189172

190-
this.in_breakable_scope(
191-
Some(loop_block),
192-
destination,
193-
scope,
194-
expr_span,
195-
move |this| {
196-
// conduct the test, if necessary
197-
let body_block = this.cfg.start_new_block();
198-
this.cfg.terminate(
199-
loop_block,
200-
source_info,
201-
TerminatorKind::FalseUnwind { real_target: body_block, unwind: None },
202-
);
203-
this.diverge_from(loop_block);
204-
205-
// The “return” value of the loop body must always be an unit. We therefore
206-
// introduce a unit temporary as the destination for the loop body.
207-
let tmp = this.get_unit_temp();
208-
// Execute the body, branching back to the test.
209-
// We don't need to provide a drop scope because `tmp`
210-
// has type `()`.
211-
let body_block_end = unpack!(this.into(tmp, None, body_block, body));
212-
this.cfg.goto(body_block_end, source_info, loop_block);
213-
schedule_drop(this);
214-
215-
// Loops are only exited by `break` expressions.
216-
None
217-
},
218-
)
173+
this.in_breakable_scope(Some(loop_block), destination, expr_span, move |this| {
174+
// conduct the test, if necessary
175+
let body_block = this.cfg.start_new_block();
176+
this.cfg.terminate(
177+
loop_block,
178+
source_info,
179+
TerminatorKind::FalseUnwind { real_target: body_block, unwind: None },
180+
);
181+
this.diverge_from(loop_block);
182+
183+
// The “return” value of the loop body must always be an unit. We therefore
184+
// introduce a unit temporary as the destination for the loop body.
185+
let tmp = this.get_unit_temp();
186+
// Execute the body, branching back to the test.
187+
let body_block_end = unpack!(this.into(tmp, body_block, body));
188+
this.cfg.goto(body_block_end, source_info, loop_block);
189+
190+
// Loops are only exited by `break` expressions.
191+
None
192+
})
219193
}
220194
ExprKind::Call { ty: _, fun, args, from_hir_call, fn_span } => {
221195
let fun = unpack!(block = this.as_local_operand(block, fun));
@@ -250,10 +224,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
250224
},
251225
);
252226
this.diverge_from(block);
253-
schedule_drop(this);
254227
success.unit()
255228
}
256-
ExprKind::Use { source } => this.into(destination, scope, block, source),
229+
ExprKind::Use { source } => this.into(destination, block, source),
257230
ExprKind::Borrow { arg, borrow_kind } => {
258231
// We don't do this in `as_rvalue` because we use `as_place`
259232
// for borrow expressions, so we cannot create an `RValue` that
@@ -337,7 +310,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
337310
destination,
338311
Rvalue::Aggregate(adt, fields),
339312
);
340-
schedule_drop(this);
341313
block.unit()
342314
}
343315
ExprKind::InlineAsm { template, operands, options, line_spans } => {
@@ -434,7 +406,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
434406
let place = unpack!(block = this.as_place(block, expr));
435407
let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place));
436408
this.cfg.push_assign(block, source_info, destination, rvalue);
437-
schedule_drop(this);
438409
block.unit()
439410
}
440411
ExprKind::Index { .. } | ExprKind::Deref { .. } | ExprKind::Field { .. } => {
@@ -452,7 +423,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
452423
let place = unpack!(block = this.as_place(block, expr));
453424
let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place));
454425
this.cfg.push_assign(block, source_info, destination, rvalue);
455-
schedule_drop(this);
456426
block.unit()
457427
}
458428

@@ -467,7 +437,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
467437
TerminatorKind::Yield { value, resume, resume_arg: destination, drop: None },
468438
);
469439
this.generator_drop_cleanup(block);
470-
schedule_drop(this);
471440
resume.unit()
472441
}
473442

@@ -499,7 +468,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
499468

500469
let rvalue = unpack!(block = this.as_local_rvalue(block, expr));
501470
this.cfg.push_assign(block, source_info, destination, rvalue);
502-
schedule_drop(this);
503471
block.unit()
504472
}
505473
};

compiler/rustc_mir_build/src/build/into.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,13 @@
66
77
use crate::build::{BlockAnd, Builder};
88
use crate::thir::*;
9-
use rustc_middle::middle::region;
109
use rustc_middle::mir::*;
1110

1211
pub(in crate::build) trait EvalInto<'tcx> {
1312
fn eval_into(
1413
self,
1514
builder: &mut Builder<'_, 'tcx>,
1615
destination: Place<'tcx>,
17-
scope: Option<region::Scope>,
1816
block: BasicBlock,
1917
) -> BlockAnd<()>;
2018
}
@@ -23,14 +21,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2321
crate fn into<E>(
2422
&mut self,
2523
destination: Place<'tcx>,
26-
scope: Option<region::Scope>,
2724
block: BasicBlock,
2825
expr: E,
2926
) -> BlockAnd<()>
3027
where
3128
E: EvalInto<'tcx>,
3229
{
33-
expr.eval_into(self, destination, scope, block)
30+
expr.eval_into(self, destination, block)
3431
}
3532
}
3633

@@ -39,11 +36,10 @@ impl<'tcx> EvalInto<'tcx> for ExprRef<'tcx> {
3936
self,
4037
builder: &mut Builder<'_, 'tcx>,
4138
destination: Place<'tcx>,
42-
scope: Option<region::Scope>,
4339
block: BasicBlock,
4440
) -> BlockAnd<()> {
4541
let expr = builder.hir.mirror(self);
46-
builder.into_expr(destination, scope, block, expr)
42+
builder.into_expr(destination, block, expr)
4743
}
4844
}
4945

@@ -52,9 +48,8 @@ impl<'tcx> EvalInto<'tcx> for Expr<'tcx> {
5248
self,
5349
builder: &mut Builder<'_, 'tcx>,
5450
destination: Place<'tcx>,
55-
scope: Option<region::Scope>,
5651
block: BasicBlock,
5752
) -> BlockAnd<()> {
58-
builder.into_expr(destination, scope, block, self)
53+
builder.into_expr(destination, block, self)
5954
}
6055
}

0 commit comments

Comments
 (0)