`DerefMut` auto-deref error for `union` fields sometimes doesn't trigger
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.2k
- PR merge metrics
- PR metrics pending
Description
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
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 https://github.com/rust-lang/rust-clippy/pull/14387
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;
}
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the two Rust Playground reproductions linked in the issue and compare the direct and reference-based union-field assignments. Trace the compiler handling of implicit DerefMut for these expressions, then add a regression test showing that both assignments produce the expected error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100