]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #53227 - nivkner:pin_move, r=RalfJung
authorbors <bors@rust-lang.org>
Mon, 27 Aug 2018 22:56:15 +0000 (22:56 +0000)
committerbors <bors@rust-lang.org>
Mon, 27 Aug 2018 22:56:15 +0000 (22:56 +0000)
move the Pin API into its own module for centralized documentation

This implements the change proposed by @withoutboats in #49150, as suggested by @RalfJung in the review of #53104,
along with the documentation that was originally in it, that was deemed more appropriate in module-level documentation.

r? @RalfJung

18 files changed:
src/liballoc/boxed.rs
src/liballoc/lib.rs
src/liballoc/pin.rs [new file with mode: 0644]
src/libcore/future/future.rs
src/libcore/future/future_obj.rs
src/libcore/lib.rs
src/libcore/marker.rs
src/libcore/mem.rs
src/libcore/option.rs
src/libcore/pin.rs [new file with mode: 0644]
src/libstd/future.rs
src/libstd/lib.rs
src/libstd/macros.rs
src/libstd/panic.rs
src/test/run-pass/async-await.rs
src/test/run-pass/futures-api.rs
src/test/rustdoc-js/pinbox-new.js
src/test/rustdoc-js/vec-new.js

index 32292e61f94d2f597568e600f8648dfba842bd16..c25f3eb8f17504776b8da2abb6f448e53309661d 100644 (file)
 use core::hash::{Hash, Hasher};
 use core::iter::FusedIterator;
 use core::marker::{Unpin, Unsize};
-use core::mem::{self, PinMut};
+use core::mem;
+use core::pin::PinMut;
 use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
 use core::ptr::{self, NonNull, Unique};
 use core::task::{Context, Poll, Spawn, SpawnErrorKind, SpawnObjError};
 
 use raw_vec::RawVec;
+use pin::PinBox;
 use str::from_boxed_utf8_unchecked;
 
 /// A pointer type for heap allocation.
@@ -758,166 +760,6 @@ unsafe fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return> {
     }
 }
 
-/// A pinned, heap allocated reference.
-#[unstable(feature = "pin", issue = "49150")]
-#[fundamental]
-#[repr(transparent)]
-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.
-    #[inline]
-    pub fn as_pin_mut<'a>(&'a mut self) -> PinMut<'a, T> {
-        unsafe { PinMut::new_unchecked(&mut *self.inner) }
-    }
-
-    /// Constructs a `PinBox` from a raw pointer.
-    ///
-    /// After calling this function, the raw pointer is owned by the
-    /// resulting `PinBox`. Specifically, the `PinBox` destructor will call
-    /// the destructor of `T` and free the allocated memory. Since the
-    /// way `PinBox` allocates and releases memory is unspecified, the
-    /// only valid pointer to pass to this function is the one taken
-    /// from another `PinBox` via the [`PinBox::into_raw`] function.
-    ///
-    /// This function is unsafe because improper use may lead to
-    /// memory problems. For example, a double-free may occur if the
-    /// function is called twice on the same raw pointer.
-    ///
-    /// [`PinBox::into_raw`]: struct.PinBox.html#method.into_raw
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(pin)]
-    /// use std::boxed::PinBox;
-    /// let x = PinBox::new(5);
-    /// let ptr = PinBox::into_raw(x);
-    /// let x = unsafe { PinBox::from_raw(ptr) };
-    /// ```
-    #[inline]
-    pub unsafe fn from_raw(raw: *mut T) -> Self {
-        PinBox { inner: Box::from_raw(raw) }
-    }
-
-    /// Consumes the `PinBox`, returning the wrapped raw pointer.
-    ///
-    /// After calling this function, the caller is responsible for the
-    /// memory previously managed by the `PinBox`. In particular, the
-    /// caller should properly destroy `T` and release the memory. The
-    /// proper way to do so is to convert the raw pointer back into a
-    /// `PinBox` with the [`PinBox::from_raw`] function.
-    ///
-    /// Note: this is an associated function, which means that you have
-    /// to call it as `PinBox::into_raw(b)` instead of `b.into_raw()`. This
-    /// is so that there is no conflict with a method on the inner type.
-    ///
-    /// [`PinBox::from_raw`]: struct.PinBox.html#method.from_raw
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(pin)]
-    /// use std::boxed::PinBox;
-    /// let x = PinBox::new(5);
-    /// let ptr = PinBox::into_raw(x);
-    /// ```
-    #[inline]
-    pub fn into_raw(b: PinBox<T>) -> *mut T {
-        Box::into_raw(b.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.
-    #[inline]
-    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.
-    #[inline]
-    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> {}
-
-#[unstable(feature = "pin", issue = "49150")]
-impl<T: ?Sized> Unpin for PinBox<T> {}
-
 #[unstable(feature = "futures_api", issue = "50547")]
 impl<F: ?Sized + Future + Unpin> Future for Box<F> {
     type Output = F::Output;
@@ -927,15 +769,6 @@ fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
     }
 }
 
-#[unstable(feature = "futures_api", issue = "50547")]
-impl<F: ?Sized + Future> Future for PinBox<F> {
-    type Output = F::Output;
-
-    fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
-        self.as_pin_mut().poll(cx)
-    }
-}
-
 #[unstable(feature = "futures_api", issue = "50547")]
 unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Box<F>
     where F: Future<Output = T> + 'a
