Commit e43ec0c
authored
Rollup merge of #157542 - Dnreikronos:pin_v2_ban_repr_packed, r=mejrs
Reject `#[repr(packed)]` on `#[pin_v2]` types
Fixes #157011
`#[repr(packed)]` can store an over-aligned field below its alignment, and the drop glue for a packed type moves that field to a properly aligned spot before dropping it. When the field is structurally pinned, that move pulls it out from under a `Pin<&mut _>` we already handed out, which breaks the pin invariant. The repro in the issue makes it pretty clear: it prints one address during pinned access and a different one on drop.
So the fix just rejects the combo at the type definition. If a type is both `#[pin_v2]` and `#[repr(packed)]`, it no longer compiles. The check sits in `check_packed` in `rustc_hir_analysis`, so it catches the concrete case and the generic one too (like `One<T>`, where we don't know `T`'s alignment yet), with no layout or monomorphization needed.
One thing I want to be upfront about: this is necessary but don't solve the problem entirely. Sure, it stops the spelling the issue used, but you can still trigger the same move-on-drop through an explicit `&pin mut` / `ref pin mut` projection with no `#[pin_v2]` anywhere. Leaving that broader case open is intentional, imo the narrow ban is the right call for now, and the leftover stays tracked on the pin ergonomics tracking issue #130494.
This is the direction we landed on with `@workingjubilee` over on Zulip, lgtm from their side: https://rust-lang.zulipchat.com/#narrow/channel/182449-t-compiler.2Fhelp/topic/.60pin_v2.60.20is.20unsound.20with.20.60packed.60/with/600522893
Tests live in `tests/ui/pin-ergonomics/pin_v2-packed.rs`: the three rejected shapes (packed struct, generic `packed(4)` struct, packed union), plus two controls that still compile fine, `#[pin_v2]` without packed and packed without `#[pin_v2]`.
*Disclosure: AI tooling was used on the code changes, and everything was strictly validated by me before sending to remote.*4 files changed
Lines changed: 106 additions & 0 deletions
File tree
- compiler/rustc_hir_analysis/src
- check
- tests/ui/pin-ergonomics
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1635 | 1635 | | |
1636 | 1636 | | |
1637 | 1637 | | |
| 1638 | + | |
| 1639 | + | |
| 1640 | + | |
| 1641 | + | |
| 1642 | + | |
| 1643 | + | |
| 1644 | + | |
| 1645 | + | |
| 1646 | + | |
| 1647 | + | |
1638 | 1648 | | |
1639 | 1649 | | |
1640 | 1650 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2035 | 2035 | | |
2036 | 2036 | | |
2037 | 2037 | | |
| 2038 | + | |
| 2039 | + | |
| 2040 | + | |
| 2041 | + | |
| 2042 | + | |
| 2043 | + | |
| 2044 | + | |
| 2045 | + | |
| 2046 | + | |
| 2047 | + | |
| 2048 | + | |
| 2049 | + | |
| 2050 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
0 commit comments