]>
Commit | Line | Data |
---|---|---|
532ac7d7 | 1 | //! Types that pin data to its location in memory. |
b7449926 | 2 | //! |
dc9dc135 | 3 | //! It is sometimes useful to have objects that are guaranteed not to move, |
0bf4aa26 | 4 | //! in the sense that their placement in memory does not change, and can thus be relied upon. |
a1dfa0c6 | 5 | //! A prime example of such a scenario would be building self-referential structs, |
dc9dc135 XL |
6 | //! as moving an object with pointers to itself will invalidate them, which could cause undefined |
7 | //! behavior. | |
0bf4aa26 | 8 | //! |
cdc7bbd5 | 9 | //! At a high level, a <code>[Pin]\<P></code> ensures that the pointee of any pointer type |
3dfed10e XL |
10 | //! `P` has a stable location in memory, meaning it cannot be moved elsewhere |
11 | //! and its memory cannot be deallocated until it gets dropped. We say that the | |
12 | //! pointee is "pinned". Things get more subtle when discussing types that | |
13 | //! combine pinned with non-pinned data; [see below](#projections-and-structural-pinning) | |
14 | //! for more details. | |
0bf4aa26 | 15 | //! |
0731742a | 16 | //! By default, all types in Rust are movable. Rust allows passing all types by-value, |
cdc7bbd5 XL |
17 | //! and common smart-pointer types such as <code>[Box]\<T></code> and <code>[&mut] T</code> allow |
18 | //! replacing and moving the values they contain: you can move out of a <code>[Box]\<T></code>, | |
19 | //! or you can use [`mem::swap`]. <code>[Pin]\<P></code> wraps a pointer type `P`, so | |
20 | //! <code>[Pin]<[Box]\<T>></code> functions much like a regular <code>[Box]\<T></code>: | |
21 | //! when a <code>[Pin]<[Box]\<T>></code> gets dropped, so do its contents, and the memory gets | |
22 | //! deallocated. Similarly, <code>[Pin]<[&mut] T></code> is a lot like <code>[&mut] T</code>. | |
23 | //! However, <code>[Pin]\<P></code> does not let clients actually obtain a <code>[Box]\<T></code> | |
24 | //! or <code>[&mut] T</code> to pinned data, which implies that you cannot use operations such | |
25 | //! as [`mem::swap`]: | |
dc9dc135 | 26 | //! |
0731742a XL |
27 | //! ``` |
28 | //! use std::pin::Pin; | |
29 | //! fn swap_pins<T>(x: Pin<&mut T>, y: Pin<&mut T>) { | |
30 | //! // `mem::swap` needs `&mut T`, but we cannot get it. | |
31 | //! // We are stuck, we cannot swap the contents of these references. | |
32 | //! // We could use `Pin::get_unchecked_mut`, but that is unsafe for a reason: | |
33 | //! // we are not allowed to use it for moving things out of the `Pin`. | |
34 | //! } | |
35 | //! ``` | |
0bf4aa26 | 36 | //! |
cdc7bbd5 XL |
37 | //! It is worth reiterating that <code>[Pin]\<P></code> does *not* change the fact that a Rust |
38 | //! compiler considers all types movable. [`mem::swap`] remains callable for any `T`. Instead, | |
39 | //! <code>[Pin]\<P></code> prevents certain *values* (pointed to by pointers wrapped in | |
40 | //! <code>[Pin]\<P></code>) from being moved by making it impossible to call methods that require | |
41 | //! <code>[&mut] T</code> on them (like [`mem::swap`]). | |
42 | //! | |
43 | //! <code>[Pin]\<P></code> can be used to wrap any pointer type `P`, and as such it interacts with | |
44 | //! [`Deref`] and [`DerefMut`]. A <code>[Pin]\<P></code> where <code>P: [Deref]</code> should be | |
45 | //! considered as a "`P`-style pointer" to a pinned <code>P::[Target]</code> – so, a | |
46 | //! <code>[Pin]<[Box]\<T>></code> is an owned pointer to a pinned `T`, and a | |
47 | //! <code>[Pin]<[Rc]\<T>></code> is a reference-counted pointer to a pinned `T`. | |
48 | //! For correctness, <code>[Pin]\<P></code> relies on the implementations of [`Deref`] and | |
dc9dc135 XL |
49 | //! [`DerefMut`] not to move out of their `self` parameter, and only ever to |
50 | //! return a pointer to pinned data when they are called on a pinned pointer. | |
0bf4aa26 | 51 | //! |
0731742a | 52 | //! # `Unpin` |
0bf4aa26 | 53 | //! |
dc9dc135 XL |
54 | //! Many types are always freely movable, even when pinned, because they do not |
55 | //! rely on having a stable address. This includes all the basic types (like | |
416331ca | 56 | //! [`bool`], [`i32`], and references) as well as types consisting solely of these |
dc9dc135 | 57 | //! types. Types that do not care about pinning implement the [`Unpin`] |
cdc7bbd5 XL |
58 | //! auto-trait, which cancels the effect of <code>[Pin]\<P></code>. For <code>T: [Unpin]</code>, |
59 | //! <code>[Pin]<[Box]\<T>></code> and <code>[Box]\<T></code> function identically, as do | |
60 | //! <code>[Pin]<[&mut] T></code> and <code>[&mut] T</code>. | |
0731742a | 61 | //! |
cdc7bbd5 XL |
62 | //! Note that pinning and [`Unpin`] only affect the pointed-to type <code>P::[Target]</code>, |
63 | //! not the pointer type `P` itself that got wrapped in <code>[Pin]\<P></code>. For example, | |
64 | //! whether or not <code>[Box]\<T></code> is [`Unpin`] has no effect on the behavior of | |
65 | //! <code>[Pin]<[Box]\<T>></code> (here, `T` is the pointed-to type). | |
0bf4aa26 | 66 | //! |
0731742a XL |
67 | //! # Example: self-referential struct |
68 | //! | |
3dfed10e | 69 | //! Before we go into more details to explain the guarantees and choices |
cdc7bbd5 | 70 | //! associated with <code>[Pin]\<P></code>, we discuss some examples for how it might be used. |
3dfed10e XL |
71 | //! Feel free to [skip to where the theoretical discussion continues](#drop-guarantee). |
72 | //! | |
0731742a | 73 | //! ```rust |
0bf4aa26 | 74 | //! use std::pin::Pin; |
0731742a | 75 | //! use std::marker::PhantomPinned; |
0bf4aa26 XL |
76 | //! use std::ptr::NonNull; |
77 | //! | |
dc9dc135 | 78 | //! // This is a self-referential struct because the slice field points to the data field. |
0bf4aa26 | 79 | //! // We cannot inform the compiler about that with a normal reference, |
dc9dc135 XL |
80 | //! // as this pattern cannot be described with the usual borrowing rules. |
81 | //! // Instead we use a raw pointer, though one which is known not to be null, | |
82 | //! // as we know it's pointing at the string. | |
0bf4aa26 XL |
83 | //! struct Unmovable { |
84 | //! data: String, | |
85 | //! slice: NonNull<String>, | |
0731742a | 86 | //! _pin: PhantomPinned, |
0bf4aa26 XL |
87 | //! } |
88 | //! | |
89 | //! impl Unmovable { | |
90 | //! // To ensure the data doesn't move when the function returns, | |
91 | //! // we place it in the heap where it will stay for the lifetime of the object, | |
92 | //! // and the only way to access it would be through a pointer to it. | |
93 | //! fn new(data: String) -> Pin<Box<Self>> { | |
94 | //! let res = Unmovable { | |
95 | //! data, | |
96 | //! // we only create the pointer once the data is in place | |
97 | //! // otherwise it will have already moved before we even started | |
98 | //! slice: NonNull::dangling(), | |
0731742a | 99 | //! _pin: PhantomPinned, |
0bf4aa26 | 100 | //! }; |
0731742a | 101 | //! let mut boxed = Box::pin(res); |
0bf4aa26 XL |
102 | //! |
103 | //! let slice = NonNull::from(&boxed.data); | |
104 | //! // we know this is safe because modifying a field doesn't move the whole struct | |
105 | //! unsafe { | |
106 | //! let mut_ref: Pin<&mut Self> = Pin::as_mut(&mut boxed); | |
0731742a | 107 | //! Pin::get_unchecked_mut(mut_ref).slice = slice; |
0bf4aa26 XL |
108 | //! } |
109 | //! boxed | |
110 | //! } | |
111 | //! } | |
112 | //! | |
113 | //! let unmoved = Unmovable::new("hello".to_string()); | |
114 | //! // The pointer should point to the correct location, | |
115 | //! // so long as the struct hasn't moved. | |
116 | //! // Meanwhile, we are free to move the pointer around. | |
117 | //! # #[allow(unused_mut)] | |
118 | //! let mut still_unmoved = unmoved; | |
119 | //! assert_eq!(still_unmoved.slice, NonNull::from(&still_unmoved.data)); | |
120 | //! | |
121 | //! // Since our type doesn't implement Unpin, this will fail to compile: | |
532ac7d7 | 122 | //! // let mut new_unmoved = Unmovable::new("world".to_string()); |
0bf4aa26 XL |
123 | //! // std::mem::swap(&mut *still_unmoved, &mut *new_unmoved); |
124 | //! ``` | |
0731742a XL |
125 | //! |
126 | //! # Example: intrusive doubly-linked list | |
127 | //! | |
128 | //! In an intrusive doubly-linked list, the collection does not actually allocate | |
129 | //! the memory for the elements itself. Allocation is controlled by the clients, | |
130 | //! and elements can live on a stack frame that lives shorter than the collection does. | |
131 | //! | |
132 | //! To make this work, every element has pointers to its predecessor and successor in | |
133 | //! the list. Elements can only be added when they are pinned, because moving the elements | |
cdc7bbd5 | 134 | //! around would invalidate the pointers. Moreover, the [`Drop`][Drop] implementation of a linked |
0731742a XL |
135 | //! list element will patch the pointers of its predecessor and successor to remove itself |
136 | //! from the list. | |
137 | //! | |
416331ca XL |
138 | //! Crucially, we have to be able to rely on [`drop`] being called. If an element |
139 | //! could be deallocated or otherwise invalidated without calling [`drop`], the pointers into it | |
3dfed10e | 140 | //! from its neighboring elements would become invalid, which would break the data structure. |
0731742a | 141 | //! |
416331ca | 142 | //! Therefore, pinning also comes with a [`drop`]-related guarantee. |
0731742a XL |
143 | //! |
144 | //! # `Drop` guarantee | |
145 | //! | |
146 | //! The purpose of pinning is to be able to rely on the placement of some data in memory. | |
147 | //! To make this work, not just moving the data is restricted; deallocating, repurposing, or | |
148 | //! otherwise invalidating the memory used to store the data is restricted, too. | |
149 | //! Concretely, for pinned data you have to maintain the invariant | |
dc9dc135 | 150 | //! that *its memory will not get invalidated or repurposed from the moment it gets pinned until |
f9f354fc XL |
151 | //! when [`drop`] is called*. Only once [`drop`] returns or panics, the memory may be reused. |
152 | //! | |
153 | //! Memory can be "invalidated" by deallocation, but also by | |
cdc7bbd5 XL |
154 | //! replacing a <code>[Some]\(v)</code> by [`None`], or calling [`Vec::set_len`] to "kill" some |
155 | //! elements off of a vector. It can be repurposed by using [`ptr::write`] to overwrite it without | |
f9f354fc | 156 | //! calling the destructor first. None of this is allowed for pinned data without calling [`drop`]. |
0731742a XL |
157 | //! |
158 | //! This is exactly the kind of guarantee that the intrusive linked list from the previous | |
159 | //! section needs to function correctly. | |
160 | //! | |
161 | //! Notice that this guarantee does *not* mean that memory does not leak! It is still | |
94222f64 | 162 | //! completely okay to not ever call [`drop`] on a pinned element (e.g., you can still |
cdc7bbd5 | 163 | //! call [`mem::forget`] on a <code>[Pin]<[Box]\<T>></code>). In the example of the doubly-linked |
94222f64 | 164 | //! list, that element would just stay in the list. However you must not free or reuse the storage |
416331ca | 165 | //! *without calling [`drop`]*. |
0731742a XL |
166 | //! |
167 | //! # `Drop` implementation | |
168 | //! | |
169 | //! If your type uses pinning (such as the two examples above), you have to be careful | |
cdc7bbd5 | 170 | //! when implementing [`Drop`][Drop]. The [`drop`] function takes <code>[&mut] self</code>, but this |
0731742a | 171 | //! is called *even if your type was previously pinned*! It is as if the |
416331ca | 172 | //! compiler automatically called [`Pin::get_unchecked_mut`]. |
0731742a | 173 | //! |
48663c56 XL |
174 | //! This can never cause a problem in safe code because implementing a type that |
175 | //! relies on pinning requires unsafe code, but be aware that deciding to make | |
176 | //! use of pinning in your type (for example by implementing some operation on | |
cdc7bbd5 | 177 | //! <code>[Pin]<[&]Self></code> or <code>[Pin]<[&mut] Self></code>) has consequences for your |
04454e1e | 178 | //! [`Drop`][Drop] implementation as well: if an element of your type could have been pinned, |
cdc7bbd5 | 179 | //! you must treat [`Drop`][Drop] as implicitly taking <code>[Pin]<[&mut] Self></code>. |
0731742a | 180 | //! |
cdc7bbd5 | 181 | //! For example, you could implement [`Drop`][Drop] as follows: |
416331ca | 182 | //! |
dc9dc135 XL |
183 | //! ```rust,no_run |
184 | //! # use std::pin::Pin; | |
185 | //! # struct Type { } | |
186 | //! impl Drop for Type { | |
187 | //! fn drop(&mut self) { | |
188 | //! // `new_unchecked` is okay because we know this value is never used | |
189 | //! // again after being dropped. | |
190 | //! inner_drop(unsafe { Pin::new_unchecked(self)}); | |
191 | //! fn inner_drop(this: Pin<&mut Type>) { | |
192 | //! // Actual drop code goes here. | |
193 | //! } | |
194 | //! } | |
195 | //! } | |
196 | //! ``` | |
416331ca XL |
197 | //! |
198 | //! The function `inner_drop` has the type that [`drop`] *should* have, so this makes sure that | |
dc9dc135 XL |
199 | //! you do not accidentally use `self`/`this` in a way that is in conflict with pinning. |
200 | //! | |
201 | //! Moreover, if your type is `#[repr(packed)]`, the compiler will automatically | |
416331ca XL |
202 | //! move fields around to be able to drop them. It might even do |
203 | //! that for fields that happen to be sufficiently aligned. As a consequence, you cannot use | |
0731742a XL |
204 | //! pinning with a `#[repr(packed)]` type. |
205 | //! | |
206 | //! # Projections and Structural Pinning | |
207 | //! | |
dc9dc135 | 208 | //! When working with pinned structs, the question arises how one can access the |
cdc7bbd5 | 209 | //! fields of that struct in a method that takes just <code>[Pin]<[&mut] Struct></code>. |
dc9dc135 | 210 | //! The usual approach is to write helper methods (so called *projections*) |
cdc7bbd5 XL |
211 | //! that turn <code>[Pin]<[&mut] Struct></code> into a reference to the field, but what type should |
212 | //! that reference have? Is it <code>[Pin]<[&mut] Field></code> or <code>[&mut] Field</code>? | |
dc9dc135 | 213 | //! The same question arises with the fields of an `enum`, and also when considering |
cdc7bbd5 XL |
214 | //! container/wrapper types such as <code>[Vec]\<T></code>, <code>[Box]\<T></code>, |
215 | //! or <code>[RefCell]\<T></code>. (This question applies to both mutable and shared references, | |
216 | //! we just use the more common case of mutable references here for illustration.) | |
dc9dc135 | 217 | //! |
cdc7bbd5 XL |
218 | //! It turns out that it is actually up to the author of the data structure to decide whether |
219 | //! the pinned projection for a particular field turns <code>[Pin]<[&mut] Struct></code> | |
220 | //! into <code>[Pin]<[&mut] Field></code> or <code>[&mut] Field</code>. There are some | |
dc9dc135 XL |
221 | //! constraints though, and the most important constraint is *consistency*: |
222 | //! every field can be *either* projected to a pinned reference, *or* have | |
223 | //! pinning removed as part of the projection. If both are done for the same field, | |
224 | //! that will likely be unsound! | |
225 | //! | |
226 | //! As the author of a data structure you get to decide for each field whether pinning | |
227 | //! "propagates" to this field or not. Pinning that propagates is also called "structural", | |
228 | //! because it follows the structure of the type. | |
229 | //! In the following subsections, we describe the considerations that have to be made | |
230 | //! for either choice. | |
231 | //! | |
232 | //! ## Pinning *is not* structural for `field` | |
233 | //! | |
234 | //! It may seem counter-intuitive that the field of a pinned struct might not be pinned, | |
cdc7bbd5 | 235 | //! but that is actually the easiest choice: if a <code>[Pin]<[&mut] Field></code> is never created, |
dc9dc135 XL |
236 | //! nothing can go wrong! So, if you decide that some field does not have structural pinning, |
237 | //! all you have to ensure is that you never create a pinned reference to that field. | |
238 | //! | |
239 | //! Fields without structural pinning may have a projection method that turns | |
cdc7bbd5 | 240 | //! <code>[Pin]<[&mut] Struct></code> into <code>[&mut] Field</code>: |
416331ca | 241 | //! |
dc9dc135 XL |
242 | //! ```rust,no_run |
243 | //! # use std::pin::Pin; | |
244 | //! # type Field = i32; | |
245 | //! # struct Struct { field: Field } | |
246 | //! impl Struct { | |
e1599b0c | 247 | //! fn pin_get_field(self: Pin<&mut Self>) -> &mut Field { |
dc9dc135 XL |
248 | //! // This is okay because `field` is never considered pinned. |
249 | //! unsafe { &mut self.get_unchecked_mut().field } | |
250 | //! } | |
251 | //! } | |
252 | //! ``` | |
0731742a | 253 | //! |
cdc7bbd5 | 254 | //! You may also <code>impl [Unpin] for Struct</code> *even if* the type of `field` |
416331ca | 255 | //! is not [`Unpin`]. What that type thinks about pinning is not relevant |
cdc7bbd5 | 256 | //! when no <code>[Pin]<[&mut] Field></code> is ever created. |
dc9dc135 XL |
257 | //! |
258 | //! ## Pinning *is* structural for `field` | |
259 | //! | |
260 | //! The other option is to decide that pinning is "structural" for `field`, | |
261 | //! meaning that if the struct is pinned then so is the field. | |
262 | //! | |
cdc7bbd5 | 263 | //! This allows writing a projection that creates a <code>[Pin]<[&mut] Field></code>, thus |
dc9dc135 | 264 | //! witnessing that the field is pinned: |
416331ca | 265 | //! |
dc9dc135 XL |
266 | //! ```rust,no_run |
267 | //! # use std::pin::Pin; | |
268 | //! # type Field = i32; | |
269 | //! # struct Struct { field: Field } | |
270 | //! impl Struct { | |
e1599b0c | 271 | //! fn pin_get_field(self: Pin<&mut Self>) -> Pin<&mut Field> { |
dc9dc135 XL |
272 | //! // This is okay because `field` is pinned when `self` is. |
273 | //! unsafe { self.map_unchecked_mut(|s| &mut s.field) } | |
274 | //! } | |
275 | //! } | |
276 | //! ``` | |
0731742a | 277 | //! |
dc9dc135 | 278 | //! However, structural pinning comes with a few extra requirements: |
0731742a | 279 | //! |
dc9dc135 | 280 | //! 1. The struct must only be [`Unpin`] if all the structural fields are |
416331ca | 281 | //! [`Unpin`]. This is the default, but [`Unpin`] is a safe trait, so as the author of |
dc9dc135 | 282 | //! the struct it is your responsibility *not* to add something like |
cdc7bbd5 | 283 | //! <code>impl\<T> [Unpin] for Struct\<T></code>. (Notice that adding a projection operation |
416331ca | 284 | //! requires unsafe code, so the fact that [`Unpin`] is a safe trait does not break |
cdc7bbd5 | 285 | //! the principle that you only have to worry about any of this if you use [`unsafe`].) |
dc9dc135 | 286 | //! 2. The destructor of the struct must not move structural fields out of its argument. This |
cdc7bbd5 XL |
287 | //! is the exact point that was raised in the [previous section][drop-impl]: [`drop`] takes |
288 | //! <code>[&mut] self</code>, but the struct (and hence its fields) might have been pinned | |
289 | //! before. You have to guarantee that you do not move a field inside your [`Drop`][Drop] | |
290 | //! implementation. In particular, as explained previously, this means that your struct | |
291 | //! must *not* be `#[repr(packed)]`. | |
416331ca | 292 | //! See that section for how to write [`drop`] in a way that the compiler can help you |
dc9dc135 | 293 | //! not accidentally break pinning. |
0731742a | 294 | //! 3. You must make sure that you uphold the [`Drop` guarantee][drop-guarantee]: |
dc9dc135 | 295 | //! once your struct is pinned, the memory that contains the |
0731742a | 296 | //! content is not overwritten or deallocated without calling the content's destructors. |
cdc7bbd5 XL |
297 | //! This can be tricky, as witnessed by <code>[VecDeque]\<T></code>: the destructor of |
298 | //! <code>[VecDeque]\<T></code> can fail to call [`drop`] on all elements if one of the | |
299 | //! destructors panics. This violates the [`Drop`][Drop] guarantee, because it can lead to | |
300 | //! elements being deallocated without their destructor being called. | |
301 | //! (<code>[VecDeque]\<T></code> has no pinning projections, so this | |
0731742a XL |
302 | //! does not cause unsoundness.) |
303 | //! 4. You must not offer any other operations that could lead to data being moved out of | |
dc9dc135 | 304 | //! the structural fields when your type is pinned. For example, if the struct contains an |
cdc7bbd5 XL |
305 | //! <code>[Option]\<T></code> and there is a [`take`][Option::take]-like operation with type |
306 | //! <code>fn([Pin]<[&mut] Struct\<T>>) -> [Option]\<T></code>, | |
307 | //! that operation can be used to move a `T` out of a pinned `Struct<T>` – which means | |
dc9dc135 | 308 | //! pinning cannot be structural for the field holding this data. |
0731742a | 309 | //! |
cdc7bbd5 XL |
310 | //! For a more complex example of moving data out of a pinned type, |
311 | //! imagine if <code>[RefCell]\<T></code> had a method | |
312 | //! <code>fn get_pin_mut(self: [Pin]<[&mut] Self>) -> [Pin]<[&mut] T></code>. | |
0731742a XL |
313 | //! Then we could do the following: |
314 | //! ```compile_fail | |
532ac7d7 | 315 | //! fn exploit_ref_cell<T>(rc: Pin<&mut RefCell<T>>) { |
0731742a XL |
316 | //! { let p = rc.as_mut().get_pin_mut(); } // Here we get pinned access to the `T`. |
317 | //! let rc_shr: &RefCell<T> = rc.into_ref().get_ref(); | |
318 | //! let b = rc_shr.borrow_mut(); | |
319 | //! let content = &mut *b; // And here we have `&mut T` to the same data. | |
320 | //! } | |
321 | //! ``` | |
cdc7bbd5 XL |
322 | //! This is catastrophic, it means we can first pin the content of the |
323 | //! <code>[RefCell]\<T></code> (using <code>[RefCell]::get_pin_mut</code>) and then move that | |
324 | //! content using the mutable reference we got later. | |
0731742a | 325 | //! |
dc9dc135 XL |
326 | //! ## Examples |
327 | //! | |
cdc7bbd5 XL |
328 | //! For a type like <code>[Vec]\<T></code>, both possibilities (structural pinning or not) make |
329 | //! sense. A <code>[Vec]\<T></code> with structural pinning could have `get_pin`/`get_pin_mut` | |
330 | //! methods to get pinned references to elements. However, it could *not* allow calling | |
331 | //! [`pop`][Vec::pop] on a pinned <code>[Vec]\<T></code> because that would move the (structurally | |
332 | //! pinned) contents! Nor could it allow [`push`][Vec::push], which might reallocate and thus also | |
333 | //! move the contents. | |
416331ca | 334 | //! |
cdc7bbd5 XL |
335 | //! A <code>[Vec]\<T></code> without structural pinning could |
336 | //! <code>impl\<T> [Unpin] for [Vec]\<T></code>, because the contents are never pinned | |
337 | //! and the <code>[Vec]\<T></code> itself is fine with being moved as well. | |
dc9dc135 | 338 | //! At that point pinning just has no effect on the vector at all. |
0731742a XL |
339 | //! |
340 | //! In the standard library, pointer types generally do not have structural pinning, | |
cdc7bbd5 XL |
341 | //! and thus they do not offer pinning projections. This is why <code>[Box]\<T>: [Unpin]</code> |
342 | //! holds for all `T`. It makes sense to do this for pointer types, because moving the | |
343 | //! <code>[Box]\<T></code> does not actually move the `T`: the <code>[Box]\<T></code> can be freely | |
344 | //! movable (aka [`Unpin`]) even if the `T` is not. In fact, even <code>[Pin]<[Box]\<T>></code> and | |
345 | //! <code>[Pin]<[&mut] T></code> are always [`Unpin`] themselves, for the same reason: | |
346 | //! their contents (the `T`) are pinned, but the pointers themselves can be moved without moving | |
347 | //! the pinned data. For both <code>[Box]\<T></code> and <code>[Pin]<[Box]\<T>></code>, | |
348 | //! whether the content is pinned is entirely independent of whether the | |
416331ca | 349 | //! pointer is pinned, meaning pinning is *not* structural. |
0731742a | 350 | //! |
dc9dc135 | 351 | //! When implementing a [`Future`] combinator, you will usually need structural pinning |
416331ca | 352 | //! for the nested futures, as you need to get pinned references to them to call [`poll`]. |
dc9dc135 XL |
353 | //! But if your combinator contains any other data that does not need to be pinned, |
354 | //! you can make those fields not structural and hence freely access them with a | |
cdc7bbd5 | 355 | //! mutable reference even when you just have <code>[Pin]<[&mut] Self></code> (such as in your own |
416331ca | 356 | //! [`poll`] implementation). |
dc9dc135 | 357 | //! |
cdc7bbd5 XL |
358 | //! [Deref]: crate::ops::Deref "ops::Deref" |
359 | //! [`Deref`]: crate::ops::Deref "ops::Deref" | |
360 | //! [Target]: crate::ops::Deref::Target "ops::Deref::Target" | |
361 | //! [`DerefMut`]: crate::ops::DerefMut "ops::DerefMut" | |
362 | //! [`mem::swap`]: crate::mem::swap "mem::swap" | |
363 | //! [`mem::forget`]: crate::mem::forget "mem::forget" | |
364 | //! [Vec]: ../../std/vec/struct.Vec.html "Vec" | |
365 | //! [`Vec::set_len`]: ../../std/vec/struct.Vec.html#method.set_len "Vec::set_len" | |
366 | //! [Box]: ../../std/boxed/struct.Box.html "Box" | |
367 | //! [Vec::pop]: ../../std/vec/struct.Vec.html#method.pop "Vec::pop" | |
368 | //! [Vec::push]: ../../std/vec/struct.Vec.html#method.push "Vec::push" | |
369 | //! [Rc]: ../../std/rc/struct.Rc.html "rc::Rc" | |
370 | //! [RefCell]: crate::cell::RefCell "cell::RefCell" | |
c295e0f8 | 371 | //! [`drop`]: Drop::drop |
cdc7bbd5 XL |
372 | //! [VecDeque]: ../../std/collections/struct.VecDeque.html "collections::VecDeque" |
373 | //! [`ptr::write`]: crate::ptr::write "ptr::write" | |
374 | //! [`Future`]: crate::future::Future "future::Future" | |
0731742a XL |
375 | //! [drop-impl]: #drop-implementation |
376 | //! [drop-guarantee]: #drop-guarantee | |
cdc7bbd5 | 377 | //! [`poll`]: crate::future::Future::poll "future::Future::poll" |
c295e0f8 XL |
378 | //! [&]: reference "shared reference" |
379 | //! [&mut]: reference "mutable reference" | |
cdc7bbd5 | 380 | //! [`unsafe`]: ../../std/keyword.unsafe.html "keyword unsafe" |
b7449926 | 381 | |
0731742a | 382 | #![stable(feature = "pin", since = "1.33.0")] |
b7449926 | 383 | |
60c5eb7d | 384 | use crate::cmp::{self, PartialEq, PartialOrd}; |
48663c56 | 385 | use crate::fmt; |
60c5eb7d | 386 | use crate::hash::{Hash, Hasher}; |
48663c56 | 387 | use crate::marker::{Sized, Unpin}; |
60c5eb7d | 388 | use crate::ops::{CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Receiver}; |
0bf4aa26 XL |
389 | |
390 | /// A pinned pointer. | |
b7449926 | 391 | /// |
0bf4aa26 XL |
392 | /// This is a wrapper around a kind of pointer which makes that pointer "pin" its |
393 | /// value in place, preventing the value referenced by that pointer from being moved | |
394 | /// unless it implements [`Unpin`]. | |
b7449926 | 395 | /// |
49aad941 FG |
396 | /// `Pin<P>` is guaranteed to have the same memory layout and ABI as `P`. |
397 | /// | |
48663c56 | 398 | /// *See the [`pin` module] documentation for an explanation of pinning.* |
b7449926 | 399 | /// |
3dfed10e | 400 | /// [`pin` module]: self |
0bf4aa26 | 401 | // |
60c5eb7d XL |
402 | // Note: the `Clone` derive below causes unsoundness as it's possible to implement |
403 | // `Clone` for mutable references. | |
404 | // See <https://internals.rust-lang.org/t/unsoundness-in-pin/11311> for more details. | |
0731742a | 405 | #[stable(feature = "pin", since = "1.33.0")] |
532ac7d7 | 406 | #[lang = "pin"] |
b7449926 | 407 | #[fundamental] |
0731742a | 408 | #[repr(transparent)] |
60c5eb7d | 409 | #[derive(Copy, Clone)] |
0bf4aa26 | 410 | pub struct Pin<P> { |
5099ac24 FG |
411 | // FIXME(#93176): this field is made `#[unstable] #[doc(hidden)] pub` to: |
412 | // - deter downstream users from accessing it (which would be unsound!), | |
413 | // - let the `pin!` macro access it (such a macro requires using struct | |
414 | // literal syntax in order to benefit from lifetime extension). | |
415 | // Long-term, `unsafe` fields or macro hygiene are expected to offer more robust alternatives. | |
416 | #[unstable(feature = "unsafe_pin_internals", issue = "none")] | |
417 | #[doc(hidden)] | |
418 | pub pointer: P, | |
b7449926 XL |
419 | } |
420 | ||
60c5eb7d XL |
421 | // The following implementations aren't derived in order to avoid soundness |
422 | // issues. `&self.pointer` should not be accessible to untrusted trait | |
423 | // implementations. | |
424 | // | |
425 | // See <https://internals.rust-lang.org/t/unsoundness-in-pin/11311/73> for more details. | |
426 | ||
427 | #[stable(feature = "pin_trait_impls", since = "1.41.0")] | |
428 | impl<P: Deref, Q: Deref> PartialEq<Pin<Q>> for Pin<P> | |
9fa01778 | 429 | where |
60c5eb7d | 430 | P::Target: PartialEq<Q::Target>, |
9fa01778 XL |
431 | { |
432 | fn eq(&self, other: &Pin<Q>) -> bool { | |
60c5eb7d | 433 | P::Target::eq(self, other) |
9fa01778 XL |
434 | } |
435 | ||
436 | fn ne(&self, other: &Pin<Q>) -> bool { | |
60c5eb7d | 437 | P::Target::ne(self, other) |
9fa01778 XL |
438 | } |
439 | } | |
440 | ||
60c5eb7d XL |
441 | #[stable(feature = "pin_trait_impls", since = "1.41.0")] |
442 | impl<P: Deref<Target: Eq>> Eq for Pin<P> {} | |
443 | ||
444 | #[stable(feature = "pin_trait_impls", since = "1.41.0")] | |
445 | impl<P: Deref, Q: Deref> PartialOrd<Pin<Q>> for Pin<P> | |
9fa01778 | 446 | where |
60c5eb7d | 447 | P::Target: PartialOrd<Q::Target>, |
9fa01778 XL |
448 | { |
449 | fn partial_cmp(&self, other: &Pin<Q>) -> Option<cmp::Ordering> { | |
60c5eb7d | 450 | P::Target::partial_cmp(self, other) |
9fa01778 XL |
451 | } |
452 | ||
453 | fn lt(&self, other: &Pin<Q>) -> bool { | |
60c5eb7d | 454 | P::Target::lt(self, other) |
9fa01778 XL |
455 | } |
456 | ||
457 | fn le(&self, other: &Pin<Q>) -> bool { | |
60c5eb7d | 458 | P::Target::le(self, other) |
9fa01778 XL |
459 | } |
460 | ||
461 | fn gt(&self, other: &Pin<Q>) -> bool { | |
60c5eb7d | 462 | P::Target::gt(self, other) |
9fa01778 XL |
463 | } |
464 | ||
465 | fn ge(&self, other: &Pin<Q>) -> bool { | |
60c5eb7d XL |
466 | P::Target::ge(self, other) |
467 | } | |
468 | } | |
469 | ||
470 | #[stable(feature = "pin_trait_impls", since = "1.41.0")] | |
471 | impl<P: Deref<Target: Ord>> Ord for Pin<P> { | |
472 | fn cmp(&self, other: &Self) -> cmp::Ordering { | |
473 | P::Target::cmp(self, other) | |
474 | } | |
475 | } | |
476 | ||
477 | #[stable(feature = "pin_trait_impls", since = "1.41.0")] | |
478 | impl<P: Deref<Target: Hash>> Hash for Pin<P> { | |
479 | fn hash<H: Hasher>(&self, state: &mut H) { | |
480 | P::Target::hash(self, state); | |
9fa01778 XL |
481 | } |
482 | } | |
483 | ||
416331ca | 484 | impl<P: Deref<Target: Unpin>> Pin<P> { |
0731742a XL |
485 | /// Construct a new `Pin<P>` around a pointer to some data of a type that |
486 | /// implements [`Unpin`]. | |
487 | /// | |
488 | /// Unlike `Pin::new_unchecked`, this method is safe because the pointer | |
489 | /// `P` dereferences to an [`Unpin`] type, which cancels the pinning guarantees. | |
9c376795 FG |
490 | /// |
491 | /// # Examples | |
492 | /// | |
493 | /// ``` | |
494 | /// use std::pin::Pin; | |
495 | /// | |
496 | /// let mut val: u8 = 5; | |
497 | /// // We can pin the value, since it doesn't care about being moved | |
498 | /// let mut pinned: Pin<&mut u8> = Pin::new(&mut val); | |
499 | /// ``` | |
0bf4aa26 | 500 | #[inline(always)] |
1b1a35ee XL |
501 | #[rustc_const_unstable(feature = "const_pin", issue = "76654")] |
502 | #[stable(feature = "pin", since = "1.33.0")] | |
503 | pub const fn new(pointer: P) -> Pin<P> { | |
504 | // SAFETY: the value pointed to is `Unpin`, and so has no requirements | |
0bf4aa26 XL |
505 | // around pinning. |
506 | unsafe { Pin::new_unchecked(pointer) } | |
b7449926 | 507 | } |
48663c56 XL |
508 | |
509 | /// Unwraps this `Pin<P>` returning the underlying pointer. | |
510 | /// | |
9c376795 | 511 | /// This requires that the data inside this `Pin` implements [`Unpin`] so that we |
48663c56 | 512 | /// can ignore the pinning invariants when unwrapping it. |
9c376795 FG |
513 | /// |
514 | /// # Examples | |
515 | /// | |
516 | /// ``` | |
517 | /// use std::pin::Pin; | |
518 | /// | |
519 | /// let mut val: u8 = 5; | |
520 | /// let pinned: Pin<&mut u8> = Pin::new(&mut val); | |
521 | /// // Unwrap the pin to get a reference to the value | |
522 | /// let r = Pin::into_inner(pinned); | |
523 | /// assert_eq!(*r, 5); | |
524 | /// ``` | |
48663c56 | 525 | #[inline(always)] |
1b1a35ee XL |
526 | #[rustc_const_unstable(feature = "const_pin", issue = "76654")] |
527 | #[stable(feature = "pin_into_inner", since = "1.39.0")] | |
528 | pub const fn into_inner(pin: Pin<P>) -> P { | |
48663c56 XL |
529 | pin.pointer |
530 | } | |
0bf4aa26 | 531 | } |
b7449926 | 532 | |
0bf4aa26 | 533 | impl<P: Deref> Pin<P> { |
0731742a | 534 | /// Construct a new `Pin<P>` around a reference to some data of a type that |
0bf4aa26 XL |
535 | /// may or may not implement `Unpin`. |
536 | /// | |
0731742a XL |
537 | /// If `pointer` dereferences to an `Unpin` type, `Pin::new` should be used |
538 | /// instead. | |
539 | /// | |
0bf4aa26 XL |
540 | /// # Safety |
541 | /// | |
542 | /// This constructor is unsafe because we cannot guarantee that the data | |
0731742a XL |
543 | /// pointed to by `pointer` is pinned, meaning that the data will not be moved or |
544 | /// its storage invalidated until it gets dropped. If the constructed `Pin<P>` does | |
545 | /// not guarantee that the data `P` points to is pinned, that is a violation of | |
546 | /// the API contract and may lead to undefined behavior in later (safe) operations. | |
0bf4aa26 | 547 | /// |
0731742a XL |
548 | /// By using this method, you are making a promise about the `P::Deref` and |
549 | /// `P::DerefMut` implementations, if they exist. Most importantly, they | |
550 | /// must not move out of their `self` arguments: `Pin::as_mut` and `Pin::as_ref` | |
551 | /// will call `DerefMut::deref_mut` and `Deref::deref` *on the pinned pointer* | |
552 | /// and expect these methods to uphold the pinning invariants. | |
553 | /// Moreover, by calling this method you promise that the reference `P` | |
554 | /// dereferences to will not be moved out of again; in particular, it | |
555 | /// must not be possible to obtain a `&mut P::Target` and then | |
556 | /// move out of that reference (using, for example [`mem::swap`]). | |
557 | /// | |
558 | /// For example, calling `Pin::new_unchecked` on an `&'a mut T` is unsafe because | |
559 | /// while you are able to pin it for the given lifetime `'a`, you have no control | |
560 | /// over whether it is kept pinned once `'a` ends: | |
561 | /// ``` | |
562 | /// use std::mem; | |
563 | /// use std::pin::Pin; | |
564 | /// | |
565 | /// fn move_pinned_ref<T>(mut a: T, mut b: T) { | |
566 | /// unsafe { | |
567 | /// let p: Pin<&mut T> = Pin::new_unchecked(&mut a); | |
568 | /// // This should mean the pointee `a` can never move again. | |
569 | /// } | |
487cf647 | 570 | /// mem::swap(&mut a, &mut b); // Potential UB down the road ⚠️ |
0731742a XL |
571 | /// // The address of `a` changed to `b`'s stack slot, so `a` got moved even |
572 | /// // though we have previously pinned it! We have violated the pinning API contract. | |
573 | /// } | |
574 | /// ``` | |
781aab86 FG |
575 | /// A value, once pinned, must remain pinned until it is dropped (unless its type implements |
576 | /// `Unpin`). Because `Pin<&mut T>` does not own the value, dropping the `Pin` will not drop | |
577 | /// the value and will not end the pinning contract. So moving the value after dropping the | |
578 | /// `Pin<&mut T>` is still a violation of the API contract. | |
0731742a | 579 | /// |
74b04a01 | 580 | /// Similarly, calling `Pin::new_unchecked` on an `Rc<T>` is unsafe because there could be |
0731742a XL |
581 | /// aliases to the same data that are not subject to the pinning restrictions: |
582 | /// ``` | |
583 | /// use std::rc::Rc; | |
584 | /// use std::pin::Pin; | |
585 | /// | |
586 | /// fn move_pinned_rc<T>(mut x: Rc<T>) { | |
1b1a35ee | 587 | /// let pinned = unsafe { Pin::new_unchecked(Rc::clone(&x)) }; |
0731742a XL |
588 | /// { |
589 | /// let p: Pin<&T> = pinned.as_ref(); | |
590 | /// // This should mean the pointee can never move again. | |
591 | /// } | |
592 | /// drop(pinned); | |
487cf647 | 593 | /// let content = Rc::get_mut(&mut x).unwrap(); // Potential UB down the road ⚠️ |
0731742a XL |
594 | /// // Now, if `x` was the only reference, we have a mutable reference to |
595 | /// // data that we pinned above, which we could use to move it as we have | |
596 | /// // seen in the previous example. We have violated the pinning API contract. | |
597 | /// } | |
598 | /// ``` | |
599 | /// | |
487cf647 FG |
600 | /// ## Pinning of closure captures |
601 | /// | |
602 | /// Particular care is required when using `Pin::new_unchecked` in a closure: | |
603 | /// `Pin::new_unchecked(&mut var)` where `var` is a by-value (moved) closure capture | |
604 | /// implicitly makes the promise that the closure itself is pinned, and that *all* uses | |
605 | /// of this closure capture respect that pinning. | |
606 | /// ``` | |
607 | /// use std::pin::Pin; | |
608 | /// use std::task::Context; | |
609 | /// use std::future::Future; | |
610 | /// | |
611 | /// fn move_pinned_closure(mut x: impl Future, cx: &mut Context<'_>) { | |
612 | /// // Create a closure that moves `x`, and then internally uses it in a pinned way. | |
613 | /// let mut closure = move || unsafe { | |
614 | /// let _ignore = Pin::new_unchecked(&mut x).poll(cx); | |
615 | /// }; | |
616 | /// // Call the closure, so the future can assume it has been pinned. | |
617 | /// closure(); | |
618 | /// // Move the closure somewhere else. This also moves `x`! | |
619 | /// let mut moved = closure; | |
620 | /// // Calling it again means we polled the future from two different locations, | |
621 | /// // violating the pinning API contract. | |
622 | /// moved(); // Potential UB ⚠️ | |
623 | /// } | |
624 | /// ``` | |
625 | /// When passing a closure to another API, it might be moving the closure any time, so | |
626 | /// `Pin::new_unchecked` on closure captures may only be used if the API explicitly documents | |
627 | /// that the closure is pinned. | |
628 | /// | |
629 | /// The better alternative is to avoid all that trouble and do the pinning in the outer function | |
9c376795 | 630 | /// instead (here using the [`pin!`][crate::pin::pin] macro): |
487cf647 | 631 | /// ``` |
487cf647 FG |
632 | /// use std::pin::pin; |
633 | /// use std::task::Context; | |
634 | /// use std::future::Future; | |
635 | /// | |
636 | /// fn move_pinned_closure(mut x: impl Future, cx: &mut Context<'_>) { | |
637 | /// let mut x = pin!(x); | |
638 | /// // Create a closure that captures `x: Pin<&mut _>`, which is safe to move. | |
639 | /// let mut closure = move || { | |
640 | /// let _ignore = x.as_mut().poll(cx); | |
641 | /// }; | |
642 | /// // Call the closure, so the future can assume it has been pinned. | |
643 | /// closure(); | |
644 | /// // Move the closure somewhere else. | |
645 | /// let mut moved = closure; | |
646 | /// // Calling it again here is fine (except that we might be polling a future that already | |
647 | /// // returned `Poll::Ready`, but that is a separate problem). | |
648 | /// moved(); | |
649 | /// } | |
650 | /// ``` | |
651 | /// | |
3dfed10e | 652 | /// [`mem::swap`]: crate::mem::swap |
1b1a35ee | 653 | #[lang = "new_unchecked"] |
0bf4aa26 | 654 | #[inline(always)] |
1b1a35ee XL |
655 | #[rustc_const_unstable(feature = "const_pin", issue = "76654")] |
656 | #[stable(feature = "pin", since = "1.33.0")] | |
657 | pub const unsafe fn new_unchecked(pointer: P) -> Pin<P> { | |
0bf4aa26 XL |
658 | Pin { pointer } |
659 | } | |
660 | ||
0731742a XL |
661 | /// Gets a pinned shared reference from this pinned pointer. |
662 | /// | |
663 | /// This is a generic method to go from `&Pin<Pointer<T>>` to `Pin<&T>`. | |
664 | /// It is safe because, as part of the contract of `Pin::new_unchecked`, | |
665 | /// the pointee cannot move after `Pin<Pointer<T>>` got created. | |
666 | /// "Malicious" implementations of `Pointer::Deref` are likewise | |
667 | /// ruled out by the contract of `Pin::new_unchecked`. | |
668 | #[stable(feature = "pin", since = "1.33.0")] | |
0bf4aa26 | 669 | #[inline(always)] |
e1599b0c | 670 | pub fn as_ref(&self) -> Pin<&P::Target> { |
60c5eb7d | 671 | // SAFETY: see documentation on this function |
0bf4aa26 | 672 | unsafe { Pin::new_unchecked(&*self.pointer) } |
b7449926 | 673 | } |
48663c56 XL |
674 | |
675 | /// Unwraps this `Pin<P>` returning the underlying pointer. | |
676 | /// | |
677 | /// # Safety | |
678 | /// | |
679 | /// This function is unsafe. You must guarantee that you will continue to | |
680 | /// treat the pointer `P` as pinned after you call this function, so that | |
681 | /// the invariants on the `Pin` type can be upheld. If the code using the | |
682 | /// resulting `P` does not continue to maintain the pinning invariants that | |
683 | /// is a violation of the API contract and may lead to undefined behavior in | |
684 | /// later (safe) operations. | |
685 | /// | |
686 | /// If the underlying data is [`Unpin`], [`Pin::into_inner`] should be used | |
687 | /// instead. | |
48663c56 | 688 | #[inline(always)] |
1b1a35ee XL |
689 | #[rustc_const_unstable(feature = "const_pin", issue = "76654")] |
690 | #[stable(feature = "pin_into_inner", since = "1.39.0")] | |
691 | pub const unsafe fn into_inner_unchecked(pin: Pin<P>) -> P { | |
48663c56 XL |
692 | pin.pointer |
693 | } | |
b7449926 XL |
694 | } |
695 | ||
0bf4aa26 | 696 | impl<P: DerefMut> Pin<P> { |
0731742a XL |
697 | /// Gets a pinned mutable reference from this pinned pointer. |
698 | /// | |
699 | /// This is a generic method to go from `&mut Pin<Pointer<T>>` to `Pin<&mut T>`. | |
700 | /// It is safe because, as part of the contract of `Pin::new_unchecked`, | |
701 | /// the pointee cannot move after `Pin<Pointer<T>>` got created. | |
702 | /// "Malicious" implementations of `Pointer::DerefMut` are likewise | |
703 | /// ruled out by the contract of `Pin::new_unchecked`. | |
e1599b0c XL |
704 | /// |
705 | /// This method is useful when doing multiple calls to functions that consume the pinned type. | |
706 | /// | |
707 | /// # Example | |
708 | /// | |
709 | /// ``` | |
710 | /// use std::pin::Pin; | |
711 | /// | |
712 | /// # struct Type {} | |
713 | /// impl Type { | |
714 | /// fn method(self: Pin<&mut Self>) { | |
715 | /// // do something | |
716 | /// } | |
717 | /// | |
718 | /// fn call_method_twice(mut self: Pin<&mut Self>) { | |
719 | /// // `method` consumes `self`, so reborrow the `Pin<&mut Self>` via `as_mut`. | |
720 | /// self.as_mut().method(); | |
721 | /// self.as_mut().method(); | |
722 | /// } | |
723 | /// } | |
724 | /// ``` | |
0731742a | 725 | #[stable(feature = "pin", since = "1.33.0")] |
0bf4aa26 | 726 | #[inline(always)] |
e1599b0c | 727 | pub fn as_mut(&mut self) -> Pin<&mut P::Target> { |
60c5eb7d | 728 | // SAFETY: see documentation on this function |
0bf4aa26 XL |
729 | unsafe { Pin::new_unchecked(&mut *self.pointer) } |
730 | } | |
b7449926 | 731 | |
0731742a XL |
732 | /// Assigns a new value to the memory behind the pinned reference. |
733 | /// | |
734 | /// This overwrites pinned data, but that is okay: its destructor gets | |
735 | /// run before being overwritten, so no pinning guarantee is violated. | |
9c376795 FG |
736 | /// |
737 | /// # Example | |
738 | /// | |
739 | /// ``` | |
740 | /// use std::pin::Pin; | |
741 | /// | |
742 | /// let mut val: u8 = 5; | |
743 | /// let mut pinned: Pin<&mut u8> = Pin::new(&mut val); | |
744 | /// println!("{}", pinned); // 5 | |
745 | /// pinned.as_mut().set(10); | |
746 | /// println!("{}", pinned); // 10 | |
747 | /// ``` | |
0731742a | 748 | #[stable(feature = "pin", since = "1.33.0")] |
0bf4aa26 | 749 | #[inline(always)] |
e1599b0c | 750 | pub fn set(&mut self, value: P::Target) |
0bf4aa26 XL |
751 | where |
752 | P::Target: Sized, | |
753 | { | |
0731742a | 754 | *(self.pointer) = value; |
0bf4aa26 XL |
755 | } |
756 | } | |
757 | ||
758 | impl<'a, T: ?Sized> Pin<&'a T> { | |
0731742a | 759 | /// Constructs a new pin by mapping the interior value. |
b7449926 | 760 | /// |
9c376795 | 761 | /// For example, if you wanted to get a `Pin` of a field of something, |
0bf4aa26 | 762 | /// you could use this to get access to that field in one line of code. |
0731742a XL |
763 | /// However, there are several gotchas with these "pinning projections"; |
764 | /// see the [`pin` module] documentation for further details on that topic. | |
0bf4aa26 XL |
765 | /// |
766 | /// # Safety | |
767 | /// | |
768 | /// This function is unsafe. You must guarantee that the data you return | |
769 | /// will not move so long as the argument value does not move (for example, | |
770 | /// because it is one of the fields of that value), and also that you do | |
771 | /// not move out of the argument you receive to the interior function. | |
0731742a | 772 | /// |
1b1a35ee | 773 | /// [`pin` module]: self#projections-and-structural-pinning |
0731742a | 774 | #[stable(feature = "pin", since = "1.33.0")] |
60c5eb7d XL |
775 | pub unsafe fn map_unchecked<U, F>(self, func: F) -> Pin<&'a U> |
776 | where | |
dfeec247 | 777 | U: ?Sized, |
0bf4aa26 XL |
778 | F: FnOnce(&T) -> &U, |
779 | { | |
0731742a | 780 | let pointer = &*self.pointer; |
0bf4aa26 | 781 | let new_pointer = func(pointer); |
f035d41b XL |
782 | |
783 | // SAFETY: the safety contract for `new_unchecked` must be | |
784 | // upheld by the caller. | |
785 | unsafe { Pin::new_unchecked(new_pointer) } | |
b7449926 XL |
786 | } |
787 | ||
9fa01778 | 788 | /// Gets a shared reference out of a pin. |
b7449926 | 789 | /// |
0731742a XL |
790 | /// This is safe because it is not possible to move out of a shared reference. |
791 | /// It may seem like there is an issue here with interior mutability: in fact, | |
792 | /// it *is* possible to move a `T` out of a `&RefCell<T>`. However, this is | |
793 | /// not a problem as long as there does not also exist a `Pin<&T>` pointing | |
794 | /// to the same data, and `RefCell<T>` does not let you create a pinned reference | |
795 | /// to its contents. See the discussion on ["pinning projections"] for further | |
796 | /// details. | |
797 | /// | |
0bf4aa26 XL |
798 | /// Note: `Pin` also implements `Deref` to the target, which can be used |
799 | /// to access the inner value. However, `Deref` only provides a reference | |
800 | /// that lives for as long as the borrow of the `Pin`, not the lifetime of | |
801 | /// the `Pin` itself. This method allows turning the `Pin` into a reference | |
802 | /// with the same lifetime as the original `Pin`. | |
0731742a | 803 | /// |
1b1a35ee | 804 | /// ["pinning projections"]: self#projections-and-structural-pinning |
0bf4aa26 | 805 | #[inline(always)] |
3c0e092e | 806 | #[must_use] |
1b1a35ee XL |
807 | #[rustc_const_unstable(feature = "const_pin", issue = "76654")] |
808 | #[stable(feature = "pin", since = "1.33.0")] | |
809 | pub const fn get_ref(self) -> &'a T { | |
0731742a | 810 | self.pointer |
0bf4aa26 XL |
811 | } |
812 | } | |
813 | ||
814 | impl<'a, T: ?Sized> Pin<&'a mut T> { | |
9fa01778 | 815 | /// Converts this `Pin<&mut T>` into a `Pin<&T>` with the same lifetime. |
0bf4aa26 | 816 | #[inline(always)] |
c295e0f8 | 817 | #[must_use = "`self` will be dropped if the result is not used"] |
1b1a35ee XL |
818 | #[rustc_const_unstable(feature = "const_pin", issue = "76654")] |
819 | #[stable(feature = "pin", since = "1.33.0")] | |
820 | pub const fn into_ref(self) -> Pin<&'a T> { | |
0731742a | 821 | Pin { pointer: self.pointer } |
0bf4aa26 XL |
822 | } |
823 | ||
9fa01778 | 824 | /// Gets a mutable reference to the data inside of this `Pin`. |
0bf4aa26 XL |
825 | /// |
826 | /// This requires that the data inside this `Pin` is `Unpin`. | |
827 | /// | |
828 | /// Note: `Pin` also implements `DerefMut` to the data, which can be used | |
829 | /// to access the inner value. However, `DerefMut` only provides a reference | |
830 | /// that lives for as long as the borrow of the `Pin`, not the lifetime of | |
831 | /// the `Pin` itself. This method allows turning the `Pin` into a reference | |
832 | /// with the same lifetime as the original `Pin`. | |
0bf4aa26 | 833 | #[inline(always)] |
c295e0f8 | 834 | #[must_use = "`self` will be dropped if the result is not used"] |
1b1a35ee XL |
835 | #[stable(feature = "pin", since = "1.33.0")] |
836 | #[rustc_const_unstable(feature = "const_pin", issue = "76654")] | |
837 | pub const fn get_mut(self) -> &'a mut T | |
60c5eb7d XL |
838 | where |
839 | T: Unpin, | |
0bf4aa26 | 840 | { |
0731742a | 841 | self.pointer |
b7449926 XL |
842 | } |
843 | ||
9fa01778 | 844 | /// Gets a mutable reference to the data inside of this `Pin`. |
0bf4aa26 XL |
845 | /// |
846 | /// # Safety | |
b7449926 XL |
847 | /// |
848 | /// This function is unsafe. You must guarantee that you will never move | |
849 | /// the data out of the mutable reference you receive when you call this | |
0bf4aa26 XL |
850 | /// function, so that the invariants on the `Pin` type can be upheld. |
851 | /// | |
852 | /// If the underlying data is `Unpin`, `Pin::get_mut` should be used | |
853 | /// instead. | |
0bf4aa26 | 854 | #[inline(always)] |
c295e0f8 | 855 | #[must_use = "`self` will be dropped if the result is not used"] |
1b1a35ee XL |
856 | #[stable(feature = "pin", since = "1.33.0")] |
857 | #[rustc_const_unstable(feature = "const_pin", issue = "76654")] | |
858 | pub const unsafe fn get_unchecked_mut(self) -> &'a mut T { | |
0731742a | 859 | self.pointer |
b7449926 XL |
860 | } |
861 | ||
862 | /// Construct a new pin by mapping the interior value. | |
863 | /// | |
9c376795 | 864 | /// For example, if you wanted to get a `Pin` of a field of something, |
b7449926 | 865 | /// you could use this to get access to that field in one line of code. |
0731742a XL |
866 | /// However, there are several gotchas with these "pinning projections"; |
867 | /// see the [`pin` module] documentation for further details on that topic. | |
b7449926 | 868 | /// |
0bf4aa26 XL |
869 | /// # Safety |
870 | /// | |
b7449926 XL |
871 | /// This function is unsafe. You must guarantee that the data you return |
872 | /// will not move so long as the argument value does not move (for example, | |
873 | /// because it is one of the fields of that value), and also that you do | |
874 | /// not move out of the argument you receive to the interior function. | |
0731742a | 875 | /// |
1b1a35ee | 876 | /// [`pin` module]: self#projections-and-structural-pinning |
c295e0f8 | 877 | #[must_use = "`self` will be dropped if the result is not used"] |
0731742a | 878 | #[stable(feature = "pin", since = "1.33.0")] |
60c5eb7d XL |
879 | pub unsafe fn map_unchecked_mut<U, F>(self, func: F) -> Pin<&'a mut U> |
880 | where | |
dfeec247 | 881 | U: ?Sized, |
0bf4aa26 | 882 | F: FnOnce(&mut T) -> &mut U, |
b7449926 | 883 | { |
f035d41b XL |
884 | // SAFETY: the caller is responsible for not moving the |
885 | // value out of this reference. | |
886 | let pointer = unsafe { Pin::get_unchecked_mut(self) }; | |
0bf4aa26 | 887 | let new_pointer = func(pointer); |
f035d41b XL |
888 | // SAFETY: as the value of `this` is guaranteed to not have |
889 | // been moved out, this call to `new_unchecked` is safe. | |
890 | unsafe { Pin::new_unchecked(new_pointer) } | |
b7449926 XL |
891 | } |
892 | } | |
893 | ||
2a314972 XL |
894 | impl<T: ?Sized> Pin<&'static T> { |
895 | /// Get a pinned reference from a static reference. | |
896 | /// | |
897 | /// This is safe, because `T` is borrowed for the `'static` lifetime, which | |
898 | /// never ends. | |
5e7ed085 | 899 | #[stable(feature = "pin_static_ref", since = "1.61.0")] |
2a314972 XL |
900 | #[rustc_const_unstable(feature = "const_pin", issue = "76654")] |
901 | pub const fn static_ref(r: &'static T) -> Pin<&'static T> { | |
902 | // SAFETY: The 'static borrow guarantees the data will not be | |
903 | // moved/invalidated until it gets dropped (which is never). | |
904 | unsafe { Pin::new_unchecked(r) } | |
905 | } | |
906 | } | |
907 | ||
94222f64 XL |
908 | impl<'a, P: DerefMut> Pin<&'a mut Pin<P>> { |
909 | /// Gets a pinned mutable reference from this nested pinned pointer. | |
910 | /// | |
911 | /// This is a generic method to go from `Pin<&mut Pin<Pointer<T>>>` to `Pin<&mut T>`. It is | |
912 | /// safe because the existence of a `Pin<Pointer<T>>` ensures that the pointee, `T`, cannot | |
913 | /// move in the future, and this method does not enable the pointee to move. "Malicious" | |
914 | /// implementations of `P::DerefMut` are likewise ruled out by the contract of | |
915 | /// `Pin::new_unchecked`. | |
916 | #[unstable(feature = "pin_deref_mut", issue = "86918")] | |
c295e0f8 | 917 | #[must_use = "`self` will be dropped if the result is not used"] |
94222f64 XL |
918 | #[inline(always)] |
919 | pub fn as_deref_mut(self) -> Pin<&'a mut P::Target> { | |
920 | // SAFETY: What we're asserting here is that going from | |
921 | // | |
922 | // Pin<&mut Pin<P>> | |
923 | // | |
924 | // to | |
925 | // | |
926 | // Pin<&mut P::Target> | |
927 | // | |
928 | // is safe. | |
929 | // | |
930 | // We need to ensure that two things hold for that to be the case: | |
931 | // | |
932 | // 1) Once we give out a `Pin<&mut P::Target>`, an `&mut P::Target` will not be given out. | |
933 | // 2) By giving out a `Pin<&mut P::Target>`, we do not risk of violating `Pin<&mut Pin<P>>` | |
934 | // | |
935 | // The existence of `Pin<P>` is sufficient to guarantee #1: since we already have a | |
936 | // `Pin<P>`, it must already uphold the pinning guarantees, which must mean that | |
937 | // `Pin<&mut P::Target>` does as well, since `Pin::as_mut` is safe. We do not have to rely | |
938 | // on the fact that P is _also_ pinned. | |
939 | // | |
940 | // For #2, we need to ensure that code given a `Pin<&mut P::Target>` cannot cause the | |
941 | // `Pin<P>` to move? That is not possible, since `Pin<&mut P::Target>` no longer retains | |
942 | // any access to the `P` itself, much less the `Pin<P>`. | |
943 | unsafe { self.get_unchecked_mut() }.as_mut() | |
944 | } | |
945 | } | |
946 | ||
2a314972 XL |
947 | impl<T: ?Sized> Pin<&'static mut T> { |
948 | /// Get a pinned mutable reference from a static mutable reference. | |
949 | /// | |
950 | /// This is safe, because `T` is borrowed for the `'static` lifetime, which | |
951 | /// never ends. | |
5e7ed085 | 952 | #[stable(feature = "pin_static_ref", since = "1.61.0")] |
2a314972 XL |
953 | #[rustc_const_unstable(feature = "const_pin", issue = "76654")] |
954 | pub const fn static_mut(r: &'static mut T) -> Pin<&'static mut T> { | |
955 | // SAFETY: The 'static borrow guarantees the data will not be | |
956 | // moved/invalidated until it gets dropped (which is never). | |
957 | unsafe { Pin::new_unchecked(r) } | |
958 | } | |
959 | } | |
960 | ||
0731742a | 961 | #[stable(feature = "pin", since = "1.33.0")] |
0bf4aa26 XL |
962 | impl<P: Deref> Deref for Pin<P> { |
963 | type Target = P::Target; | |
964 | fn deref(&self) -> &P::Target { | |
965 | Pin::get_ref(Pin::as_ref(self)) | |
b7449926 XL |
966 | } |
967 | } | |
968 | ||
0731742a | 969 | #[stable(feature = "pin", since = "1.33.0")] |
416331ca | 970 | impl<P: DerefMut<Target: Unpin>> DerefMut for Pin<P> { |
0bf4aa26 XL |
971 | fn deref_mut(&mut self) -> &mut P::Target { |
972 | Pin::get_mut(Pin::as_mut(self)) | |
b7449926 XL |
973 | } |
974 | } | |
975 | ||
dfeec247 | 976 | #[unstable(feature = "receiver_trait", issue = "none")] |
0731742a XL |
977 | impl<P: Receiver> Receiver for Pin<P> {} |
978 | ||
979 | #[stable(feature = "pin", since = "1.33.0")] | |
0bf4aa26 | 980 | impl<P: fmt::Debug> fmt::Debug for Pin<P> { |
48663c56 | 981 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
0bf4aa26 | 982 | fmt::Debug::fmt(&self.pointer, f) |
b7449926 XL |
983 | } |
984 | } | |
985 | ||
0731742a | 986 | #[stable(feature = "pin", since = "1.33.0")] |
0bf4aa26 | 987 | impl<P: fmt::Display> fmt::Display for Pin<P> { |
48663c56 | 988 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
0bf4aa26 | 989 | fmt::Display::fmt(&self.pointer, f) |
b7449926 XL |
990 | } |
991 | } | |
992 | ||
0731742a | 993 | #[stable(feature = "pin", since = "1.33.0")] |
0bf4aa26 | 994 | impl<P: fmt::Pointer> fmt::Pointer for Pin<P> { |
48663c56 | 995 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
0bf4aa26 | 996 | fmt::Pointer::fmt(&self.pointer, f) |
b7449926 XL |
997 | } |
998 | } | |
999 | ||
0bf4aa26 XL |
1000 | // Note: this means that any impl of `CoerceUnsized` that allows coercing from |
1001 | // a type that impls `Deref<Target=impl !Unpin>` to a type that impls | |
1002 | // `Deref<Target=Unpin>` is unsound. Any such impl would probably be unsound | |
1003 | // for other reasons, though, so we just need to take care not to allow such | |
1004 | // impls to land in std. | |
0731742a | 1005 | #[stable(feature = "pin", since = "1.33.0")] |
60c5eb7d | 1006 | impl<P, U> CoerceUnsized<Pin<U>> for Pin<P> where P: CoerceUnsized<U> {} |
b7449926 | 1007 | |
0731742a | 1008 | #[stable(feature = "pin", since = "1.33.0")] |
60c5eb7d | 1009 | impl<P, U> DispatchFromDyn<Pin<U>> for Pin<P> where P: DispatchFromDyn<U> {} |
5099ac24 | 1010 | |
353b0b11 | 1011 | /// Constructs a <code>[Pin]<[&mut] T></code>, by pinning a `value: T` locally. |
5099ac24 | 1012 | /// |
353b0b11 FG |
1013 | /// Unlike [`Box::pin`], this does not create a new heap allocation. As explained |
1014 | /// below, the element might still end up on the heap however. | |
5099ac24 | 1015 | /// |
353b0b11 FG |
1016 | /// The local pinning performed by this macro is usually dubbed "stack"-pinning. |
1017 | /// Outside of `async` contexts locals do indeed get stored on the stack. In | |
1018 | /// `async` functions or blocks however, any locals crossing an `.await` point | |
1019 | /// are part of the state captured by the `Future`, and will use the storage of | |
1020 | /// those. That storage can either be on the heap or on the stack. Therefore, | |
1021 | /// local pinning is a more accurate term. | |
5099ac24 | 1022 | /// |
353b0b11 FG |
1023 | /// If the type of the given value does not implement [`Unpin`], then this macro |
1024 | /// pins the value in memory in a way that prevents moves. On the other hand, | |
1025 | /// if the type does implement [`Unpin`], <code>[Pin]<[&mut] T></code> behaves | |
1026 | /// like <code>[&mut] T</code>, and operations such as | |
1027 | /// [`mem::replace()`][crate::mem::replace] or [`mem::take()`](crate::mem::take) | |
1028 | /// will allow moves of the value. | |
1029 | /// See [the `Unpin` section of the `pin` module][self#unpin] for details. | |
5099ac24 FG |
1030 | /// |
1031 | /// ## Examples | |
1032 | /// | |
1033 | /// ### Basic usage | |
1034 | /// | |
1035 | /// ```rust | |
5099ac24 FG |
1036 | /// # use core::marker::PhantomPinned as Foo; |
1037 | /// use core::pin::{pin, Pin}; | |
1038 | /// | |
1039 | /// fn stuff(foo: Pin<&mut Foo>) { | |
1040 | /// // … | |
1041 | /// # let _ = foo; | |
1042 | /// } | |
1043 | /// | |
1044 | /// let pinned_foo = pin!(Foo { /* … */ }); | |
1045 | /// stuff(pinned_foo); | |
1046 | /// // or, directly: | |
1047 | /// stuff(pin!(Foo { /* … */ })); | |
1048 | /// ``` | |
1049 | /// | |
5e7ed085 | 1050 | /// ### Manually polling a `Future` (without `Unpin` bounds) |
5099ac24 FG |
1051 | /// |
1052 | /// ```rust | |
5099ac24 FG |
1053 | /// use std::{ |
1054 | /// future::Future, | |
1055 | /// pin::pin, | |
1056 | /// task::{Context, Poll}, | |
1057 | /// thread, | |
1058 | /// }; | |
1059 | /// # use std::{sync::Arc, task::Wake, thread::Thread}; | |
1060 | /// | |
1061 | /// # /// A waker that wakes up the current thread when called. | |
1062 | /// # struct ThreadWaker(Thread); | |
1063 | /// # | |
1064 | /// # impl Wake for ThreadWaker { | |
1065 | /// # fn wake(self: Arc<Self>) { | |
1066 | /// # self.0.unpark(); | |
1067 | /// # } | |
1068 | /// # } | |
1069 | /// # | |
1070 | /// /// Runs a future to completion. | |
1071 | /// fn block_on<Fut: Future>(fut: Fut) -> Fut::Output { | |
1072 | /// let waker_that_unparks_thread = // … | |
1073 | /// # Arc::new(ThreadWaker(thread::current())).into(); | |
1074 | /// let mut cx = Context::from_waker(&waker_that_unparks_thread); | |
1075 | /// // Pin the future so it can be polled. | |
1076 | /// let mut pinned_fut = pin!(fut); | |
1077 | /// loop { | |
1078 | /// match pinned_fut.as_mut().poll(&mut cx) { | |
1079 | /// Poll::Pending => thread::park(), | |
1080 | /// Poll::Ready(res) => return res, | |
1081 | /// } | |
1082 | /// } | |
1083 | /// } | |
1084 | /// # | |
1085 | /// # assert_eq!(42, block_on(async { 42 })); | |
1086 | /// ``` | |
1087 | /// | |
1088 | /// ### With `Generator`s | |
1089 | /// | |
1090 | /// ```rust | |
9c376795 | 1091 | /// #![feature(generators, generator_trait)] |
5099ac24 FG |
1092 | /// use core::{ |
1093 | /// ops::{Generator, GeneratorState}, | |
1094 | /// pin::pin, | |
1095 | /// }; | |
1096 | /// | |
1097 | /// fn generator_fn() -> impl Generator<Yield = usize, Return = ()> /* not Unpin */ { | |
1098 | /// // Allow generator to be self-referential (not `Unpin`) | |
1099 | /// // vvvvvv so that locals can cross yield points. | |
1100 | /// static || { | |
923072b8 FG |
1101 | /// let foo = String::from("foo"); |
1102 | /// let foo_ref = &foo; // ------+ | |
1103 | /// yield 0; // | <- crosses yield point! | |
1104 | /// println!("{foo_ref}"); // <--+ | |
5099ac24 FG |
1105 | /// yield foo.len(); |
1106 | /// } | |
1107 | /// } | |
1108 | /// | |
1109 | /// fn main() { | |
1110 | /// let mut generator = pin!(generator_fn()); | |
1111 | /// match generator.as_mut().resume(()) { | |
1112 | /// GeneratorState::Yielded(0) => {}, | |
1113 | /// _ => unreachable!(), | |
1114 | /// } | |
1115 | /// match generator.as_mut().resume(()) { | |
1116 | /// GeneratorState::Yielded(3) => {}, | |
1117 | /// _ => unreachable!(), | |
1118 | /// } | |
1119 | /// match generator.resume(()) { | |
1120 | /// GeneratorState::Yielded(_) => unreachable!(), | |
1121 | /// GeneratorState::Complete(()) => {}, | |
1122 | /// } | |
1123 | /// } | |
1124 | /// ``` | |
1125 | /// | |
1126 | /// ## Remarks | |
1127 | /// | |
1128 | /// Precisely because a value is pinned to local storage, the resulting <code>[Pin]<[&mut] T></code> | |
1129 | /// reference ends up borrowing a local tied to that block: it can't escape it. | |
1130 | /// | |
1131 | /// The following, for instance, fails to compile: | |
1132 | /// | |
1133 | /// ```rust,compile_fail | |
5099ac24 FG |
1134 | /// use core::pin::{pin, Pin}; |
1135 | /// # use core::{marker::PhantomPinned as Foo, mem::drop as stuff}; | |
1136 | /// | |
1137 | /// let x: Pin<&mut Foo> = { | |
1138 | /// let x: Pin<&mut Foo> = pin!(Foo { /* … */ }); | |
1139 | /// x | |
1140 | /// }; // <- Foo is dropped | |
1141 | /// stuff(x); // Error: use of dropped value | |
1142 | /// ``` | |
1143 | /// | |
1144 | /// <details><summary>Error message</summary> | |
1145 | /// | |
1146 | /// ```console | |
1147 | /// error[E0716]: temporary value dropped while borrowed | |
1148 | /// --> src/main.rs:9:28 | |
1149 | /// | | |
1150 | /// 8 | let x: Pin<&mut Foo> = { | |
1151 | /// | - borrow later stored here | |
1152 | /// 9 | let x: Pin<&mut Foo> = pin!(Foo { /* … */ }); | |
487cf647 | 1153 | /// | ^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use |
5099ac24 FG |
1154 | /// 10 | x |
1155 | /// 11 | }; // <- Foo is dropped | |
1156 | /// | - temporary value is freed at the end of this statement | |
1157 | /// | | |
1158 | /// = note: consider using a `let` binding to create a longer lived value | |
1159 | /// ``` | |
1160 | /// | |
1161 | /// </details> | |
1162 | /// | |
1163 | /// This makes [`pin!`] **unsuitable to pin values when intending to _return_ them**. Instead, the | |
1164 | /// value is expected to be passed around _unpinned_ until the point where it is to be consumed, | |
1165 | /// where it is then useful and even sensible to pin the value locally using [`pin!`]. | |
1166 | /// | |
1167 | /// If you really need to return a pinned value, consider using [`Box::pin`] instead. | |
1168 | /// | |
353b0b11 FG |
1169 | /// On the other hand, local pinning using [`pin!`] is likely to be cheaper than |
1170 | /// pinning into a fresh heap allocation using [`Box::pin`]. Moreover, by virtue of not | |
1171 | /// requiring an allocator, [`pin!`] is the main non-`unsafe` `#![no_std]`-compatible [`Pin`] | |
5099ac24 FG |
1172 | /// constructor. |
1173 | /// | |
1174 | /// [`Box::pin`]: ../../std/boxed/struct.Box.html#method.pin | |
9c376795 | 1175 | #[stable(feature = "pin_macro", since = "1.68.0")] |
5099ac24 FG |
1176 | #[rustc_macro_transparency = "semitransparent"] |
1177 | #[allow_internal_unstable(unsafe_pin_internals)] | |
1178 | pub macro pin($value:expr $(,)?) { | |
1179 | // This is `Pin::new_unchecked(&mut { $value })`, so, for starters, let's | |
1180 | // review such a hypothetical macro (that any user-code could define): | |
1181 | // | |
1182 | // ```rust | |
1183 | // macro_rules! pin {( $value:expr ) => ( | |
1184 | // match &mut { $value } { at_value => unsafe { // Do not wrap `$value` in an `unsafe` block. | |
1185 | // $crate::pin::Pin::<&mut _>::new_unchecked(at_value) | |
1186 | // }} | |
1187 | // )} | |
1188 | // ``` | |
1189 | // | |
1190 | // Safety: | |
1191 | // - `type P = &mut _`. There are thus no pathological `Deref{,Mut}` impls | |
1192 | // that would break `Pin`'s invariants. | |
1193 | // - `{ $value }` is braced, making it a _block expression_, thus **moving** | |
1194 | // the given `$value`, and making it _become an **anonymous** temporary_. | |
5e7ed085 FG |
1195 | // By virtue of being anonymous, it can no longer be accessed, thus |
1196 | // preventing any attempts to `mem::replace` it or `mem::forget` it, _etc._ | |
5099ac24 FG |
1197 | // |
1198 | // This gives us a `pin!` definition that is sound, and which works, but only | |
1199 | // in certain scenarios: | |
1200 | // - If the `pin!(value)` expression is _directly_ fed to a function call: | |
1201 | // `let poll = pin!(fut).poll(cx);` | |
1202 | // - If the `pin!(value)` expression is part of a scrutinee: | |
1203 | // ```rust | |
1204 | // match pin!(fut) { pinned_fut => { | |
1205 | // pinned_fut.as_mut().poll(...); | |
1206 | // pinned_fut.as_mut().poll(...); | |
1207 | // }} // <- `fut` is dropped here. | |
1208 | // ``` | |
1209 | // Alas, it doesn't work for the more straight-forward use-case: `let` bindings. | |
1210 | // ```rust | |
1211 | // let pinned_fut = pin!(fut); // <- temporary value is freed at the end of this statement | |
1212 | // pinned_fut.poll(...) // error[E0716]: temporary value dropped while borrowed | |
1213 | // // note: consider using a `let` binding to create a longer lived value | |
1214 | // ``` | |
1215 | // - Issues such as this one are the ones motivating https://github.com/rust-lang/rfcs/pull/66 | |
1216 | // | |
1217 | // This makes such a macro incredibly unergonomic in practice, and the reason most macros | |
1218 | // out there had to take the path of being a statement/binding macro (_e.g._, `pin!(future);`) | |
1219 | // instead of featuring the more intuitive ergonomics of an expression macro. | |
1220 | // | |
1221 | // Luckily, there is a way to avoid the problem. Indeed, the problem stems from the fact that a | |
1222 | // temporary is dropped at the end of its enclosing statement when it is part of the parameters | |
1223 | // given to function call, which has precisely been the case with our `Pin::new_unchecked()`! | |
1224 | // For instance, | |
1225 | // ```rust | |
1226 | // let p = Pin::new_unchecked(&mut <temporary>); | |
1227 | // ``` | |
1228 | // becomes: | |
1229 | // ```rust | |
1230 | // let p = { let mut anon = <temporary>; &mut anon }; | |
1231 | // ``` | |
1232 | // | |
1233 | // However, when using a literal braced struct to construct the value, references to temporaries | |
1234 | // can then be taken. This makes Rust change the lifespan of such temporaries so that they are, | |
1235 | // instead, dropped _at the end of the enscoping block_. | |
1236 | // For instance, | |
1237 | // ```rust | |
1238 | // let p = Pin { pointer: &mut <temporary> }; | |
1239 | // ``` | |
1240 | // becomes: | |
1241 | // ```rust | |
1242 | // let mut anon = <temporary>; | |
1243 | // let p = Pin { pointer: &mut anon }; | |
1244 | // ``` | |
1245 | // which is *exactly* what we want. | |
1246 | // | |
1247 | // See https://doc.rust-lang.org/1.58.1/reference/destructors.html#temporary-lifetime-extension | |
1248 | // for more info. | |
1249 | $crate::pin::Pin::<&mut _> { pointer: &mut { $value } } | |
1250 | } |