Skip to content

Commit 3ec1810

Browse files
committed
Cleanup and fix method resolution issue
1 parent 974bdc8 commit 3ec1810

File tree

6 files changed

+117
-73
lines changed

6 files changed

+117
-73
lines changed

src/liballoc/boxed.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,9 @@ impl<T> Box<T> {
9898
}
9999

100100
#[unstable(feature = "pin", issue = "49150")]
101+
#[inline(always)]
101102
pub fn pinned(x: T) -> Pin<Box<T>> {
102-
unsafe { Pin::new_unchecked(box x) }
103+
(box x).into()
103104
}
104105
}
105106

@@ -434,6 +435,9 @@ impl<T> From<T> for Box<T> {
434435
#[unstable(feature = "pin", issue = "49150")]
435436
impl<T> From<Box<T>> for Pin<Box<T>> {
436437
fn from(boxed: Box<T>) -> Self {
438+
// It's not possible to move or replace the insides of a `Pin<Box<T>>`
439+
// when `T: !Unpin`, so it's safe to pin it directly without any
440+
// additional requirements.
437441
unsafe { Pin::new_unchecked(boxed) }
438442
}
439443
}

src/libcore/future/future.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,14 @@ impl<'a, F: ?Sized + Future + Unpin> Future for &'a mut F {
104104
}
105105
}
106106

107-
impl<P, F> Future for Pin<P> where
108-
P: ops::DerefMut<Target = F> + Unpin,
109-
F: Future + ?Sized,
107+
impl<P> Future for Pin<P>
108+
where
109+
P: ops::DerefMut,
110+
P::Target: Future,
110111
{
111-
type Output = F::Output;
112+
type Output = <<P as ops::Deref>::Target as Future>::Output;
112113

113-
fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context) -> Poll<Self::Output> {
114-
let pin: Pin<&mut F> = Pin::as_mut(&mut *self);
115-
F::poll(pin, cx)
114+
fn poll(self: Pin<&mut Self>, cx: &mut task::Context) -> Poll<Self::Output> {
115+
Pin::get_mut(self).as_mut().poll(cx)
116116
}
117117
}

src/libcore/option.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,7 @@ impl<T> Option<T> {
276276
#[unstable(feature = "pin", issue = "49150")]
277277
pub fn as_pin_ref<'a>(self: Pin<&'a Option<T>>) -> Option<Pin<&'a T>> {
278278
unsafe {
279-
let option: Option<&'a T> = Pin::get(self).as_ref();
280-
option.map(|x| Pin::new_unchecked(x))
279+
Pin::get_ref(self).as_ref().map(|x| Pin::new_unchecked(x))
281280
}
282281
}
283282

@@ -286,8 +285,7 @@ impl<T> Option<T> {
286285
#[unstable(feature = "pin", issue = "49150")]
287286
pub fn as_pin_mut<'a>(self: Pin<&'a mut Option<T>>) -> Option<Pin<&'a mut T>> {
288287
unsafe {
289-
let option: Option<&'a mut T> = Pin::get_mut_unchecked(self).as_mut();
290-
option.map(|x| Pin::new_unchecked(x))
288+
Pin::get_mut_unchecked(self).as_mut().map(|x| Pin::new_unchecked(x))
291289
}
292290
}
293291

src/libcore/pin.rs

