7
7
//! since moving an object with pointers to itself will invalidate them,
8
8
//! which could cause undefined behavior.
9
9
//!
10
- //! In order to prevent objects from moving, they must be * pinned*,
10
+ //! In order to prevent objects from moving, they must be pinned
11
11
//! by wrapping a pointer to the data in the [`Pin`] type. A pointer wrapped
12
12
//! in a `Pin` is otherwise equivalent to its normal version, e.g. `Pin<Box<T>>`
13
13
//! and `Box<T>` work the same way except that the first is pinning the value
14
14
//! of `T` in place.
15
15
//!
16
16
//! First of all, these are pointer types because pinned data mustn't be passed around by value
17
17
//! (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`],
19
19
//! which causes their contents to swap places in memory,
20
20
//! we need dedicated types that prohibit such operations.
21
21
//!
28
28
//! [`Pin`]: struct.Pin.html
29
29
//! [`Unpin`]: trait.Unpin.html
30
30
//! [`swap`]: ../../std/mem/fn.swap.html
31
- //! [`Box`]: ../boxed/struct.Box.html
31
+ //! [`Box`]: ../../std/ boxed/struct.Box.html
32
32
//!
33
33
//! # Examples
34
34
//!
66
66
//!
67
67
//! let slice = NonNull::from(&boxed.data);
68
68
//! // we know this is safe because modifying a field doesn't move the whole struct
69
- //! unsafe {
69
+ //! unsafe {
70
70
//! let mut_ref: Pin<&mut Self> = Pin::as_mut(&mut boxed);
71
71
//! Pin::get_mut_unchecked(mut_ref).slice = slice;
72
72
//! }
90
90
#![ unstable( feature = "pin" , issue = "49150" ) ]
91
91
92
92
use fmt;
93
- use marker:: { Sized , Unpin , Unsize } ;
93
+ use marker:: Sized ;
94
94
use ops:: { Deref , DerefMut , CoerceUnsized } ;
95
95
96
+ #[ doc( inline) ]
97
+ pub use marker:: Unpin ;
98
+
96
99
/// A pinned pointer.
97
100
///
98
101
/// This is a wrapper around a kind of pointer which makes that pointer "pin" its
@@ -103,71 +106,78 @@ use ops::{Deref, DerefMut, CoerceUnsized};
103
106
///
104
107
/// [`Unpin`]: ../../std/marker/trait.Unpin.html
105
108
/// [`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`.
106
112
#[ unstable( feature = "pin" , issue = "49150" ) ]
107
113
#[ fundamental]
108
114
#[ derive( Copy , Clone , Hash , Eq , PartialEq , Ord , PartialOrd ) ]
109
115
pub struct Pin < P > {
110
116
pointer : P ,
111
117
}
112
118
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 ,
116
122
{
117
123
/// Construct a new `Pin` around a pointer to some data of a type that
118
124
/// implements `Unpin`.
119
125
#[ unstable( feature = "pin" , issue = "49150" ) ]
126
+ #[ inline( always) ]
120
127
pub fn new ( pointer : P ) -> Pin < P > {
128
+ // Safety: the value pointed to is `Unpin`, and so has no requirements
129
+ // around pinning.
121
130
unsafe { Pin :: new_unchecked ( pointer) }
122
131
}
123
132
}
124
133
125
- impl < P , T > Pin < P > where
126
- P : Deref < Target = T > ,
127
- T : ?Sized ,
128
- {
134
+ impl < P : Deref > Pin < P > {
129
135
/// Construct a new `Pin` around a reference to some data of a type that
130
136
/// may or may not implement `Unpin`.
131
137
///
132
138
/// # Safety
133
139
///
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.
138
147
#[ unstable( feature = "pin" , issue = "49150" ) ]
148
+ #[ inline( always) ]
139
149
pub unsafe fn new_unchecked ( pointer : P ) -> Pin < P > {
140
150
Pin { pointer }
141
151
}
142
152
143
-
144
153
/// Get a pinned shared reference from this pinned pointer.
145
154
#[ 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 ) }
148
158
}
149
159
}
150
160
151
- impl < P , T > Pin < P > where
152
- P : DerefMut < Target = T > ,
153
- T : ?Sized ,
154
- {
161
+ impl < P : DerefMut > Pin < P > {
155
162
/// Get a pinned mutable reference from this pinned pointer.
156
163
#[ 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 ) }
159
167
}
160
168
161
169
/// Assign a new value to the memory behind the pinned reference.
162
170
#[ 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 ,
165
175
{
166
- * this . pointer = value;
176
+ * self . pointer = value;
167
177
}
168
178
}
169
179
170
- impl < ' a , T > Pin < & ' a T > {
180
+ impl < ' a , T : ? Sized > Pin < & ' a T > {
171
181
/// Construct a new pin by mapping the interior value.
172
182
///
173
183
/// For example, if you wanted to get a `Pin` of a field of something,
@@ -188,22 +198,57 @@ impl<'a, T> Pin<&'a T> {
188
198
Pin :: new_unchecked ( new_pointer)
189
199
}
190
200
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`.
192
208
#[ 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 {
194
211
this. pointer
195
212
}
196
213
}
197
214
198
215
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
+
199
240
/// Get a mutable reference to the data inside of this `Pin`.
200
241
///
201
242
/// # Safety
202
243
///
203
244
/// This function is unsafe. You must guarantee that you will never move
204
245
/// the data out of the mutable reference you receive when you call this
205
246
/// 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.
206
250
#[ unstable( feature = "pin" , issue = "49150" ) ]
251
+ #[ inline( always) ]
207
252
pub unsafe fn get_mut_unchecked ( this : Pin < & ' a mut T > ) -> & ' a mut T {
208
253
this. pointer
209
254
}
@@ -230,22 +275,19 @@ impl<'a, T> Pin<&'a mut T> {
230
275
}
231
276
232
277
#[ 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 {
239
281
& * self . pointer
240
282
}
241
283
}
242
284
243
285
#[ 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
247
289
{
248
- fn deref_mut ( & mut self ) -> & mut T {
290
+ fn deref_mut ( & mut self ) -> & mut P :: Target {
249
291
& mut * self . pointer
250
292
}
251
293
}
@@ -271,14 +313,16 @@ impl<'a, P: fmt::Pointer> fmt::Pointer for Pin<P> {
271
313
}
272
314
}
273
315
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.
274
321
#[ 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
+ { }
282
326
283
327
#[ unstable( feature = "pin" , issue = "49150" ) ]
284
- impl < ' a , T : ? Sized > Unpin for Pin < & ' a mut T > { }
328
+ impl < ' a , P > Unpin for Pin < P > { }
0 commit comments