Skip to content

Commit

Permalink
Auto merge of #50497 - RalfJung:pinmut, r=withoutboats
Browse files Browse the repository at this point in the history
Rename Pin to PinMut, and some more breaking changes

As discussed at [1] §3 and [2] and [3], a formal look at pinning requires considering a distinguished "shared pinned" mode/typestate.  Given that, it seems desirable to at least eventually actually expose that typestate as a reference type.  This renames Pin to PinMut, freeing the name Pin in case we want to use it for a shared pinned reference later on.

[1] https://www.ralfj.de/blog/2018/04/10/safe-intrusive-collections-with-pinning.html
[2] rust-lang/rfcs#2349 (comment)
[3] #49150 (comment)

Cc @withoutboats
  • Loading branch information
bors committed May 8, 2018
2 parents b183bd0 + 939c25a commit c166b03
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 31 deletions.
6 changes: 3 additions & 3 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ use core::fmt;
use core::hash::{Hash, Hasher};
use core::iter::FusedIterator;
use core::marker::{Unpin, Unsize};
use core::mem::{self, Pin};
use core::mem::{self, PinMut};
use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
use core::ptr::{self, NonNull, Unique};
use core::convert::From;
Expand Down Expand Up @@ -771,8 +771,8 @@ impl<T> PinBox<T> {
#[unstable(feature = "pin", issue = "49150")]
impl<T: ?Sized> PinBox<T> {
/// Get a pinned reference to the data in this PinBox.
pub fn as_pin<'a>(&'a mut self) -> Pin<'a, T> {
unsafe { Pin::new_unchecked(&mut *self.inner) }
pub fn as_pin_mut<'a>(&'a mut self) -> PinMut<'a, T> {
unsafe { PinMut::new_unchecked(&mut *self.inner) }
}

/// Get a mutable reference to the data inside this PinBox.
Expand Down
8 changes: 4 additions & 4 deletions src/libcore/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,15 +595,15 @@ unsafe impl<T: ?Sized> Freeze for *mut T {}
unsafe impl<'a, T: ?Sized> Freeze for &'a T {}
unsafe impl<'a, T: ?Sized> Freeze for &'a mut T {}

/// Types which can be moved out of a `Pin`.
/// Types which can be moved out of a `PinMut`.
///
/// The `Unpin` trait is used to control the behavior of the [`Pin`] type. If a
/// The `Unpin` trait is used to control the behavior of the [`PinMut`] type. If a
/// type implements `Unpin`, it is safe to move a value of that type out of the
/// `Pin` pointer.
/// `PinMut` pointer.
///
/// This trait is automatically implemented for almost every type.
///
/// [`Pin`]: ../mem/struct.Pin.html
/// [`PinMut`]: ../mem/struct.PinMut.html
#[unstable(feature = "pin", issue = "49150")]
pub unsafe auto trait Unpin {}

Expand Down
51 changes: 27 additions & 24 deletions src/libcore/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1101,69 +1101,72 @@ impl<T: ::hash::Hash> ::hash::Hash for ManuallyDrop<T> {
/// value implements the `Unpin` trait.
#[unstable(feature = "pin", issue = "49150")]
#[fundamental]
pub struct Pin<'a, T: ?Sized + 'a> {
pub struct PinMut<'a, T: ?Sized + 'a> {
inner: &'a mut T,
}

#[unstable(feature = "pin", issue = "49150")]
impl<'a, T: ?Sized + Unpin> Pin<'a, T> {
/// Construct a new `Pin` around a reference to some data of a type that
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) -> Pin<'a, T> {
Pin { inner: reference }
pub fn new(reference: &'a mut T) -> PinMut<'a, T> {
PinMut { inner: reference }
}
}


#[unstable(feature = "pin", issue = "49150")]
impl<'a, T: ?Sized> Pin<'a, T> {
/// Construct a new `Pin` around a reference to some data of a type that
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) -> Pin<'a, T> {
Pin { inner: reference }
pub unsafe fn new_unchecked(reference: &'a mut T) -> PinMut<'a, T> {
PinMut { inner: reference }
}

/// Borrow a Pin for a shorter lifetime than it already has.
/// 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 borrow<'b>(this: &'b mut Pin<'a, T>) -> Pin<'b, T> {
Pin { inner: this.inner }
pub fn reborrow<'b>(&'b mut self) -> PinMut<'b, T> {
PinMut { inner: self.inner }
}

/// Get a mutable reference to the data inside of this `Pin`.
/// 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<'b>(this: &'b mut Pin<'a, T>) -> &'b mut T {
pub unsafe fn get_mut(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 `Pin` of a field of something, you
/// 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<'b, U, F>(this: &'b mut Pin<'a, T>, f: F) -> Pin<'b, U> where
pub unsafe fn map<U, F>(this: PinMut<'a, T>, f: F) -> PinMut<'a, U> where
F: FnOnce(&mut T) -> &mut U
{
Pin { inner: f(this.inner) }
PinMut { inner: f(this.inner) }
}
}

#[unstable(feature = "pin", issue = "49150")]
impl<'a, T: ?Sized> Deref for Pin<'a, T> {
impl<'a, T: ?Sized> Deref for PinMut<'a, T> {
type Target = T;

fn deref(&self) -> &T {
Expand All @@ -1172,35 +1175,35 @@ impl<'a, T: ?Sized> Deref for Pin<'a, T> {
}

#[unstable(feature = "pin", issue = "49150")]
impl<'a, T: ?Sized + Unpin> DerefMut for Pin<'a, T> {
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 Pin<'a, T> {
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 Pin<'a, T> {
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 Pin<'a, T> {
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<Pin<'a, U>> for Pin<'a, T> {}
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<PinMut<'a, U>> for PinMut<'a, T> {}

#[unstable(feature = "pin", issue = "49150")]
unsafe impl<'a, T: ?Sized> Unpin for Pin<'a, T> {}
unsafe impl<'a, T: ?Sized> Unpin for PinMut<'a, T> {}

0 comments on commit c166b03

Please sign in to comment.