-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Pin stabilization #56939
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pin stabilization #56939
Changes from all commits
20d694a
610bcaf
3005bf3
684fe9a
861df06
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,15 +36,13 @@ | |
//! are always freely movable, even if the data they point to isn't. | ||
//! | ||
//! [`Pin`]: struct.Pin.html | ||
//! [`Unpin`]: trait.Unpin.html | ||
//! [`Unpin`]: ../../std/marker/trait.Unpin.html | ||
//! [`swap`]: ../../std/mem/fn.swap.html | ||
//! [`Box`]: ../../std/boxed/struct.Box.html | ||
//! | ||
//! # Examples | ||
//! | ||
//! ```rust | ||
//! #![feature(pin)] | ||
//! | ||
//! use std::pin::Pin; | ||
//! use std::marker::PhantomPinned; | ||
//! use std::ptr::NonNull; | ||
|
@@ -72,13 +70,13 @@ | |
//! slice: NonNull::dangling(), | ||
//! _pin: PhantomPinned, | ||
//! }; | ||
//! let mut boxed = Box::pinned(res); | ||
//! let mut boxed = Box::pin(res); | ||
//! | ||
//! let slice = NonNull::from(&boxed.data); | ||
//! // we know this is safe because modifying a field doesn't move the whole struct | ||
//! unsafe { | ||
//! let mut_ref: Pin<&mut Self> = Pin::as_mut(&mut boxed); | ||
//! Pin::get_mut_unchecked(mut_ref).slice = slice; | ||
//! Pin::get_unchecked_mut(mut_ref).slice = slice; | ||
//! } | ||
//! boxed | ||
//! } | ||
|
@@ -97,15 +95,12 @@ | |
//! // std::mem::swap(&mut *still_unmoved, &mut *new_unmoved); | ||
//! ``` | ||
|
||
#![unstable(feature = "pin", issue = "49150")] | ||
#![stable(feature = "pin", since = "1.33.0")] | ||
|
||
use fmt; | ||
use marker::Sized; | ||
use marker::{Sized, Unpin}; | ||
use ops::{Deref, DerefMut, Receiver, CoerceUnsized, DispatchFromDyn}; | ||
|
||
#[doc(inline)] | ||
pub use marker::Unpin; | ||
|
||
/// A pinned pointer. | ||
/// | ||
/// This is a wrapper around a kind of pointer which makes that pointer "pin" its | ||
|
@@ -119,8 +114,9 @@ pub use marker::Unpin; | |
// | ||
// Note: the derives below are allowed because they all only use `&P`, so they | ||
// cannot move the value behind `pointer`. | ||
#[unstable(feature = "pin", issue = "49150")] | ||
#[stable(feature = "pin", since = "1.33.0")] | ||
#[fundamental] | ||
#[repr(transparent)] | ||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] | ||
pub struct Pin<P> { | ||
pointer: P, | ||
|
@@ -132,7 +128,7 @@ where | |
{ | ||
/// Construct a new `Pin` around a pointer to some data of a type that | ||
/// implements `Unpin`. | ||
#[unstable(feature = "pin", issue = "49150")] | ||
#[stable(feature = "pin", since = "1.33.0")] | ||
#[inline(always)] | ||
pub fn new(pointer: P) -> Pin<P> { | ||
// Safety: the value pointed to is `Unpin`, and so has no requirements | ||
|
@@ -154,14 +150,14 @@ impl<P: Deref> Pin<P> { | |
/// | ||
/// If `pointer` dereferences to an `Unpin` type, `Pin::new` should be used | ||
/// instead. | ||
#[unstable(feature = "pin", issue = "49150")] | ||
#[stable(feature = "pin", since = "1.33.0")] | ||
#[inline(always)] | ||
pub unsafe fn new_unchecked(pointer: P) -> Pin<P> { | ||
Pin { pointer } | ||
} | ||
|
||
/// Get a pinned shared reference from this pinned pointer. | ||
#[unstable(feature = "pin", issue = "49150")] | ||
#[stable(feature = "pin", since = "1.33.0")] | ||
#[inline(always)] | ||
pub fn as_ref(self: &Pin<P>) -> Pin<&P::Target> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I talked with @withoutboats in person about this a bit as I was slightly concerned about this, so I just wanted to make sure to write down some thoughts. The Along those lines, I think it definitely makes sense to be consistent with Concretely my worry is that we may not be able to add inherent Again though, just wanted to make sure I brought that up and ensure it was weighed! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The ergonomic improvement from I'm totally sympathetic to the concerns here and am interested in any ideas you might have for making this easier. One thing I will say is that I think it's much more common to call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok sure thing, I just wanted to double-confirm. I agree that the usage pattern of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One thing @alexcrichton and I talked about was making only as_ref and as_mut associated functions, so you'd get There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd probably want something not called There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (to be clear: I'm fine making this change if it's the one @rust-lang/libs wants, it's just much more ergonomic and easier to read the chained-method version) |
||
unsafe { Pin::new_unchecked(&*self.pointer) } | ||
|
@@ -170,14 +166,14 @@ impl<P: Deref> Pin<P> { | |
|
||
impl<P: DerefMut> Pin<P> { | ||
/// Get a pinned mutable reference from this pinned pointer. | ||
#[unstable(feature = "pin", issue = "49150")] | ||
#[stable(feature = "pin", since = "1.33.0")] | ||
#[inline(always)] | ||
pub fn as_mut(self: &mut Pin<P>) -> Pin<&mut P::Target> { | ||
unsafe { Pin::new_unchecked(&mut *self.pointer) } | ||
} | ||
|
||
/// Assign a new value to the memory behind the pinned reference. | ||
#[unstable(feature = "pin", issue = "49150")] | ||
#[stable(feature = "pin", since = "1.33.0")] | ||
#[inline(always)] | ||
pub fn set(mut self: Pin<P>, value: P::Target) | ||
where | ||
|
@@ -199,11 +195,11 @@ impl<'a, T: ?Sized> Pin<&'a T> { | |
/// 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: Pin<&'a T>, func: F) -> Pin<&'a U> where | ||
#[stable(feature = "pin", since = "1.33.0")] | ||
pub unsafe fn map_unchecked<U, F>(self: Pin<&'a T>, func: F) -> Pin<&'a U> where | ||
F: FnOnce(&T) -> &U, | ||
{ | ||
let pointer = &*this.pointer; | ||
let pointer = &*self.pointer; | ||
let new_pointer = func(pointer); | ||
Pin::new_unchecked(new_pointer) | ||
} | ||
|
@@ -215,19 +211,19 @@ impl<'a, T: ?Sized> Pin<&'a T> { | |
/// that lives for as long as the borrow of the `Pin`, not the lifetime of | ||
/// the `Pin` itself. This method allows turning the `Pin` into a reference | ||
/// with the same lifetime as the original `Pin`. | ||
#[unstable(feature = "pin", issue = "49150")] | ||
#[stable(feature = "pin", since = "1.33.0")] | ||
#[inline(always)] | ||
pub fn get_ref(this: Pin<&'a T>) -> &'a T { | ||
this.pointer | ||
pub fn get_ref(self: Pin<&'a T>) -> &'a T { | ||
self.pointer | ||
} | ||
} | ||
|
||
impl<'a, T: ?Sized> Pin<&'a mut T> { | ||
/// Convert this `Pin<&mut T>` into a `Pin<&T>` with the same lifetime. | ||
#[unstable(feature = "pin", issue = "49150")] | ||
#[stable(feature = "pin", since = "1.33.0")] | ||
#[inline(always)] | ||
pub fn into_ref(this: Pin<&'a mut T>) -> Pin<&'a T> { | ||
Pin { pointer: this.pointer } | ||
pub fn into_ref(self: Pin<&'a mut T>) -> Pin<&'a T> { | ||
Pin { pointer: self.pointer } | ||
} | ||
|
||
/// Get a mutable reference to the data inside of this `Pin`. | ||
|
@@ -239,12 +235,12 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { | |
/// that lives for as long as the borrow of the `Pin`, not the lifetime of | ||
/// the `Pin` itself. This method allows turning the `Pin` into a reference | ||
/// with the same lifetime as the original `Pin`. | ||
#[unstable(feature = "pin", issue = "49150")] | ||
#[stable(feature = "pin", since = "1.33.0")] | ||
#[inline(always)] | ||
pub fn get_mut(this: Pin<&'a mut T>) -> &'a mut T | ||
pub fn get_mut(self: Pin<&'a mut T>) -> &'a mut T | ||
where T: Unpin, | ||
{ | ||
this.pointer | ||
self.pointer | ||
} | ||
|
||
/// Get a mutable reference to the data inside of this `Pin`. | ||
|
@@ -257,10 +253,10 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { | |
/// | ||
/// If the underlying data is `Unpin`, `Pin::get_mut` should be used | ||
/// instead. | ||
#[unstable(feature = "pin", issue = "49150")] | ||
#[stable(feature = "pin", since = "1.33.0")] | ||
#[inline(always)] | ||
pub unsafe fn get_mut_unchecked(this: Pin<&'a mut T>) -> &'a mut T { | ||
this.pointer | ||
pub unsafe fn get_unchecked_mut(self: Pin<&'a mut T>) -> &'a mut T { | ||
self.pointer | ||
} | ||
|
||
/// Construct a new pin by mapping the interior value. | ||
|
@@ -274,25 +270,25 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { | |
/// 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_mut<U, F>(this: Pin<&'a mut T>, func: F) -> Pin<&'a mut U> where | ||
#[stable(feature = "pin", since = "1.33.0")] | ||
pub unsafe fn map_unchecked_mut<U, F>(self: Pin<&'a mut T>, func: F) -> Pin<&'a mut U> where | ||
F: FnOnce(&mut T) -> &mut U, | ||
{ | ||
let pointer = Pin::get_mut_unchecked(this); | ||
let pointer = Pin::get_unchecked_mut(self); | ||
let new_pointer = func(pointer); | ||
Pin::new_unchecked(new_pointer) | ||
} | ||
} | ||
|
||
#[unstable(feature = "pin", issue = "49150")] | ||
#[stable(feature = "pin", since = "1.33.0")] | ||
impl<P: Deref> Deref for Pin<P> { | ||
type Target = P::Target; | ||
fn deref(&self) -> &P::Target { | ||
Pin::get_ref(Pin::as_ref(self)) | ||
} | ||
} | ||
|
||
#[unstable(feature = "pin", issue = "49150")] | ||
#[stable(feature = "pin", since = "1.33.0")] | ||
impl<P: DerefMut> DerefMut for Pin<P> | ||
where | ||
P::Target: Unpin | ||
|
@@ -305,21 +301,21 @@ where | |
#[unstable(feature = "receiver_trait", issue = "0")] | ||
impl<P: Receiver> Receiver for Pin<P> {} | ||
|
||
#[unstable(feature = "pin", issue = "49150")] | ||
#[stable(feature = "pin", since = "1.33.0")] | ||
impl<P: fmt::Debug> fmt::Debug for Pin<P> { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
fmt::Debug::fmt(&self.pointer, f) | ||
} | ||
} | ||
|
||
#[unstable(feature = "pin", issue = "49150")] | ||
#[stable(feature = "pin", since = "1.33.0")] | ||
impl<P: fmt::Display> fmt::Display for Pin<P> { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
fmt::Display::fmt(&self.pointer, f) | ||
} | ||
} | ||
|
||
#[unstable(feature = "pin", issue = "49150")] | ||
#[stable(feature = "pin", since = "1.33.0")] | ||
impl<P: fmt::Pointer> fmt::Pointer for Pin<P> { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
fmt::Pointer::fmt(&self.pointer, f) | ||
|
@@ -331,17 +327,14 @@ impl<P: fmt::Pointer> fmt::Pointer for Pin<P> { | |
// `Deref<Target=Unpin>` is unsound. Any such impl would probably be unsound | ||
// for other reasons, though, so we just need to take care not to allow such | ||
// impls to land in std. | ||
#[unstable(feature = "pin", issue = "49150")] | ||
#[stable(feature = "pin", since = "1.33.0")] | ||
impl<P, U> CoerceUnsized<Pin<U>> for Pin<P> | ||
where | ||
P: CoerceUnsized<U>, | ||
{} | ||
|
||
#[unstable(feature = "pin", issue = "49150")] | ||
#[stable(feature = "pin", since = "1.33.0")] | ||
impl<'a, P, U> DispatchFromDyn<Pin<U>> for Pin<P> | ||
where | ||
P: DispatchFromDyn<U>, | ||
{} | ||
|
||
#[unstable(feature = "pin", issue = "49150")] | ||
impl<P> Unpin for Pin<P> {} |
Uh oh!
There was an error while loading. Please reload this page.