about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-03-19 23:01:37 +0000
committerbors <bors@rust-lang.org>2018-03-19 23:01:37 +0000
commit6bfa7d02d6713acd15ead20c199b808e85031f9e (patch)
tree314b54e459b791bac4983db47dbdc87da55e19eb /src/liballoc
parenta04b88d1941644df01fa5e31dd43e0f57c13d938 (diff)
parent540021ff5d4771d3dfb8ce8ea5346a0ff2c1d060 (diff)
downloadrust-6bfa7d02d6713acd15ead20c199b808e85031f9e.tar.gz
rust-6bfa7d02d6713acd15ead20c199b808e85031f9e.zip
Auto merge of #49058 - withoutboats:pin, r=cramertj
Pin, Unpin, PinBox

Implementing rust-lang/rfcs#2349 (do not merge until RFC is merged)

@bors r? @cramertj
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/boxed.rs101
-rw-r--r--src/liballoc/lib.rs1
2 files changed, 100 insertions, 2 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index b776556d59f..abe2071973b 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -64,8 +64,8 @@ use core::cmp::Ordering;
 use core::fmt;
 use core::hash::{self, Hash, Hasher};
 use core::iter::FusedIterator;
-use core::marker::{self, Unsize};
-use core::mem;
+use core::marker::{self, Unpin, Unsize};
+use core::mem::{self, Pin};
 use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
 use core::ops::{BoxPlace, Boxed, InPlace, Place, Placer};
 use core::ptr::{self, NonNull, Unique};
@@ -896,3 +896,100 @@ impl<T> Generator for Box<T>
         (**self).resume()
     }
 }
+
+/// A pinned, heap allocated reference.
+#[unstable(feature = "pin", issue = "49150")]
+#[fundamental]
+pub struct PinBox<T: ?Sized> {
+    inner: Box<T>,
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T> PinBox<T> {
+    /// Allocate memory on the heap, move the data into it and pin it.
+    #[unstable(feature = "pin", issue = "49150")]
+    pub fn new(data: T) -> PinBox<T> {
+        PinBox { inner: Box::new(data) }
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T: ?Sized> PinBox<T> {
+    /// Get a pinned reference to the data in this PinBox.
+    pub fn as_pin<'a>(&'a mut self) -> Pin<'a, T> {
+        unsafe { Pin::new_unchecked(&mut *self.inner) }
+    }
+
+    /// Get a mutable reference to the data inside this PinBox.
+    ///
+    /// This function is unsafe. Users must guarantee that the data is never
+    /// moved out of this reference.
+    pub unsafe fn get_mut<'a>(this: &'a mut PinBox<T>) -> &'a mut T {
+        &mut *this.inner
+    }
+
+    /// Convert this PinBox into an unpinned Box.
+    ///
+    /// This function is unsafe. Users must guarantee that the data is never
+    /// moved out of the box.
+    pub unsafe fn unpin(this: PinBox<T>) -> Box<T> {
+        this.inner
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T: ?Sized> From<Box<T>> for PinBox<T> {
+    fn from(boxed: Box<T>) -> PinBox<T> {
+        PinBox { inner: boxed }
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T: Unpin + ?Sized> From<PinBox<T>> for Box<T> {
+    fn from(pinned: PinBox<T>) -> Box<T> {
+        pinned.inner
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T: ?Sized> Deref for PinBox<T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        &*self.inner
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T: Unpin + ?Sized> DerefMut for PinBox<T> {
+    fn deref_mut(&mut self) -> &mut T {
+        &mut *self.inner
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T: fmt::Display + ?Sized> fmt::Display for PinBox<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(&*self.inner, f)
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T: fmt::Debug + ?Sized> fmt::Debug for PinBox<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Debug::fmt(&*self.inner, f)
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T: ?Sized> fmt::Pointer for PinBox<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        // It's not possible to extract the inner Uniq directly from the Box,
+        // instead we cast it to a *const which aliases the Unique
+        let ptr: *const T = &*self.inner;
+        fmt::Pointer::fmt(&ptr, f)
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<PinBox<U>> for PinBox<T> {}
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 2727bcaa28a..04de5c95bee 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -105,6 +105,7 @@
 #![feature(offset_to)]
 #![feature(optin_builtin_traits)]
 #![feature(pattern)]
+#![feature(pin)]
 #![feature(placement_in_syntax)]
 #![feature(placement_new_protocol)]
 #![feature(ptr_internals)]