|
177 | 177 | //! In a similar vein, when can a generic wrapper type (such as `Vec`, `Box`, or `RefCell`)
|
178 | 178 | //! have an operation with type `fn(Pin<&[mut] Wrapper<T>>) -> Pin<&[mut] T>`?
|
179 | 179 | //!
|
180 |
| -//! This question is closely related to the question of whether pinning is "structural": |
181 |
| -//! when you have pinned a wrapper type, have you pinned its contents? Deciding this |
182 |
| -//! is entirely up to the author of any given type. For many types, both answers are reasonable |
183 |
| -//! (e.g., there could be a version of `Vec` with structural pinning and another |
184 |
| -//! version where the contents remain movable even when the `Vec` is pinned). |
185 |
| -//! If the type should have pinning projections, pinning must be structural. |
| 180 | +//! This question is closely related to the question of whether pinning is "structural". |
| 181 | +//! Structural pinning means that when you have pinned a wrapper type, the contents are |
| 182 | +//! also pinned. Structural pinning thus explains why pinning projections are correct. This means |
| 183 | +//! that if the type should have pinning projections for some fields, pinning must be structural |
| 184 | +//! for those fields. |
| 185 | +//! |
| 186 | +//! In general, deciding for which fields pinning is structural (and thus for which fields |
| 187 | +//! pinning projections could be offered) is entirely up to the author of any given type. |
| 188 | +//! For many types, both answers are reasonable. For example, there could be a version |
| 189 | +//! of `Vec` with structural pinning and `get_pin`/`get_pin_mut` projections to access |
| 190 | +//! the `Vec` elements, and another version where the contents remain movable even when |
| 191 | +//! the `Vec` is pinned. |
| 192 | +//! |
186 | 193 | //! However, structural pinning comes with a few extra requirements:
|
187 | 194 | //!
|
188 |
| -//! 1. The wrapper must only be [`Unpin`] if all the fields one can project to are |
| 195 | +//! 1. The wrapper must only be [`Unpin`] if all the structural fields are |
189 | 196 | //! `Unpin`. This is the default, but `Unpin` is a safe trait, so as the author of
|
190 | 197 | //! the wrapper it is your responsibility *not* to add something like
|
191 | 198 | //! `impl<T> Unpin for Wrapper<T>`. (Notice that adding a projection operation
|
192 | 199 | //! requires unsafe code, so the fact that `Unpin` is a safe trait does not break
|
193 | 200 | //! the principle that you only have to worry about any of this if you use `unsafe`.)
|
194 |
| -//! 2. The destructor of the wrapper must not move out of its argument. This is the exact |
195 |
| -//! point that was raised in the [previous section][drop-impl]: `drop` takes `&mut self`, |
196 |
| -//! but the wrapper (and hence its fields) might have been pinned before. |
| 201 | +//! 2. The destructor of the wrapper must not move structural fields out of its argument. This |
| 202 | +//! is the exact point that was raised in the [previous section][drop-impl]: `drop` takes |
| 203 | +//! `&mut self`, but the wrapper (and hence its fields) might have been pinned before. |
197 | 204 | //! You have to guarantee that you do not move a field inside your `Drop` implementation.
|
198 | 205 | //! In particular, as explained previously, this means that your wrapper type must *not*
|
199 | 206 | //! be `#[repr(packed)]`.
|
|
0 commit comments