Auto merge of #29475 - apasel422:drop-in, r=alexcrichton
This is a rebase of #27204. r? @alexcrichton CC @Gankro
This commit is contained in:
commit
cc8d398e28
@ -26,12 +26,11 @@ this is totally fine.
|
||||
For instance, a custom implementation of `Box` might write `Drop` like this:
|
||||
|
||||
```rust
|
||||
#![feature(alloc, heap_api, core_intrinsics, unique)]
|
||||
#![feature(alloc, heap_api, drop_in_place, unique)]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use std::ptr::Unique;
|
||||
use std::intrinsics::drop_in_place;
|
||||
use std::ptr::{drop_in_place, Unique};
|
||||
use std::mem;
|
||||
|
||||
use alloc::heap;
|
||||
@ -58,12 +57,11 @@ use-after-free the `ptr` because when drop exits, it becomes inaccessible.
|
||||
However this wouldn't work:
|
||||
|
||||
```rust
|
||||
#![feature(alloc, heap_api, core_intrinsics, unique)]
|
||||
#![feature(alloc, heap_api, drop_in_place, unique)]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use std::ptr::Unique;
|
||||
use std::intrinsics::drop_in_place;
|
||||
use std::ptr::{drop_in_place, Unique};
|
||||
use std::mem;
|
||||
|
||||
use alloc::heap;
|
||||
@ -137,12 +135,11 @@ The classic safe solution to overriding recursive drop and allowing moving out
|
||||
of Self during `drop` is to use an Option:
|
||||
|
||||
```rust
|
||||
#![feature(alloc, heap_api, core_intrinsics, unique)]
|
||||
#![feature(alloc, heap_api, drop_in_place, unique)]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use std::ptr::Unique;
|
||||
use std::intrinsics::drop_in_place;
|
||||
use std::ptr::{drop_in_place, Unique};
|
||||
use std::mem;
|
||||
|
||||
use alloc::heap;
|
||||
|
@ -77,7 +77,7 @@ use core::borrow;
|
||||
use core::fmt;
|
||||
use core::cmp::Ordering;
|
||||
use core::mem::{align_of_val, size_of_val};
|
||||
use core::intrinsics::{drop_in_place, abort};
|
||||
use core::intrinsics::abort;
|
||||
use core::mem;
|
||||
use core::ops::{Deref, CoerceUnsized};
|
||||
use core::ptr::{self, Shared};
|
||||
@ -304,7 +304,7 @@ impl<T: ?Sized> Arc<T> {
|
||||
|
||||
// Destroy the data at this time, even though we may not free the box
|
||||
// allocation itself (there may still be weak pointers lying around).
|
||||
drop_in_place(&mut (*ptr).data);
|
||||
ptr::drop_in_place(&mut (*ptr).data);
|
||||
|
||||
if self.inner().weak.fetch_sub(1, Release) == 1 {
|
||||
atomic::fence(Acquire);
|
||||
|
@ -103,6 +103,8 @@
|
||||
#![feature(unsize)]
|
||||
#![feature(core_slice_ext)]
|
||||
#![feature(core_str_ext)]
|
||||
#![feature(drop_in_place)]
|
||||
|
||||
#![cfg_attr(stage0, feature(alloc_system))]
|
||||
#![cfg_attr(not(stage0), feature(needs_allocator))]
|
||||
|
||||
|
@ -160,7 +160,7 @@ use core::cell::Cell;
|
||||
use core::cmp::Ordering;
|
||||
use core::fmt;
|
||||
use core::hash::{Hasher, Hash};
|
||||
use core::intrinsics::{assume, drop_in_place, abort};
|
||||
use core::intrinsics::{assume, abort};
|
||||
use core::marker::{self, Unsize};
|
||||
use core::mem::{self, align_of_val, size_of_val, forget};
|
||||
use core::ops::{CoerceUnsized, Deref};
|
||||
@ -460,7 +460,7 @@ impl<T: ?Sized> Drop for Rc<T> {
|
||||
self.dec_strong();
|
||||
if self.strong() == 0 {
|
||||
// destroy the contained object
|
||||
drop_in_place(&mut (*ptr).value);
|
||||
ptr::drop_in_place(&mut (*ptr).value);
|
||||
|
||||
// remove the implicit "strong weak" pointer now that we've
|
||||
// destroyed the contents.
|
||||
|
@ -65,6 +65,7 @@
|
||||
#![feature(dropck_parametricity)]
|
||||
#![feature(unsafe_no_drop_flag, filling_drop)]
|
||||
#![feature(decode_utf16)]
|
||||
#![feature(drop_in_place)]
|
||||
#![cfg_attr(test, feature(clone_from_slice, rand, test))]
|
||||
|
||||
#![feature(no_std)]
|
||||
|
@ -65,7 +65,7 @@ use alloc::heap::EMPTY;
|
||||
use core::cmp::Ordering;
|
||||
use core::fmt;
|
||||
use core::hash::{self, Hash};
|
||||
use core::intrinsics::{arith_offset, assume, drop_in_place, needs_drop};
|
||||
use core::intrinsics::{arith_offset, assume, needs_drop};
|
||||
use core::iter::FromIterator;
|
||||
use core::mem;
|
||||
use core::ops::{Index, IndexMut, Deref};
|
||||
@ -1394,7 +1394,7 @@ impl<T> Drop for Vec<T> {
|
||||
// Without the branch, dropping Vec<u8> takes linear time.
|
||||
if needs_drop::<T>() {
|
||||
for x in self.iter_mut() {
|
||||
drop_in_place(x);
|
||||
ptr::drop_in_place(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -195,7 +195,26 @@ extern "rust-intrinsic" {
|
||||
|
||||
pub fn size_of_val<T: ?Sized>(_: &T) -> usize;
|
||||
pub fn min_align_of_val<T: ?Sized>(_: &T) -> usize;
|
||||
pub fn drop_in_place<T: ?Sized>(_: *mut T);
|
||||
|
||||
/// Executes the destructor (if any) of the pointed-to value.
|
||||
///
|
||||
/// This has two use cases:
|
||||
///
|
||||
/// * It is *required* to use `drop_in_place` to drop unsized types like
|
||||
/// trait objects, because they can't be read out onto the stack and
|
||||
/// dropped normally.
|
||||
///
|
||||
/// * It is friendlier to the optimizer to do this over `ptr::read` when
|
||||
/// dropping manually allocated memory (e.g. when writing Box/Rc/Vec),
|
||||
/// as the compiler doesn't need to prove that it's sound to elide the
|
||||
/// copy.
|
||||
///
|
||||
/// # Undefined Behavior
|
||||
///
|
||||
/// This has all the same safety problems as `ptr::read` with respect to
|
||||
/// invalid pointers, types, and double drops.
|
||||
#[unstable(feature = "drop_in_place", reason = "just exposed, needs FCP", issue = "27908")]
|
||||
pub fn drop_in_place<T: ?Sized>(to_drop: *mut T);
|
||||
|
||||
/// Gets a static string slice containing the name of a type.
|
||||
pub fn type_name<T: ?Sized>() -> &'static str;
|
||||
|
@ -40,6 +40,8 @@ pub use intrinsics::copy;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use intrinsics::write_bytes;
|
||||
|
||||
pub use intrinsics::drop_in_place;
|
||||
|
||||
/// Creates a null raw pointer.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -251,6 +251,8 @@
|
||||
#![feature(vec_push_all)]
|
||||
#![feature(wrapping)]
|
||||
#![feature(zero_one)]
|
||||
#![feature(drop_in_place)]
|
||||
|
||||
#![cfg_attr(windows, feature(str_utf16))]
|
||||
#![cfg_attr(test, feature(float_from_str_radix, range_inclusive, float_extras))]
|
||||
#![cfg_attr(test, feature(test, rustc_private))]
|
||||
|
@ -411,7 +411,7 @@ mod imp {
|
||||
if cfg!(target_os = "macos") {
|
||||
ptr::read((*ptr).inner.get());
|
||||
} else {
|
||||
intrinsics::drop_in_place((*ptr).inner.get());
|
||||
ptr::drop_in_place((*ptr).inner.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,14 +10,14 @@
|
||||
|
||||
// aux-build:fat_drop.rs
|
||||
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(drop_in_place)]
|
||||
|
||||
extern crate fat_drop;
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let s: &mut fat_drop::S = std::mem::uninitialized();
|
||||
std::intrinsics::drop_in_place(s);
|
||||
std::ptr::drop_in_place(s);
|
||||
assert!(fat_drop::DROPPED);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user