Skip to content

multiple_unsafe_ops_per_block: false positive with write to field holding a union #17454

Description

@DanielEScherzer

Summary

Writing to a union is considered safe. However, when a structure contains a field that is a union, multiple_unsafe_ops_per_block considers writing to that union to be unsafe.

Lint Name

multiple_unsafe_ops_per_block

Reproducer

I tried this code:

#![warn(clippy::multiple_unsafe_ops_per_block)]

union Example {
    f1: u32,
    f2: bool,
}
struct HoldsExample {
    e: Example,
}

fn set_union_value(target: &mut HoldsExample, value: *const u32) {
    unsafe {
        target.e.f1 = *value;
    };
}

fn main() {
    let mut example = HoldsExample { e: Example { f2: true } };
    set_union_value(&mut example, &5);
    println!("Value: {}", unsafe { example.e.f1 } );
}

I saw this happen:

    Checking playground v0.0.1 (/playground)
warning: this `unsafe` block contains 2 unsafe operations, expected only one
  --> src/main.rs:12:5
   |
12 | /     unsafe {
13 | |         target.e.f1 = *value;
14 | |     };
   | |_____^
   |
note: raw pointer dereference occurs here
  --> src/main.rs:13:23
   |
13 |         target.e.f1 = *value;
   |                       ^^^^^^
note: union field access occurs here
  --> src/main.rs:13:9
   |
13 |         target.e.f1 = *value;
   |         ^^^^^^^^^^^
   = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.97.0/index.html#multiple_unsafe_ops_per_block
note: the lint level is defined here
  --> src/main.rs:1:9
   |
 1 | #![warn(clippy::multiple_unsafe_ops_per_block)]
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: `playground` (bin "playground") generated 1 warning
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.62s

I expected to see this happen:

Lint not triggered, the note: union field access occurs here note is for something that is entirely safe, can be verified by switching set_union_value() to be:

fn set_union_value(target: &mut HoldsExample, value: *const u32) {
    let dereferenced = unsafe { *value };
    target.e.f1 = dereferenced;
}

Version

Clippy 0.1.97 (2026-07-14 8bab26f4f6)
Playground 1.97.1

Additional Labels

No response

Metadata

Metadata

Labels

C-bugCategory: Clippy is not doing the correct thingI-false-positiveIssue: The lint was triggered on code it shouldn't have

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions