Skip to content

Commit 5605b5d

Browse files
committed
Auto merge of #81257 - pnkfelix:issue-80949-short-term-resolution-via-revert-of-pr-78373, r=matthewjasper
Revert 78373 ("dont leak return value after panic in drop") Short term resolution for issue #80949. Reopen #47949 after this lands. (We plan to fine-tune PR #78373 to not run into this problem.)
2 parents f9435f4 + dce5e9e commit 5605b5d

30 files changed

+10904
-11043
lines changed

compiler/rustc_mir_build/src/build/block.rs

+3-7
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

+4-16
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ use rustc_middle::mir::*;
1212
use rustc_middle::ty::{self, Ty, UpvarSubsts};
1313
use rustc_span::Span;
1414

15-
use std::slice;
16-
1715
impl<'a, 'tcx> Builder<'a, 'tcx> {
1816
/// Returns an rvalue suitable for use until the end of the current
1917
/// scope expression.
@@ -115,19 +113,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
115113
let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
116114
this.cfg.push_assign(block, source_info, Place::from(result), box_);
117115

118-
// Initialize the box contents. No scope is needed since the
119-
// `Box` is already scheduled to be dropped.
116+
// initialize the box contents:
120117
unpack!(
121-
block = this.into(
122-
this.hir.tcx().mk_place_deref(Place::from(result)),
123-
None,
124-
block,
125-
value,
126-
)
118+
block =
119+
this.into(this.hir.tcx().mk_place_deref(Place::from(result)), block, value)
127120
);
128-
let result_operand = Operand::Move(Place::from(result));
129-
this.record_operands_moved(slice::from_ref(&result_operand));
130-
block.and(Rvalue::Use(result_operand))
121+
block.and(Rvalue::Use(Operand::Move(Place::from(result))))
131122
}
132123
ExprKind::Cast { source } => {
133124
let source = unpack!(block = this.as_operand(block, scope, source));
@@ -171,7 +162,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
171162
.map(|f| unpack!(block = this.as_operand(block, scope, f)))
172163
.collect();
173164

174-
this.record_operands_moved(&fields);
175165
block.and(Rvalue::Aggregate(box AggregateKind::Array(el_ty), fields))
176166
}
177167
ExprKind::Tuple { fields } => {
@@ -182,7 +172,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
182172
.map(|f| unpack!(block = this.as_operand(block, scope, f)))
183173
.collect();
184174

185-
this.record_operands_moved(&fields);
186175
block.and(Rvalue::Aggregate(box AggregateKind::Tuple, fields))
187176
}
188177
ExprKind::Closure { closure_id, substs, upvars, movability } => {
@@ -234,7 +223,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
234223
}
235224
UpvarSubsts::Closure(substs) => box AggregateKind::Closure(closure_id, substs),
236225
};
237-
this.record_operands_moved(&operands);
238226
block.and(Rvalue::Aggregate(result, operands))
239227
}
240228
ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => {

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

+5-1
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

+27-63
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,25 @@
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

15-
use std::slice;
16-
1713
impl<'a, 'tcx> Builder<'a, 'tcx> {
1814
/// Compile `expr`, storing the result into `destination`, which
1915
/// 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.
2216
crate fn into_expr(
2317
&mut self,
2418
destination: Place<'tcx>,
25-
scope: Option<region::Scope>,
2619
mut block: BasicBlock,
2720
expr: Expr<'tcx>,
2821
) -> BlockAnd<()> {
29-
debug!(
30-
"into_expr(destination={:?}, scope={:?}, block={:?}, expr={:?})",
31-
destination, scope, block, expr
32-
);
22+
debug!("into_expr(destination={:?}, block={:?}, expr={:?})", destination, block, expr);
3323

3424
// since we frequently have to reference `self` from within a
3525
// closure, where `self` would be shadowed, it's easier to
@@ -41,14 +31,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
4131
let expr_is_block_or_scope =
4232
matches!(expr.kind, ExprKind::Block { .. } | ExprKind::Scope { .. });
4333

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-
5234
if !expr_is_block_or_scope {
5335
this.block_context.push(BlockFrame::SubExpr);
5436
}
@@ -58,15 +40,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
5840
let region_scope = (region_scope, source_info);
5941
ensure_sufficient_stack(|| {
6042
this.in_scope(region_scope, lint_level, |this| {
61-
this.into(destination, scope, block, value)
43+
this.into(destination, block, value)
6244
})
6345
})
6446
}
6547
ExprKind::Block { body: ast_block } => {
66-
this.ast_block(destination, scope, block, ast_block, source_info)
48+
this.ast_block(destination, block, ast_block, source_info)
6749
}
6850
ExprKind::Match { scrutinee, arms } => {
69-
this.match_expr(destination, scope, expr_span, block, scrutinee, arms)
51+
this.match_expr(destination, expr_span, block, scrutinee, arms)
7052
}
7153
ExprKind::If { cond, then, else_opt } => {
7254
let place = unpack!(
@@ -79,9 +61,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
7961
let term = TerminatorKind::if_(this.hir.tcx(), operand, then_block, else_block);
8062
this.cfg.terminate(block, source_info, term);
8163

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

118100
// This is an optimization. If the expression was a call then we already have an
119101
// unreachable block. Don't bother to terminate it and create a new one.
120-
schedule_drop(this);
121102
if is_call {
122103
block.unit()
123104
} else {
@@ -193,35 +174,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
193174
// Start the loop.
194175
this.cfg.goto(block, source_info, loop_block);
195176

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-
)
177+
this.in_breakable_scope(Some(loop_block), destination, expr_span, move |this| {
178+
// conduct the test, if necessary
179+
let body_block = this.cfg.start_new_block();
180+
this.cfg.terminate(
181+
loop_block,
182+
source_info,
183+
TerminatorKind::FalseUnwind { real_target: body_block, unwind: None },
184+
);
185+
this.diverge_from(loop_block);
186+
187+
// The “return” value of the loop body must always be an unit. We therefore
188+
// introduce a unit temporary as the destination for the loop body.
189+
let tmp = this.get_unit_temp();
190+
// Execute the body, branching back to the test.
191+
let body_block_end = unpack!(this.into(tmp, body_block, body));
192+
this.cfg.goto(body_block_end, source_info, loop_block);
193+
194+
// Loops are only exited by `break` expressions.
195+
None
196+
})
225197
}
226198
ExprKind::Call { ty: _, fun, args, from_hir_call, fn_span } => {
227199
let fun = unpack!(block = this.as_local_operand(block, fun));
@@ -256,10 +228,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
256228
},
257229
);
258230
this.diverge_from(block);
259-
schedule_drop(this);
260231
success.unit()
261232
}
262-
ExprKind::Use { source } => this.into(destination, scope, block, source),
233+
ExprKind::Use { source } => this.into(destination, block, source),
263234
ExprKind::Borrow { arg, borrow_kind } => {
264235
// We don't do this in `as_rvalue` because we use `as_place`
265236
// for borrow expressions, so we cannot create an `RValue` that
@@ -341,14 +312,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
341312
user_ty,
342313
active_field_index,
343314
);
344-
this.record_operands_moved(&fields);
345315
this.cfg.push_assign(
346316
block,
347317
source_info,
348318
destination,
349319
Rvalue::Aggregate(adt, fields),
350320
);
351-
schedule_drop(this);
352321
block.unit()
353322
}
354323
ExprKind::InlineAsm { template, operands, options, line_spans } => {
@@ -445,7 +414,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
445414
let place = unpack!(block = this.as_place(block, expr));
446415
let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place));
447416
this.cfg.push_assign(block, source_info, destination, rvalue);
448-
schedule_drop(this);
449417
block.unit()
450418
}
451419
ExprKind::Index { .. } | ExprKind::Deref { .. } | ExprKind::Field { .. } => {
@@ -463,22 +431,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
463431
let place = unpack!(block = this.as_place(block, expr));
464432
let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place));
465433
this.cfg.push_assign(block, source_info, destination, rvalue);
466-
schedule_drop(this);
467434
block.unit()
468435
}
469436

