Skip to content

Commit 360a768

Browse files
Improve the PhantomData table (#417)
1 parent 83d0151 commit 360a768

File tree

1 file changed

+23
-12
lines changed

1 file changed

+23
-12
lines changed

src/phantom-data.md

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,14 @@ that that `Vec<T>` _owns_ values of type `T` (more precisely: may use values of
106106
in its `Drop` implementation), and Rust will thus not allow them to _dangle_ should a
107107
`Vec<T>` be dropped.
108108

109-
**Adding an extra `_owns_T: PhantomData<T>` field is thus _superfluous_ and accomplishes nothing**.
109+
When a type already has a `Drop impl`, **adding an extra `_owns_T: PhantomData<T>` field
110+
is thus _superfluous_ and accomplishes nothing**, dropck-wise (it still affects variance
111+
and auto-traits).
112+
113+
- (advanced edge case: if the type containing the `PhantomData` has no `Drop` impl at all,
114+
but still has drop glue (by having _another_ field with drop glue), then the
115+
dropck/`#[may_dangle]` considerations mentioned herein do apply as well: a `PhantomData<T>`
116+
field will then require `T` to be droppable whenever the containing type goes out of scope).
110117

111118
___
112119

@@ -234,14 +241,18 @@ standard library made a utility for itself called `Unique<T>` which:
234241

235242
Here’s a table of all the wonderful ways `PhantomData` could be used:
236243

237-
| Phantom type | `'a` | `T` | `Send` | `Sync` |
238-
|-----------------------------|-----------|-----------------------------|-----------|-----------|
239-
| `PhantomData<T>` | - | covariant (with drop check) | `T: Send` | `T: Sync` |
240-
| `PhantomData<&'a T>` | covariant | covariant | `T: Sync` | `T: Sync` |
241-
| `PhantomData<&'a mut T>` | covariant | invariant | `T: Send` | `T: Sync` |
242-
| `PhantomData<*const T>` | - | covariant | - | - |
243-
| `PhantomData<*mut T>` | - | invariant | - | - |
244-
| `PhantomData<fn(T)>` | - | contravariant | `Send` | `Sync` |
245-
| `PhantomData<fn() -> T>` | - | covariant | `Send` | `Sync` |
246-
| `PhantomData<fn(T) -> T>` | - | invariant | `Send` | `Sync` |
247-
| `PhantomData<Cell<&'a ()>>` | invariant | - | `Send` | - |
244+
| Phantom type | variance of `'a` | variance of `T` | `Send`/`Sync`<br/>(or lack thereof) | dangling `'a` or `T` in drop glue<br/>(_e.g._, `#[may_dangle] Drop`) |
245+
|-----------------------------|:----------------:|:-----------------:|:-----------------------------------------:|:------------------------------------------------:|
246+
| `PhantomData<T>` | - | **cov**ariant | inherited | disallowed ("owns `T`") |
247+
| `PhantomData<&'a T>` | **cov**ariant | **cov**ariant | `Send + Sync`<br/>requires<br/>`T : Sync` | allowed |
248+
| `PhantomData<&'a mut T>` | **cov**ariant | **inv**ariant | inherited | allowed |
249+
| `PhantomData<*const T>` | - | **cov**ariant | `!Send + !Sync` | allowed |
250+
| `PhantomData<*mut T>` | - | **inv**ariant | `!Send + !Sync` | allowed |
251+
| `PhantomData<fn(T)>` | - | **contra**variant | `Send + Sync` | allowed |
252+
| `PhantomData<fn() -> T>` | - | **cov**ariant | `Send + Sync` | allowed |
253+
| `PhantomData<fn(T) -> T>` | - | **inv**ariant | `Send + Sync` | allowed |
254+
| `PhantomData<Cell<&'a ()>>` | **inv**ariant | - | `Send + !Sync` | allowed |
255+
256+
- Note: opting out of the `Unpin` auto-trait requires the dedicated [`PhantomPinned`] type instead.
257+
258+
[`PhantomPinned`]: ../core/marker/struct.PhantomPinned.html

0 commit comments

Comments
 (0)