Rollup merge of #157542 - Dnreikronos:pin_v2_ban_repr_packed, r=mejrs Reject `#[repr(packed)]` on `#[pin_v2]` types Fixes rust-lang/rust#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 rust-lang/rust#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.*
Website | Getting started | Learn | Documentation | Contributing
This is the main source code repository for Rust. It contains the compiler, standard library, and documentation.
Performance: Fast and memory-efficient, suitable for critical services, embedded devices, and easily integrated with other languages.
Reliability: Our rich type system and ownership model ensure memory and thread safety, reducing bugs at compile-time.
Productivity: Comprehensive documentation, a compiler committed to providing great diagnostics, and advanced tooling including package manager and build tool (Cargo), auto-formatter (rustfmt), linter (Clippy) and editor support (rust-analyzer).
Read “Installation” from The Book.
If you really want to install from source (though this is not recommended), see INSTALL.md.
See https://www.rust-lang.org/community for a list of chat platforms and forums.
See CONTRIBUTING.md.
For a detailed explanation of the compiler's architecture and how to begin contributing, see the rustc-dev-guide.
Rust is primarily distributed under the terms of both the MIT license and the Apache License (Version 2.0), with portions covered by various BSD-like licenses.
See LICENSE-APACHE, LICENSE-MIT, and COPYRIGHT for details.
The Rust Foundation owns and protects the Rust and Cargo trademarks and logos (the “Rust Trademarks”).
If you want to use these names or brands, please read the Rust language trademark policy.
Third-party logos may be subject to third-party copyrights and trademarks. See Licenses for details.