Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8c2b371

Browse files
committedAug 27, 2018
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
2 parents f7202e4 + 83ca347 commit 8c2b371

File tree

18 files changed

+496
-365
lines changed

18 files changed

+496
-365
lines changed
 

‎src/liballoc/boxed.rs

Lines changed: 9 additions & 202 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,14 @@ use core::future::{Future, FutureObj, LocalFutureObj, UnsafeFutureObj};
6464
use core::hash::{Hash, Hasher};
6565
use core::iter::FusedIterator;
6666
use core::marker::{Unpin, Unsize};
67-
use core::mem::{self, PinMut};
67+
use core::mem;
68+
use core::pin::PinMut;
6869
use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
6970
use core::ptr::{self, NonNull, Unique};
7071
use core::task::{Context, Poll, Spawn, SpawnErrorKind, SpawnObjError};
7172

7273
use raw_vec::RawVec;
74+
use pin::PinBox;
7375
use str::from_boxed_utf8_unchecked;
7476

7577
/// A pointer type for heap allocation.
@@ -758,166 +760,6 @@ impl<T> Generator for Box<T>
758760
}
759761
}
760762

761-
/// A pinned, heap allocated reference.
762-
#[unstable(feature = "pin", issue = "49150")]
763-
#[fundamental]
764-
#[repr(transparent)]
765-
pub struct PinBox<T: ?Sized> {
766-
inner: Box<T>,
767-
}
768-
769-
#[unstable(feature = "pin", issue = "49150")]
770-
impl<T> PinBox<T> {
771-
/// Allocate memory on the heap, move the data into it and pin it.
772-
#[unstable(feature = "pin", issue = "49150")]
773-
pub fn new(data: T) -> PinBox<T> {
774-
PinBox { inner: Box::new(data) }
775-
}
776-
}
777-
778-
#[unstable(feature = "pin", issue = "49150")]
779-
impl<T: ?Sized> PinBox<T> {
780-
/// Get a pinned reference to the data in this PinBox.
781-
#[inline]
782-
pub fn as_pin_mut<'a>(&'a mut self) -> PinMut<'a, T> {
783-
unsafe { PinMut::new_unchecked(&mut *self.inner) }
784-
}
785-
786-
/// Constructs a `PinBox` from a raw pointer.
787-
///
788-
/// After calling this function, the raw pointer is owned by the
789-
/// resulting `PinBox`. Specifically, the `PinBox` destructor will call
790-
/// the destructor of `T` and free the allocated memory. Since the
791-
/// way `PinBox` allocates and releases memory is unspecified, the
792-
/// only valid pointer to pass to this function is the one taken
793-
/// from another `PinBox` via the [`PinBox::into_raw`] function.
794-
///
795-
/// This function is unsafe because improper use may lead to
796-
/// memory problems. For example, a double-free may occur if the
797-
/// function is called twice on the same raw pointer.
798-
///
799-
/// [`PinBox::into_raw`]: struct.PinBox.html#method.into_raw
800-
///
801-
/// # Examples
802-
///
803-
/// ```
804-
/// #![feature(pin)]
805-
/// use std::boxed::PinBox;
806-
/// let x = PinBox::new(5);
807-
/// let ptr = PinBox::into_raw(x);
808-
/// let x = unsafe { PinBox::from_raw(ptr) };
809-
/// ```
810-
#[inline]
811-
pub unsafe fn from_raw(raw: *mut T) -> Self {
812-
PinBox { inner: Box::from_raw(raw) }
813-
}
814-
815-
/// Consumes the `PinBox`, returning the wrapped raw pointer.
816-
///
817-
/// After calling this function, the caller is responsible for the
818-
/// memory previously managed by the `PinBox`. In particular, the
819-
/// caller should properly destroy `T` and release the memory. The
820-
/// proper way to do so is to convert the raw pointer back into a
821-
/// `PinBox` with the [`PinBox::from_raw`] function.
822-
///
823-
/// Note: this is an associated function, which means that you have
824-
/// to call it as `PinBox::into_raw(b)` instead of `b.into_raw()`. This
825-
/// is so that there is no conflict with a method on the inner type.
826-
///
827-
/// [`PinBox::from_raw`]: struct.PinBox.html#method.from_raw
828-
///
829-
/// # Examples
830-
///
831-
/// ```
832-
/// #![feature(pin)]
833-
/// use std::boxed::PinBox;
834-
/// let x = PinBox::new(5);
835-
/// let ptr = PinBox::into_raw(x);
836-
/// ```
837-
#[inline]
838-
pub fn into_raw(b: PinBox<T>) -> *mut T {
839-
Box::into_raw(b.inner)
840-
}
841-
842-
/// Get a mutable reference to the data inside this PinBox.
843-
///
844-
/// This function is unsafe. Users must guarantee that the data is never
845-
/// moved out of this reference.
846-
#[inline]
847-
pub unsafe fn get_mut<'a>(this: &'a mut PinBox<T>) -> &'a mut T {
848-
&mut *this.inner
849-
}
850-
851-
/// Convert this PinBox into an unpinned Box.
852-
///
853-
/// This function is unsafe. Users must guarantee that the data is never
854-
/// moved out of the box.
855-
#[inline]
856-
pub unsafe fn unpin(this: PinBox<T>) -> Box<T> {
857-
this.inner
858-
}
859-
}
860-
861-
#[unstable(feature = "pin", issue = "49150")]
862-
impl<T: ?Sized> From<Box<T>> for PinBox<T> {
863-
fn from(boxed: Box<T>) -> PinBox<T> {
864-
PinBox { inner: boxed }
865-
}
866-
}
867-
868-
#[unstable(feature = "pin", issue = "49150")]
869-
impl<T: Unpin + ?Sized> From<PinBox<T>> for Box<T> {
870-
fn from(pinned: PinBox<T>) -> Box<T> {
871-
pinned.inner
872-
}
873-
}
874-
875-
#[unstable(feature = "pin", issue = "49150")]
876-
impl<T: ?Sized> Deref for PinBox<T> {
877-
type Target = T;
878-
879-
fn deref(&self) -> &T {
880-
&*self.inner
881-
}
882-
}
883-
884-
#[unstable(feature = "pin", issue = "49150")]
885-
impl<T: Unpin + ?Sized> DerefMut for PinBox<T> {
886-
fn deref_mut(&mut self) -> &mut T {
887-
&mut *self.inner
888-
}
889-
}
890-
891-
#[unstable(feature = "pin", issue = "49150")]
892-
impl<T: fmt::Display + ?Sized> fmt::Display for PinBox<T> {
893-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
894-
fmt::Display::fmt(&*self.inner, f)
895-
}
896-
}
897-
898-
#[unstable(feature = "pin", issue = "49150")]
899-
impl<T: fmt::Debug + ?Sized> fmt::Debug for PinBox<T> {
900-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
901-
fmt::Debug::fmt(&*self.inner, f)
902-
}
903-
}
904-
905-
#[unstable(feature = "pin", issue = "49150")]
906-
impl<T: ?Sized> fmt::Pointer for PinBox<T> {
907-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
908-
// It's not possible to extract the inner Uniq directly from the Box,
909-
// instead we cast it to a *const which aliases the Unique
910-
let ptr: *const T = &*self.inner;
911-
fmt::Pointer::fmt(&ptr, f)
912-
}
913-
}
914-
915-
#[unstable(feature = "pin", issue = "49150")]
916-
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<PinBox<U>> for PinBox<T> {}
917-
918-
#[unstable(feature = "pin", issue = "49150")]
919-
impl<T: ?Sized> Unpin for PinBox<T> {}
920-
921763
#[unstable(feature = "futures_api", issue = "50547")]
922764
impl<F: ?Sized + Future + Unpin> Future for Box<F> {
923765
type Output = F::Output;
@@ -927,15 +769,6 @@ impl<F: ?Sized + Future + Unpin> Future for Box<F> {
927769
}
928770
}
929771

