Skip to content

Commit 7123552

Browse files
committed
Auto merge of rust-lang#125923 - matthewjasper:no-return-leak, r=<try>
Fix leaks from panics in destructors Resurrects rust-lang#78373. This avoids the problem with rust-lang#80949 by not unscheduling drops of function arguments until after the call (so they still get a drop terminator on the function unwind path). Closes rust-lang#47949 r? `@lcnr`
2 parents f9515fd + 016ce8f commit 7123552

21 files changed

+729
-492
lines changed

compiler/rustc_mir_build/src/build/block.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1111
pub(crate) fn ast_block(
1212
&mut self,
1313
destination: Place<'tcx>,
14+
scope: Option<Scope>,
1415
block: BasicBlock,
1516
ast_block: BlockId,
1617
source_info: SourceInfo,
@@ -19,18 +20,27 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1920
self.thir[ast_block];
2021
self.in_scope((region_scope, source_info), LintLevel::Inherited, move |this| {
2122
if targeted_by_break {
22-
this.in_breakable_scope(None, destination, span, |this| {
23-
Some(this.ast_block_stmts(destination, block, span, stmts, expr, region_scope))
23+
this.in_breakable_scope(None, destination, scope, span, |this| {
24+
Some(this.ast_block_stmts(
25+
destination,
26+
scope,
27+
block,
28+
span,
29+
stmts,
30+
expr,
31+
region_scope,
32+
))
2433
})
2534
} else {
26-
this.ast_block_stmts(destination, block, span, stmts, expr, region_scope)
35+
this.ast_block_stmts(destination, scope, block, span, stmts, expr, region_scope)
2736
}
2837
})
2938
}
3039

3140
fn ast_block_stmts(
3241
&mut self,
3342
destination: Place<'tcx>,
43+
scope: Option<Scope>,
3444
mut block: BasicBlock,
3545
span: Span,
3646
stmts: &[StmtId],
@@ -168,6 +178,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
168178
unpack!(
169179
failure_block = this.ast_block(
170180
dummy_place,
181+
None,
171182
failure_entry,
172183
*else_block,
173184
this.source_info(else_block_span),
@@ -321,7 +332,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
321332
this.block_context
322333
.push(BlockFrame::TailExpr { tail_result_is_ignored, span: expr.span });
323334

324-
unpack!(block = this.expr_into_dest(destination, block, expr_id));
335+
unpack!(block = this.expr_into_dest(destination, scope, block, expr_id));
325336
let popped = this.block_context.pop();
326337

327338
assert!(popped.is_some_and(|bf| bf.is_tail_expr()));

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

+12-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ use rustc_middle::ty::{self, Ty, UpvarArgs};
2020
use rustc_span::{Span, DUMMY_SP};
2121
use tracing::debug;
2222

23+
use std::slice;
24+
2325
impl<'a, 'tcx> Builder<'a, 'tcx> {
2426
/// Returns an rvalue suitable for use until the end of the current
2527
/// scope expression.
@@ -183,15 +185,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
183185
let box_ = Rvalue::ShallowInitBox(Operand::Move(storage), value_ty);
184186
this.cfg.push_assign(block, source_info, Place::from(result), box_);
185187

186-
// initialize the box contents:
188+
// Initialize the box contents. No scope is needed since the
189+
// `Box` is already scheduled to be dropped.
187190
unpack!(
188191
block = this.expr_into_dest(
189192
this.tcx.mk_place_deref(Place::from(result)),
193+
None,
190194
block,
191195
value,
192196
)
193197
);
194-
block.and(Rvalue::Use(Operand::Move(Place::from(result))))
198+
let result_operand = Operand::Move(Place::from(result));
199+
this.record_operands_moved(slice::from_ref(&result_operand));
200+
block.and(Rvalue::Use(result_operand))
195201
}
196202
ExprKind::Cast { source } => {
197203
let source_expr = &this.thir[source];
@@ -359,6 +365,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
359365
})
360366
.collect();
361367

368+
this.record_operands_moved(&fields.raw);
362369
block.and(Rvalue::Aggregate(Box::new(AggregateKind::Array(el_ty)), fields))
363370
}
364371
ExprKind::Tuple { ref fields } => {
@@ -380,6 +387,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
380387
})
381388
.collect();
382389

390+
this.record_operands_moved(&fields.raw);
383391
block.and(Rvalue::Aggregate(Box::new(AggregateKind::Tuple), fields))
384392
}
385393
ExprKind::Closure(box ClosureExpr {
@@ -482,6 +490,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
482490
Box::new(AggregateKind::CoroutineClosure(closure_id.to_def_id(), args))
483491
}
484492
};
493+
this.record_operands_moved(&operands.raw);
485494
block.and(Rvalue::Aggregate(result, operands))
486495
}
487496
ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => {
@@ -737,7 +746,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
737746
this.diverge_from(block);
738747
block = success;
739748
}
740-
this.record_operands_moved(&[Spanned { node: value_operand, span: DUMMY_SP }]);
749+
this.record_operands_moved(&[value_operand]);
741750
}
742751
block.and(Rvalue::Aggregate(Box::new(AggregateKind::Array(elem_ty)), IndexVec::new()))
743752
}

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

+1-5
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
112112
}
113113
}
114114

115-
unpack!(block = this.expr_into_dest(temp_place, block, expr_id));
116-
117-
if let Some(temp_lifetime) = temp_lifetime {
118-
this.schedule_drop(expr_span, temp_lifetime, temp, DropKind::Value);
119-
}
115+
unpack!(block = this.expr_into_dest(temp_place, temp_lifetime, block, expr_id));
120116

121117
block.and(temp)
122118
}

0 commit comments

Comments
 (0)