Skip to content

Commit eba5432

Browse files
borsehuss
authored andcommitted
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.)
1 parent 78e57dc commit eba5432

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,37 +1,27 @@
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::{self, CanonicalUserTypeAnnotation};
1412
use rustc_span::symbol::sym;
1513
use rustc_target::spec::abi::Abi;
1614

17-
use std::slice;
18-
1915
impl<'a, 'tcx> Builder<'a, 'tcx> {
2016
/// Compile `expr`, storing the result into `destination`, which
2117
/// is assumed to be uninitialized.
22-
/// If a `drop_scope` is provided, `destination` is scheduled to be dropped
23-
/// in `scope` once it has been initialized.
2418
crate fn into_expr(
2519
&mut self,
2620
destination: Place<'tcx>,
27-
scope: Option<region::Scope>,
2821
mut block: BasicBlock,
2922
expr: Expr<'tcx>,
3023
) -> BlockAnd<()> {
31-
debug!(
32-
"into_expr(destination={:?}, scope={:?}, block={:?}, expr={:?})",
33-
destination, scope, block, expr
34-
);
24+
debug!("into_expr(destination={:?}, block={:?}, expr={:?})", destination, block, expr);
3525

3626
// since we frequently have to reference `self` from within a
3727
// closure, where `self` would be shadowed, it's easier to
@@ -46,14 +36,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
4636
_ => false,
4737
};
4838

49-
let schedule_drop = move |this: &mut Self| {
50-
if let Some(drop_scope) = scope {
51-
let local =
52-
destination.as_local().expect("cannot schedule drop of non-Local place");
53-
this.schedule_drop(expr_span, drop_scope, local, DropKind::Value);
54-
}
55-
};
56-
5739
if !expr_is_block_or_scope {
5840
this.block_context.push(BlockFrame::SubExpr);
5941
}
@@ -63,15 +45,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
6345
let region_scope = (region_scope, source_info);
6446
ensure_sufficient_stack(|| {
6547
this.in_scope(region_scope, lint_level, |this| {
66-
this.into(destination, scope, block, value)
48+
this.into(destination, block, value)
6749
})
6850
})
6951
}
7052
ExprKind::Block { body: ast_block } => {
71-
this.ast_block(destination, scope, block, ast_block, source_info)
53+
this.ast_block(destination, block, ast_block, source_info)
7254
}
7355
ExprKind::Match { scrutinee, arms } => {
74-
this.match_expr(destination, scope, expr_span, block, scrutinee, arms)
56+
this.match_expr(destination, expr_span, block, scrutinee, arms)
7557
}
7658
ExprKind::NeverToAny { source } => {
7759
let source = this.hir.mirror(source);
@@ -83,7 +65,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
8365

8466
// This is an optimization. If the expression was a call then we already have an
8567
// unreachable block. Don't bother to terminate it and create a new one.
86-
schedule_drop(this);
8768
if is_call {
8869
block.unit()
8970
} else {
@@ -159,35 +140,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
159140
// Start the loop.
160141
this.cfg.goto(block, source_info, loop_block);
161142

162-
this.in_breakable_scope(
163-
Some(loop_block),
164-
destination,
165-
scope,
166-
expr_span,
167-
move |this| {
168-
// conduct the test, if necessary
169-
let body_block = this.cfg.start_new_block();
170-
this.cfg.terminate(
171-
loop_block,
172-
source_info,
173-
TerminatorKind::FalseUnwind { real_target: body_block, unwind: None },
174-
);
175-
this.diverge_from(loop_block);
176-
177-
// The “return” value of the loop body must always be an unit. We therefore
178-
// introduce a unit temporary as the destination for the loop body.
179-
let tmp = this.get_unit_temp();
180-
// Execute the body, branching back to the test.
181-
// We don't need to provide a drop scope because `tmp`
182-
// has type `()`.
183-
let body_block_end = unpack!(this.into(tmp, None, body_block, body));
184-
this.cfg.goto(body_block_end, source_info, loop_block);
185-
schedule_drop(this);
186-
187-
// Loops are only exited by `break` expressions.
188-
None
189-
},
190-
)
143+
this.in_breakable_scope(Some(loop_block), destination, expr_span, move |this| {
144+
// conduct the test, if necessary
145+
let body_block = this.cfg.start_new_block();
146+
this.cfg.terminate(
147+
loop_block,
148+
source_info,
149+
TerminatorKind::FalseUnwind { real_target: body_block, unwind: None },
150+
);
151+
this.diverge_from(loop_block);
152+
153+
// The “return” value of the loop body must always be an unit. We therefore
154+
// introduce a unit temporary as the destination for the loop body.
155+
let tmp = this.get_unit_temp();
156+
// Execute the body, branching back to the test.
157+
let body_block_end = unpack!(this.into(tmp, body_block, body));
158+
this.cfg.goto(body_block_end, source_info, loop_block);
159+
160+
// Loops are only exited by `break` expressions.
161+
None
162+
})
191163
}
192164
ExprKind::Call { ty, fun, args, from_hir_call, fn_span } => {
193165
let intrinsic = match *ty.kind() {
@@ -220,13 +192,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
220192
.push(LocalDecl::with_source_info(ptr_ty, source_info).internal());
221193
let ptr_temp = Place::from(ptr_temp);
222194
// No need for a scope, ptr_temp doesn't need drop
223-
let block = unpack!(this.into(ptr_temp, None, block, ptr));
195+
let block = unpack!(this.into(ptr_temp, block, ptr));
224196
// Maybe we should provide a scope here so that
225197
// `move_val_init` wouldn't leak on panic even with an
226198
// arbitrary `val` expression, but `schedule_drop`,
227199
// borrowck and drop elaboration all prevent us from
228200
// dropping `ptr_temp.deref()`.
229-
this.into(this.hir.tcx().mk_place_deref(ptr_temp), None, block, val)
201+
this.into(this.hir.tcx().mk_place_deref(ptr_temp), block, val)
230202
} else {
231203
let args: Vec<_> = args
232204
.into_iter()
@@ -259,11 +231,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
259231
},
260232
);
261233
this.diverge_from(block);
262-
schedule_drop(this);
263234
success.unit()
264235
}
265236
}
266-
ExprKind::Use { source } => this.into(destination, scope, block, source),
237+
ExprKind::Use { source } => this.into(destination, block, source),
267238
ExprKind::Borrow { arg, borrow_kind } => {
268239
// We don't do this in `as_rvalue` because we use `as_place`
269240
// for borrow expressions, so we cannot create an `RValue` that
@@ -340,14 +311,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
340311
user_ty,
341312
active_field_index,
342313
);
343-
this.record_operands_moved(&fields);
344314
this.cfg.push_assign(
345315
block,
346316
source_info,
347317
destination,
348318
Rvalue::Aggregate(adt, fields),
349319
);
350-
schedule_drop(this);
351320
block.unit()
352321
}
353322
ExprKind::InlineAsm { template, operands, options, line_spans } => {
@@ -444,7 +413,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
444413
let place = unpack!(block = this.as_place(block, expr));
445414
let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place));
446415
this.cfg.push_assign(block, source_info, destination, rvalue);
447-
schedule_drop(this);
448416
block.unit()
449417
}
450418
ExprKind::Index { .. } | ExprKind::Deref { .. } | ExprKind::Field { .. } => {
@@ -462,22 +430,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
462430
let place = unpack!(block = this.as_place(block, expr));
463431
let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place));
464432
this.cfg.push_assign(block, source_info, destination, rvalue);
465-
schedule_drop(this);
466433
block.unit()
467434
}
468435

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

@@ -509,7 +474,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
509474

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

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)