930-
#[unstable(feature = "futures_api", issue = "50547")]
931-
impl<F: ?Sized + Future> Future for PinBox<F> {
932-
type Output = F::Output;
933-
934-
fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
935-
self.as_pin_mut().poll(cx)
936-
}
937-
}
938-
939772
#[unstable(feature = "futures_api", issue = "50547")]
940773
unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Box<F>
941774
where F: Future<Output = T> + 'a
@@ -955,25 +788,6 @@ unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Box<F>
955788
}
956789
}
957790

958-
#[unstable(feature = "futures_api", issue = "50547")]
959-
unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for PinBox<F>
960-
where F: Future<Output = T> + 'a
961-
{
962-
fn into_raw(self) -> *mut () {
963-
PinBox::into_raw(self) as *mut ()
964-
}
965-
966-
unsafe fn poll(ptr: *mut (), cx: &mut Context) -> Poll<T> {
967-
let ptr = ptr as *mut F;
968-
let pin: PinMut<F> = PinMut::new_unchecked(&mut *ptr);
969-
pin.poll(cx)
970-
}
971-
972-
unsafe fn drop(ptr: *mut ()) {
973-
drop(PinBox::from_raw(ptr as *mut F))
974-
}
975-
}
976-
977791
#[unstable(feature = "futures_api", issue = "50547")]
978792
impl<Sp> Spawn for Box<Sp>
979793
where Sp: Spawn + ?Sized
@@ -990,13 +804,6 @@ impl<Sp> Spawn for Box<Sp>
990804
}
991805
}
992806

993-
#[unstable(feature = "futures_api", issue = "50547")]
994-
impl<'a, F: Future<Output = ()> + Send + 'a> From<PinBox<F>> for FutureObj<'a, ()> {
995-
fn from(boxed: PinBox<F>) -> Self {
996-
FutureObj::new(boxed)
997-
}
998-
}
999-
1000807
#[unstable(feature = "futures_api", issue = "50547")]
1001808
impl<'a, F: Future<Output = ()> + Send + 'a> From<Box<F>> for FutureObj<'a, ()> {
1002809
fn from(boxed: Box<F>) -> Self {
@@ -1005,15 +812,15 @@ impl<'a, F: Future<Output = ()> + Send + 'a> From<Box<F>> for FutureObj<'a, ()>
1005812
}
1006813

1007814
#[unstable(feature = "futures_api", issue = "50547")]
1008-
impl<'a, F: Future<Output = ()> + 'a> From<PinBox<F>> for LocalFutureObj<'a, ()> {
1009-
fn from(boxed: PinBox<F>) -> Self {
815+
impl<'a, F: Future<Output = ()> + 'a> From<Box<F>> for LocalFutureObj<'a, ()> {
816+
fn from(boxed: Box<F>) -> Self {
1010817
LocalFutureObj::new(boxed)
1011818
}
1012819
}
1013820