@@ -955,25 +788,6 @@ unsafe fn drop(ptr: *mut ()) {
     }
 }
 
-#[unstable(feature = "futures_api", issue = "50547")]
-unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for PinBox<F>
-    where F: Future<Output = T> + 'a
-{
-    fn into_raw(self) -> *mut () {
-        PinBox::into_raw(self) as *mut ()
-    }
-
-    unsafe fn poll(ptr: *mut (), cx: &mut Context) -> Poll<T> {
-        let ptr = ptr as *mut F;
-        let pin: PinMut<F> = PinMut::new_unchecked(&mut *ptr);
-        pin.poll(cx)
-    }
-
-    unsafe fn drop(ptr: *mut ()) {
-        drop(PinBox::from_raw(ptr as *mut F))
-    }
-}
-
 #[unstable(feature = "futures_api", issue = "50547")]
 impl<Sp> Spawn for Box<Sp>
     where Sp: Spawn + ?Sized
@@ -990,13 +804,6 @@ fn status(&self) -> Result<(), SpawnErrorKind> {
     }
 }
 
-#[unstable(feature = "futures_api", issue = "50547")]
-impl<'a, F: Future<Output = ()> + Send + 'a> From<PinBox<F>> for FutureObj<'a, ()> {
-    fn from(boxed: PinBox<F>) -> Self {
-        FutureObj::new(boxed)
-    }
-}
-
 #[unstable(feature = "futures_api", issue = "50547")]
 impl<'a, F: Future<Output = ()> + Send + 'a> From<Box<F>> for FutureObj<'a, ()> {
     fn from(boxed: Box<F>) -> Self {
@@ -1005,15 +812,15 @@ fn from(boxed: Box<F>) -> Self {
 }
 
 #[unstable(feature = "futures_api", issue = "50547")]
-impl<'a, F: Future<Output = ()> + 'a> From<PinBox<F>> for LocalFutureObj<'a, ()> {
-    fn from(boxed: PinBox<F>) -> Self {
+impl<'a, F: Future<Output = ()> + 'a> From<Box<F>> for LocalFutureObj<'a, ()> {
+    fn from(boxed: Box<F>) -> Self {
         LocalFutureObj::new(boxed)
     }
 }
 
-#[unstable(feature = "futures_api", issue = "50547")]
-impl<'a, F: Future<Output = ()> + 'a> From<Box<F>> for LocalFutureObj<'a, ()> {
-    fn from(boxed: Box<F>) -> Self {
-        LocalFutureObj::new(boxed)
+#[unstable(feature = "pin", issue = "49150")]
+impl<T: Unpin + ?Sized> From<PinBox<T>> for Box<T> {
+    fn from(pinned: PinBox<T>) -> Box<T> {
+        unsafe { PinBox::unpin(pinned) }
     }
 }
index 18d8cd773eba9f96af3a6ee13875e995dd0c7521..676c977514f320299f06087a34521b7f5312f9d8 100644 (file)
@@ -160,6 +160,7 @@ mod boxed {
 pub mod sync;
 pub mod rc;
 pub mod raw_vec;
+pub mod pin;
 pub mod prelude;
 pub mod borrow;
 pub mod fmt;
diff --git a/src/liballoc/pin.rs b/src/liballoc/pin.rs
new file mode 100644 (file)
index 0000000..17bbc98
--- /dev/null
@@ -0,0 +1,302 @@
+//! Types which pin data to its location in memory
+//!
+//! It is sometimes useful to have objects that are guaranteed to not move,
+//! in the sense that their placement in memory does not change, and can thus be relied upon.
+//!
+//! A prime example of such a scenario would be building self-referencial structs,
+//! since moving an object with pointers to itself will invalidate them,
+//! which could cause undefined behavior.
+//!
+//! In order to prevent objects from moving, they must be *pinned*,
+//! by wrapping the data in pinning pointer types, such as [`PinMut`] and [`PinBox`],
+//! which are otherwise equivalent to `& mut` and [`Box`], respectively.
+//!
+//! First of all, these are pointer types because pinned data mustn't be passed around by value
+//! (that would change its location in memory).
+//! Secondly, since data can be moved out of `&mut` and [`Box`] with functions such as [`swap`],
+//! which causes their contents to swap places in memory,
+//! we need dedicated types that prohibit such operations.
+//!
+//! However, these restrictions are usually not necessary,
+//! so most types implement the [`Unpin`] auto-trait,
+//! which indicates that the type can be moved out safely.
+//! Doing so removes the limitations of pinning types,
+//! making them the same as their non-pinning counterparts.
+//!
+//! [`PinMut`]: struct.PinMut.html
+//! [`PinBox`]: struct.PinBox.html
+//! [`Unpin`]: trait.Unpin.html
+//! [`swap`]: ../../std/mem/fn.swap.html
+//! [`Box`]: ../boxed/struct.Box.html
+//!
+//! # Examples
+//!
+//! ```rust
+//! #![feature(pin)]
+//!
+//! use std::pin::PinBox;
+//! use std::marker::Pinned;
+//! use std::ptr::NonNull;
+//!
+//! // This is a self referencial struct since the slice field points to the data field.
+//! // We cannot inform the compiler about that with a normal reference,
+//! // since this pattern cannot be described with the usual borrowing rules.
+//! // Instead we use a raw pointer, though one which is known to not be null,
+//! // since we know it's pointing at the string.
+//! struct Unmovable {
+//!     data: String,
+//!     slice: NonNull<String>,
+//!     _pin: Pinned,
+//! }
+//!
+//! impl Unmovable {
+//!     // To ensure the data doesn't move when the function returns,
+//!     // we place it in the heap where it will stay for the lifetime of the object,
+//!     // and the only way to access it would be through a pointer to it.
+//!     fn new(data: String) -> PinBox<Self> {
+//!         let res = Unmovable {
+//!             data,
+//!             // we only create the pointer once the data is in place
+//!             // otherwise it will have already moved before we even started
+//!             slice: NonNull::dangling(),
+//!             _pin: Pinned,
+//!         };
+//!         let mut boxed = PinBox::new(res);
+//!
+//!         let slice = NonNull::from(&boxed.data);
+//!         // we know this is safe because modifying a field doesn't move the whole struct
+//!         unsafe { PinBox::get_mut(&mut boxed).slice = slice };
+//!         boxed
+//!     }
+//! }
+//!
+//! let unmoved = Unmovable::new("hello".to_string());
+//! // The pointer should point to the correct location,
+//! // so long as the struct hasn't moved.
+//! // Meanwhile, we are free to move the pointer around.
+//! # #[allow(unused_mut)]
+//! let mut still_unmoved = unmoved;
+//! assert_eq!(still_unmoved.slice, NonNull::from(&still_unmoved.data));
+//!
+//! // Since our type doesn't implement Unpin, this will fail to compile:
+//! // let new_unmoved = Unmovable::new("world".to_string());
+//! // std::mem::swap(&mut *still_unmoved, &mut *new_unmoved);
+//! ```
+
+#![unstable(feature = "pin", issue = "49150")]
+
+pub use core::pin::*;
+pub use core::marker::Unpin;
+
+use core::convert::From;
+use core::fmt;
+use core::future::{Future, FutureObj, LocalFutureObj, UnsafeFutureObj};
+use core::marker::Unsize;
+use core::ops::{CoerceUnsized, Deref, DerefMut};
+use core::task::{Context, Poll};
+
+use boxed::Box;
+
+/// A pinned, heap allocated reference.
+///
+/// This type is similar to [`Box`], except that it pins its value,
+/// which prevents it from moving out of the reference, unless it implements [`Unpin`].
+///
+/// See the [module documentation] for furthur explaination on pinning.
+///
+/// [`Box`]: ../boxed/struct.Box.html
+/// [`Unpin`]: ../../std/marker/trait.Unpin.html
+/// [module documentation]: index.html
+#[unstable(feature = "pin", issue = "49150")]
+#[fundamental]
+#[repr(transparent)]
+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.
+    #[inline]
+    pub fn as_pin_mut<'a>(&'a mut self) -> PinMut<'a, T> {
+        unsafe { PinMut::new_unchecked(&mut *self.inner) }
+    }
+
+    /// Constructs a `PinBox` from a raw pointer.
+    ///
+    /// After calling this function, the raw pointer is owned by the
+    /// resulting `PinBox`. Specifically, the `PinBox` destructor will call
+    /// the destructor of `T` and free the allocated memory. Since the
+    /// way `PinBox` allocates and releases memory is unspecified, the
+    /// only valid pointer to pass to this function is the one taken
+    /// from another `PinBox` via the [`PinBox::into_raw`] function.
+    ///
+    /// This function is unsafe because improper use may lead to
+    /// memory problems. For example, a double-free may occur if the
+    /// function is called twice on the same raw pointer.
+    ///
+    /// [`PinBox::into_raw`]: struct.PinBox.html#method.into_raw
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(pin)]
+    /// use std::pin::PinBox;
+    /// let x = PinBox::new(5);
+    /// let ptr = PinBox::into_raw(x);
+    /// let x = unsafe { PinBox::from_raw(ptr) };
+    /// ```
+    #[inline]
+    pub unsafe fn from_raw(raw: *mut T) -> Self {
+        PinBox { inner: Box::from_raw(raw) }
+    }
+
+    /// Consumes the `PinBox`, returning the wrapped raw pointer.
+    ///
+    /// After calling this function, the caller is responsible for the
+    /// memory previously managed by the `PinBox`. In particular, the
+    /// caller should properly destroy `T` and release the memory. The
+    /// proper way to do so is to convert the raw pointer back into a
+    /// `PinBox` with the [`PinBox::from_raw`] function.
+    ///
+    /// Note: this is an associated function, which means that you have
+    /// to call it as `PinBox::into_raw(b)` instead of `b.into_raw()`. This
+    /// is so that there is no conflict with a method on the inner type.
+    ///
+    /// [`PinBox::from_raw`]: struct.PinBox.html#method.from_raw
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(pin)]
+    /// use std::pin::PinBox;
+    /// let x = PinBox::new(5);
+    /// let ptr = PinBox::into_raw(x);
+    /// ```
+    #[inline]
+    pub fn into_raw(b: PinBox<T>) -> *mut T {
+        Box::into_raw(b.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.
+    #[inline]
+    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.
+    #[inline]
+    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: ?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> {}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T: ?Sized> Unpin for PinBox<T> {}
+
+#[unstable(feature = "futures_api", issue = "50547")]
+impl<F: ?Sized + Future> Future for PinBox<F> {
+    type Output = F::Output;
+
+    fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
+        self.as_pin_mut().poll(cx)
+    }
+}
+
+#[unstable(feature = "futures_api", issue = "50547")]
+unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for PinBox<F>
+    where F: Future<Output = T> + 'a
+{
+    fn into_raw(self) -> *mut () {
+        PinBox::into_raw(self) as *mut ()
+    }
+
+    unsafe fn poll(ptr: *mut (), cx: &mut Context) -> Poll<T> {
+        let ptr = ptr as *mut F;
+        let pin: PinMut<F> = PinMut::new_unchecked(&mut *ptr);
+        pin.poll(cx)
+    }
+
+    unsafe fn drop(ptr: *mut ()) {
+        drop(PinBox::from_raw(ptr as *mut F))
+    }
+}
+
+#[unstable(feature = "futures_api", issue = "50547")]
+impl<'a, F: Future<Output = ()> + Send + 'a> From<PinBox<F>> for FutureObj<'a, ()> {
+    fn from(boxed: PinBox<F>) -> Self {
+        FutureObj::new(boxed)
+    }
+}
+
+#[unstable(feature = "futures_api", issue = "50547")]
+impl<'a, F: Future<Output = ()> + 'a> From<PinBox<F>> for LocalFutureObj<'a, ()> {
+    fn from(boxed: PinBox<F>) -> Self {
+        LocalFutureObj::new(boxed)
+    }
+}
index 10b4ca9b0b27a5e55f089501c1bf45f8ebaf633e..520b6ebbbaaa59a072eda6529d6f22acd1e4249e 100644 (file)
@@ -12,7 +12,7 @@
             reason = "futures in libcore are unstable",
             issue = "50547")]
 
