Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit a71a819

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

File tree

20 files changed

+10733
-10930
lines changed

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
@@ -41,14 +33,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
4133
let expr_is_block_or_scope =
4234
matches!(expr.kind, ExprKind::Block { .. } | ExprKind::Scope { .. });
4335

44-
let schedule_drop = move |this: &mut Self| {
45-
if let Some(drop_scope) = scope {
46-
let local =
47-
destination.as_local().expect("cannot schedule drop of non-Local place");
48-
this.schedule_drop(expr_span, drop_scope, local, DropKind::Value);
49-
}
50-
};
51-
5236
if !expr_is_block_or_scope {
5337
this.block_context.push(BlockFrame::SubExpr);
5438
}
@@ -58,15 +42,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
5842
let region_scope = (region_scope, source_info);
5943
ensure_sufficient_stack(|| {
6044
this.in_scope(region_scope, lint_level, |this| {
61-
this.into(destination, scope, block, value)
45+
this.into(destination, block, value)
6246
})
6347
})
6448
}
6549
ExprKind::Block { body: ast_block } => {
66-
this.ast_block(destination, scope, block, ast_block, source_info)
50+
this.ast_block(destination, block, ast_block, source_info)
6751
}
6852
ExprKind::Match { scrutinee, arms } => {
69-
this.match_expr(destination, scope, expr_span, block, scrutinee, arms)
53+
this.match_expr(destination, expr_span, block, scrutinee, arms)
7054
}
7155
ExprKind::If { cond, then, else_opt } => {
7256
let place = unpack!(
@@ -79,9 +63,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
7963
let term = TerminatorKind::if_(this.hir.tcx(), operand, then_block, else_block);
8064
this.cfg.terminate(block, source_info, term);
8165

82-
unpack!(then_block = this.into(destination, scope, then_block, then));
66+
unpack!(then_block = this.into(destination, then_block, then));
8367
else_block = if let Some(else_opt) = else_opt {
84-
unpack!(this.into(destination, None, else_block, else_opt))
68+
unpack!(this.into(destination, else_block, else_opt))
8569
} else {
8670
// Body of the `if` expression without an `else` clause must return `()`, thus
8771
// we implicitly generate a `else {}` if it is not specified.
@@ -117,7 +101,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
117101

118102
// This is an optimization. If the expression was a call then we already have an
119103
// unreachable block. Don't bother to terminate it and create a new one.
120-
schedule_drop(this);
121104
if is_call {
122105
block.unit()
123106
} else {
@@ -193,35 +176,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
193176
// Start the loop.
194177
this.cfg.goto(block, source_info, loop_block);
195178

196-
this.in_breakable_scope(
197-
Some(loop_block),
198-
destination,
199-
scope,
200-
expr_span,
201-
move |this| {
202-
// conduct the test, if necessary
203-
let body_block = this.cfg.start_new_block();
204-
this.cfg.terminate(
205-
loop_block,
206-
source_info,
207-
TerminatorKind::FalseUnwind { real_target: body_block, unwind: None },
208-
);
209-
this.diverge_from(loop_block);
210-
211-
// The “return” value of the loop body must always be an unit. We therefore
212-
// introduce a unit temporary as the destination for the loop body.
213-
let tmp = this.get_unit_temp();
214-
// Execute the body, branching back to the test.
215-
// We don't need to provide a drop scope because `tmp`
216-
// has type `()`.
217-
let body_block_end = unpack!(this.into(tmp, None, body_block, body));
218-
this.cfg.goto(body_block_end, source_info, loop_block);
219-
schedule_drop(this);
220-
221-
// Loops are only exited by `break` expressions.
222-
None
223-
},
224-
)
179+
this.in_breakable_scope(Some(loop_block), destination, expr_span, move |this| {
180+
// conduct the test, if necessary
181+
let body_block = this.cfg.start_new_block();
182+
this.cfg.terminate(
183+
loop_block,
184+
source_info,
185+
TerminatorKind::FalseUnwind { real_target: body_block, unwind: None },
186+
);
187+
this.diverge_from(loop_block);
188+
189+
// The “return” value of the loop body must always be an unit. We therefore
190+
// introduce a unit temporary as the destination for the loop body.
191+
let tmp = this.get_unit_temp();
192+
// Execute the body, branching back to the test.
193+
let body_block_end = unpack!(this.into(tmp, body_block, body));
194+
this.cfg.goto(body_block_end, source_info, loop_block);
195+
196+
// Loops are only exited by `break` expressions.
197+
None
198+
})
225199
}
226200
ExprKind::Call { ty: _, fun, args, from_hir_call, fn_span } => {
227201
let fun = unpack!(block = this.as_local_operand(block, fun));
@@ -256,10 +230,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
256230
},
257231
);
258232
this.diverge_from(block);
259-
schedule_drop(this);
260233
success.unit()
261234
}
262-
ExprKind::Use { source } => this.into(destination, scope, block, source),
235+
ExprKind::Use { source } => this.into(destination, block, source),
263236
ExprKind::Borrow { arg, borrow_kind } => {
264237
// We don't do this in `as_rvalue` because we use `as_place`
265238
// for borrow expressions, so we cannot create an `RValue` that
@@ -348,7 +321,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
348321
destination,
349322
Rvalue::Aggregate(adt, fields),
350323
);
351-
schedule_drop(this);
352324
block.unit()
353325
}
354326
ExprKind::InlineAsm { template, operands, options, line_spans } => {
@@ -445,7 +417,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
445417
let place = unpack!(block = this.as_place(block, expr));
446418
let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place));
447419
this.cfg.push_assign(block, source_info, destination, rvalue);
448-
schedule_drop(this);
449420
block.unit()
450421
}
451422
ExprKind::Index { .. } | ExprKind::Deref { .. } | ExprKind::Field { .. } => {
@@ -463,7 +434,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
463434
let place = unpack!(block = this.as_place(block, expr));
464435
let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place));
465436
this.cfg.push_assign(block, source_info, destination, rvalue);
466-
schedule_drop(this);
467437
block.unit()
468438
}
469439

@@ -478,7 +448,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
478448
TerminatorKind::Yield { value, resume, resume_arg: destination, drop: None },
479449
);
480450
this.generator_drop_cleanup(block);
481-
schedule_drop(this);
482451
resume.unit()
483452
}
484453

@@ -510,7 +479,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
510479

511480
let rvalue = unpack!(block = this.as_local_rvalue(block, expr));
512481
this.cfg.push_assign(block, source_info, destination, rvalue);
513-
schedule_drop(this);
514482
block.unit()
515483
}
516484
};

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)