1014-
#[unstable(feature = "futures_api", issue = "50547")]
1015-
impl<'a, F: Future<Output = ()> + 'a> From<Box<F>> for LocalFutureObj<'a, ()> {
1016-
fn from(boxed: Box<F>) -> Self {
1017-
LocalFutureObj::new(boxed)
821+
#[unstable(feature = "pin", issue = "49150")]
822+
impl<T: Unpin + ?Sized> From<PinBox<T>> for Box<T> {
823+
fn from(pinned: PinBox<T>) -> Box<T> {
824+
unsafe { PinBox::unpin(pinned) }
1018825
}
1019826
}

‎src/liballoc/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ pub mod collections;
160160
pub mod sync;
161161
pub mod rc;
162162
pub mod raw_vec;
163+
pub mod pin;
163164
pub mod prelude;
164165
pub mod borrow;
165166
pub mod fmt;

‎src/liballoc/pin.rs

Lines changed: 302 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,302 @@
1+
//! Types which pin data to its location in memory
2+
//!
3+
//! It is sometimes useful to have objects that are guaranteed to not move,
4+
//! in the sense that their placement in memory does not change, and can thus be relied upon.
5+
//!
6+
//! A prime example of such a scenario would be building self-referencial structs,
7+
//! since moving an object with pointers to itself will invalidate them,
8+
//! which could cause undefined behavior.
9+
//!
10+
//! In order to prevent objects from moving, they must be *pinned*,
11+
//! by wrapping the data in pinning pointer types, such as [`PinMut`] and [`PinBox`],
12+
//! which are otherwise equivalent to `& mut` and [`Box`], respectively.
13+
//!
14+
//! First of all, these are pointer types because pinned data mustn't be passed around by value
15+
//! (that would change its location in memory).
16+
//! Secondly, since data can be moved out of `&mut` and [`Box`] with functions such as [`swap`],
17+
//! which causes their contents to swap places in memory,
18+
//! we need dedicated types that prohibit such operations.
19+
//!
20+
//! However, these restrictions are usually not necessary,
21+
//! so most types implement the [`Unpin`] auto-trait,
22+
//! which indicates that the type can be moved out safely.
23+
//! Doing so removes the limitations of pinning types,
24+
//! making them the same as their non-pinning counterparts.
25+
//!
26+
//! [`PinMut`]: struct.PinMut.html
27+
//! [`PinBox`]: struct.PinBox.html
28+
//! [`Unpin`]: trait.Unpin.html
29+
//! [`swap`]: ../../std/mem/fn.swap.html
30+
//! [`Box`]: ../boxed/struct.Box.html
31+
//!
32+
//! # Examples
33+
//!
34+
//! ```rust
35+
//! #![feature(pin)]
36+
//!
37+
//! use std::pin::PinBox;
38+
//! use std::marker::Pinned;
39+
//! use std::ptr::NonNull;
40+
//!
41+
//! // This is a self referencial struct since the slice field points to the data field.
42+
//! // We cannot inform the compiler about that with a normal reference,
43+
//! // since this pattern cannot be described with the usual borrowing rules.
44+
//! // Instead we use a raw pointer, though one which is known to not be null,
45+
//! // since we know it's pointing at the string.
46+
//! struct Unmovable {
47+
//! data: String,
48+
//! slice: NonNull<String>,
49+
//! _pin: Pinned,
50+
//! }
51+
//!
52+
//! impl Unmovable {
53+
//! // To ensure the data doesn't move when the function returns,
54+
//! // we place it in the heap where it will stay for the lifetime of the object,
55+
//! // and the only way to access it would be through a pointer to it.
56+
//! fn new(data: String) -> PinBox<Self> {
57+
//! let res = Unmovable {
58+
//! data,
59+
//! // we only create the pointer once the data is in place
60+
//! // otherwise it will have already moved before we even started
61+
//! slice: NonNull::dangling(),
62+
//! _pin: Pinned,
63+
//! };
64+
//! let mut boxed = PinBox::new(res);
65+
//!
66+
//! let slice = NonNull::from(&boxed.data);
67+
//! // we know this is safe because modifying a field doesn't move the whole struct
68+
//! unsafe { PinBox::get_mut(&mut boxed).slice = slice };
69+
//! boxed
70+
//! }
71+
//! }
72+
//!
73+
//! let unmoved = Unmovable::new("hello".to_string());
74+
//! // The pointer should point to the correct location,
75+
//! // so long as the struct hasn't moved.
76+
//! // Meanwhile, we are free to move the pointer around.
77+
//! # #[allow(unused_mut)]
78+
//! let mut still_unmoved = unmoved;
79+
//! assert_eq!(still_unmoved.slice, NonNull::from(&still_unmoved.data));
80+
//!
81+
//! // Since our type doesn't implement Unpin, this will fail to compile:
82+
//! // let new_unmoved = Unmovable::new("world".to_string());
83+
//! // std::mem::swap(&mut *still_unmoved, &mut *new_unmoved);
84+
//! ```
85+
86+
#![unstable(feature = "pin", issue = "49150")]
87+
88+
pub use core::pin::*;
89+
pub use core::marker::Unpin;
90+
91+
use core::convert::From;
92+
use core::fmt;
93+
use core::future::{Future, FutureObj, LocalFutureObj, UnsafeFutureObj};
94+
use core::marker::Unsize;
95+
use core::ops::{CoerceUnsized, Deref, DerefMut};
96+
use core::task::{Context, Poll};
97+
98+
use boxed::Box;
99+
100+
/// A pinned, heap allocated reference.
101+
///
102+
/// This type is similar to [`Box`], except that it pins its value,
103+
/// which prevents it from moving out of the reference, unless it implements [`Unpin`].
104+
///
105+
/// See the [module documentation] for furthur explaination on pinning.
106+
///
107+
/// [`Box`]: ../boxed/struct.Box.html
108+
/// [`Unpin`]: ../../std/marker/trait.Unpin.html
109+
/// [module documentation]: index.html
110+
#[unstable(feature = "pin", issue = "49150")]
111+
#[fundamental]
112+
#[repr(transparent)]
113+
pub struct PinBox<T: ?Sized> {
114+
inner: Box<T>,
115+
}
116+
117+
#[unstable(feature = "pin", issue = "49150")]
118+
impl<T> PinBox<T> {
119+
/// Allocate memory on the heap, move the data into it and pin it.
120+
#[unstable(feature = "pin", issue = "49150")]
121+
pub fn new(data: T) -> PinBox<T> {
122+
PinBox { inner: Box::new(data) }
123+
}
124+
}
125+
126+
#[unstable(feature = "pin", issue = "49150")]
127+
impl<T: ?Sized> PinBox<T> {
128+
/// Get a pinned reference to the data in this PinBox.
129+
#[inline]
130+
pub fn as_pin_mut<'a>(&'a mut self) -> PinMut<'a, T> {
131+
unsafe { PinMut::new_unchecked(&mut *self.inner) }
132+
}
133+
134+
/// Constructs a `PinBox` from a raw pointer.
135+
///
136+
/// After calling this function, the raw pointer is owned by the
137+
/// resulting `PinBox`. Specifically, the `PinBox` destructor will call
138+
/// the destructor of `T` and free the allocated memory. Since the
139+
/// way `PinBox` allocates and releases memory is unspecified, the
140+
/// only valid pointer to pass to this function is the one taken
141+
/// from another `PinBox` via the [`PinBox::into_raw`] function.
142+
///
143+
/// This function is unsafe because improper use may lead to
144+
/// memory problems. For example, a double-free may occur if the
145+
/// function is called twice on the same raw pointer.
146+
///
147+
/// [`PinBox::into_raw`]: struct.PinBox.html#method.into_raw
148+
///
149+
/// # Examples
150+
///
151+
/// ```
152+
/// #![feature(pin)]
153+
/// use std::pin::PinBox;
154+
/// let x = PinBox::new(5);
155+
/// let ptr = PinBox::into_raw(x);
156+
/// let x = unsafe { PinBox::from_raw(ptr) };
157+
/// ```
158+
#[inline]
159+
pub unsafe fn from_raw(raw: *mut T) -> Self {
160+
PinBox { inner: Box::from_raw(raw) }
161+
}
162+
163+
/// Consumes the `PinBox`, returning the wrapped raw pointer.
164+
///
165+
/// After calling this function, the caller is responsible for the
166+
/// memory previously managed by the `PinBox`. In particular, the
167+
/// caller should properly destroy `T` and release the memory. The
168+
/// proper way to do so is to convert the raw pointer back into a
169+
/// `PinBox` with the [`PinBox::from_raw`] function.
170+
///
171+
/// Note: this is an associated function, which means that you have
172+
/// to call it as `PinBox::into_raw(b)` instead of `b.into_raw()`. This
173+
/// is so that there is no conflict with a method on the inner type.
174+
///
175+
/// [`PinBox::from_raw`]: struct.PinBox.html#method.from_raw
176+
///
177+
/// # Examples
178+
///
179+
/// ```
180+
/// #![feature(pin)]
181+
/// use std::pin::PinBox;
182+
/// let x = PinBox::new(5);
183+
/// let ptr = PinBox::into_raw(x);
184+
/// ```
185+
#[inline]
186+
pub fn into_raw(b: PinBox<T>) -> *mut T {
187+
Box::into_raw(b.inner)
188+
}
189+
190+
/// Get a mutable reference to the data inside this PinBox.
191+
///
192+
/// This function is unsafe. Users must guarantee that the data is never
193+
/// moved out of this reference.
194+
#[inline]
195+
pub unsafe fn get_mut<'a>(this: &'a mut PinBox<T>) -> &'a mut T {
196+
&mut *this.inner
197+
}
198+
199+
/// Convert this PinBox into an unpinned Box.
200+
///
201+
/// This function is unsafe. Users must guarantee that the data is never
202+
/// moved out of the box.
203+
#[inline]
204+
pub unsafe fn unpin(this: PinBox<T>) -> Box<T> {
205+
this.inner
206+
}
207+
}
208+
209+
#[unstable(feature = "pin", issue = "49150")]
210+
impl<T: ?Sized> From<Box<T>> for PinBox<T> {
211+
fn from(boxed: Box<T>) -> PinBox<T> {
212+
PinBox { inner: boxed }
213+
}
214+
}
215+
216+
#[unstable(feature = "pin", issue = "49150")]
217+
impl<T: ?Sized> Deref for PinBox<T> {
218+
type Target = T;
219+
220+
fn deref(&self) -> &T {
221+
&*self.inner
222+
}
223+
}
224+
225+
#[unstable(feature = "pin", issue = "49150")]
226+
impl<T: Unpin + ?Sized> DerefMut for PinBox<T> {
227+
fn deref_mut(&mut self) -> &mut T {
228+
&mut *self.inner
229+
}
230+
}
231+
232+
#[unstable(feature = "pin", issue = "49150")]
233+
impl<T: fmt::Display + ?Sized> fmt::Display for PinBox<T> {
234+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
235+
fmt::Display::fmt(&*self.inner, f)
236+
}
237+
}
238+
239+
#[unstable(feature = "pin", issue = "49150")]
240+
impl<T: fmt::Debug + ?Sized> fmt::Debug for PinBox<T> {
241+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
242+
fmt::Debug::fmt(&*self.inner, f)
243+
}
244+
}
245+
246+
#[unstable(feature = "pin", issue = "49150")]
247+
impl<T: ?Sized> fmt::Pointer for PinBox<T> {
248+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
249+
// It's not possible to extract the inner Uniq directly from the Box,
250+
// instead we cast it to a *const which aliases the Unique
251+
let ptr: *const T = &*self.inner;
252+
fmt::Pointer::fmt(&ptr, f)
253+
}
254+
}
255+
256+
#[unstable(feature = "pin", issue = "49150")]
257+
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<PinBox<U>> for PinBox<T> {}
258+
259+
#[unstable(feature = "pin", issue = "49150")]
260+
impl<T: ?Sized> Unpin for PinBox<T> {}
261+
262+
#[unstable(feature = "futures_api", issue = "50547")]
263+
impl<F: ?Sized + Future> Future for PinBox<F> {
264+
type Output = F::Output;
265+
266+
fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
267+
self.as_pin_mut().poll(cx)
268+
}
269+
}
270+
271+
#[unstable(feature = "futures_api", issue = "50547")]
272+
unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for PinBox<F>
273+
where F: Future<Output = T> + 'a
274+
{
275+
fn into_raw(self) -> *mut () {
276+
PinBox::into_raw(self) as *mut ()
277+
}
278+
279+
unsafe fn poll(ptr: *mut (), cx: &mut Context) -> Poll<T> {
280+
let ptr = ptr as *mut F;
281+
let pin: PinMut<F> = PinMut::new_unchecked(&mut *ptr);
282+
pin.poll(cx)
283+
}
284+
285+
unsafe fn drop(ptr: *mut ()) {
286+
drop(PinBox::from_raw(ptr as *mut F))
287+
}
288+
}
289+
290+
#[unstable(feature = "futures_api", issue = "50547")]
291+
impl<'a, F: Future<Output = ()> + Send + 'a> From<PinBox<F>> for FutureObj<'a, ()> {
292+
fn from(boxed: PinBox<F>) -> Self {
293+
FutureObj::new(boxed)
294+
}
295+
}
296+
297+
#[unstable(feature = "futures_api", issue = "50547")]
298+
impl<'a, F: Future<Output = ()> + 'a> From<PinBox<F>> for LocalFutureObj<'a, ()> {
299+
fn from(boxed: PinBox<F>) -> Self {
300+
LocalFutureObj::new(boxed)
301+
}
302+
}

