From a98d8ad23691acaf3b337b45976d53a692822c90 Mon Sep 17 00:00:00 2001 From: cclfmht Date: Sun, 12 Jul 2026 08:47:09 +0800 Subject: [PATCH 1/3] Fix static-mut-refs lint check logic Previously, the lint might suggested using interior mutable type even if it the compiler already decides that the referenced type is interior mutable, while it didn't give such suggestion when the referenced type is considered non-interior mutable. This commit refined the logic as follow: if the referenced type is not interior mutable, then suggests using types with interior mutability; otherwise, suggests removing `mut` if the reference is a *shared* reference. Note that in the latter case, compiler might be silent if the span of the `static mut` definition is not appropriate for suggestions (e.g., comes from macro expansion). --- compiler/rustc_lint/src/lints.rs | 2 +- compiler/rustc_lint/src/static_mut_refs.rs | 9 +++++++-- .../borrowck-unsafe-static-mutable-borrows.stderr | 1 + tests/ui/consts/const_let_assign2.stderr | 1 + ...tatic-mut-refs-interior-mutability-no-sugg.stderr | 1 - .../lint/static-mut-refs-interior-mutability.stderr | 2 +- tests/ui/lint/static-mut-refs.e2021.stderr | 12 ++++++++++++ tests/ui/lint/static-mut-refs.e2024.stderr | 12 ++++++++++++ ...thread-local-static-mut-borrow-outlives-fn.stderr | 1 + tests/ui/statics/issue-15261.stderr | 1 + .../statics/static-lazy-init-with-arena-set.stderr | 2 +- tests/ui/statics/static-mut-shared-parens.stderr | 2 ++ tests/ui/statics/static-mut-xc.stderr | 7 +++++++ tests/ui/statics/static-recursive.stderr | 2 ++ 14 files changed, 49 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index eb82afab13186..d2bb70b07f8c8 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2728,7 +2728,7 @@ pub(crate) enum MutRefSugg { #[derive(Subdiagnostic)] #[suggestion( - "this type already provides \"interior mutability\", so its binding doesn't need to be declared as mutable", + "this type already provides \"interior mutability\", so its binding doesn't need to be declared as mutable when borrowed with a shared reference", style = "verbose", applicability = "maybe-incorrect", code = "" diff --git a/compiler/rustc_lint/src/static_mut_refs.rs b/compiler/rustc_lint/src/static_mut_refs.rs index 67e83d0652c3d..78dfcf41a8309 100644 --- a/compiler/rustc_lint/src/static_mut_refs.rs +++ b/compiler/rustc_lint/src/static_mut_refs.rs @@ -184,7 +184,7 @@ fn emit_static_mut_refs( }; let (interior_mutability_help, interior_mutability_sugg) = - interior_mutability_suggestion(cx, def_id); + interior_mutability_suggestion(cx, def_id, mut_note); cx.emit_span_lint( STATIC_MUT_REFS, @@ -208,17 +208,22 @@ fn emit_static_mut_refs( fn interior_mutability_suggestion( cx: &LateContext<'_>, def_id: DefId, + mut_ref: bool, ) -> (bool, Option) { let static_ty = cx.tcx.type_of(def_id).skip_binder(); let has_interior_mutability = !static_ty.is_freeze(cx.tcx, cx.typing_env()); if !has_interior_mutability { + return (true, None); + } + + if mut_ref { return (false, None); } let sugg = static_mutability_span(cx, def_id).map(|span| StaticMutRefsInteriorMutabilitySugg { span }); - (sugg.is_none(), sugg) + (false, sugg) } fn static_mutability_span(cx: &LateContext<'_>, def_id: DefId) -> Option { diff --git a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr index 6c3fd9eb400f2..58ea9fe5a74b6 100644 --- a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr +++ b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr @@ -5,6 +5,7 @@ LL | let sfoo: *mut Foo = &mut SFOO; | ^^^^^^^^^ mutable reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default help: use `&raw mut` instead to create a raw pointer diff --git a/tests/ui/consts/const_let_assign2.stderr b/tests/ui/consts/const_let_assign2.stderr index e4edb58461054..ef6202cf7df85 100644 --- a/tests/ui/consts/const_let_assign2.stderr +++ b/tests/ui/consts/const_let_assign2.stderr @@ -5,6 +5,7 @@ LL | let ptr = unsafe { &mut BB }; | ^^^^^^^ mutable reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default help: use `&raw mut` instead to create a raw pointer diff --git a/tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.stderr b/tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.stderr index 5ce69e1a14d83..e5db09a670cc9 100644 --- a/tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.stderr +++ b/tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.stderr @@ -5,7 +5,6 @@ LL | let _lock = unsafe { MACRO_MUTEX.lock().unwrap() }; | ^^^^^^^^^^^^^^^^^^ shared reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[deny(static_mut_refs)]` (part of `#[deny(rust_2024_compatibility)]`) on by default diff --git a/tests/ui/lint/static-mut-refs-interior-mutability.stderr b/tests/ui/lint/static-mut-refs-interior-mutability.stderr index 29ab5a5c404de..d6a644374d8a2 100644 --- a/tests/ui/lint/static-mut-refs-interior-mutability.stderr +++ b/tests/ui/lint/static-mut-refs-interior-mutability.stderr @@ -7,7 +7,7 @@ LL | let _lock = unsafe { STDINOUT_MUTEX.lock().unwrap() }; = 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: for more information, see = note: `#[deny(static_mut_refs)]` (part of `#[deny(rust_2024_compatibility)]`) on by default -help: this type already provides "interior mutability", so its binding doesn't need to be declared as mutable +help: this type already provides "interior mutability", so its binding doesn't need to be declared as mutable when borrowed with a shared reference | LL - static mut STDINOUT_MUTEX: Mutex = Mutex::new(false); LL + static STDINOUT_MUTEX: Mutex = Mutex::new(false); diff --git a/tests/ui/lint/static-mut-refs.e2021.stderr b/tests/ui/lint/static-mut-refs.e2021.stderr index 56b4ad239afe3..89a4f3cc4932d 100644 --- a/tests/ui/lint/static-mut-refs.e2021.stderr +++ b/tests/ui/lint/static-mut-refs.e2021.stderr @@ -5,6 +5,7 @@ LL | let _y = &X; | ^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default help: use `&raw const` instead to create a raw pointer @@ -19,6 +20,7 @@ LL | let _y = &mut X; | ^^^^^^ mutable reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw mut` instead to create a raw pointer | @@ -32,6 +34,7 @@ LL | let ref _a = X; | ^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see warning: creating a shared reference to mutable static @@ -41,6 +44,7 @@ LL | let (_b, _c) = (&X, &Y); | ^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | @@ -54,6 +58,7 @@ LL | let (_b, _c) = (&X, &Y); | ^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | @@ -67,6 +72,7 @@ LL | foo(&X); | ^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | @@ -80,6 +86,7 @@ LL | let _ = Z.len(); | ^^^^^^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see warning: creating a shared reference to mutable static @@ -89,6 +96,7 @@ LL | let _ = format!("{:?}", Z); | ^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see warning: creating a shared reference to mutable static @@ -98,6 +106,7 @@ LL | let _v = &A.value; | ^^^^^^^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | @@ -111,6 +120,7 @@ LL | let _s = &A.s.value; | ^^^^^^^^^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | @@ -124,6 +134,7 @@ LL | let ref _v = A.value; | ^^^^^^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see warning: creating a mutable reference to mutable static @@ -136,6 +147,7 @@ LL | let _x = bar!(FOO); | --------- in this macro invocation | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: this warning originates in the macro `bar` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/lint/static-mut-refs.e2024.stderr b/tests/ui/lint/static-mut-refs.e2024.stderr index 0b7f48a507c94..a0c4e9d9620a0 100644 --- a/tests/ui/lint/static-mut-refs.e2024.stderr +++ b/tests/ui/lint/static-mut-refs.e2024.stderr @@ -5,6 +5,7 @@ LL | let _y = &X; | ^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[deny(static_mut_refs)]` (part of `#[deny(rust_2024_compatibility)]`) on by default help: use `&raw const` instead to create a raw pointer @@ -19,6 +20,7 @@ LL | let _y = &mut X; | ^^^^^^ mutable reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw mut` instead to create a raw pointer | @@ -32,6 +34,7 @@ LL | let ref _a = X; | ^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see error: creating a shared reference to mutable static @@ -41,6 +44,7 @@ LL | let (_b, _c) = (&X, &Y); | ^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | @@ -54,6 +58,7 @@ LL | let (_b, _c) = (&X, &Y); | ^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | @@ -67,6 +72,7 @@ LL | foo(&X); | ^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | @@ -80,6 +86,7 @@ LL | let _ = Z.len(); | ^^^^^^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see error: creating a shared reference to mutable static @@ -89,6 +96,7 @@ LL | let _ = format!("{:?}", Z); | ^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see error: creating a shared reference to mutable static @@ -98,6 +106,7 @@ LL | let _v = &A.value; | ^^^^^^^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | @@ -111,6 +120,7 @@ LL | let _s = &A.s.value; | ^^^^^^^^^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | @@ -124,6 +134,7 @@ LL | let ref _v = A.value; | ^^^^^^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see error: creating a mutable reference to mutable static @@ -136,6 +147,7 @@ LL | let _x = bar!(FOO); | --------- in this macro invocation | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: this error originates in the macro `bar` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr index 19a3a786ac940..95ca981679b65 100644 --- a/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr +++ b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr @@ -5,6 +5,7 @@ LL | S1 { a: unsafe { &mut X1 } } | ^^^^^^^ mutable reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default help: use `&raw mut` instead to create a raw pointer diff --git a/tests/ui/statics/issue-15261.stderr b/tests/ui/statics/issue-15261.stderr index fdc8e0c1f5ef7..b9578523de3a9 100644 --- a/tests/ui/statics/issue-15261.stderr +++ b/tests/ui/statics/issue-15261.stderr @@ -5,6 +5,7 @@ LL | static n: &'static usize = unsafe { &n_mut }; | ^^^^^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default help: use `&raw const` instead to create a raw pointer diff --git a/tests/ui/statics/static-lazy-init-with-arena-set.stderr b/tests/ui/statics/static-lazy-init-with-arena-set.stderr index 43b244607885d..4aed8b06166c8 100644 --- a/tests/ui/statics/static-lazy-init-with-arena-set.stderr +++ b/tests/ui/statics/static-lazy-init-with-arena-set.stderr @@ -12,7 +12,7 @@ LL | | }); = 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: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default -help: this type already provides "interior mutability", so its binding doesn't need to be declared as mutable +help: this type already provides "interior mutability", so its binding doesn't need to be declared as mutable when borrowed with a shared reference | LL - static mut ONCE: Once = Once::new(); LL + static ONCE: Once = Once::new(); diff --git a/tests/ui/statics/static-mut-shared-parens.stderr b/tests/ui/statics/static-mut-shared-parens.stderr index 1265bdc7cf0d3..70e43f208ac7b 100644 --- a/tests/ui/statics/static-mut-shared-parens.stderr +++ b/tests/ui/statics/static-mut-shared-parens.stderr @@ -5,6 +5,7 @@ LL | let _ = unsafe { (&TEST) as *const usize }; | ^^^^^^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default help: use `&raw const` instead to create a raw pointer @@ -19,6 +20,7 @@ LL | let _ = unsafe { (&mut TEST) as *const usize }; | ^^^^^^^^^^^ mutable reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw mut` instead to create a raw pointer | diff --git a/tests/ui/statics/static-mut-xc.stderr b/tests/ui/statics/static-mut-xc.stderr index d0b30ce6f8514..91be2b50a11f5 100644 --- a/tests/ui/statics/static-mut-xc.stderr +++ b/tests/ui/statics/static-mut-xc.stderr @@ -5,6 +5,7 @@ LL | assert_eq!(static_mut_xc::a, 3); | ^^^^^^^^^^^^^^^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default @@ -15,6 +16,7 @@ LL | assert_eq!(static_mut_xc::a, 4); | ^^^^^^^^^^^^^^^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see warning: creating a shared reference to mutable static @@ -24,6 +26,7 @@ LL | assert_eq!(static_mut_xc::a, 5); | ^^^^^^^^^^^^^^^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see warning: creating a shared reference to mutable static @@ -33,6 +36,7 @@ LL | assert_eq!(static_mut_xc::a, 15); | ^^^^^^^^^^^^^^^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see warning: creating a shared reference to mutable static @@ -42,6 +46,7 @@ LL | assert_eq!(static_mut_xc::a, -3); | ^^^^^^^^^^^^^^^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see warning: creating a shared reference to mutable static @@ -51,6 +56,7 @@ LL | static_bound(&static_mut_xc::a); | ^^^^^^^^^^^^^^^^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | @@ -64,6 +70,7 @@ LL | static_bound_set(&mut static_mut_xc::a); | ^^^^^^^^^^^^^^^^^^^^^ mutable reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw mut` instead to create a raw pointer | diff --git a/tests/ui/statics/static-recursive.stderr b/tests/ui/statics/static-recursive.stderr index 1ae96dfd5a832..56200e9f53d07 100644 --- a/tests/ui/statics/static-recursive.stderr +++ b/tests/ui/statics/static-recursive.stderr @@ -5,6 +5,7 @@ LL | static mut S: *const u8 = unsafe { &S as *const *const u8 as *const u8 }; | ^^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default help: use `&raw const` instead to create a raw pointer @@ -19,6 +20,7 @@ LL | assert_eq!(S, *(S as *const *const u8)); | ^ shared reference to mutable static | = 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 + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see warning: 2 warnings emitted From cb055bc6f78bd7de9667f1a6090a112ebf1c5fa9 Mon Sep 17 00:00:00 2001 From: cclfmht Date: Sun, 12 Jul 2026 19:01:01 +0800 Subject: [PATCH 2/3] Do not suggest interior mutable types for explicit borrows For cases like `&a` or `&mut a`, we only leave a subdiagnostic to suggest user to use raw borrow operators. Using raw pointers in such cases are also equally viable solution but it's not appropriate to suggest using interior mutable types at the same time. --- compiler/rustc_lint/src/static_mut_refs.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_lint/src/static_mut_refs.rs b/compiler/rustc_lint/src/static_mut_refs.rs index 78dfcf41a8309..0dbed4ed1c0da 100644 --- a/compiler/rustc_lint/src/static_mut_refs.rs +++ b/compiler/rustc_lint/src/static_mut_refs.rs @@ -184,7 +184,7 @@ fn emit_static_mut_refs( }; let (interior_mutability_help, interior_mutability_sugg) = - interior_mutability_suggestion(cx, def_id, mut_note); + interior_mutability_suggestion(cx, def_id, mut_note, suggest_addr_of); cx.emit_span_lint( STATIC_MUT_REFS, @@ -209,12 +209,13 @@ fn interior_mutability_suggestion( cx: &LateContext<'_>, def_id: DefId, mut_ref: bool, + suggest_addr_of: bool, ) -> (bool, Option) { let static_ty = cx.tcx.type_of(def_id).skip_binder(); let has_interior_mutability = !static_ty.is_freeze(cx.tcx, cx.typing_env()); if !has_interior_mutability { - return (true, None); + return (!suggest_addr_of, None); } if mut_ref { From 1e65341d5504281bfa0cbede63dcae4ea025ab7b Mon Sep 17 00:00:00 2001 From: cclfmht Date: Sun, 12 Jul 2026 19:22:12 +0800 Subject: [PATCH 3/3] Bless UI tests covered by `static_mut_refs` lint --- .../borrowck/borrowck-unsafe-static-mutable-borrows.stderr | 1 - tests/ui/consts/const_let_assign2.stderr | 1 - tests/ui/lint/static-mut-refs.e2021.stderr | 7 ------- tests/ui/lint/static-mut-refs.e2024.stderr | 7 ------- ...rowck-thread-local-static-mut-borrow-outlives-fn.stderr | 1 - tests/ui/statics/issue-15261.stderr | 1 - tests/ui/statics/static-mut-shared-parens.stderr | 2 -- tests/ui/statics/static-mut-xc.stderr | 2 -- tests/ui/statics/static-recursive.stderr | 1 - 9 files changed, 23 deletions(-) diff --git a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr index 58ea9fe5a74b6..6c3fd9eb400f2 100644 --- a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr +++ b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr @@ -5,7 +5,6 @@ LL | let sfoo: *mut Foo = &mut SFOO; | ^^^^^^^^^ mutable reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default help: use `&raw mut` instead to create a raw pointer diff --git a/tests/ui/consts/const_let_assign2.stderr b/tests/ui/consts/const_let_assign2.stderr index ef6202cf7df85..e4edb58461054 100644 --- a/tests/ui/consts/const_let_assign2.stderr +++ b/tests/ui/consts/const_let_assign2.stderr @@ -5,7 +5,6 @@ LL | let ptr = unsafe { &mut BB }; | ^^^^^^^ mutable reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default help: use `&raw mut` instead to create a raw pointer diff --git a/tests/ui/lint/static-mut-refs.e2021.stderr b/tests/ui/lint/static-mut-refs.e2021.stderr index 89a4f3cc4932d..e616ba0aa4b28 100644 --- a/tests/ui/lint/static-mut-refs.e2021.stderr +++ b/tests/ui/lint/static-mut-refs.e2021.stderr @@ -5,7 +5,6 @@ LL | let _y = &X; | ^^ shared reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default help: use `&raw const` instead to create a raw pointer @@ -20,7 +19,6 @@ LL | let _y = &mut X; | ^^^^^^ mutable reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw mut` instead to create a raw pointer | @@ -44,7 +42,6 @@ LL | let (_b, _c) = (&X, &Y); | ^^ shared reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | @@ -58,7 +55,6 @@ LL | let (_b, _c) = (&X, &Y); | ^^ shared reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | @@ -72,7 +68,6 @@ LL | foo(&X); | ^^ shared reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | @@ -106,7 +101,6 @@ LL | let _v = &A.value; | ^^^^^^^^ shared reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | @@ -120,7 +114,6 @@ LL | let _s = &A.s.value; | ^^^^^^^^^^ shared reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | diff --git a/tests/ui/lint/static-mut-refs.e2024.stderr b/tests/ui/lint/static-mut-refs.e2024.stderr index a0c4e9d9620a0..a8985fc8a1763 100644 --- a/tests/ui/lint/static-mut-refs.e2024.stderr +++ b/tests/ui/lint/static-mut-refs.e2024.stderr @@ -5,7 +5,6 @@ LL | let _y = &X; | ^^ shared reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[deny(static_mut_refs)]` (part of `#[deny(rust_2024_compatibility)]`) on by default help: use `&raw const` instead to create a raw pointer @@ -20,7 +19,6 @@ LL | let _y = &mut X; | ^^^^^^ mutable reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw mut` instead to create a raw pointer | @@ -44,7 +42,6 @@ LL | let (_b, _c) = (&X, &Y); | ^^ shared reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | @@ -58,7 +55,6 @@ LL | let (_b, _c) = (&X, &Y); | ^^ shared reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | @@ -72,7 +68,6 @@ LL | foo(&X); | ^^ shared reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | @@ -106,7 +101,6 @@ LL | let _v = &A.value; | ^^^^^^^^ shared reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | @@ -120,7 +114,6 @@ LL | let _s = &A.s.value; | ^^^^^^^^^^ shared reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | diff --git a/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr index 95ca981679b65..19a3a786ac940 100644 --- a/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr +++ b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr @@ -5,7 +5,6 @@ LL | S1 { a: unsafe { &mut X1 } } | ^^^^^^^ mutable reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default help: use `&raw mut` instead to create a raw pointer diff --git a/tests/ui/statics/issue-15261.stderr b/tests/ui/statics/issue-15261.stderr index b9578523de3a9..fdc8e0c1f5ef7 100644 --- a/tests/ui/statics/issue-15261.stderr +++ b/tests/ui/statics/issue-15261.stderr @@ -5,7 +5,6 @@ LL | static n: &'static usize = unsafe { &n_mut }; | ^^^^^^ shared reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default help: use `&raw const` instead to create a raw pointer diff --git a/tests/ui/statics/static-mut-shared-parens.stderr b/tests/ui/statics/static-mut-shared-parens.stderr index 70e43f208ac7b..1265bdc7cf0d3 100644 --- a/tests/ui/statics/static-mut-shared-parens.stderr +++ b/tests/ui/statics/static-mut-shared-parens.stderr @@ -5,7 +5,6 @@ LL | let _ = unsafe { (&TEST) as *const usize }; | ^^^^^^^ shared reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default help: use `&raw const` instead to create a raw pointer @@ -20,7 +19,6 @@ LL | let _ = unsafe { (&mut TEST) as *const usize }; | ^^^^^^^^^^^ mutable reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw mut` instead to create a raw pointer | diff --git a/tests/ui/statics/static-mut-xc.stderr b/tests/ui/statics/static-mut-xc.stderr index 91be2b50a11f5..f8fa25e152f67 100644 --- a/tests/ui/statics/static-mut-xc.stderr +++ b/tests/ui/statics/static-mut-xc.stderr @@ -56,7 +56,6 @@ LL | static_bound(&static_mut_xc::a); | ^^^^^^^^^^^^^^^^^ shared reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw const` instead to create a raw pointer | @@ -70,7 +69,6 @@ LL | static_bound_set(&mut static_mut_xc::a); | ^^^^^^^^^^^^^^^^^^^^^ mutable reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see help: use `&raw mut` instead to create a raw pointer | diff --git a/tests/ui/statics/static-recursive.stderr b/tests/ui/statics/static-recursive.stderr index 56200e9f53d07..9578808ec7b03 100644 --- a/tests/ui/statics/static-recursive.stderr +++ b/tests/ui/statics/static-recursive.stderr @@ -5,7 +5,6 @@ LL | static mut S: *const u8 = unsafe { &S as *const *const u8 as *const u8 }; | ^^ shared reference to mutable static | = 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 - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default help: use `&raw const` instead to create a raw pointer