Static_mut_refs lint is amusing

static mut A: S = S {};

struct S {}

impl S {
    fn mutate(&mut self) {}
}

fn main() {
    unsafe {
        // [rustc static_mut_refs] warning: creating a mutable reference to mutable static is discouraged
        // A.mutate();

        // error[E0599]: no method named `mutate` found for raw pointer `*mut S` in the current scope
        // (&raw mut A).mutate();
        
        // [clippy::deref_addrof] warning: immediately dereferencing a reference
        // [clippy::needless_borrow] warning: this expression borrows a value the compiler would automatically borrow
        // (&mut *&raw mut A).mutate();

        // [clippy::deref_addrof] warning: immediately dereferencing a reference
        // (*&raw mut A).mutate();
        
        let ptr = &raw mut A;
        (*ptr).mutate(); // good: no lint, but an extra line

        (*{ &raw mut A }).mutate(); // good: no lint, but extra braces
    }
}

playground

Full report for each group of diagnostics
warning: creating a mutable reference to mutable static is discouraged
  --> src/main.rs:12:9
   |
12 |         A.mutate();
   |         ^^^^^^^^^^ mutable reference to mutable static
   |
   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
   = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
   = note: `#[warn(static_mut_refs)]` on by default
error[E0599]: no method named `mutate` found for raw pointer `*mut S` in the current scope
  --> src/main.rs:15:22
   |
15 |         (&raw mut A).mutate();
   |                      ^^^^^^ method not found in `*mut S`
   |
note: the method `mutate` exists on the type `&mut S`
  --> src/main.rs:6:5
   |
6  |     fn mutate(&mut self) {}
   |     ^^^^^^^^^^^^^^^^^^^^
   = note: you might want to use the unsafe method `<*mut T>::as_mut` to get an optional reference to the value behind the pointer
   = note: read the documentation for `<*mut T>::as_mut` and ensure you satisfy its safety preconditions before calling it to avoid undefined behavior: https://doc.rust-lang.org/std/primitive.pointer.html#method.as_mut
// need clippy
warning: immediately dereferencing a reference
  --> src/main.rs:19:15
   |
19 |         (&mut *&raw mut A).mutate();
   |               ^^^^^^^^^^^ help: try: `A`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#deref_addrof
   = note: `#[warn(clippy::deref_addrof)]` on by default

warning: this expression borrows a value the compiler would automatically borrow
  --> src/main.rs:19:9
   |
19 |         (&mut *&raw mut A).mutate();
   |         ^^^^^^^^^^^^^^^^^^ help: change this to: `(*&raw mut A)`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow
   = note: `#[warn(clippy::needless_borrow)]` on by default
warning: immediately dereferencing a reference
  --> src/main.rs:21:10
   |
21 |         (*&raw mut A).mutate();
   |          ^^^^^^^^^^^ help: try: `A`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#deref_addrof
   = note: `#[warn(clippy::deref_addrof)]` on by default

P.S.

1 Like