‎src/libcore/future/future.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
reason = "futures in libcore are unstable",
1313
issue = "50547")]
1414

15-
use mem::PinMut;
15+
use pin::PinMut;
1616
use marker::Unpin;
1717
use task::{self, Poll};
1818

‎src/libcore/future/future_obj.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
use fmt;
1616
use future::Future;
1717
use marker::{PhantomData, Unpin};
18-
use mem::PinMut;
18+
use pin::PinMut;
1919
use task::{Context, Poll};
2020

2121
/// A custom trait object for polling futures, roughly akin to

‎src/libcore/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ pub mod cell;
191191
pub mod char;
192192
pub mod panic;
193193
pub mod panicking;
194+
pub mod pin;
194195
pub mod iter;
195196
pub mod option;
196197
pub mod raw;

‎src/libcore/marker.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,7 @@ unsafe impl<'a, T: ?Sized> Freeze for &'a mut T {}
611611
/// Instead it can be used to prevent moves through the type system,
612612
/// by controlling the behavior of special pointer types like [`PinMut`],
613613
/// which "pin" the type in place by not allowing it to be moved out of them.
614+
/// See the [`pin module`] documentation for more information on pinning.
614615
///
615616
/// Implementing this trait lifts the restrictions of pinning off a type,
616617
/// 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 {}
619620
///
620621
/// ```rust
621622
/// #![feature(pin)]
622-
/// use std::mem::{PinMut, replace};
623+
/// use std::mem::replace;
624+
/// use std::pin::PinMut;
623625
///
624626
/// let mut string = "this".to_string();
625627
/// let mut pinned_string = PinMut::new(&mut string);
@@ -630,8 +632,9 @@ unsafe impl<'a, T: ?Sized> Freeze for &'a mut T {}
630632
///
631633
/// This trait is automatically implemented for almost every type.
632634
///
633-
/// [`PinMut`]: ../mem/struct.PinMut.html
634-
/// [`replace`]: ../mem/fn.replace.html
635+
/// [`replace`]: ../../std/mem/fn.replace.html
636+
/// [`PinMut`]: ../pin/struct.PinMut.html
637+
/// [`pin module`]: ../../std/pin/index.html
635638
#[unstable(feature = "pin", issue = "49150")]
636639
pub auto trait Unpin {}
637640