-use mem::PinMut;
+use pin::PinMut;
 use marker::Unpin;
 use task::{self, Poll};
 
index 2df870a011dcb1c0f4ee3fece0c419558570c939..68fe461aeae86ebcb1e570a9796737fd5b034e6a 100644 (file)
@@ -15,7 +15,7 @@
 use fmt;
 use future::Future;
 use marker::{PhantomData, Unpin};
-use mem::PinMut;
+use pin::PinMut;
 use task::{Context, Poll};
 
 /// A custom trait object for polling futures, roughly akin to
index be739270228d9badd95358f6c03b7adfbe8faac0..2aa3226af8960b553dcd05ed3a7568021ce5af7d 100644 (file)
 pub mod char;
 pub mod panic;
 pub mod panicking;
+pub mod pin;
 pub mod iter;
 pub mod option;
 pub mod raw;
index b1dc84bb84cb8f1c8fee985546aae535b09fbc0f..dd57d2dd00910c4eee3062bc09ac6c20d626dc42 100644 (file)
@@ -611,6 +611,7 @@ unsafe impl<'a, T: ?Sized> Freeze for &'a mut T {}
 /// Instead it can be used to prevent moves through the type system,
 /// by controlling the behavior of special pointer types like [`PinMut`],
 /// which "pin" the type in place by not allowing it to be moved out of them.
