Commit 9308e4c
committed
Add the
This attribute is equivalent to `#[lang = "manually_drop"]`, and the behavior of both are
extended to allow the type to define `Drop`, in which case, that will still be run. Only
the field drop glue is suppressed.
This PR should essentially fully implement #100344.
Some additional notes:
`#[manually_drop]` means "do not destroy the fields automatically during
destruction". `ManuallyDrop`, is (or could be) "just"
`#[manually_drop] struct ManuallyDrop<T>(T);`.
The intent is, per the MCP, to allow customization of the drop order, without making the
interface for initializing or accessing the fields of the struct clumsier than a normal
Rust type. It also -- and people did seem excited about this part -- lifts `ManuallyDrop`
from being a special language supported feature to just another user of
`#[manually_drop]`.
There is the question of how this interacts with "insignificant" drop. I had trouble
understanding the comments, but insignificant drop appears to just be a static analysis
tool, and not something that changes behavior. (For example, it's used to detect if a
language change will reorder drops in a meaningful way -- meaning, reorder the
significant drops, not the insignificant ones.) Since it's unlikely to be used for
`#[manually_drop]` types, I don't think it matters a whole lot. And where a destructor
is defined, it would seem to make sense for `#[manually_drop]` types to match exactly
the behavior of `union`, since they both have the shared property that field drop
glue is suppressed.
I looked for all locations that queried for `is_manually_drop` in any form, and found two
difficult cases which are hardcoded for `ManuallyDrop` in particular.
The first is a clippy lint for redundant clones. I don't understand why it special-cases
`ManuallyDrop`, and it's almost certainly wrong for it to special-case `#[manually_drop]`
types in general. However, without understanding the original rationale, I have trouble
figuring the right fix. Perhaps it should simply be deleted altogether.
The second is unions -- specifically, the logic for disabling `DerefMut`.
`my_union.x.y = z` will automatically dereference `my_union.x` if it implements
`DerefMut`, unless it is `ManuallyDrop`, in which case it will not. This is because
`ManuallyDrop` is a pointer back to its content, and so this will automatically call `drop`
on a probably uninitialized field, and is unsafe.
This is true of `ManuallyDrop`, but not necessarily any other `#[manually_drop]` type.
I believe the correct fix would, instead, be a way to mark and detect types which are
a smart pointer whose pointee is within `self`. See, for example, this playground link:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=76fb22a6214ce453538fc18ec35a839d
But that needs to wait for a separate RFC. For now, we apply exactly the same restriction
for `ManuallyDrop` and for any other `#[manually_drop]` type, even though it may be
confusing.
1. Delete `#[lang = "manually_drop"]`. I'm not sure if anything special needs to be done
here other than replacing it with `#[manually_drop]` -- is there a compatibility
guarantee that must be upheld?
2. (Optional) Fix the redundant clone check to correctly handle `#[manually_drop]`
structs that aren't `ManuallyDrop`.
3. When there is more experience with the feature (e.g. in Crubit) create a full RFC
based on the MCP, and go through the remainder of the stabilization process.
(Also, do things like generalize the union error messages to not specifically
mention `ManuallyDrop`, but also mention `#[manually_drop]`. For as long as the
feature is unstable, the error messages would be confusing if they referenced
it...)#[manually_drop] attribute.1 parent 7ff69b4 commit 9308e4c
File tree
26 files changed
+372
-30
lines changed- compiler
- rustc_feature/src
- rustc_hir_analysis/src/check
- rustc_hir_typeck/src
- rustc_middle/src/ty
- rustc_mir_dataflow/src
- rustc_passes/src
- rustc_span/src
- rustc_trait_selection/src/traits/query
- rustc_ty_utils/src
- src
- doc/unstable-book/src/language-features
- test/ui/manually_drop_attr
- tools/clippy/clippy_lints/src
- tests/ui/union
26 files changed
+372
-30
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
442 | 442 | | |
443 | 443 | | |
444 | 444 | | |
| 445 | + | |
| 446 | + | |
445 | 447 | | |
446 | 448 | | |
447 | 449 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
480 | 480 | | |
481 | 481 | | |
482 | 482 | | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
483 | 487 | | |
484 | 488 | | |
485 | 489 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
112 | 112 | | |
113 | 113 | | |
114 | 114 | | |
115 | | - | |
116 | | - | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
117 | 119 | | |
118 | 120 | | |
119 | 121 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
330 | 330 | | |
331 | 331 | | |
332 | 332 | | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
333 | 339 | | |
334 | 340 | | |
335 | 341 | | |
336 | 342 | | |
337 | 343 | | |
338 | | - | |
| 344 | + | |
339 | 345 | | |
340 | 346 | | |
341 | 347 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
241 | 241 | | |
242 | 242 | | |
243 | 243 | | |
244 | | - | |
| 244 | + | |
245 | 245 | | |
246 | 246 | | |
247 | 247 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
443 | 443 | | |
444 | 444 | | |
445 | 445 | | |
446 | | - | |
447 | | - | |
| 446 | + | |
448 | 447 | | |
449 | 448 | | |
450 | 449 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
193 | 193 | | |
194 | 194 | | |
195 | 195 | | |
| 196 | + | |
196 | 197 | | |
197 | 198 | | |
198 | 199 | | |
| |||
2091 | 2092 | | |
2092 | 2093 | | |
2093 | 2094 | | |
| 2095 | + | |
| 2096 | + | |
| 2097 | + | |
| 2098 | + | |
| 2099 | + | |
| 2100 | + | |
| 2101 | + | |
| 2102 | + | |
| 2103 | + | |
| 2104 | + | |
| 2105 | + | |
2094 | 2106 | | |
2095 | 2107 | | |
2096 | 2108 | | |
| |||
2370 | 2382 | | |
2371 | 2383 | | |
2372 | 2384 | | |
| 2385 | + | |
2373 | 2386 | | |
2374 | 2387 | | |
2375 | 2388 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
639 | 639 | | |
640 | 640 | | |
641 | 641 | | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
642 | 649 | | |
643 | 650 | | |
644 | 651 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
902 | 902 | | |
903 | 903 | | |
904 | 904 | | |
| 905 | + | |
905 | 906 | | |
906 | 907 | | |
907 | 908 | | |
| |||
Lines changed: 3 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
49 | 49 | | |
50 | 50 | | |
51 | 51 | | |
52 | | - | |
53 | | - | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
54 | 55 | | |
55 | 56 | | |
56 | 57 | | |
| |||
0 commit comments