You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: text/0000-pin.md
+70-79Lines changed: 70 additions & 79 deletions
Original file line number
Diff line number
Diff line change
@@ -36,12 +36,12 @@ Let's take that goal apart, piece by piece, from the perspective of the futures
36
36
37
37
At the same time, we want to support futures (and iterators, etc.) that *can* move. While it's possible to do so by providing two distinct `Future` (or `Iterator`, etc) traits, such designs incur unacceptable ergonomic costs.
38
38
39
-
The key insight of this RFC is that we can create a new library type, `PinMut<'a, T>`, which encompasses *both* moveable and immobile referents. The type is paired with a new auto trait, `Unpin`, which determines the meaning of `PinMut<'a, T>`:
39
+
The key insight of this RFC is that we can create a new library type, `Pin<'a, T>`, which encompasses *both* moveable and immobile referents. The type is paired with a new auto trait, `Unpin`, which determines the meaning of `Pin<'a, T>`:
40
40
41
-
- If `T: Unpin` (which is the default), then `PinMut<'a, T>` is entirely equivalent to `&'a mut T`.
42
-
- If `T: !Unpin`, then `PinMut<'a, T>` provides a unique reference to a `T` with lifetime `'a`, but only provides `&'a T` access safely. It also guarantees that the referent will *never* be moved. However, getting `&'a mut T` access is unsafe, because operations like `mem::replace` mean that `&mut` access is enough to move data out of the referent; you must promise not to do so.
41
+
- If `T: Unpin` (which is the default), then `Pin<'a, T>` is entirely equivalent to `&'a mut T`.
42
+
- If `T: !Unpin`, then `Pin<'a, T>` provides a unique reference to a `T` with lifetime `'a`, but only provides `&'a T` access safely. It also guarantees that the referent will *never* be moved. However, getting `&'a mut T` access is unsafe, because operations like `mem::replace` mean that `&mut` access is enough to move data out of the referent; you must promise not to do so.
43
43
44
-
To be clear: the *sole* function of `Unpin` is to control the meaning of `PinMut`. Making `Unpin` an auto trait means that the vast majority of types are automatically "movable", so `PinMut` degenerates to `&mut`. In the case that you need immobility, you *opt out* of `Unpin`, and then `PinMut` becomes meaningful for your type.
44
+
To be clear: the *sole* function of `Unpin` is to control the meaning of `Pin`. Making `Unpin` an auto trait means that the vast majority of types are automatically "movable", so `Pin` degenerates to `&mut`. In the case that you need immobility, you *opt out* of `Unpin`, and then `Pin` becomes meaningful for your type.
45
45
46
46
Putting this all together, we arrive at the following definition of `Future`:
By default when implementing `Future` for a struct, this definition is equivalent to today's, which takes `&mut self`. But if you want to allow self-referencing in your future, you just opt out of `Unpin`, and `PinMut` takes care of the rest.
57
+
By default when implementing `Future` for a struct, this definition is equivalent to today's, which takes `&mut self`. But if you want to allow self-referencing in your future, you just opt out of `Unpin`, and `Pin` takes care of the rest.
58
58
59
-
This RFC also provides pinned analogies to `Box`and `&T` - `PinBox<T>` and `Pin<T>`. They work along the same lines as the `PinMut` type discussed here - if the type implements `Unpin`, they function the same as their unpinned varieties; if the type has opted out of `Unpin`, they guarantee that they type behind the reference will not be moved again.
59
+
This RFC also provides a pinned analogiy to `Box`called `PinBox<T>`. It work alongs the same lines as the `Pin` type discussed here - if the type implements `Unpin`, it functions the same as the unpinned `Box`; if the type has opted out of `Unpin`, it guarantees that they type behind the reference will not be moved again.
60
60
61
61
# Reference-level explanation
62
62
@@ -80,109 +80,87 @@ generators. Unlike previous `?Move` proposals, and unlike some traits like
80
80
types that do or don't implement it. Instead, the semantics are entirely
81
81
enforced through library APIs which use `Unpin` as a marker.
82
82
83
-
## `Pin` and `PinMut`
83
+
## `Pin`
84
84
85
-
`Pin`and `PinMut` are two types added to `core::mem` and `std::mem`. They are
86
-
analogous to `&T` and `&mut T` respectively.
85
+
The `Pin`struct is added to both `core::mem` and `std::mem`. It is a new kind
86
+
of reference, with stronger requirements than `&mut T`
87
87
88
88
```rust
89
89
#[fundamental]
90
90
pubstructPin<'a, T:?Sized+ 'a> {
91
-
data:&'aT,
92
-
}
93
-
94
-
#[fundamental]
95
-
pubstructPinMut<'a, T:?Sized+ 'a> {
96
91
data:&'amutT,
97
92
}
98
93
```
99
94
100
95
### Safe APIs
101
96
102
-
They both implement `Deref`, but `PinMut` only implements `DerefMut` if the
103
-
type it references implements `Unpin`:
97
+
`Pin` implements `Deref`, but only implements `DerefMut` if the type it
98
+
references implements `Unpin`. This way, it is not safe to call `mem::swap` or
99
+
`mem::replace` when the type referenced does not implement `Unpin`.
0 commit comments