+/// See the [`pin module`] documentation for more information on pinning.
 ///
 /// Implementing this trait lifts the restrictions of pinning off a type,
 /// which then allows it to move out with functions such as [`replace`].
@@ -619,7 +620,8 @@ unsafe impl<'a, T: ?Sized> Freeze for &'a mut T {}
 ///
 /// ```rust
 /// #![feature(pin)]
-/// use std::mem::{PinMut, replace};
+/// use std::mem::replace;
+/// use std::pin::PinMut;
 ///
 /// let mut string = "this".to_string();
 /// let mut pinned_string = PinMut::new(&mut string);
@@ -630,8 +632,9 @@ unsafe impl<'a, T: ?Sized> Freeze for &'a mut T {}
 ///
 /// This trait is automatically implemented for almost every type.
 ///
-/// [`PinMut`]: ../mem/struct.PinMut.html
-/// [`replace`]: ../mem/fn.replace.html
+/// [`replace`]: ../../std/mem/fn.replace.html
+/// [`PinMut`]: ../pin/struct.PinMut.html
+/// [`pin module`]: ../../std/pin/index.html
 #[unstable(feature = "pin", issue = "49150")]
 pub auto trait Unpin {}
 
index 67cceb9d5360590d420374229a6bb943101b55e5..f2852d98282b7be7df5cecdc89b52bbaa4523398 100644 (file)
 use clone;
 use cmp;
 use fmt;
