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: src/libs/maintaining-std.md
+3-15Lines changed: 3 additions & 15 deletions
Original file line number
Diff line number
Diff line change
@@ -189,7 +189,7 @@ Changes to collection internals may affect the order their items are dropped in.
189
189
190
190
A generic `Type<T>` that manually implements `Drop` should consider whether a `#[may_dangle]` attribute is appropriate on `T`. The [Nomicon][dropck] has some details on what `#[may_dangle]` is all about.
191
191
192
-
If a generic `Type<T>` has a manual drop implementation that may also involve dropping `T` then dropck needs to know about it. If `Type<T>`'s ownership of `T` is expressed indirectly through pointers, such as `*mut T` or `MaybeUninit<T>`, then `Type<T>` also [needs a `PhantomData<T>` field][RFC 0769 PhantomData] to tell dropck that `T` may be dropped. Types in the standard library that use the internal `Unique<T>` pointer type don't need a `PhantomData<T>` marker field. That's taken care of for them by `Unique<T>`.
192
+
If a generic `Type<T>` has a manual drop implementation that may also involve dropping `T` then dropck needs to know about it. If `Type<T>`'s ownership of `T` is expressed through types that don't drop `T` themselves such as `ManuallyDrop<T>`, `*mut T`, or `MaybeUninit<T>` then `Type<T>` also [needs a `PhantomData<T>` field][RFC 0769 PhantomData] to tell dropck that `T` may be dropped. Types in the standard library that use the internal `Unique<T>` pointer type don't need a `PhantomData<T>` marker field. That's taken care of for them by `Unique<T>`.
193
193
194
194
As a real-world example of where this can go wrong, consider an `OptionCell<T>` that looks something like this:
195
195
@@ -207,7 +207,7 @@ impl<T> Drop for OptionCell<T> {
207
207
}
208
208
```
209
209
210
-
Adding a `#[may_dangle]` attribute to this `OptionCell<T>` that didn't have a `PhantomData<T>` marker field opened up [a soundness hole][rust/issues/76367] for `T`'s that didn't strictly outlive the `OptionCell<T>`, and so could be accessed after being dropped in their own `Drop` implementations. The `OptionCell<T>` first needed a `PhantomData<T>` field:
210
+
Adding a `#[may_dangle]` attribute to this `OptionCell<T>` that didn't have a `PhantomData<T>` marker field opened up [a soundness hole][rust/issues/76367] for `T`'s that didn't strictly outlive the `OptionCell<T>`, and so could be accessed after being dropped in their own `Drop` implementations. The correct application of `#[may_dangle]` also required a `PhantomData<T>` field:
211
211
212
212
```diff
213
213
struct OptionCell<T> {
@@ -216,19 +216,7 @@ struct OptionCell<T> {
216
216
+ _marker: PhantomData<T>,
217
217
}
218
218
219
-
impl Drop<T> for OptionCell<T> {
220
-
```
221
-
222
-
Then `#[may_dangle]` could be added to the `Drop` implementation:
223
-
224
-
```diff
225
-
struct OptionCell<T> {
226
-
is_init: bool,
227
-
value: MaybeUninit<T>,
228
-
_marker: PhantomData<T>,
229
-
}
230
-
231
-
- impl Drop<T> for OptionCell<T> {
219
+
- impl<T> Drop for OptionCell<T> {
232
220
+ unsafe impl<#[may_dangle] T> Drop for OptionCell<T> {
0 commit comments