470437
ExprKind::Yield { value } => {
471438
let scope = this.local_scope();
472439
let value = unpack!(block = this.as_operand(block, Some(scope), value));
473440
let resume = this.cfg.start_new_block();
474-
this.record_operands_moved(slice::from_ref(&value));
475441
this.cfg.terminate(
476442
block,
477443
source_info,
478444
TerminatorKind::Yield { value, resume, resume_arg: destination, drop: None },
479445
);
480446
this.generator_drop_cleanup(block);
481-
schedule_drop(this);
482447
resume.unit()
483448
}
484449

@@ -510,7 +475,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
510475

511476
let rvalue = unpack!(block = this.as_local_rvalue(block, expr));
512477
this.cfg.push_assign(block, source_info, destination, rvalue);
513-
schedule_drop(this);
514478
block.unit()
515479
}
516480
};

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

-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
33
use crate::thir::*;
44
use rustc_middle::middle::region;
55
use rustc_middle::mir::*;
6-
use std::slice;
76

87
impl<'a, 'tcx> Builder<'a, 'tcx> {
98
/// Builds a block of MIR statements to evaluate the THIR `expr`.
@@ -47,7 +46,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
4746
if this.hir.needs_drop(lhs.ty) {
4847
let rhs = unpack!(block = this.as_local_operand(block, rhs));
4948
let lhs = unpack!(block = this.as_place(block, lhs));
50-
this.record_operands_moved(slice::from_ref(&rhs));
5149
unpack!(block = this.build_drop_and_replace(block, lhs_span, lhs, rhs));
5250
} else {
5351
let rhs = unpack!(block = this.as_local_rvalue(block, rhs));

0 commit comments

Comments
 (0)