+93-49
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
//! since moving an object with pointers to itself will invalidate them,
88
//! which could cause undefined behavior.
99
//!
10-
//! In order to prevent objects from moving, they must be *pinned*,
10+
//! In order to prevent objects from moving, they must be pinned
1111
//! by wrapping a pointer to the data in the [`Pin`] type. A pointer wrapped
1212
//! in a `Pin` is otherwise equivalent to its normal version, e.g. `Pin<Box<T>>`
1313
//! and `Box<T>` work the same way except that the first is pinning the value
1414
//! of `T` in place.
1515
//!
1616
//! First of all, these are pointer types because pinned data mustn't be passed around by value
1717
//! (that would change its location in memory).
18-
//! Secondly, since data can be moved out of `&mut` and [`Box`] with functions such as [`swap`],
18+
//! Secondly, since data can be moved out of `&mut` and `Box` with functions such as [`swap`],
1919
//! which causes their contents to swap places in memory,
2020
//! we need dedicated types that prohibit such operations.
2121
//!
@@ -28,7 +28,7 @@
2828
//! [`Pin`]: struct.Pin.html
2929
//! [`Unpin`]: trait.Unpin.html
3030
//! [`swap`]: ../../std/mem/fn.swap.html
31-
//! [`Box`]: ../boxed/struct.Box.html
31+
//! [`Box`]: ../../std/boxed/struct.Box.html
3232
//!
3333
//! # Examples
3434
//!
@@ -66,7 +66,7 @@
6666
//!
6767
//! let slice = NonNull::from(&boxed.data);
6868
//! // we know this is safe because modifying a field doesn't move the whole struct
69-
//! unsafe {
69+
//! unsafe {
7070
//! let mut_ref: Pin<&mut Self> = Pin::as_mut(&mut boxed);
7171
//! Pin::get_mut_unchecked(mut_ref).slice = slice;
7272
//! }
@@ -90,9 +90,12 @@
9090
#![unstable(feature = "pin", issue = "49150")]
9191

9292
use fmt;
93-
use marker::{Sized, Unpin, Unsize};
93+
use marker::Sized;
9494
use ops::{Deref, DerefMut, CoerceUnsized};
9595

96+
#[doc(inline)]
97+
pub use marker::Unpin;
98+
9699
/// A pinned pointer.
97100
///
98101
/// This is a wrapper around a kind of pointer which makes that pointer "pin" its
@@ -103,71 +106,78 @@ use ops::{Deref, DerefMut, CoerceUnsized};
103106
///
104107
/// [`Unpin`]: ../../std/marker/trait.Unpin.html
105108
/// [`pin` module]: ../../std/pin/index.html
109+
//
110+
// Note: the derives below are allowed because they all only use `&P`, so they
111+
// cannot move the value behind `pointer`.
106112
#[unstable(feature = "pin", issue = "49150")]
107113
#[fundamental]
108114
#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
109115
pub struct Pin<P> {
110116
pointer: P,
111117
}
112118

113-
impl<P, T> Pin<P> where
114-
P: Deref<Target = T>,
115-
T: ?Sized + Unpin,
119+
impl<P: Deref> Pin<P>
120+
where
121+
P::Target: Unpin,
116122
{
117123
/// Construct a new `Pin` around a pointer to some data of a type that
118124
/// implements `Unpin`.
119125
#[unstable(feature = "pin", issue = "49150")]
126+
#[inline(always)]
120127
pub fn new(pointer: P) -> Pin<P> {
128+
// Safety: the value pointed to is `Unpin`, and so has no requirements
129+
// around pinning.
121130
unsafe { Pin::new_unchecked(pointer) }
122131
}
123132
}
124133

