rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.24k stars 12.71k forks source link

Missing parenthesis in `static_mut_refs` diagnostic suggestion #131977

Open CharlyCst opened 2 weeks ago

CharlyCst commented 2 weeks ago

Code

static mut TEST: usize = 0;

fn main() {
    let _ = unsafe { (&TEST) as *const usize };
}

Current output

   Compiling playground v0.0.1 (/playground)
warning: creating a shared reference to mutable static is discouraged
 --> src/main.rs:4:22
  |
4 |     let _ = unsafe { (&TEST) as *const usize };
  |                      ^^^^^^^ shared reference to mutable static
  |
  = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
  = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
  = note: `#[warn(static_mut_refs)]` on by default
help: use `&raw const` instead to create a raw pointer
  |
4 |     let _ = unsafe { &raw const TEST) as *const usize };
  |                      ~~~~~~~~~~

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

Desired output

   Compiling playground v0.0.1 (/playground)
warning: creating a shared reference to mutable static is discouraged
 --> src/main.rs:4:22
  |
4 |     let _ = unsafe { (&TEST) as *const usize };
  |                      ^^^^^^^ shared reference to mutable static
  |
  = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
  = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
  = note: `#[warn(static_mut_refs)]` on by default
help: use `&raw const` instead to create a raw pointer
  |
4 |     let _ = unsafe { (&raw const TEST) as *const usize };
  |                       ~~~~~~~~~~

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

Rationale and extra context

The suggestion removes the left parenthesis, but keeps the right parenthesis. Of course the proposed change does not compile. Original code: (&TEST) suggestion: &raw const TEST)

Other cases

No response

Rust Version

rustc 1.84.0-nightly (da935398d 2024-10-19) binary: rustc commit-hash: da935398d582344c5b7689bd6632d8ec01b0c988 commit-date: 2024-10-19 host: aarch64-apple-darwin release: 1.84.0-nightly LLVM version: 19.1.1

Anything else?

Link to rust playground

indegrowl commented 2 weeks ago

Pretty straightforward! I'll work on it. It'll be my first PR.

gechelberger commented 2 weeks ago

This is actually more complicated than I assumed.

The offending code is operating on the HIR where parens have already been elided into the token tree heirarchy.

The suggested replacement of &raw const or &raw mut is dropped into the span err_span.with_hi(ex.span.lo()) from here.

The cleanest way to solve it would be to narrow the referenced span when lowering from the AST to the HIR so that the 'hir::Expr' node's Span doesn't point to or include the parens - only the contents of them - since the HIR isn't supposed to know about parens anyways.

I doubt that this would change the correctness of other lints and errors operating on the HIR, but it almost certainly breaks a lot of the ui compiletests which would then have different spans highlighted in their stderr contents.

Are there other lints/errors that have run into similar issues to reference?

gechelberger commented 2 weeks ago

For reference, I commented out this line which replaces the HIR Span with the AST Paren Span to get a sense for how significant of an effect it would have:

It is definitely not the solution on its own.

ui-tests.txt