Skip to content

DerefMut auto-deref error for union fields sometimes doesn't trigger #141621

@Alexendoo

Description

@Alexendoo

An implicit DerefMut of a MaybeUninit union field is an error, but sometimes that error does not fire. This is not a soundness issue as it's more like a lint

https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=3df4479c28c8a9ce5d2372e161c0e292

use std::mem::ManuallyDrop; union U { x: (), f: ManuallyDrop<(Vec<u8>,)>, } fn main() { let mut u = U { x: () }; // Errors about the implicit deref of the ManuallyDrop unsafe { u.f.0 = Vec::new() }; // equivalent to (*u.f).0 let r = &mut u; // implicitly derefs the ManuallyDrop but does not error unsafe { r.f.0 = Vec::new() }; // equivalent to (*(*r).f).0 }

I expected to see this happen: Both assignments should error

Instead, this happened: Only the first produces an error

error: not automatically applying `DerefMut` on `ManuallyDrop` union field --> src/main.rs:24:9 | 24 | a.tup.0.num = 0; | ^^^^^^^ | = help: writing to this reference calls the destructor for the old value = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor 

We ran into a similar case in rust-lang/rust-clippy#14387

https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=223c79eac2bb82ba9834354d2043d67f

use std::mem::ManuallyDrop; struct Data { num: u64, } union DataWithPadding { u: (), tup: (ManuallyDrop<Data>, ()), } fn main() { let mut a = DataWithPadding { u: () }; unsafe { // No error, but the ManuallyDrop in the tuple is being implicitly dereferenced (*&mut a.tup).0.num = 0; // equivalent to (*(*&mut a.tup).0).num // similar (&mut a.tup).0.num = 0; // Does error when written plainly a.tup.0.num = 0; } }

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-frontendArea: Compiler frontend (errors, parsing and HIR)C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions