Skip to content

Commit

Permalink
move PinMut into pin module and export through std
Browse files Browse the repository at this point in the history
  • Loading branch information
nivkner committed Aug 22, 2018
1 parent f1b506a commit 13da951
Show file tree
Hide file tree
Showing 14 changed files with 191 additions and 156 deletions.
3 changes: 2 additions & 1 deletion src/liballoc/boxed.rs
Expand Up @@ -64,7 +64,8 @@ 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};
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/future/future.rs
Expand Up @@ -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};

Expand Down
2 changes: 1 addition & 1 deletion src/libcore/future/future_obj.rs
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/libcore/lib.rs
Expand Up @@ -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;
Expand Down
149 changes: 2 additions & 147 deletions src/libcore/mem.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -1024,146 +1022,3 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
&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 ()) {}
}
2 changes: 1 addition & 1 deletion src/libcore/option.rs
Expand Up @@ -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
Expand Down
162 changes: 162 additions & 0 deletions src/libcore/pin.rs
@@ -0,0 +1,162 @@
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Types which pin data to its location in memory

#![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.
///
/// 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 ()) {}
}
2 changes: 1 addition & 1 deletion src/libstd/future.rs
Expand Up @@ -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};
Expand Down
1 change: 1 addition & 0 deletions src/libstd/lib.rs
Expand Up @@ -466,6 +466,7 @@ pub mod num;
pub mod os;
pub mod panic;
pub mod path;
pub mod pin;
pub mod process;
pub mod sync;
pub mod time;
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/macros.rs
Expand Up @@ -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;
Expand Down

0 comments on commit 13da951

Please sign in to comment.