Skip to content

Commit cc8d398

Browse files
committed
Auto merge of #29475 - apasel422:drop-in, r=alexcrichton
This is a rebase of #27204. r? @alexcrichton CC @gankro
2 parents 2aa9f7d + e351595 commit cc8d398

File tree

11 files changed

+42
-19
lines changed

11 files changed

+42
-19
lines changed

src/doc/nomicon/destructors.md

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,11 @@ this is totally fine.
2626
For instance, a custom implementation of `Box` might write `Drop` like this:
2727

2828
```rust
29-
#![feature(alloc, heap_api, core_intrinsics, unique)]
29+
#![feature(alloc, heap_api, drop_in_place, unique)]
3030

3131
extern crate alloc;
3232

33-
use std::ptr::Unique;
34-
use std::intrinsics::drop_in_place;
33+
use std::ptr::{drop_in_place, Unique};
3534
use std::mem;
3635

3736
use alloc::heap;
@@ -58,12 +57,11 @@ use-after-free the `ptr` because when drop exits, it becomes inaccessible.
5857
However this wouldn't work:
5958

6059
```rust
61-
#![feature(alloc, heap_api, core_intrinsics, unique)]
60+
#![feature(alloc, heap_api, drop_in_place, unique)]
6261

6362
extern crate alloc;
6463

65-
use std::ptr::Unique;
66-
use std::intrinsics::drop_in_place;
64+
use std::ptr::{drop_in_place, Unique};
6765
use std::mem;
6866

6967
use alloc::heap;
@@ -137,12 +135,11 @@ The classic safe solution to overriding recursive drop and allowing moving out
137135
of Self during `drop` is to use an Option:
138136

