Skip to content

Commit 8585d8c

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 a299aa5 + 5c356c7 commit 8585d8c

22 files changed

+755
-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.
@@ -184,15 +186,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
184186
let box_ = Rvalue::ShallowInitBox(Operand::Move(storage), value_ty);
185187
this.cfg.push_assign(block, source_info, Place::from(result), box_);
186188

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

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

391+
this.record_operands_moved(&fields.raw);
384392
block.and(Rvalue::Aggregate(Box::new(AggregateKind::Tuple), fields))
385393
}
386394
ExprKind::Closure(box ClosureExpr {
@@ -483,6 +491,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
483491
Box::new(AggregateKind::CoroutineClosure(closure_id.to_def_id(), args))
484492
}
485493
};
494+
this.record_operands_moved(&operands.raw);
486495
block.and(Rvalue::Aggregate(result, operands))
487496
}
488497
ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => {
@@ -738,7 +747,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
738747
this.diverge_from(block);
739748
block = success;
740749
}
741-
this.record_operands_moved(&[Spanned { node: value_operand, span: DUMMY_SP }]);
750+
this.record_operands_moved(&[value_operand]);
742751
}
743752
block.and(Rvalue::Aggregate(Box::new(AggregateKind::Array(elem_ty)), IndexVec::new()))
744753
}

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)