125-
impl<P, T> Pin<P> where
126-
P: Deref<Target = T>,
127-
T: ?Sized,
128-
{
134+
impl<P: Deref> Pin<P> {
129135
/// Construct a new `Pin` around a reference to some data of a type that
130136
/// may or may not implement `Unpin`.
131137
///
132138
/// # Safety
133139
///
134-
/// This constructor is unsafe because we cannot guarantee that the target data
135-
/// is properly pinned by this pointer. If the constructed `Pin<P>` does not guarantee
136-
/// that the data is "pinned," constructing a `Pin<P>` is undefined behavior and could lead
137-
/// to segmentation faults or worse.
140+
/// This constructor is unsafe because we cannot guarantee that the data
141+
/// pointed to by `pointer` is pinned. If the constructed `Pin<P>` does
142+
/// not guarantee that the data `P` points to is pinned, constructing a
143+
/// `Pin<P>` is undefined behavior.
144+
///
145+
/// If `pointer` dereferences to an `Unpin` type, `Pin::new` should be used
146+
/// instead.
138147
#[unstable(feature = "pin", issue = "49150")]
148+
#[inline(always)]
139149
pub unsafe fn new_unchecked(pointer: P) -> Pin<P> {
140150
Pin { pointer }
141151
}
142152

143-
144153
/// Get a pinned shared reference from this pinned pointer.
145154
#[unstable(feature = "pin", issue = "49150")]
146-
pub fn as_ref(this: &Pin<P>) -> Pin<&T> {
147-
unsafe { Pin::new_unchecked(&**this) }
155+
#[inline(always)]
156+
pub fn as_ref(self: &Pin<P>) -> Pin<&P::Target> {
157+
unsafe { Pin::new_unchecked(&**self) }
148158
}
149159
}
150160

151-
impl<P, T> Pin<P> where
152-
P: DerefMut<Target = T>,
153-
T: ?Sized,
154-
{
161+
impl<P: DerefMut> Pin<P> {
155162
/// Get a pinned mutable reference from this pinned pointer.
156163
#[unstable(feature = "pin", issue = "49150")]
157-
pub fn as_mut(this: &mut Pin<P>) -> Pin<&mut T> {
158-
unsafe { Pin::new_unchecked(&mut *this.pointer) }
164+
#[inline(always)]
165+
pub fn as_mut(self: &mut Pin<P>) -> Pin<&mut P::Target> {
166+
unsafe { Pin::new_unchecked(&mut *self.pointer) }
159167
}
160168

161169
/// Assign a new value to the memory behind the pinned reference.
162170
#[unstable(feature = "pin", issue = "49150")]
163-
pub fn set(this: Pin<&mut T>, value: T)
164-
where T: Sized,
171+
#[inline(always)]
172+
pub fn set(mut self: Pin<P>, value: P::Target)
173+
where
174+
P::Target: Sized,
165175
{
166-
*this.pointer = value;
176+
*self.pointer = value;
167177
}
168178
}
169179

170-
impl<'a, T> Pin<&'a T> {
180+
impl<'a, T: ?Sized> Pin<&'a T> {
171181
/// Construct a new pin by mapping the interior value.
172182
///
173183
/// For example, if you wanted to get a `Pin` of a field of something,
@@ -188,22 +198,57 @@ impl<'a, T> Pin<&'a T> {
188198
Pin::new_unchecked(new_pointer)
189199
}
190200

191-
/// Get a safe reference out of a pin.
201+
/// Get a shared reference out of a pin.
202+
///
203+
/// Note: `Pin` also implements `Deref` to the target, which can be used
204+
/// to access the inner value. However, `Deref` only provides a reference
205+
/// that lives for as long as the borrow of the `Pin`, not the lifetime of
206+
/// the `Pin` itself. This method allows turning the `Pin` into a reference
207+
/// with the same lifetime as the original `Pin`.
192208
#[unstable(feature = "pin", issue = "49150")]
193-
pub fn get(this: Pin<&'a T>) -> &'a T {
209+
#[inline(always)]
210+
pub fn get_ref(this: Pin<&'a T>) -> &'a T {
194211
this.pointer
195212
}
196213
}
197214

198215
impl<'a, T> Pin<&'a mut T> {
216+
/// Convert this `Pin<&mut T>` into a `Pin<&T>` with the same lifetime.
217+
#[unstable(feature = "pin", issue = "49150")]
218+
#[inline(always)]
219+
pub fn into_ref(this: Pin<&'a mut T>) -> Pin<&'a T> {
220+
Pin { pointer: this.pointer }
221+
}
222+
223+
/// Get a mutable reference to the data inside of this `Pin`.
224+
///
225+
/// This requires that the data inside this `Pin` is `Unpin`.
226+
///
227+
/// Note: `Pin` also implements `DerefMut` to the data, which can be used
228+
/// to access the inner value. However, `DerefMut` only provides a reference
229+
/// that lives for as long as the borrow of the `Pin`, not the lifetime of
230+
/// the `Pin` itself. This method allows turning the `Pin` into a reference
231+
/// with the same lifetime as the original `Pin`.
232+
#[unstable(feature = "pin", issue = "49150")]
233+
#[inline(always)]
234+
pub fn get_mut(this: Pin<&'a mut T>) -> &'a mut T
235+
where T: Unpin,
236+
{
237+
this.pointer
238+
}
239+
199240
/// Get a mutable reference to the data inside of this `Pin`.
200241
///
201242
/// # Safety
202243
///
203244
/// This function is unsafe. You must guarantee that you will never move
204245
/// the data out of the mutable reference you receive when you call this
205246
/// function, so that the invariants on the `Pin` type can be upheld.
247+
///
248+
/// If the underlying data is `Unpin`, `Pin::get_mut` should be used
249+
/// instead.
206250
#[unstable(feature = "pin", issue = "49150")]
251+
#[inline(always)]
207252
pub unsafe fn get_mut_unchecked(this: Pin<&'a mut T>) -> &'a mut T {
208253
this.pointer
209254
}
@@ -230,22 +275,19 @@ impl<'a, T> Pin<&'a mut T> {
230275
}
231276

232277
#[unstable(feature = "pin", issue = "49150")]
233-
impl<P, T> Deref for Pin<P> where
234-
P: Deref<Target = T>,
235-
T: ?Sized,
236-
{
237-
type Target = T;
238-
fn deref(&self) -> &T {
278+
impl<P: Deref> Deref for Pin<P> {
279+
type Target = P::Target;
280+
fn deref(&self) -> &P::Target {
239281
&*self.pointer
240282
}
241283
}
242284

243285
#[unstable(feature = "pin", issue = "49150")]
244-
impl<P, T> DerefMut for Pin<P> where
245-
P: DerefMut<Target = T>,
246-
T: ?Sized + Unpin,
286+
impl<P: DerefMut> DerefMut for Pin<P>
287+
where
288+
P::Target: Unpin
247289
{
248-
fn deref_mut(&mut self) -> &mut T {
290+
fn deref_mut(&mut self) -> &mut P::Target {
249291
&mut *self.pointer
250292
}
251293
}
@@ -271,14 +313,16 @@ impl<'a, P: fmt::Pointer> fmt::Pointer for Pin<P> {
271313
}
272314
}
273315

316+
// Note: this means that any impl of `CoerceUnsized` that allows coercing from
317+
// a type that impls `Deref<Target=impl !Unpin>` to a type that impls
318+
// `Deref<Target=Unpin>` is unsound. Any such impl would probably be unsound
319+
// for other reasons, though, so we just need to take care not to allow such
320+
// impls to land in std.
274321
#[unstable(feature = "pin", issue = "49150")]
275-
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Pin<&'a U>> for Pin<&'a T> {}
276-
277-
#[unstable(feature = "pin", issue = "49150")]
278-
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Pin<&'a mut U>> for Pin<&'a mut T> {}
279-
280-
#[unstable(feature = "pin", issue = "49150")]
281-
impl<'a, T: ?Sized> Unpin for Pin<&'a T> {}
322+
impl<'a, P, U> CoerceUnsized<Pin<U>> for Pin<P>
323+
where
324+
P: CoerceUnsized<U>,
325+
{}
282326

283327
#[unstable(feature = "pin", issue = "49150")]
284-
impl<'a, T: ?Sized> Unpin for Pin<&'a mut T> {}
328+
impl<'a, P> Unpin for Pin<P> {}

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

+5-6
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212

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

15-
use std::pin::PinBox;
16-
use std::pin::PinMut;
15+
use std::pin::Pin;
1716
use std::future::Future;
1817
use std::sync::{
1918
Arc,
@@ -49,7 +48,7 @@ fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) }
4948

5049
impl Future for WakeOnceThenComplete {
5150
type Output = ();
52-
fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<()> {
51+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<()> {
5352
if self.0 {
5453
Poll::Ready(())
5554
} else {
@@ -124,16 +123,16 @@ where
124123
F: FnOnce(u8) -> Fut,
125124
Fut: Future<Output = u8>,
126125
{
127-
let mut fut = PinBox::new(f(9));
126+
let mut fut = Box::pinned(f(9));
128127
let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) });
129128
let waker = local_waker_from_nonlocal(counter.clone());
130129
let spawner = &mut NoopSpawner;
131130
let cx = &mut Context::new(&waker, spawner);
132131

133132
assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst));
134-
assert_eq!(Poll::Pending, fut.as_pin_mut().poll(cx));
133+
assert_eq!(Poll::Pending, fut.as_mut().poll(cx));
135134
assert_eq!(1, counter.wakes.load(atomic::Ordering::SeqCst));
136-
assert_eq!(Poll::Ready(9), fut.as_pin_mut().poll(cx));
135+
assert_eq!(Poll::Ready(9), fut.as_mut().poll(cx));
137136
}
138137

139138
fn main() {

0 commit comments

Comments
 (0)