139137
```rust
140-
#![feature(alloc, heap_api, core_intrinsics, unique)]
138+
#![feature(alloc, heap_api, drop_in_place, unique)]
141139

142140
extern crate alloc;
143141

144-
use std::ptr::Unique;
145-
use std::intrinsics::drop_in_place;
142+
use std::ptr::{drop_in_place, Unique};
146143
use std::mem;
147144

148145
use alloc::heap;

src/liballoc/arc.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ use core::borrow;
7777
use core::fmt;
7878
use core::cmp::Ordering;
7979
use core::mem::{align_of_val, size_of_val};
80-
use core::intrinsics::{drop_in_place, abort};
80+
use core::intrinsics::abort;
8181
use core::mem;
8282
use core::ops::{Deref, CoerceUnsized};
8383
use core::ptr::{self, Shared};
@@ -304,7 +304,7 @@ impl<T: ?Sized> Arc<T> {
304304

305305
// Destroy the data at this time, even though we may not free the box
306306
// allocation itself (there may still be weak pointers lying around).
307-
drop_in_place(&mut (*ptr).data);
307+
ptr::drop_in_place(&mut (*ptr).data);
308308

309309
if self.inner().weak.fetch_sub(1, Release) == 1 {
310310
atomic::fence(Acquire);

src/liballoc/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@
103103
#![feature(unsize)]
104104
#![feature(core_slice_ext)]
105105
#![feature(core_str_ext)]
106+
#![feature(drop_in_place)]
107+
106108
#![cfg_attr(stage0, feature(alloc_system))]
107109
#![cfg_attr(not(stage0), feature(needs_allocator))]
108110

src/liballoc/rc.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ use core::cell::Cell;
160160
use core::cmp::Ordering;
161161
use core::fmt;
162162
use core::hash::{Hasher, Hash};
163-
use core::intrinsics::{assume, drop_in_place, abort};
163+
use core::intrinsics::{assume, abort};
164164
use core::marker::{self, Unsize};
165165
use core::mem::{self, align_of_val, size_of_val, forget};
166166
use core::ops::{CoerceUnsized, Deref};
@@ -460,7 +460,7 @@ impl<T: ?Sized> Drop for Rc<T> {
460460
self.dec_strong();
461461
if self.strong() == 0 {
462462
// destroy the contained object
463-
drop_in_place(&mut (*ptr).value);
463+
ptr::drop_in_place(&mut (*ptr).value);
464464

465465
// remove the implicit "strong weak" pointer now that we've
466466
// destroyed the contents.

src/libcollections/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
#![feature(dropck_parametricity)]
6666
#![feature(unsafe_no_drop_flag, filling_drop)]
6767
#![feature(decode_utf16)]
68+
#![feature(drop_in_place)]
6869
#![cfg_attr(test, feature(clone_from_slice, rand, test))]
6970

7071
#![feature(no_std)]

src/libcollections/vec.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ use alloc::heap::EMPTY;
6565
use core::cmp::Ordering;
6666
use core::fmt;
6767
use core::hash::{self, Hash};
68-
use core::intrinsics::{arith_offset, assume, drop_in_place, needs_drop};
68+
use core::intrinsics::{arith_offset, assume, needs_drop};
6969
use core::iter::FromIterator;
7070
use core::mem;
7171
use core::ops::{Index, IndexMut, Deref};
@@ -1394,7 +1394,7 @@ impl<T> Drop for Vec<T> {
13941394
// Without the branch, dropping Vec<u8> takes linear time.
13951395
if needs_drop::<T>() {
13961396
for x in self.iter_mut() {
1397-
drop_in_place(x);
1397+
ptr::drop_in_place(x);
13981398
}
13991399
}
14001400
}

src/libcore/intrinsics.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,26 @@ extern "rust-intrinsic" {
195195

196196
pub fn size_of_val<T: ?Sized>(_: &T) -> usize;
197197
pub fn min_align_of_val<T: ?Sized>(_: &T) -> usize;
198-
pub fn drop_in_place<T: ?Sized>(_: *mut T);
198+
199+
/// Executes the destructor (if any) of the pointed-to value.
200+
///
201+
/// This has two use cases:
202+
///
203+
/// * It is *required* to use `drop_in_place` to drop unsized types like
204+
/// trait objects, because they can't be read out onto the stack and
205+
/// dropped normally.
206+
///
207+
/// * It is friendlier to the optimizer to do this over `ptr::read` when
208+
/// dropping manually allocated memory (e.g. when writing Box/Rc/Vec),
209+
/// as the compiler doesn't need to prove that it's sound to elide the
210+
/// copy.
211+
///
212+
/// # Undefined Behavior
213+
///
214+
/// This has all the same safety problems as `ptr::read` with respect to
215+
/// invalid pointers, types, and double drops.
216+
#[unstable(feature = "drop_in_place", reason = "just exposed, needs FCP", issue = "27908")]
217+
pub fn drop_in_place<T: ?Sized>(to_drop: *mut T);
199218

200219
/// Gets a static string slice containing the name of a type.
201220
pub fn type_name<T: ?Sized>() -> &'static str;

src/libcore/ptr.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ pub use intrinsics::copy;
4040
#[stable(feature = "rust1", since = "1.0.0")]
4141
pub use intrinsics::write_bytes;
4242

43+
pub use intrinsics::drop_in_place;
44+
4345
/// Creates a null raw pointer.
4446
///
4547
/// # Examples

src/libstd/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,8 @@
251251
#![feature(vec_push_all)]
252252
#![feature(wrapping)]
253253
#![feature(zero_one)]
254+
#![feature(drop_in_place)]
255+
254256
#![cfg_attr(windows, feature(str_utf16))]
255257
#![cfg_attr(test, feature(float_from_str_radix, range_inclusive, float_extras))]
256258
#![cfg_attr(test, feature(test, rustc_private))]

src/libstd/thread/local.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ mod imp {
411411
if cfg!(target_os = "macos") {
412412
ptr::read((*ptr).inner.get());
413413
} else {
414-
intrinsics::drop_in_place((*ptr).inner.get());
414+
ptr::drop_in_place((*ptr).inner.get());
415415
}
416416
}
417417
}

src/test/run-pass/extern_fat_drop.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@
1010

1111
// aux-build:fat_drop.rs
1212

13-
#![feature(core_intrinsics)]
13+
#![feature(drop_in_place)]
1414

1515
extern crate fat_drop;
1616

1717
fn main() {
1818
unsafe {
1919
let s: &mut fat_drop::S = std::mem::uninitialized();
20-
std::intrinsics::drop_in_place(s);
20+
std::ptr::drop_in_place(s);
2121
assert!(fat_drop::DROPPED);
2222
}
2323
}

0 commit comments

Comments
 (0)