diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 32292e61f94d2..c25f3eb8f1750 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -64,12 +64,14 @@ use core::future::{Future, FutureObj, LocalFutureObj, UnsafeFutureObj}; 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 @@ impl Generator for Box } } -/// A pinned, heap allocated reference. -#[unstable(feature = "pin", issue = "49150")] -#[fundamental] -#[repr(transparent)] -pub struct PinBox { - inner: Box, -} - -#[unstable(feature = "pin", issue = "49150")] -impl PinBox { - /// Allocate memory on the heap, move the data into it and pin it. - #[unstable(feature = "pin", issue = "49150")] - pub fn new(data: T) -> PinBox { - PinBox { inner: Box::new(data) } - } -} - -#[unstable(feature = "pin", issue = "49150")] -impl PinBox { - /// 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) -> *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) -> &'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) -> Box { - this.inner - } -} - -#[unstable(feature = "pin", issue = "49150")] -impl From> for PinBox { - fn from(boxed: Box) -> PinBox { - PinBox { inner: boxed } - } -} - -#[unstable(feature = "pin", issue = "49150")] -impl From> for Box { - fn from(pinned: PinBox) -> Box { - pinned.inner - } -} - -#[unstable(feature = "pin", issue = "49150")] -impl Deref for PinBox { - type Target = T; - - fn deref(&self) -> &T { - &*self.inner - } -} - -#[unstable(feature = "pin", issue = "49150")] -impl DerefMut for PinBox { - fn deref_mut(&mut self) -> &mut T { - &mut *self.inner - } -} - -#[unstable(feature = "pin", issue = "49150")] -impl fmt::Display for PinBox { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&*self.inner, f) - } -} - -#[unstable(feature = "pin", issue = "49150")] -impl fmt::Debug for PinBox { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&*self.inner, f) - } -} - -#[unstable(feature = "pin", issue = "49150")] -impl fmt::Pointer for PinBox { - 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, U: ?Sized> CoerceUnsized> for PinBox {} - -#[unstable(feature = "pin", issue = "49150")] -impl Unpin for PinBox {} - #[unstable(feature = "futures_api", issue = "50547")] impl Future for Box { type Output = F::Output; @@ -927,15 +769,6 @@ impl Future for Box { } } -#[unstable(feature = "futures_api", issue = "50547")] -impl Future for PinBox { - type Output = F::Output; - - fn poll(mut self: PinMut, cx: &mut Context) -> Poll { - self.as_pin_mut().poll(cx) - } -} - #[unstable(feature = "futures_api", issue = "50547")] unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Box where F: Future + 'a @@ -955,25 +788,6 @@ unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Box } } -#[unstable(feature = "futures_api", issue = "50547")] -unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for PinBox - where F: Future + 'a -{ - fn into_raw(self) -> *mut () { - PinBox::into_raw(self) as *mut () - } - - unsafe fn poll(ptr: *mut (), cx: &mut Context) -> Poll { - let ptr = ptr as *mut F; - let pin: PinMut = 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 Spawn for Box where Sp: Spawn + ?Sized @@ -990,13 +804,6 @@ impl Spawn for Box } } -#[unstable(feature = "futures_api", issue = "50547")] -impl<'a, F: Future + Send + 'a> From> for FutureObj<'a, ()> { - fn from(boxed: PinBox) -> Self { - FutureObj::new(boxed) - } -} - #[unstable(feature = "futures_api", issue = "50547")] impl<'a, F: Future + Send + 'a> From> for FutureObj<'a, ()> { fn from(boxed: Box) -> Self { @@ -1005,15 +812,15 @@ impl<'a, F: Future + Send + 'a> From> for FutureObj<'a, ()> } #[unstable(feature = "futures_api", issue = "50547")] -impl<'a, F: Future + 'a> From> for LocalFutureObj<'a, ()> { - fn from(boxed: PinBox) -> Self { +impl<'a, F: Future + 'a> From> for LocalFutureObj<'a, ()> { + fn from(boxed: Box) -> Self { LocalFutureObj::new(boxed) } } -#[unstable(feature = "futures_api", issue = "50547")] -impl<'a, F: Future + 'a> From> for LocalFutureObj<'a, ()> { - fn from(boxed: Box) -> Self { - LocalFutureObj::new(boxed) +#[unstable(feature = "pin", issue = "49150")] +impl From> for Box { + fn from(pinned: PinBox) -> Box { + unsafe { PinBox::unpin(pinned) } } } diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 18d8cd773eba9..676c977514f32 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -160,6 +160,7 @@ pub mod collections; 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 index 0000000000000..17bbc9882d976 --- /dev/null +++ b/src/liballoc/pin.rs @@ -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, +//! _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 { +//! 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 { + inner: Box, +} + +#[unstable(feature = "pin", issue = "49150")] +impl PinBox { + /// Allocate memory on the heap, move the data into it and pin it. + #[unstable(feature = "pin", issue = "49150")] + pub fn new(data: T) -> PinBox { + PinBox { inner: Box::new(data) } + } +} + +#[unstable(feature = "pin", issue = "49150")] +impl PinBox { + /// 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) -> *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) -> &'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) -> Box { + this.inner + } +} + +#[unstable(feature = "pin", issue = "49150")] +impl From> for PinBox { + fn from(boxed: Box) -> PinBox { + PinBox { inner: boxed } + } +} + +#[unstable(feature = "pin", issue = "49150")] +impl Deref for PinBox { + type Target = T; + + fn deref(&self) -> &T { + &*self.inner + } +} + +#[unstable(feature = "pin", issue = "49150")] +impl DerefMut for PinBox { + fn deref_mut(&mut self) -> &mut T { + &mut *self.inner + } +} + +#[unstable(feature = "pin", issue = "49150")] +impl fmt::Display for PinBox { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&*self.inner, f) + } +} + +#[unstable(feature = "pin", issue = "49150")] +impl fmt::Debug for PinBox { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&*self.inner, f) + } +} + +#[unstable(feature = "pin", issue = "49150")] +impl fmt::Pointer for PinBox { + 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, U: ?Sized> CoerceUnsized> for PinBox {} + +#[unstable(feature = "pin", issue = "49150")] +impl Unpin for PinBox {} + +#[unstable(feature = "futures_api", issue = "50547")] +impl Future for PinBox { + type Output = F::Output; + + fn poll(mut self: PinMut, cx: &mut Context) -> Poll { + self.as_pin_mut().poll(cx) + } +} + +#[unstable(feature = "futures_api", issue = "50547")] +unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for PinBox + where F: Future + 'a +{ + fn into_raw(self) -> *mut () { + PinBox::into_raw(self) as *mut () + } + + unsafe fn poll(ptr: *mut (), cx: &mut Context) -> Poll { + let ptr = ptr as *mut F; + let pin: PinMut = 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 + Send + 'a> From> for FutureObj<'a, ()> { + fn from(boxed: PinBox) -> Self { + FutureObj::new(boxed) + } +} + +#[unstable(feature = "futures_api", issue = "50547")] +impl<'a, F: Future + 'a> From> for LocalFutureObj<'a, ()> { + fn from(boxed: PinBox) -> Self { + LocalFutureObj::new(boxed) + } +} diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs index 10b4ca9b0b27a..520b6ebbbaaa5 100644 --- a/src/libcore/future/future.rs +++ b/src/libcore/future/future.rs @@ -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}; diff --git a/src/libcore/future/future_obj.rs b/src/libcore/future/future_obj.rs index 2df870a011dcb..68fe461aeae86 100644 --- a/src/libcore/future/future_obj.rs +++ b/src/libcore/future/future_obj.rs @@ -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 diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index be739270228d9..2aa3226af8960 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -191,6 +191,7 @@ pub mod cell; pub mod char; pub mod panic; pub mod panicking; +pub mod pin; pub mod iter; pub mod option; pub mod raw; diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index b1dc84bb84cb8..dd57d2dd00910 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -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 {} diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 67cceb9d53605..f2852d98282b7 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -18,13 +18,11 @@ 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 @@ impl DerefMut for ManuallyDrop { &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(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: ?Sized> CoerceUnsized> 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 + '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 { - PinMut::new_unchecked(&mut *(ptr as *mut F)).poll(cx) - } - - unsafe fn drop(_ptr: *mut ()) {} -} diff --git a/src/libcore/option.rs b/src/libcore/option.rs index f743fbfd0752b..3879abb0af973 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -147,7 +147,7 @@ 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 index 0000000000000..e9001f86b3526 --- /dev/null +++ b/src/libcore/pin.rs @@ -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(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: ?Sized> CoerceUnsized> 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 + '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 { + PinMut::new_unchecked(&mut *(ptr as *mut F)).poll(cx) + } + + unsafe fn drop(_ptr: *mut ()) {} +} diff --git a/src/libstd/future.rs b/src/libstd/future.rs index cadb5c0ba5d0e..d9657f691c79f 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -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}; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 87abf02b4458d..310475d31fded 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -435,6 +435,8 @@ pub use alloc_crate::borrow; 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")] diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index f15494c5fd7f5..6945a41a5e73b 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -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; diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs index b8c1c4f9e68e7..47547aedcbdec 100644 --- a/src/libstd/panic.rs +++ b/src/libstd/panic.rs @@ -16,7 +16,7 @@ use any::Any; use cell::UnsafeCell; use fmt; use future::Future; -use mem::PinMut; +use pin::PinMut; use ops::{Deref, DerefMut}; use panicking; use ptr::{Unique, NonNull}; diff --git a/src/test/run-pass/async-await.rs b/src/test/run-pass/async-await.rs index 99b8ad83bf6cc..46f228459079a 100644 --- a/src/test/run-pass/async-await.rs +++ b/src/test/run-pass/async-await.rs @@ -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, diff --git a/src/test/run-pass/futures-api.rs b/src/test/run-pass/futures-api.rs index 476cb48c0d2ee..69a04437691dd 100644 --- a/src/test/run-pass/futures-api.rs +++ b/src/test/run-pass/futures-api.rs @@ -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, diff --git a/src/test/rustdoc-js/pinbox-new.js b/src/test/rustdoc-js/pinbox-new.js index 061c7b30741d9..55842dc8e45e6 100644 --- a/src/test/rustdoc-js/pinbox-new.js +++ b/src/test/rustdoc-js/pinbox-new.js @@ -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' }, ], }; diff --git a/src/test/rustdoc-js/vec-new.js b/src/test/rustdoc-js/vec-new.js index 702953e2e9dd1..4a654ccb13503 100644 --- a/src/test/rustdoc-js/vec-new.js +++ b/src/test/rustdoc-js/vec-new.js @@ -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' }, ], };