Skip to content

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

Open
@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;
    }
}

Activity

added
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on May 26, 2025
added
T-langRelevant to the language team
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
A-frontendArea: Compiler frontend (errors, parsing and HIR)
and removed
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on May 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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

        Participants

        @Alexendoo@lolbinarycat@rustbot

        Issue actions

          `DerefMut` auto-deref error for `union` fields sometimes doesn't trigger · Issue #141621 · rust-lang/rust