-use future::{Future, UnsafeFutureObj};
 use hash;
 use intrinsics;
-use marker::{Copy, PhantomData, Sized, Unpin, Unsize};
+use marker::{Copy, PhantomData, Sized};
 use ptr;
-use task::{Context, Poll};
-use ops::{Deref, DerefMut, CoerceUnsized};
+use ops::{Deref, DerefMut};
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use intrinsics::transmute;
@@ -992,146 +990,3 @@ fn deref_mut(&mut self) -> &mut Self::Target {
         &mut self.value
     }
 }
-
-/// A pinned reference.
-///
-/// A pinned reference is a lot like a mutable reference, except that it is not
-/// safe to move a value out of a pinned reference unless the type of that
-/// value implements the `Unpin` trait.
-#[unstable(feature = "pin", issue = "49150")]
-#[fundamental]
-pub struct PinMut<'a, T: ?Sized + 'a> {
-    inner: &'a mut T,
-}
-
-#[unstable(feature = "pin", issue = "49150")]
-impl<'a, T: ?Sized + Unpin> PinMut<'a, T> {
-    /// Construct a new `PinMut` around a reference to some data of a type that
-    /// implements `Unpin`.
-    #[unstable(feature = "pin", issue = "49150")]
-    pub fn new(reference: &'a mut T) -> PinMut<'a, T> {
-        PinMut { inner: reference }
-    }
-
-    /// Get a mutable reference to the data inside of this `PinMut`.
-    #[unstable(feature = "pin", issue = "49150")]
-    pub fn get_mut(this: PinMut<'a, T>) -> &'a mut T {
-        this.inner
-    }
-}
-
-
-#[unstable(feature = "pin", issue = "49150")]
-impl<'a, T: ?Sized> PinMut<'a, T> {
-    /// Construct a new `PinMut` around a reference to some data of a type that
-    /// may or may not implement `Unpin`.
-    ///
-    /// This constructor is unsafe because we do not know what will happen with
-    /// that data after the reference ends. If you cannot guarantee that the
-    /// data will never move again, calling this constructor is invalid.
-    #[unstable(feature = "pin", issue = "49150")]
-    pub unsafe fn new_unchecked(reference: &'a mut T) -> PinMut<'a, T> {
-        PinMut { inner: reference }
-    }
-
-    /// Reborrow a `PinMut` for a shorter lifetime.
-    ///
-    /// For example, `PinMut::get_mut(x.reborrow())` (unsafely) returns a
-    /// short-lived mutable reference reborrowing from `x`.
-    #[unstable(feature = "pin", issue = "49150")]
-    pub fn reborrow<'b>(&'b mut self) -> PinMut<'b, T> {
-        PinMut { inner: self.inner }
-    }
-
-    /// Get a mutable reference to the data inside of this `PinMut`.
-    ///
-    /// This function is unsafe. You must guarantee that you will never move
-    /// the data out of the mutable reference you receive when you call this
-    /// function.
-    #[unstable(feature = "pin", issue = "49150")]
-    pub unsafe fn get_mut_unchecked(this: PinMut<'a, T>) -> &'a mut T {
-        this.inner
-    }
-
-    /// Construct a new pin by mapping the interior value.
-    ///
-    /// For example, if you  wanted to get a `PinMut` of a field of something,
-    /// you could use this to get access to that field in one line of code.
-    ///
-    /// This function is unsafe. You must guarantee that the data you return
-    /// will not move so long as the argument value does not move (for example,
-    /// because it is one of the fields of that value), and also that you do
-    /// not move out of the argument you receive to the interior function.
-    #[unstable(feature = "pin", issue = "49150")]
-    pub unsafe fn map_unchecked<U, F>(this: PinMut<'a, T>, f: F) -> PinMut<'a, U> where
-        F: FnOnce(&mut T) -> &mut U
-    {
-        PinMut { inner: f(this.inner) }
-    }
-
-    /// Assign a new value to the memory behind the pinned reference.
-    #[unstable(feature = "pin", issue = "49150")]
-    pub fn set(this: PinMut<'a, T>, value: T)
-        where T: Sized,
-    {
-        *this.inner = value;
-    }
-}
-
-#[unstable(feature = "pin", issue = "49150")]
-impl<'a, T: ?Sized> Deref for PinMut<'a, T> {
-    type Target = T;
-
-    fn deref(&self) -> &T {
-        &*self.inner
-    }
-}
-
-#[unstable(feature = "pin", issue = "49150")]
-impl<'a, T: ?Sized + Unpin> DerefMut for PinMut<'a, T> {
-    fn deref_mut(&mut self) -> &mut T {
-        self.inner
-    }
-}
-
-#[unstable(feature = "pin", issue = "49150")]
-impl<'a, T: fmt::Debug + ?Sized> fmt::Debug for PinMut<'a, T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Debug::fmt(&**self, f)
-    }
-}
-
-#[unstable(feature = "pin", issue = "49150")]
-impl<'a, T: fmt::Display + ?Sized> fmt::Display for PinMut<'a, T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Display::fmt(&**self, f)
-    }
-}
-
-#[unstable(feature = "pin", issue = "49150")]
-impl<'a, T: ?Sized> fmt::Pointer for PinMut<'a, T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Pointer::fmt(&(&*self.inner as *const T), f)
-    }
-}
-
-#[unstable(feature = "pin", issue = "49150")]
-impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<PinMut<'a, U>> for PinMut<'a, T> {}
-
-#[unstable(feature = "pin", issue = "49150")]
-impl<'a, T: ?Sized> Unpin for PinMut<'a, T> {}
-
-#[unstable(feature = "futures_api", issue = "50547")]
-unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for PinMut<'a, F>
-    where F: Future<Output = T> + 'a
-{
-    fn into_raw(self) -> *mut () {
-        unsafe { PinMut::get_mut_unchecked(self) as *mut F as *mut () }
-    }
-
-    unsafe fn poll(ptr: *mut (), cx: &mut Context) -> Poll<T> {
-        PinMut::new_unchecked(&mut *(ptr as *mut F)).poll(cx)
-    }
-
-    unsafe fn drop(_ptr: *mut ()) {}
-}
index f743fbfd0752b6931151abf9c54146d64141e2d1..3879abb0af973d7084c911f93c660cc686288d08 100644 (file)
 
 use iter::{FromIterator, FusedIterator, TrustedLen};
 use {hint, mem, ops::{self, Deref}};