‎src/libcore/mem.rs

Lines changed: 2 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,11 @@
1818
use clone;
1919
use cmp;
2020
use fmt;
21-
use future::{Future, UnsafeFutureObj};
2221
use hash;
2322
use intrinsics;
24-
use marker::{Copy, PhantomData, Sized, Unpin, Unsize};
23+
use marker::{Copy, PhantomData, Sized};
2524
use ptr;
26-
use task::{Context, Poll};
27-
use ops::{Deref, DerefMut, CoerceUnsized};
25+
use ops::{Deref, DerefMut};
2826

2927
#[stable(feature = "rust1", since = "1.0.0")]
3028
pub use intrinsics::transmute;
@@ -992,146 +990,3 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
992990
&mut self.value
993991
}
994992
}
995-
996-
/// A pinned reference.
997-
///
998-
/// A pinned reference is a lot like a mutable reference, except that it is not
999-
/// safe to move a value out of a pinned reference unless the type of that
1000-
/// value implements the `Unpin` trait.
1001-
#[unstable(feature = "pin", issue = "49150")]
1002-
#[fundamental]
1003-
pub struct PinMut<'a, T: ?Sized + 'a> {
1004-
inner: &'a mut T,
1005-
}
1006-
1007-
#[unstable(feature = "pin", issue = "49150")]
1008-
impl<'a, T: ?Sized + Unpin> PinMut<'a, T> {
1009-
/// Construct a new `PinMut` around a reference to some data of a type that
1010-
/// implements `Unpin`.
1011-
#[unstable(feature = "pin", issue = "49150")]
1012-
pub fn new(reference: &'a mut T) -> PinMut<'a, T> {
1013-
PinMut { inner: reference }
1014-
}
1015-
1016-
/// Get a mutable reference to the data inside of this `PinMut`.
1017-
#[unstable(feature = "pin", issue = "49150")]
1018-
pub fn get_mut(this: PinMut<'a, T>) -> &'a mut T {
1019-
this.inner
1020-
}
1021-
}
1022-
1023-
1024-
#[unstable(feature = "pin", issue = "49150")]
1025-
impl<'a, T: ?Sized> PinMut<'a, T> {
1026-
/// Construct a new `PinMut` around a reference to some data of a type that
1027-
/// may or may not implement `Unpin`.
1028-
///
1029-
/// This constructor is unsafe because we do not know what will happen with
1030-
/// that data after the reference ends. If you cannot guarantee that the
1031-
/// data will never move again, calling this constructor is invalid.
1032-
#[unstable(feature = "pin", issue = "49150")]
1033-
pub unsafe fn new_unchecked(reference: &'a mut T) -> PinMut<'a, T> {
1034-
PinMut { inner: reference }
1035-
}
1036-
1037-
/// Reborrow a `PinMut` for a shorter lifetime.
1038-
///
1039-
/// For example, `PinMut::get_mut(x.reborrow())` (unsafely) returns a
1040-
/// short-lived mutable reference reborrowing from `x`.
1041-
#[unstable(feature = "pin", issue = "49150")]
1042-
pub fn reborrow<'b>(&'b mut self) -> PinMut<'b, T> {
1043-
PinMut { inner: self.inner }
1044-
}
1045-
1046-
/// Get a mutable reference to the data inside of this `PinMut`.
1047-
///
1048-
/// This function is unsafe. You must guarantee that you will never move
1049-
/// the data out of the mutable reference you receive when you call this
1050-
/// function.
1051-
#[unstable(feature = "pin", issue = "49150")]
1052-
pub unsafe fn get_mut_unchecked(this: PinMut<'a, T>) -> &'a mut T {
1053-
this.inner
1054-
}
1055-
1056-
/// Construct a new pin by mapping the interior value.
1057-
///
1058-
/// For example, if you wanted to get a `PinMut` of a field of something,
1059-
/// you could use this to get access to that field in one line of code.
1060-
///
1061-
/// This function is unsafe. You must guarantee that the data you return
1062-
/// will not move so long as the argument value does not move (for example,
1063-
/// because it is one of the fields of that value), and also that you do
1064-
/// not move out of the argument you receive to the interior function.
1065-
#[unstable(feature = "pin", issue = "49150")]
1066-
pub unsafe fn map_unchecked<U, F>(this: PinMut<'a, T>, f: F) -> PinMut<'a, U> where
1067-
F: FnOnce(&mut T) -> &mut U
1068-
{
1069-
PinMut { inner: f(this.inner) }
1070-
}
1071-
1072-
/// Assign a new value to the memory behind the pinned reference.
1073-
#[unstable(feature = "pin", issue = "49150")]
1074-
pub fn set(this: PinMut<'a, T>, value: T)
1075-
where T: Sized,
1076-
{
1077-
*this.inner = value;
1078-
}
1079-
}
1080-
1081-
#[unstable(feature = "pin", issue = "49150")]
1082-
impl<'a, T: ?Sized> Deref for PinMut<'a, T> {
1083-
type Target = T;
1084-
1085-
fn deref(&self) -> &T {
1086-
&*self.inner
1087-
}
1088-
}
1089-
1090-
#[unstable(feature = "pin", issue = "49150")]
1091-
impl<'a, T: ?Sized + Unpin> DerefMut for PinMut<'a, T> {
1092-
fn deref_mut(&mut self) -> &mut T {
1093-
self.inner
1094-
}
1095-
}
1096-
1097-
#[unstable(feature = "pin", issue = "49150")]
1098-
impl<'a, T: fmt::Debug + ?Sized> fmt::Debug for PinMut<'a, T> {
1099-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1100-
fmt::Debug::fmt(&**self, f)
1101-
}
1102-
}
1103-
1104-
#[unstable(feature = "pin", issue = "49150")]
1105-
impl<'a, T: fmt::Display + ?Sized> fmt::Display for PinMut<'a, T> {
1106-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1107-
fmt::Display::fmt(&**self, f)
1108-
}
1109-
}
1110-
1111-
#[unstable(feature = "pin", issue = "49150")]
1112-
impl<'a, T: ?Sized> fmt::Pointer for PinMut<'a, T> {
1113-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1114-
fmt::Pointer::fmt(&(&*self.inner as *const T), f)
1115-
}
1116-
}
1117-
1118-
#[unstable(feature = "pin", issue = "49150")]
1119-
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<PinMut<'a, U>> for PinMut<'a, T> {}
1120-
1121-
#[unstable(feature = "pin", issue = "49150")]
1122-
impl<'a, T: ?Sized> Unpin for PinMut<'a, T> {}
1123-
1124-
#[unstable(feature = "futures_api", issue = "50547")]
1125-
unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for PinMut<'a, F>
1126-
where F: Future<Output = T> + 'a
1127-
{
1128-
fn into_raw(self) -> *mut () {
1129-
unsafe { PinMut::get_mut_unchecked(self) as *mut F as *mut () }
1130-
}
1131-
1132-
unsafe fn poll(ptr: *mut (), cx: &mut Context) -> Poll<T> {
1133-
PinMut::new_unchecked(&mut *(ptr as *mut F)).poll(cx)
1134-
}
1135-
1136-
unsafe fn drop(_ptr: *mut ()) {}
1137-
}

‎src/libcore/option.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@
147147

148148
use iter::{FromIterator, FusedIterator, TrustedLen};
149149
use {hint, mem, ops::{self, Deref}};
150-
use mem::PinMut;
150+
use pin::PinMut;
151151

152152
// Note that this is not a lang item per se, but it has a hidden dependency on
153153
// `Iterator`, which is one. The compiler assumes that the `next` method of

‎src/libcore/pin.rs

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
//! Types which pin data to its location in memory
2+
//!
3+
//! See the [standard library module] for more information.
4+
//!
5+
//! [standard library module]: ../../std/pin/index.html
6+
7+
#![unstable(feature = "pin", issue = "49150")]
8+
9+
use fmt;
10+
use future::{Future, UnsafeFutureObj};
11+
use marker::{Sized, Unpin, Unsize};
12+
use task::{Context, Poll};
13+
use ops::{Deref, DerefMut, CoerceUnsized};
14+
15+
/// A pinned reference.
16+
///
17+
/// This type is similar to a mutable reference, except that it pins its value,
18+
/// which prevents it from moving out of the reference, unless it implements [`Unpin`].
19+
///
20+
/// See the [`pin` module] documentation for furthur explanation on pinning.
21+
///
22+
/// [`Unpin`]: ../../std/marker/trait.Unpin.html
23+
/// [`pin` module]: ../../std/pin/index.html
24+
#[unstable(feature = "pin", issue = "49150")]
25+
#[fundamental]
26+
pub struct PinMut<'a, T: ?Sized + 'a> {
27+
inner: &'a mut T,
28+
}
29+
30+
#[unstable(feature = "pin", issue = "49150")]
31+
impl<'a, T: ?Sized + Unpin> PinMut<'a, T> {
32+
/// Construct a new `PinMut` around a reference to some data of a type that
33+
/// implements `Unpin`.
34+
#[unstable(feature = "pin", issue = "49150")]
35+
pub fn new(reference: &'a mut T) -> PinMut<'a, T> {
36+
PinMut { inner: reference }
37+
}
38+
39+
/// Get a mutable reference to the data inside of this `PinMut`.
40+
#[unstable(feature = "pin", issue = "49150")]
41+
pub fn get_mut(this: PinMut<'a, T>) -> &'a mut T {
42+
this.inner
43+
}
44+
}
45+
46+
47+
#[unstable(feature = "pin", issue = "49150")]
48+
impl<'a, T: ?Sized> PinMut<'a, T> {
49+
/// Construct a new `PinMut` around a reference to some data of a type that
50+
/// may or may not implement `Unpin`.
51+
///
52+
/// This constructor is unsafe because we do not know what will happen with
53+
/// that data after the lifetime of the reference ends. If you cannot guarantee that the
54+
/// data will never move again, calling this constructor is invalid.
55+
#[unstable(feature = "pin", issue = "49150")]
56+
pub unsafe fn new_unchecked(reference: &'a mut T) -> PinMut<'a, T> {
57+
PinMut { inner: reference }
58+
}
59+
60+
/// Reborrow a `PinMut` for a shorter lifetime.
61+
///
62+
/// For example, `PinMut::get_mut(x.reborrow())` (unsafely) returns a
63+
/// short-lived mutable reference reborrowing from `x`.
64+
#[unstable(feature = "pin", issue = "49150")]
65+
pub fn reborrow<'b>(&'b mut self) -> PinMut<'b, T> {
66+
PinMut { inner: self.inner }
67+
}
68+
69+
/// Get a mutable reference to the data inside of this `PinMut`.
70+
///
71+
/// This function is unsafe. You must guarantee that you will never move
72+
/// the data out of the mutable reference you receive when you call this
73+
/// function.
74+
#[unstable(feature = "pin", issue = "49150")]
75+
pub unsafe fn get_mut_unchecked(this: PinMut<'a, T>) -> &'a mut T {
76+
this.inner
77+
}
78+
79+
/// Construct a new pin by mapping the interior value.
80+
///
81+
/// For example, if you wanted to get a `PinMut` of a field of something,
82+
/// you could use this to get access to that field in one line of code.
83+
///
84+
/// This function is unsafe. You must guarantee that the data you return
85+
/// will not move so long as the argument value does not move (for example,
86+
/// because it is one of the fields of that value), and also that you do
87+
/// not move out of the argument you receive to the interior function.
88+
#[unstable(feature = "pin", issue = "49150")]
89+
pub unsafe fn map_unchecked<U, F>(this: PinMut<'a, T>, f: F) -> PinMut<'a, U> where
90+
F: FnOnce(&mut T) -> &mut U
91+
{
92+
PinMut { inner: f(this.inner) }
93+
}
94+
95+
/// Assign a new value to the memory behind the pinned reference.
96+
#[unstable(feature = "pin", issue = "49150")]
97+
pub fn set(this: PinMut<'a, T>, value: T)
98+
where T: Sized,
99+
{
100+
*this.inner = value;
101+
}
102+
}
103+
104+
#[unstable(feature = "pin", issue = "49150")]
105+
impl<'a, T: ?Sized> Deref for PinMut<'a, T> {
106+
type Target = T;
107+
108+
fn deref(&self) -> &T {
109+
&*self.inner
110+
}
111+
}
112+
113+
#[unstable(feature = "pin", issue = "49150")]
114+
impl<'a, T: ?Sized + Unpin> DerefMut for PinMut<'a, T> {
115+
fn deref_mut(&mut self) -> &mut T {
116+
self.inner
117+
}
118+
}
119+
120+
#[unstable(feature = "pin", issue = "49150")]
121+
impl<'a, T: fmt::Debug + ?Sized> fmt::Debug for PinMut<'a, T> {
122+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
123+
fmt::Debug::fmt(&**self, f)
124+
}
125+
}
126+
127+
#[unstable(feature = "pin", issue = "49150")]
128+
impl<'a, T: fmt::Display + ?Sized> fmt::Display for PinMut<'a, T> {
129+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
130+
fmt::Display::fmt(&**self, f)
131+
}
132+
}
133+
134+
#[unstable(feature = "pin", issue = "49150")]
135+
impl<'a, T: ?Sized> fmt::Pointer for PinMut<'a, T> {
136+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
137+
fmt::Pointer::fmt(&(&*self.inner as *const T), f)
138+
}
139+
}
140+
141+
#[unstable(feature = "pin", issue = "49150")]
142+
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<PinMut<'a, U>> for PinMut<'a, T> {}
143+
144+
#[unstable(feature = "pin", issue = "49150")]
145+
impl<'a, T: ?Sized> Unpin for PinMut<'a, T> {}
146+
147+
#[unstable(feature = "futures_api", issue = "50547")]
148+
unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for PinMut<'a, F>
149+
where F: Future<Output = T> + 'a
150+
{
151+
fn into_raw(self) -> *mut () {
152+
unsafe { PinMut::get_mut_unchecked(self) as *mut F as *mut () }
153+
}
154+
155+
unsafe fn poll(ptr: *mut (), cx: &mut Context) -> Poll<T> {
156+
PinMut::new_unchecked(&mut *(ptr as *mut F)).poll(cx)
157+
}
158+
159+
unsafe fn drop(_ptr: *mut ()) {}
160+
}

‎src/libstd/future.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
1313
use core::cell::Cell;
1414
use core::marker::Unpin;
15-
use core::mem::PinMut;
15+
use core::pin::PinMut;
1616
use core::option::Option;
1717
use core::ptr::NonNull;
1818
use core::task::{self, Poll};

‎src/libstd/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,8 @@ pub use alloc_crate::borrow;
435435
pub use alloc_crate::fmt;
436436
#[stable(feature = "rust1", since = "1.0.0")]
437437
pub use alloc_crate::format;
438+
#[unstable(feature = "pin", issue = "49150")]
439+
pub use alloc_crate::pin;
438440
#[stable(feature = "rust1", since = "1.0.0")]
439441
pub use alloc_crate::slice;
440442
#[stable(feature = "rust1", since = "1.0.0")]

‎src/libstd/macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ macro_rules! await {
230230
loop {
231231
if let $crate::task::Poll::Ready(x) =
232232
$crate::future::poll_in_task_cx(unsafe {
233-
$crate::mem::PinMut::new_unchecked(&mut pinned)
233+
$crate::pin::PinMut::new_unchecked(&mut pinned)
234234
})
235235
{
236236
break x;

‎src/libstd/panic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use any::Any;
1616
use cell::UnsafeCell;
1717
use fmt;
1818
use future::Future;
19-
use mem::PinMut;
19+
use pin::PinMut;
2020
use ops::{Deref, DerefMut};
2121
use panicking;
2222
use ptr::{Unique, NonNull};

‎src/test/run-pass/async-await.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212

1313
#![feature(arbitrary_self_types, async_await, await_macro, futures_api, pin)]
1414

15-
use std::boxed::PinBox;
16-
use std::mem::PinMut;
15+
use std::pin::PinBox;
16+
use std::pin::PinMut;
1717
use std::future::Future;
1818
use std::sync::{
1919
Arc,

‎src/test/run-pass/futures-api.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
#![feature(arbitrary_self_types, futures_api, pin)]
1212
#![allow(unused)]
1313

14-
use std::boxed::PinBox;
14+
use std::pin::PinBox;
1515
use std::future::Future;
16-
use std::mem::PinMut;
16+
use std::pin::PinMut;
1717
use std::rc::Rc;
1818
use std::sync::{
1919
Arc,

‎src/test/rustdoc-js/pinbox-new.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const QUERY = 'pinbox::new';
1414

1515
const EXPECTED = {
1616
'others': [
17-
{ 'path': 'std::boxed::PinBox', 'name': 'new' },
18-
{ 'path': 'alloc::boxed::PinBox', 'name': 'new' },
17+
{ 'path': 'std::pin::PinBox', 'name': 'new' },
18+
{ 'path': 'alloc::pin::PinBox', 'name': 'new' },
1919
],
2020
};

‎src/test/rustdoc-js/vec-new.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ const EXPECTED = {
1414
'others': [
1515
{ 'path': 'std::vec::Vec', 'name': 'new' },
1616
{ 'path': 'std::vec::Vec', 'name': 'ne' },
17-
{ 'path': 'std::boxed::PinBox', 'name': 'new' },
17+
{ 'path': 'std::pin::PinBox', 'name': 'new' },
1818
],
1919
};

0 commit comments

Comments
 (0)
Please sign in to comment.