Skip to content

Commit 6b9d6c7

Browse files
committed
stop clearing box's drop flags early
1 parent bfe5e8c commit 6b9d6c7

File tree

4 files changed

+56
-13
lines changed

4 files changed

+56
-13
lines changed

compiler/rustc_mir_dataflow/src/elaborate_drops.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -460,13 +460,19 @@ where
460460

461461
if adt.is_box() {
462462
// we need to drop the inside of the box before running the destructor
463-
let succ = self.destructor_call_block(contents_drop);
463+
let destructor = self.destructor_call_block(contents_drop);
464464
let unwind = contents_drop
465465
.1
466466
.map(|unwind| self.destructor_call_block((unwind, Unwind::InCleanup)));
467467

468-
self.open_drop_for_box_contents(adt, args, succ, unwind)
468+
let boxed_drop = self.open_drop_for_box_contents(adt, args, destructor, unwind);
469+
470+
// the drop flag will be at the end of contents_drop
471+
self.drop_flag_test_block(boxed_drop, self.succ, unwind)
469472
} else if adt.has_dtor(self.tcx()) {
473+
// We don't need to test drop flags here because
474+
// this path is only taken with DropShimElaborator
475+
// where testing drop flags is a noop
470476
self.destructor_call_block(contents_drop)
471477
} else {
472478
contents_drop.0
@@ -659,13 +665,7 @@ where
659665
}),
660666
is_cleanup: unwind.is_cleanup(),
661667
};
662-
663-
let destructor_block = self.elaborator.patch().new_block(result);
664-
665-
let block_start = Location { block: destructor_block, statement_index: 0 };
666-
self.elaborator.clear_drop_flag(block_start, self.path, DropFlagMode::Shallow);
667-
668-
self.drop_flag_test_block(destructor_block, succ, unwind)
668+
self.elaborator.patch().new_block(result)
669669
}
670670

671671
/// Create a loop that drops an array:

compiler/rustc_mir_transform/src/elaborate_drops.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,8 @@ struct ElaborateDropsCtxt<'a, 'tcx> {
241241
}
242242

243243
impl fmt::Debug for ElaborateDropsCtxt<'_, '_> {
244-
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
245-
Ok(())
244+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
245+
f.debug_struct("ElaborateDropsCtxt").finish_non_exhaustive()
246246
}
247247
}
248248

compiler/rustc_mir_transform/src/shim.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -339,8 +339,8 @@ pub(super) struct DropShimElaborator<'a, 'tcx> {
339339
}
340340

341341
impl fmt::Debug for DropShimElaborator<'_, '_> {
342-
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
343-
Ok(())
342+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
343+
f.debug_struct("DropShimElaborator").finish_non_exhaustive()
344344
}
345345
}
346346

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//@ run-pass
2+
#![feature(allocator_api)]
3+
4+
// Regression test for #131082.
5+
// Testing that the allocator of a Box is dropped in conditional drops
6+
7+
use std::alloc::{AllocError, Allocator, Global, Layout};
8+
use std::cell::Cell;
9+
use std::ptr::NonNull;
10+
11+
struct DropCheckingAllocator<'a>(&'a Cell<bool>);
12+
13+
unsafe impl Allocator for DropCheckingAllocator<'_> {
14+
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
15+
Global.allocate(layout)
16+
}
17+
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
18+
Global.deallocate(ptr, layout);
19+
}
20+
}
21+
impl Drop for DropCheckingAllocator<'_> {
22+
fn drop(&mut self) {
23+
self.0.set(true);
24+
}
25+
}
26+
27+
struct HasDrop;
28+
impl Drop for HasDrop {
29+
fn drop(&mut self) {}
30+
}
31+
32+
fn main() {
33+
let dropped = Cell::new(false);
34+
{
35+
let b = Box::new_in(HasDrop, DropCheckingAllocator(&dropped));
36+
if true {
37+
drop(*b);
38+
} else {
39+
drop(b);
40+
}
41+
}
42+
assert!(dropped.get());
43+
}

0 commit comments

Comments
 (0)