-use mem::PinMut;
+use pin::PinMut;
 
 // Note that this is not a lang item per se, but it has a hidden dependency on
 // `Iterator`, which is one. The compiler assumes that the `next` method of
diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs
new file mode 100644 (file)
index 0000000..e9001f8
--- /dev/null
@@ -0,0 +1,160 @@
+//! Types which pin data to its location in memory
+//!
+//! See the [standard library module] for more information.
+//!
+//! [standard library module]: ../../std/pin/index.html
+
+#![unstable(feature = "pin", issue = "49150")]
+
+use fmt;
+use future::{Future, UnsafeFutureObj};
+use marker::{Sized, Unpin, Unsize};
+use task::{Context, Poll};
+use ops::{Deref, DerefMut, CoerceUnsized};
+
+/// A pinned reference.
+///
+/// This type is similar to a mutable reference, except that it pins its value,
+/// which prevents it from moving out of the reference, unless it implements [`Unpin`].
+///
+/// See the [`pin` module] documentation for furthur explanation on pinning.
+///
+/// [`Unpin`]: ../../std/marker/trait.Unpin.html
+/// [`pin` module]: ../../std/pin/index.html
+#[unstable(feature = "pin", issue = "49150")]
+#[fundamental]
+pub struct PinMut<'a, T: ?Sized + 'a> {
+    inner: &'a mut T,
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<'a, T: ?Sized + Unpin> PinMut<'a, T> {
+    /// Construct a new `PinMut` around a reference to some data of a type that
+    /// implements `Unpin`.
+    #[unstable(feature = "pin", issue = "49150")]
+    pub fn new(reference: &'a mut T) -> PinMut<'a, T> {
+        PinMut { inner: reference }
+    }
+
+    /// Get a mutable reference to the data inside of this `PinMut`.
+    #[unstable(feature = "pin", issue = "49150")]
+    pub fn get_mut(this: PinMut<'a, T>) -> &'a mut T {
+        this.inner
+    }
+}
+
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<'a, T: ?Sized> PinMut<'a, T> {
+    /// Construct a new `PinMut` around a reference to some data of a type that
+    /// may or may not implement `Unpin`.
+    ///
+    /// This constructor is unsafe because we do not know what will happen with
+    /// that data after the lifetime of the reference ends. If you cannot guarantee that the
+    /// data will never move again, calling this constructor is invalid.
+    #[unstable(feature = "pin", issue = "49150")]
+    pub unsafe fn new_unchecked(reference: &'a mut T) -> PinMut<'a, T> {
+        PinMut { inner: reference }
+    }
+
+    /// Reborrow a `PinMut` for a shorter lifetime.
+    ///
+    /// For example, `PinMut::get_mut(x.reborrow())` (unsafely) returns a
+    /// short-lived mutable reference reborrowing from `x`.
+    #[unstable(feature = "pin", issue = "49150")]
+    pub fn reborrow<'b>(&'b mut self) -> PinMut<'b, T> {
+        PinMut { inner: self.inner }
+    }
+
+    /// Get a mutable reference to the data inside of this `PinMut`.
+    ///
+    /// This function is unsafe. You must guarantee that you will never move
+    /// the data out of the mutable reference you receive when you call this
+    /// function.
+    #[unstable(feature = "pin", issue = "49150")]
+    pub unsafe fn get_mut_unchecked(this: PinMut<'a, T>) -> &'a mut T {
+        this.inner
+    }
+
+    /// Construct a new pin by mapping the interior value.
+    ///
+    /// For example, if you  wanted to get a `PinMut` of a field of something,
+    /// you could use this to get access to that field in one line of code.
+    ///
+    /// This function is unsafe. You must guarantee that the data you return
+    /// will not move so long as the argument value does not move (for example,
+    /// because it is one of the fields of that value), and also that you do
+    /// not move out of the argument you receive to the interior function.
+    #[unstable(feature = "pin", issue = "49150")]
+    pub unsafe fn map_unchecked<U, F>(this: PinMut<'a, T>, f: F) -> PinMut<'a, U> where
+        F: FnOnce(&mut T) -> &mut U
+    {
+        PinMut { inner: f(this.inner) }
+    }
+
+    /// Assign a new value to the memory behind the pinned reference.
+    #[unstable(feature = "pin", issue = "49150")]
+    pub fn set(this: PinMut<'a, T>, value: T)
+        where T: Sized,
+    {
+        *this.inner = value;
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<'a, T: ?Sized> Deref for PinMut<'a, T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        &*self.inner
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<'a, T: ?Sized + Unpin> DerefMut for PinMut<'a, T> {
+    fn deref_mut(&mut self) -> &mut T {
+        self.inner
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<'a, T: fmt::Debug + ?Sized> fmt::Debug for PinMut<'a, T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Debug::fmt(&**self, f)
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<'a, T: fmt::Display + ?Sized> fmt::Display for PinMut<'a, T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(&**self, f)
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<'a, T: ?Sized> fmt::Pointer for PinMut<'a, T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Pointer::fmt(&(&*self.inner as *const T), f)
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<PinMut<'a, U>> for PinMut<'a, T> {}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<'a, T: ?Sized> Unpin for PinMut<'a, T> {}
+
+#[unstable(feature = "futures_api", issue = "50547")]
+unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for PinMut<'a, F>
+    where F: Future<Output = T> + 'a
+{
+    fn into_raw(self) -> *mut () {
+        unsafe { PinMut::get_mut_unchecked(self) as *mut F as *mut () }
+    }
+
+    unsafe fn poll(ptr: *mut (), cx: &mut Context) -> Poll<T> {
+        PinMut::new_unchecked(&mut *(ptr as *mut F)).poll(cx)
+    }
+
+    unsafe fn drop(_ptr: *mut ()) {}
+}
index cadb5c0ba5d0e019b5a1156512e5c97b1a466cf0..d9657f691c79fdc59a4b07445cd3c79876494423 100644 (file)
@@ -12,7 +12,7 @@
 
 use core::cell::Cell;
 use core::marker::Unpin;
-use core::mem::PinMut;
+use core::pin::PinMut;
 use core::option::Option;
 use core::ptr::NonNull;
 use core::task::{self, Poll};
index 87abf02b4458d7cdb8c4abadec7dfbbe280fa017..310475d31fdede876081aef27c22295a16135f70 100644 (file)
 pub use alloc_crate::fmt;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use alloc_crate::format;
+#[unstable(feature = "pin", issue = "49150")]
+pub use alloc_crate::pin;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use alloc_crate::slice;
 #[stable(feature = "rust1", since = "1.0.0")]
index f15494c5fd7f59beeab250014135eeb81f1ef5da..6945a41a5e73bef0e94cb7614a0a1af936ce621a 100644 (file)
@@ -230,7 +230,7 @@ macro_rules! await {
         loop {
             if let $crate::task::Poll::Ready(x) =
                 $crate::future::poll_in_task_cx(unsafe {
-                    $crate::mem::PinMut::new_unchecked(&mut pinned)
+                    $crate::pin::PinMut::new_unchecked(&mut pinned)
                 })
             {
                 break x;
index b8c1c4f9e68e7602ad5ab3b78679abf3f84e7988..47547aedcbdec8e0269d5a5d716ef7f1f475f911 100644 (file)
@@ -16,7 +16,7 @@
 use cell::UnsafeCell;
 use fmt;
 use future::Future;
-use mem::PinMut;
+use pin::PinMut;
 use ops::{Deref, DerefMut};
 use panicking;
 use ptr::{Unique, NonNull};
index 99b8ad83bf6ccfe44c76d2f25274cbf4da569b6a..46f228459079a25806ebd417e607754e52dac171 100644 (file)
@@ -12,8 +12,8 @@
 
 #![feature(arbitrary_self_types, async_await, await_macro, futures_api, pin)]
 
-use std::boxed::PinBox;
-use std::mem::PinMut;
+use std::pin::PinBox;
+use std::pin::PinMut;
 use std::future::Future;
 use std::sync::{
     Arc,
index 476cb48c0d2ee7af5169b9616a3b425bb83f5f12..69a04437691dd3f0a7e4c8654c0954b46fcf0529 100644 (file)
@@ -11,9 +11,9 @@
 #![feature(arbitrary_self_types, futures_api, pin)]
 #![allow(unused)]
 
-use std::boxed::PinBox;
+use std::pin::PinBox;
 use std::future::Future;
-use std::mem::PinMut;
+use std::pin::PinMut;
 use std::rc::Rc;
 use std::sync::{
     Arc,
index 061c7b30741d935d1f58e22b87de6575588daca6..55842dc8e45e66d36001e10298f724236b22be0a 100644 (file)
@@ -14,7 +14,7 @@ const QUERY = 'pinbox::new';
 
 const EXPECTED = {
     'others': [
-        { 'path': 'std::boxed::PinBox', 'name': 'new' },
-        { 'path': 'alloc::boxed::PinBox', 'name': 'new' },
+        { 'path': 'std::pin::PinBox', 'name': 'new' },
+        { 'path': 'alloc::pin::PinBox', 'name': 'new' },
     ],
 };
index 702953e2e9dd104781f66075b589b4b1dd290855..4a654ccb1350351e13fb47a3579fe7d5b3301a66 100644 (file)
@@ -14,6 +14,6 @@ const EXPECTED = {
     'others': [
         { 'path': 'std::vec::Vec', 'name': 'new' },
         { 'path': 'std::vec::Vec', 'name': 'ne' },
-        { 'path': 'std::boxed::PinBox', 'name': 'new' },
+        { 'path': 'std::pin::PinBox', 'name': 'new' },
     ],
 };