about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-10-30 19:06:43 +0000
committerbors <bors@rust-lang.org>2015-10-30 19:06:43 +0000
commitcc8d398e28b6b1918ef85479c2d040dfd0fe582d (patch)
treeb509827a80ff356e37cf103d1af204eca809edfe /src
parent2aa9f7d3916dcff36a5b8b4978981c056ceb8398 (diff)
parente351595c61614c41be08f7508422d5f8a02d1a0e (diff)
downloadrust-cc8d398e28b6b1918ef85479c2d040dfd0fe582d.tar.gz
rust-cc8d398e28b6b1918ef85479c2d040dfd0fe582d.zip
Auto merge of #29475 - apasel422:drop-in, r=alexcrichton
This is a rebase of #27204.

r? @alexcrichton 
CC @Gankro 
Diffstat (limited to 'src')
-rw-r--r--src/doc/nomicon/destructors.md15
-rw-r--r--src/liballoc/arc.rs4
-rw-r--r--src/liballoc/lib.rs2
-rw-r--r--src/liballoc/rc.rs4
-rw-r--r--src/libcollections/lib.rs1
-rw-r--r--src/libcollections/vec.rs4
-rw-r--r--src/libcore/intrinsics.rs21
-rw-r--r--src/libcore/ptr.rs2
-rw-r--r--src/libstd/lib.rs2
-rw-r--r--src/libstd/thread/local.rs2
-rw-r--r--src/test/run-pass/extern_fat_drop.rs4
11 files changed, 42 insertions, 19 deletions
diff --git a/src/doc/nomicon/destructors.md b/src/doc/nomicon/destructors.md
index 604370b6365..c6fa5b079db 100644
--- a/src/doc/nomicon/destructors.md
+++ b/src/doc/nomicon/destructors.md
@@ -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;
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs
index 33ca80ba372..95dcdd22fd0 100644
--- a/src/liballoc/arc.rs
+++ b/src/liballoc/arc.rs
@@ -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);
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index c78ebdf4340..899e7de4ed5 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -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))]
 
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index d695c0edd1d..463f66b58e9 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -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.
diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs
index 3bb8a11c6a5..670c32776df 100644
--- a/src/libcollections/lib.rs
+++ b/src/libcollections/lib.rs
@@ -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)]
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index a0ca2e4d36a..a22e66583c4 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -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);
                     }
                 }
             }
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 45b1c8a3599..429f4fbed28 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -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;
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 52a888d797b..54cd3d0c867 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -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
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 93d1ce168b7..e78081f5bf4 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -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))]
diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs
index c204f79614a..119429cc584 100644
--- a/src/libstd/thread/local.rs
+++ b/src/libstd/thread/local.rs
@@ -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());
         }
     }
 }
diff --git a/src/test/run-pass/extern_fat_drop.rs b/src/test/run-pass/extern_fat_drop.rs
index f587dc7821d..deb7e6bd539 100644
--- a/src/test/run-pass/extern_fat_drop.rs
+++ b/src/test/run-pass/extern_fat_drop.rs
@@ -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);
     }
 }