提交 8c2b371e 编写于 作者: B bors

Auto merge of #53227 - nivkner:pin_move, r=RalfJung

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
......@@ -64,12 +64,14 @@
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) }
}
}
......@@ -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;
......
//! 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)
}
}
......@@ -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};
......
......@@ -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
......
......@@ -191,6 +191,7 @@
pub mod char;
pub mod panic;
pub mod panicking;
pub mod pin;
pub mod iter;
pub mod option;
pub mod raw;
......
......@@ -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 {}
......
......@@ -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 @@ 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 ()) {}
}
......@@ -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
......
//! 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 ()) {}
}
......@@ -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};
......
......@@ -435,6 +435,8 @@
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")]
......
......@@ -230,7 +230,7 @@
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;
......
......@@ -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};
......
......@@ -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,
......
......@@ -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,
......
......@@ -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' },
],
};
......@@ -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' },
],
};
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册