about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs3
-rw-r--r--compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs3
-rw-r--r--library/panic_unwind/src/seh.rs4
-rw-r--r--library/std/src/panicking.rs2
-rw-r--r--library/std/src/sys/common/thread_local/fast_local.rs2
-rw-r--r--library/std/src/sys/common/thread_local/static_local.rs2
-rw-r--r--library/std/src/thread/local.rs2
-rw-r--r--src/tools/lint-docs/src/groups.rs1
-rw-r--r--src/tools/miri/tests/fail/tls/tls_static_dealloc.rs2
-rw-r--r--src/tools/miri/tests/pass/static_mut.rs3
-rw-r--r--src/tools/miri/tests/pass/tls/tls_static.rs2
-rw-r--r--tests/ui/abi/statics/static-mut-foreign.rs2
-rw-r--r--tests/ui/abi/statics/static-mut-foreign.stderr31
-rw-r--r--tests/ui/borrowck/borrowck-access-permissions.rs36
-rw-r--r--tests/ui/borrowck/borrowck-access-permissions.stderr33
-rw-r--r--tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs9
-rw-r--r--tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr17
-rw-r--r--tests/ui/borrowck/issue-20801.rs1
-rw-r--r--tests/ui/borrowck/issue-20801.stderr25
-rw-r--r--tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs41
-rw-r--r--tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr75
-rw-r--r--tests/ui/consts/const_let_assign2.rs1
-rw-r--r--tests/ui/consts/const_let_assign2.stderr17
-rw-r--r--tests/ui/consts/issue-17718-const-bad-values.rs3
-rw-r--r--tests/ui/consts/issue-17718-const-bad-values.stderr17
-rw-r--r--tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr77
-rw-r--r--tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr77
-rw-r--r--tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs22
-rw-r--r--tests/ui/consts/static_mut_containing_mut_ref.rs1
-rw-r--r--tests/ui/consts/static_mut_containing_mut_ref.stderr17
-rw-r--r--tests/ui/consts/static_mut_containing_mut_ref2.mut_refs.stderr23
-rw-r--r--tests/ui/consts/static_mut_containing_mut_ref2.rs10
-rw-r--r--tests/ui/consts/static_mut_containing_mut_ref2.stock.stderr23
-rw-r--r--tests/ui/drop/issue-23338-ensure-param-drop-order.rs90
-rw-r--r--tests/ui/drop/issue-23338-ensure-param-drop-order.stderr17
-rw-r--r--tests/ui/error-codes/E0017.rs12
-rw-r--r--tests/ui/error-codes/E0017.stderr29
-rw-r--r--tests/ui/impl-header-lifetime-elision/bare_type.rs (renamed from tests/ui/issues/issue-20616.rs)9
-rw-r--r--tests/ui/issues/issue-23611-enum-swap-in-drop.rs44
-rw-r--r--tests/ui/issues/issue-23611-enum-swap-in-drop.stderr17
-rw-r--r--tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs5
-rw-r--r--tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr17
-rw-r--r--tests/ui/static/reference-of-mut-static-safe.e2021.stderr4
-rw-r--r--tests/ui/static/safe-extern-statics-mut.rs2
-rw-r--r--tests/ui/static/safe-extern-statics-mut.stderr35
-rw-r--r--tests/ui/statics/issue-15261.rs3
-rw-r--r--tests/ui/statics/issue-15261.stderr17
-rw-r--r--tests/ui/statics/static-mut-xc.rs3
-rw-r--r--tests/ui/statics/static-mut-xc.stderr31
-rw-r--r--tests/ui/statics/static-recursive.rs27
-rw-r--r--tests/ui/statics/static-recursive.stderr17
-rw-r--r--tests/ui/thread-local/thread-local-static.rs3
-rw-r--r--tests/ui/thread-local/thread-local-static.stderr17
-rw-r--r--tests/ui/thread-local/thread-local-static.thir.stderr59
54 files changed, 805 insertions, 237 deletions
diff --git a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
index a1cdf31c68a..2a7b1107ffc 100644
--- a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
+++ b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
@@ -111,6 +111,9 @@ fn start<T: Termination + 'static>(
 }
 
 static mut NUM: u8 = 6 * 7;
+
+// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
+#[allow(static_mut_ref)]
 static NUM_REF: &'static u8 = unsafe { &NUM };
 
 unsafe fn zeroed<T>() -> T {
diff --git a/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs b/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs
index 40a1ad22c0e..9827e299f2a 100644
--- a/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs
+++ b/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs
@@ -98,6 +98,9 @@ fn start<T: Termination + 'static>(
 }
 
 static mut NUM: u8 = 6 * 7;
+
+// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
+#[allow(static_mut_ref)]
 static NUM_REF: &'static u8 = unsafe { &NUM };
 
 macro_rules! assert {
diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs
index 99db00e5490..ccae406cc28 100644
--- a/library/panic_unwind/src/seh.rs
+++ b/library/panic_unwind/src/seh.rs
@@ -261,6 +261,8 @@ cfg_if::cfg_if! {
    }
 }
 
+// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
+#[cfg_attr(not(bootstrap), allow(static_mut_ref))]
 pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
     use core::intrinsics::atomic_store_seqcst;
 
@@ -322,6 +324,8 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
     _CxxThrowException(throw_ptr, &mut THROW_INFO as *mut _ as *mut _);
 }
 
+// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
+#[cfg_attr(not(bootstrap), allow(static_mut_ref))]
 pub unsafe fn cleanup(payload: *mut u8) -> Box<dyn Any + Send> {
     // A null payload here means that we got here from the catch (...) of
     // __rust_try. This happens when a non-Rust foreign exception is caught.
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index 66b4ec37c8e..c80f15d8a61 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -337,6 +337,8 @@ pub mod panic_count {
 #[doc(hidden)]
 #[cfg(not(feature = "panic_immediate_abort"))]
 #[unstable(feature = "update_panic_count", issue = "none")]
+// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
+#[cfg_attr(not(bootstrap), allow(static_mut_ref))]
 pub mod panic_count {
     use crate::cell::Cell;
     use crate::sync::atomic::{AtomicUsize, Ordering};
diff --git a/library/std/src/sys/common/thread_local/fast_local.rs b/library/std/src/sys/common/thread_local/fast_local.rs
index c0a9619bf7b..9206588be06 100644
--- a/library/std/src/sys/common/thread_local/fast_local.rs
+++ b/library/std/src/sys/common/thread_local/fast_local.rs
@@ -13,6 +13,8 @@ pub macro thread_local_inner {
     (@key $t:ty, const $init:expr) => {{
         #[inline]
         #[deny(unsafe_op_in_unsafe_fn)]
+        // FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
+        #[cfg_attr(not(bootstrap), allow(static_mut_ref))]
         unsafe fn __getit(
             _init: $crate::option::Option<&mut $crate::option::Option<$t>>,
         ) -> $crate::option::Option<&'static $t> {
diff --git a/library/std/src/sys/common/thread_local/static_local.rs b/library/std/src/sys/common/thread_local/static_local.rs
index 5cb6c541a0e..51cba66fad7 100644
--- a/library/std/src/sys/common/thread_local/static_local.rs
+++ b/library/std/src/sys/common/thread_local/static_local.rs
@@ -11,6 +11,8 @@ pub macro thread_local_inner {
     (@key $t:ty, const $init:expr) => {{
         #[inline] // see comments below
         #[deny(unsafe_op_in_unsafe_fn)]
+        // FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
+        #[cfg_attr(not(bootstrap), allow(static_mut_ref))]
         unsafe fn __getit(
             _init: $crate::option::Option<&mut $crate::option::Option<$t>>,
         ) -> $crate::option::Option<&'static $t> {
diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs
index 9cf37b0e634..338567777f7 100644
--- a/library/std/src/thread/local.rs
+++ b/library/std/src/thread/local.rs
@@ -180,6 +180,8 @@ impl<T: 'static> fmt::Debug for LocalKey<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[cfg_attr(not(test), rustc_diagnostic_item = "thread_local_macro")]
 #[allow_internal_unstable(thread_local_internals)]
+// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
+#[cfg_attr(not(bootstrap), allow(static_mut_ref))]
 macro_rules! thread_local {
     // empty (base case for the recursion)
     () => {};
diff --git a/src/tools/lint-docs/src/groups.rs b/src/tools/lint-docs/src/groups.rs
index 5be8ef7996b..c5cd30ccc34 100644
--- a/src/tools/lint-docs/src/groups.rs
+++ b/src/tools/lint-docs/src/groups.rs
@@ -15,6 +15,7 @@ static GROUP_DESCRIPTIONS: &[(&str, &str)] = &[
     ("future-incompatible", "Lints that detect code that has future-compatibility problems"),
     ("rust-2018-compatibility", "Lints used to transition code from the 2015 edition to 2018"),
     ("rust-2021-compatibility", "Lints used to transition code from the 2018 edition to 2021"),
+    ("rust-2024-compatibility", "Lints used to transition code from the 2021 edition to 2024"),
 ];
 
 type LintGroups = BTreeMap<String, BTreeSet<String>>;
diff --git a/src/tools/miri/tests/fail/tls/tls_static_dealloc.rs b/src/tools/miri/tests/fail/tls/tls_static_dealloc.rs
index d5e6d37226a..762a8d85314 100644
--- a/src/tools/miri/tests/fail/tls/tls_static_dealloc.rs
+++ b/src/tools/miri/tests/fail/tls/tls_static_dealloc.rs
@@ -1,6 +1,8 @@
 //! Ensure that thread-local statics get deallocated when the thread dies.
 
 #![feature(thread_local)]
+// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
+#![allow(static_mut_ref)]
 
 #[thread_local]
 static mut TLS: u8 = 0;
diff --git a/src/tools/miri/tests/pass/static_mut.rs b/src/tools/miri/tests/pass/static_mut.rs
index 218b02525bd..c1e58b70adb 100644
--- a/src/tools/miri/tests/pass/static_mut.rs
+++ b/src/tools/miri/tests/pass/static_mut.rs
@@ -1,4 +1,7 @@
 static mut FOO: i32 = 42;
+
+// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
+#[allow(static_mut_ref)]
 static BAR: Foo = Foo(unsafe { &FOO as *const _ });
 
 #[allow(dead_code)]
diff --git a/src/tools/miri/tests/pass/tls/tls_static.rs b/src/tools/miri/tests/pass/tls/tls_static.rs
index fc4c8a283dd..9be00af47aa 100644
--- a/src/tools/miri/tests/pass/tls/tls_static.rs
+++ b/src/tools/miri/tests/pass/tls/tls_static.rs
@@ -8,6 +8,8 @@
 //! test, we also check that thread-locals act as per-thread statics.
 
 #![feature(thread_local)]
+// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
+#![allow(static_mut_ref)]
 
 use std::thread;
 
diff --git a/tests/ui/abi/statics/static-mut-foreign.rs b/tests/ui/abi/statics/static-mut-foreign.rs
index ecd8ee94a01..eb732e7c2c3 100644
--- a/tests/ui/abi/statics/static-mut-foreign.rs
+++ b/tests/ui/abi/statics/static-mut-foreign.rs
@@ -33,7 +33,9 @@ unsafe fn run() {
     rust_dbg_static_mut = -3;
     assert_eq!(rust_dbg_static_mut, -3);
     static_bound(&rust_dbg_static_mut);
+    //~^ WARN shared reference of mutable static is discouraged [static_mut_ref]
     static_bound_set(&mut rust_dbg_static_mut);
+    //~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
 }
 
 pub fn main() {
diff --git a/tests/ui/abi/statics/static-mut-foreign.stderr b/tests/ui/abi/statics/static-mut-foreign.stderr
new file mode 100644
index 00000000000..144ac056f87
--- /dev/null
+++ b/tests/ui/abi/statics/static-mut-foreign.stderr
@@ -0,0 +1,31 @@
+warning: shared reference of mutable static is discouraged
+  --> $DIR/static-mut-foreign.rs:35:18
+   |
+LL |     static_bound(&rust_dbg_static_mut);
+   |                  ^^^^^^^^^^^^^^^^^^^^ shared reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
+   |
+LL |     static_bound(addr_of!(rust_dbg_static_mut));
+   |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+warning: mutable reference of mutable static is discouraged
+  --> $DIR/static-mut-foreign.rs:37:22
+   |
+LL |     static_bound_set(&mut rust_dbg_static_mut);
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^ mutable reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
+   |
+LL |     static_bound_set(addr_of_mut!(rust_dbg_static_mut));
+   |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/borrowck/borrowck-access-permissions.rs b/tests/ui/borrowck/borrowck-access-permissions.rs
index 469ad508b0e..1638644103b 100644
--- a/tests/ui/borrowck/borrowck-access-permissions.rs
+++ b/tests/ui/borrowck/borrowck-access-permissions.rs
@@ -1,21 +1,27 @@
-static static_x : i32 = 1;
-static mut static_x_mut : i32 = 1;
+static static_x: i32 = 1;
+static mut static_x_mut: i32 = 1;
 
 fn main() {
     let x = 1;
     let mut x_mut = 1;
 
-    { // borrow of local
+    {
+        // borrow of local
         let _y1 = &mut x; //~ ERROR [E0596]
         let _y2 = &mut x_mut; // No error
     }
 
-    { // borrow of static
+    {
+        // borrow of static
         let _y1 = &mut static_x; //~ ERROR [E0596]
-        unsafe { let _y2 = &mut static_x_mut; } // No error
+        unsafe {
+            let _y2 = &mut static_x_mut;
+            //~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
+        }
     }
 
-    { // borrow of deref to box
+    {
+        // borrow of deref to box
         let box_x = Box::new(1);
         let mut box_x_mut = Box::new(1);
 
@@ -23,7 +29,8 @@ fn main() {
         let _y2 = &mut *box_x_mut; // No error
     }
 
-    { // borrow of deref to reference
+    {
+        // borrow of deref to reference
         let ref_x = &x;
         let ref_x_mut = &mut x_mut;
 
@@ -31,9 +38,10 @@ fn main() {
         let _y2 = &mut *ref_x_mut; // No error
     }
 
-    { // borrow of deref to pointer
-        let ptr_x : *const _ = &x;
-        let ptr_mut_x : *mut _ = &mut x_mut;
+    {
+        // borrow of deref to pointer
+        let ptr_x: *const _ = &x;
+        let ptr_mut_x: *mut _ = &mut x_mut;
 
         unsafe {
             let _y1 = &mut *ptr_x; //~ ERROR [E0596]
@@ -41,8 +49,12 @@ fn main() {
         }
     }
 
-    { // borrowing mutably through an immutable reference
-        struct Foo<'a> { f: &'a mut i32, g: &'a i32 };
+    {
+        // borrowing mutably through an immutable reference
+        struct Foo<'a> {
+            f: &'a mut i32,
+            g: &'a i32,
+        };
         let mut foo = Foo { f: &mut x_mut, g: &x };
         let foo_ref = &foo;
         let _y = &mut *foo_ref.f; //~ ERROR [E0596]
diff --git a/tests/ui/borrowck/borrowck-access-permissions.stderr b/tests/ui/borrowck/borrowck-access-permissions.stderr
index c161e2d95b4..93d92295dd9 100644
--- a/tests/ui/borrowck/borrowck-access-permissions.stderr
+++ b/tests/ui/borrowck/borrowck-access-permissions.stderr
@@ -1,5 +1,20 @@
+warning: mutable reference of mutable static is discouraged
+  --> $DIR/borrowck-access-permissions.rs:18:23
+   |
+LL |             let _y2 = &mut static_x_mut;
+   |                       ^^^^^^^^^^^^^^^^^ mutable reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
+   |
+LL |             let _y2 = addr_of_mut!(static_x_mut);
+   |                       ~~~~~~~~~~~~~~~~~~~~~~~~~~
+
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
-  --> $DIR/borrowck-access-permissions.rs:9:19
+  --> $DIR/borrowck-access-permissions.rs:10:19
    |
 LL |         let _y1 = &mut x;
    |                   ^^^^^^ cannot borrow as mutable
@@ -10,13 +25,13 @@ LL |     let mut x = 1;
    |         +++
 
 error[E0596]: cannot borrow immutable static item `static_x` as mutable
-  --> $DIR/borrowck-access-permissions.rs:14:19
+  --> $DIR/borrowck-access-permissions.rs:16:19
    |
 LL |         let _y1 = &mut static_x;
    |                   ^^^^^^^^^^^^^ cannot borrow as mutable
 
 error[E0596]: cannot borrow `*box_x` as mutable, as `box_x` is not declared as mutable
-  --> $DIR/borrowck-access-permissions.rs:22:19
+  --> $DIR/borrowck-access-permissions.rs:28:19
    |
 LL |         let _y1 = &mut *box_x;
    |                   ^^^^^^^^^^^ cannot borrow as mutable
@@ -27,7 +42,7 @@ LL |         let mut box_x = Box::new(1);
    |             +++
 
 error[E0596]: cannot borrow `*ref_x` as mutable, as it is behind a `&` reference
-  --> $DIR/borrowck-access-permissions.rs:30:19
+  --> $DIR/borrowck-access-permissions.rs:37:19
    |
 LL |         let _y1 = &mut *ref_x;
    |                   ^^^^^^^^^^^ `ref_x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
@@ -38,18 +53,18 @@ LL |         let ref_x = &mut x;
    |                      +++
 
 error[E0596]: cannot borrow `*ptr_x` as mutable, as it is behind a `*const` pointer
-  --> $DIR/borrowck-access-permissions.rs:39:23
+  --> $DIR/borrowck-access-permissions.rs:47:23
    |
 LL |             let _y1 = &mut *ptr_x;
    |                       ^^^^^^^^^^^ `ptr_x` is a `*const` pointer, so the data it refers to cannot be borrowed as mutable
    |
 help: consider changing this to be a mutable pointer
    |
-LL |         let ptr_x : *const _ = &mut x;
-   |                                 +++
+LL |         let ptr_x: *const _ = &mut x;
+   |                                +++
 
 error[E0596]: cannot borrow `*foo_ref.f` as mutable, as it is behind a `&` reference
-  --> $DIR/borrowck-access-permissions.rs:48:18
+  --> $DIR/borrowck-access-permissions.rs:60:18
    |
 LL |         let _y = &mut *foo_ref.f;
    |                  ^^^^^^^^^^^^^^^ `foo_ref` is a `&` reference, so the data it refers to cannot be borrowed as mutable
@@ -59,6 +74,6 @@ help: consider changing this to be a mutable reference
 LL |         let foo_ref = &mut foo;
    |                        +++
 
-error: aborting due to 6 previous errors
+error: aborting due to 6 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0596`.
diff --git a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs
index adc7dfd541f..1bf079e24ca 100644
--- a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs
+++ b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs
@@ -2,17 +2,22 @@
 
 // Test file taken from issue 45129 (https://github.com/rust-lang/rust/issues/45129)
 
-struct Foo { x: [usize; 2] }
+struct Foo {
+    x: [usize; 2],
+}
 
 static mut SFOO: Foo = Foo { x: [23, 32] };
 
 impl Foo {
-    fn x(&mut self) -> &mut usize { &mut self.x[0] }
+    fn x(&mut self) -> &mut usize {
+        &mut self.x[0]
+    }
 }
 
 fn main() {
     unsafe {
         let sfoo: *mut Foo = &mut SFOO;
+        //~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
         let x = (*sfoo).x();
         (*sfoo).x[1] += 1;
         *x += 1;
diff --git a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr
new file mode 100644
index 00000000000..7a3824f79a4
--- /dev/null
+++ b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr
@@ -0,0 +1,17 @@
+warning: mutable reference of mutable static is discouraged
+  --> $DIR/borrowck-unsafe-static-mutable-borrows.rs:19:30
+   |
+LL |         let sfoo: *mut Foo = &mut SFOO;
+   |                              ^^^^^^^^^ mutable reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
+   |
+LL |         let sfoo: *mut Foo = addr_of_mut!(SFOO);
+   |                              ~~~~~~~~~~~~~~~~~~
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/borrowck/issue-20801.rs b/tests/ui/borrowck/issue-20801.rs
index c3f136f2876..ec83af5d5df 100644
--- a/tests/ui/borrowck/issue-20801.rs
+++ b/tests/ui/borrowck/issue-20801.rs
@@ -12,6 +12,7 @@ fn imm_ref() -> &'static T {
 
 fn mut_ref() -> &'static mut T {
     unsafe { &mut GLOBAL_MUT_T }
+    //~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
 }
 
 fn mut_ptr() -> *mut T {
diff --git a/tests/ui/borrowck/issue-20801.stderr b/tests/ui/borrowck/issue-20801.stderr
index 215bf010063..b2bee2d8803 100644
--- a/tests/ui/borrowck/issue-20801.stderr
+++ b/tests/ui/borrowck/issue-20801.stderr
@@ -1,5 +1,20 @@
+warning: mutable reference of mutable static is discouraged
+  --> $DIR/issue-20801.rs:14:14
+   |
+LL |     unsafe { &mut GLOBAL_MUT_T }
+   |              ^^^^^^^^^^^^^^^^^ mutable reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
+   |
+LL |     unsafe { addr_of_mut!(GLOBAL_MUT_T) }
+   |              ~~~~~~~~~~~~~~~~~~~~~~~~~~
+
 error[E0507]: cannot move out of a mutable reference
-  --> $DIR/issue-20801.rs:26:22
+  --> $DIR/issue-20801.rs:27:22
    |
 LL |     let a = unsafe { *mut_ref() };
    |                      ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait
@@ -11,7 +26,7 @@ LL +     let a = unsafe { mut_ref() };
    |
 
 error[E0507]: cannot move out of a shared reference
-  --> $DIR/issue-20801.rs:29:22
+  --> $DIR/issue-20801.rs:30:22
    |
 LL |     let b = unsafe { *imm_ref() };
    |                      ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait
@@ -23,7 +38,7 @@ LL +     let b = unsafe { imm_ref() };
    |
 
 error[E0507]: cannot move out of a raw pointer
-  --> $DIR/issue-20801.rs:32:22
+  --> $DIR/issue-20801.rs:33:22
    |
 LL |     let c = unsafe { *mut_ptr() };
    |                      ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait
@@ -35,7 +50,7 @@ LL +     let c = unsafe { mut_ptr() };
    |
 
 error[E0507]: cannot move out of a raw pointer
-  --> $DIR/issue-20801.rs:35:22
+  --> $DIR/issue-20801.rs:36:22
    |
 LL |     let d = unsafe { *const_ptr() };
    |                      ^^^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait
@@ -46,6 +61,6 @@ LL -     let d = unsafe { *const_ptr() };
 LL +     let d = unsafe { const_ptr() };
    |
 
-error: aborting due to 4 previous errors
+error: aborting due to 4 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0507`.
diff --git a/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs b/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs
index b3cce1b3a06..9b172b41319 100644
--- a/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs
+++ b/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs
@@ -8,7 +8,10 @@ mod borrowck_closures_unique {
         static mut Y: isize = 3;
         let mut c1 = |y: &'static mut isize| x = y;
         //~^ ERROR is not declared as mutable
-        unsafe { c1(&mut Y); }
+        unsafe {
+            c1(&mut Y);
+            //~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
+        }
     }
 }
 
@@ -17,36 +20,50 @@ mod borrowck_closures_unique_grandparent {
         static mut Z: isize = 3;
         let mut c1 = |z: &'static mut isize| {
             let mut c2 = |y: &'static mut isize| x = y;
-        //~^ ERROR is not declared as mutable
+            //~^ ERROR is not declared as mutable
             c2(z);
         };
-        unsafe { c1(&mut Z); }
+        unsafe {
+            c1(&mut Z);
+            //~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
+        }
     }
 }
 
 // adapted from mutability_errors.rs
 mod mutability_errors {
     pub fn capture_assign_whole(x: (i32,)) {
-        || { x = (1,); };
-        //~^ ERROR is not declared as mutable
+        || {
+            x = (1,);
+            //~^ ERROR is not declared as mutable
+        };
     }
     pub fn capture_assign_part(x: (i32,)) {
-        || { x.0 = 1; };
-        //~^ ERROR is not declared as mutable
+        || {
+            x.0 = 1;
+            //~^ ERROR is not declared as mutable
+        };
     }
     pub fn capture_reborrow_whole(x: (i32,)) {
-        || { &mut x; };
-        //~^ ERROR is not declared as mutable
+        || {
+            &mut x;
+            //~^ ERROR is not declared as mutable
+        };
     }
     pub fn capture_reborrow_part(x: (i32,)) {
-        || { &mut x.0; };
-        //~^ ERROR is not declared as mutable
+        || {
+            &mut x.0;
+            //~^ ERROR is not declared as mutable
+        };
     }
 }
 
 fn main() {
     static mut X: isize = 2;
-    unsafe { borrowck_closures_unique::e(&mut X); }
+    unsafe {
+        borrowck_closures_unique::e(&mut X);
+        //~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
+    }
 
     mutability_errors::capture_assign_whole((1000,));
     mutability_errors::capture_assign_part((2000,));
diff --git a/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr b/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr
index 4c299cdc455..e4e4947fce1 100644
--- a/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr
+++ b/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr
@@ -1,3 +1,46 @@
+warning: mutable reference of mutable static is discouraged
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:12:16
+   |
+LL |             c1(&mut Y);
+   |                ^^^^^^ mutable reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
+   |
+LL |             c1(addr_of_mut!(Y));
+   |                ~~~~~~~~~~~~~~~
+
+warning: mutable reference of mutable static is discouraged
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:27:16
+   |
+LL |             c1(&mut Z);
+   |                ^^^^^^ mutable reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
+   |
+LL |             c1(addr_of_mut!(Z));
+   |                ~~~~~~~~~~~~~~~
+
+warning: mutable reference of mutable static is discouraged
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:64:37
+   |
+LL |         borrowck_closures_unique::e(&mut X);
+   |                                     ^^^^^^ mutable reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
+   |
+LL |         borrowck_closures_unique::e(addr_of_mut!(X));
+   |                                     ~~~~~~~~~~~~~~~
+
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:9:46
    |
@@ -8,7 +51,7 @@ LL |         let mut c1 = |y: &'static mut isize| x = y;
    |                                              ^^^^^ cannot assign
 
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:19:50
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:22:50
    |
 LL |     pub fn ee(x: &'static mut isize) {
    |               - help: consider changing this to be mutable: `mut x`
@@ -17,38 +60,42 @@ LL |             let mut c2 = |y: &'static mut isize| x = y;
    |                                                  ^^^^^ cannot assign
 
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:30:14
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:37:13
    |
 LL |     pub fn capture_assign_whole(x: (i32,)) {
    |                                 - help: consider changing this to be mutable: `mut x`
-LL |         || { x = (1,); };
-   |              ^^^^^^^^ cannot assign
+LL |         || {
+LL |             x = (1,);
+   |             ^^^^^^^^ cannot assign
 
 error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:34:14
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:43:13
    |
 LL |     pub fn capture_assign_part(x: (i32,)) {
    |                                - help: consider changing this to be mutable: `mut x`
-LL |         || { x.0 = 1; };
-   |              ^^^^^^^ cannot assign
+LL |         || {
+LL |             x.0 = 1;
+   |             ^^^^^^^ cannot assign
 
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:38:14
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:49:13
    |
 LL |     pub fn capture_reborrow_whole(x: (i32,)) {
    |                                   - help: consider changing this to be mutable: `mut x`
-LL |         || { &mut x; };
-   |              ^^^^^^ cannot borrow as mutable
+LL |         || {
+LL |             &mut x;
+   |             ^^^^^^ cannot borrow as mutable
 
 error[E0596]: cannot borrow `x.0` as mutable, as `x` is not declared as mutable
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:42:14
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:55:13
    |
 LL |     pub fn capture_reborrow_part(x: (i32,)) {
    |                                  - help: consider changing this to be mutable: `mut x`
-LL |         || { &mut x.0; };
-   |              ^^^^^^^^ cannot borrow as mutable
+LL |         || {
+LL |             &mut x.0;
+   |             ^^^^^^^^ cannot borrow as mutable
 
-error: aborting due to 6 previous errors
+error: aborting due to 6 previous errors; 3 warnings emitted
 
 Some errors have detailed explanations: E0594, E0596.
 For more information about an error, try `rustc --explain E0594`.
diff --git a/tests/ui/consts/const_let_assign2.rs b/tests/ui/consts/const_let_assign2.rs
index 28265c85dd1..1c7afe0e3d6 100644
--- a/tests/ui/consts/const_let_assign2.rs
+++ b/tests/ui/consts/const_let_assign2.rs
@@ -16,6 +16,7 @@ static mut BB: AA = AA::new();
 
 fn main() {
     let ptr = unsafe { &mut BB };
+    //~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
     for a in ptr.data.iter() {
         println!("{}", a);
     }
diff --git a/tests/ui/consts/const_let_assign2.stderr b/tests/ui/consts/const_let_assign2.stderr
new file mode 100644
index 00000000000..2764153a8a5
--- /dev/null
+++ b/tests/ui/consts/const_let_assign2.stderr
@@ -0,0 +1,17 @@
+warning: mutable reference of mutable static is discouraged
+  --> $DIR/const_let_assign2.rs:18:24
+   |
+LL |     let ptr = unsafe { &mut BB };
+   |                        ^^^^^^^ mutable reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
+   |
+LL |     let ptr = unsafe { addr_of_mut!(BB) };
+   |                        ~~~~~~~~~~~~~~~~
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/consts/issue-17718-const-bad-values.rs b/tests/ui/consts/issue-17718-const-bad-values.rs
index 62bbb3b569c..4fedc48452b 100644
--- a/tests/ui/consts/issue-17718-const-bad-values.rs
+++ b/tests/ui/consts/issue-17718-const-bad-values.rs
@@ -3,7 +3,8 @@ const C1: &'static mut [usize] = &mut [];
 
 static mut S: usize = 3;
 const C2: &'static mut usize = unsafe { &mut S };
-//~^ ERROR: constants cannot refer to statics
+//~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
+//~^^ ERROR: constants cannot refer to statics
 //~| ERROR: constants cannot refer to statics
 
 fn main() {}
diff --git a/tests/ui/consts/issue-17718-const-bad-values.stderr b/tests/ui/consts/issue-17718-const-bad-values.stderr
index 405c2195dec..2dc91f52669 100644
--- a/tests/ui/consts/issue-17718-const-bad-values.stderr
+++ b/tests/ui/consts/issue-17718-const-bad-values.stderr
@@ -1,3 +1,18 @@
+warning: mutable reference of mutable static is discouraged
+  --> $DIR/issue-17718-const-bad-values.rs:5:41
+   |
+LL | const C2: &'static mut usize = unsafe { &mut S };
+   |                                         ^^^^^^ mutable reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
+   |
+LL | const C2: &'static mut usize = unsafe { addr_of_mut!(S) };
+   |                                         ~~~~~~~~~~~~~~~
+
 error[E0764]: mutable references are not allowed in the final value of constants
   --> $DIR/issue-17718-const-bad-values.rs:1:34
    |
@@ -21,7 +36,7 @@ LL | const C2: &'static mut usize = unsafe { &mut S };
    = help: consider extracting the value of the `static` to a `const`, and referring to that
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: aborting due to 3 previous errors
+error: aborting due to 3 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0013, E0764.
 For more information about an error, try `rustc --explain E0013`.
diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr
index 7960648ce3a..ed9db675426 100644
--- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr
+++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr
@@ -1,3 +1,18 @@
+warning: shared reference of mutable static is discouraged
+  --> $DIR/const_refers_to_static_cross_crate.rs:13:14
+   |
+LL |     unsafe { &static_cross_crate::ZERO }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^ shared reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
+   |
+LL |     unsafe { addr_of!(static_cross_crate::ZERO) }
+   |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/const_refers_to_static_cross_crate.rs:10:1
    |
@@ -10,13 +25,13 @@ LL | const SLICE_MUT: &[u8; 1] = {
            }
 
 error: could not evaluate constant pattern
-  --> $DIR/const_refers_to_static_cross_crate.rs:34:9
+  --> $DIR/const_refers_to_static_cross_crate.rs:42:9
    |
 LL |         SLICE_MUT => true,
    |         ^^^^^^^^^
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/const_refers_to_static_cross_crate.rs:15:1
+  --> $DIR/const_refers_to_static_cross_crate.rs:17:1
    |
 LL | const U8_MUT: &u8 = {
    | ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant
@@ -27,31 +42,31 @@ LL | const U8_MUT: &u8 = {
            }
 
 error: could not evaluate constant pattern
-  --> $DIR/const_refers_to_static_cross_crate.rs:42:9
+  --> $DIR/const_refers_to_static_cross_crate.rs:50:9
    |
 LL |         U8_MUT => true,
    |         ^^^^^^
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_refers_to_static_cross_crate.rs:22:15
+  --> $DIR/const_refers_to_static_cross_crate.rs:25:15
    |
 LL |     unsafe { &(*static_cross_crate::ZERO_REF)[0] }
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
 
 error: could not evaluate constant pattern
-  --> $DIR/const_refers_to_static_cross_crate.rs:52:9
+  --> $DIR/const_refers_to_static_cross_crate.rs:60:9
    |
 LL |         U8_MUT2 => true,
    |         ^^^^^^^
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_refers_to_static_cross_crate.rs:27:20
+  --> $DIR/const_refers_to_static_cross_crate.rs:31:15
    |
-LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
+LL |         match static_cross_crate::OPT_ZERO {
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
 
 error: could not evaluate constant pattern
-  --> $DIR/const_refers_to_static_cross_crate.rs:59:9
+  --> $DIR/const_refers_to_static_cross_crate.rs:67:9
    |
 LL |         U8_MUT3 => true,
    |         ^^^^^^^
@@ -59,61 +74,61 @@ LL |         U8_MUT3 => true,
 warning: skipping const checks
    |
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:12:15
+  --> $DIR/const_refers_to_static_cross_crate.rs:13:15
    |
 LL |     unsafe { &static_cross_crate::ZERO }
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:12:15
+  --> $DIR/const_refers_to_static_cross_crate.rs:13:15
    |
 LL |     unsafe { &static_cross_crate::ZERO }
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:17:15
+  --> $DIR/const_refers_to_static_cross_crate.rs:20:15
    |
 LL |     unsafe { &static_cross_crate::ZERO[0] }
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:17:15
+  --> $DIR/const_refers_to_static_cross_crate.rs:20:15
    |
 LL |     unsafe { &static_cross_crate::ZERO[0] }
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:17:15
+  --> $DIR/const_refers_to_static_cross_crate.rs:20:15
    |
 LL |     unsafe { &static_cross_crate::ZERO[0] }
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:22:17
+  --> $DIR/const_refers_to_static_cross_crate.rs:25:17
    |
 LL |     unsafe { &(*static_cross_crate::ZERO_REF)[0] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:27:20
+  --> $DIR/const_refers_to_static_cross_crate.rs:31:15
    |
-LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         match static_cross_crate::OPT_ZERO {
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:27:20
+  --> $DIR/const_refers_to_static_cross_crate.rs:31:15
    |
-LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         match static_cross_crate::OPT_ZERO {
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:27:20
+  --> $DIR/const_refers_to_static_cross_crate.rs:31:15
    |
-LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         match static_cross_crate::OPT_ZERO {
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:27:20
+  --> $DIR/const_refers_to_static_cross_crate.rs:31:15
    |
-LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         match static_cross_crate::OPT_ZERO {
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:27:20
+  --> $DIR/const_refers_to_static_cross_crate.rs:31:15
    |
-LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         match static_cross_crate::OPT_ZERO {
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 8 previous errors; 1 warning emitted
+error: aborting due to 8 previous errors; 2 warnings emitted
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr
index 6ae0b2d1bfe..275323bc286 100644
--- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr
+++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr
@@ -1,3 +1,18 @@
+warning: shared reference of mutable static is discouraged
+  --> $DIR/const_refers_to_static_cross_crate.rs:13:14
+   |
+LL |     unsafe { &static_cross_crate::ZERO }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^ shared reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
+   |
+LL |     unsafe { addr_of!(static_cross_crate::ZERO) }
+   |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/const_refers_to_static_cross_crate.rs:10:1
    |
@@ -10,13 +25,13 @@ LL | const SLICE_MUT: &[u8; 1] = {
            }
 
 error: could not evaluate constant pattern
-  --> $DIR/const_refers_to_static_cross_crate.rs:34:9
+  --> $DIR/const_refers_to_static_cross_crate.rs:42:9
    |
 LL |         SLICE_MUT => true,
    |         ^^^^^^^^^
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/const_refers_to_static_cross_crate.rs:15:1
+  --> $DIR/const_refers_to_static_cross_crate.rs:17:1
    |
 LL | const U8_MUT: &u8 = {
    | ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant
@@ -27,31 +42,31 @@ LL | const U8_MUT: &u8 = {
            }
 
 error: could not evaluate constant pattern
-  --> $DIR/const_refers_to_static_cross_crate.rs:42:9
+  --> $DIR/const_refers_to_static_cross_crate.rs:50:9
    |
 LL |         U8_MUT => true,
    |         ^^^^^^
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_refers_to_static_cross_crate.rs:22:15
+  --> $DIR/const_refers_to_static_cross_crate.rs:25:15
    |
 LL |     unsafe { &(*static_cross_crate::ZERO_REF)[0] }
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
 
 error: could not evaluate constant pattern
-  --> $DIR/const_refers_to_static_cross_crate.rs:52:9
+  --> $DIR/const_refers_to_static_cross_crate.rs:60:9
    |
 LL |         U8_MUT2 => true,
    |         ^^^^^^^
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_refers_to_static_cross_crate.rs:27:20
+  --> $DIR/const_refers_to_static_cross_crate.rs:31:15
    |
-LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
+LL |         match static_cross_crate::OPT_ZERO {
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
 
 error: could not evaluate constant pattern
-  --> $DIR/const_refers_to_static_cross_crate.rs:59:9
+  --> $DIR/const_refers_to_static_cross_crate.rs:67:9
    |
 LL |         U8_MUT3 => true,
    |         ^^^^^^^
@@ -59,61 +74,61 @@ LL |         U8_MUT3 => true,
 warning: skipping const checks
    |
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:12:15
+  --> $DIR/const_refers_to_static_cross_crate.rs:13:15
    |
 LL |     unsafe { &static_cross_crate::ZERO }
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:12:15
+  --> $DIR/const_refers_to_static_cross_crate.rs:13:15
    |
 LL |     unsafe { &static_cross_crate::ZERO }
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:17:15
+  --> $DIR/const_refers_to_static_cross_crate.rs:20:15
    |
 LL |     unsafe { &static_cross_crate::ZERO[0] }
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:17:15
+  --> $DIR/const_refers_to_static_cross_crate.rs:20:15
    |
 LL |     unsafe { &static_cross_crate::ZERO[0] }
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:17:15
+  --> $DIR/const_refers_to_static_cross_crate.rs:20:15
    |
 LL |     unsafe { &static_cross_crate::ZERO[0] }
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:22:17
+  --> $DIR/const_refers_to_static_cross_crate.rs:25:17
    |
 LL |     unsafe { &(*static_cross_crate::ZERO_REF)[0] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:27:20
+  --> $DIR/const_refers_to_static_cross_crate.rs:31:15
    |
-LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         match static_cross_crate::OPT_ZERO {
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:27:20
+  --> $DIR/const_refers_to_static_cross_crate.rs:31:15
    |
-LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         match static_cross_crate::OPT_ZERO {
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:27:20
+  --> $DIR/const_refers_to_static_cross_crate.rs:31:15
    |
-LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         match static_cross_crate::OPT_ZERO {
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:27:20
+  --> $DIR/const_refers_to_static_cross_crate.rs:31:15
    |
-LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         match static_cross_crate::OPT_ZERO {
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
-  --> $DIR/const_refers_to_static_cross_crate.rs:27:20
+  --> $DIR/const_refers_to_static_cross_crate.rs:31:15
    |
-LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         match static_cross_crate::OPT_ZERO {
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 8 previous errors; 1 warning emitted
+error: aborting due to 8 previous errors; 2 warnings emitted
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs
index bbaa32ddfd1..3eafa58d9f9 100644
--- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs
+++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs
@@ -7,13 +7,16 @@ extern crate static_cross_crate;
 
 // Sneaky: reference to a mutable static.
 // Allowing this would be a disaster for pattern matching, we could violate exhaustiveness checking!
-const SLICE_MUT: &[u8; 1] = { //~ ERROR undefined behavior to use this value
-//~| encountered a reference pointing to a static variable
+const SLICE_MUT: &[u8; 1] = {
+    //~^ ERROR undefined behavior to use this value
+    //~| encountered a reference pointing to a static variable
     unsafe { &static_cross_crate::ZERO }
+    //~^ WARN shared reference of mutable static is discouraged [static_mut_ref]
 };
 
-const U8_MUT: &u8 = { //~ ERROR undefined behavior to use this value
-//~| encountered a reference pointing to a static variable
+const U8_MUT: &u8 = {
+    //~^ ERROR undefined behavior to use this value
+    //~| encountered a reference pointing to a static variable
     unsafe { &static_cross_crate::ZERO[0] }
 };
 
@@ -24,9 +27,14 @@ const U8_MUT2: &u8 = {
     //~| constant accesses static
 };
 const U8_MUT3: &u8 = {
-    unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
-    //~^ ERROR evaluation of constant value failed
-    //~| constant accesses static
+    unsafe {
+        match static_cross_crate::OPT_ZERO {
+            //~^ ERROR evaluation of constant value failed
+            //~| constant accesses static
+            Some(ref u) => u,
+            None => panic!(),
+        }
+    }
 };
 
 pub fn test(x: &[u8; 1]) -> bool {
diff --git a/tests/ui/consts/static_mut_containing_mut_ref.rs b/tests/ui/consts/static_mut_containing_mut_ref.rs
index df09c76c558..874aa59df0b 100644
--- a/tests/ui/consts/static_mut_containing_mut_ref.rs
+++ b/tests/ui/consts/static_mut_containing_mut_ref.rs
@@ -3,5 +3,6 @@
 static mut STDERR_BUFFER_SPACE: [u8; 42] = [0u8; 42];
 
 pub static mut STDERR_BUFFER: *mut [u8] = unsafe { &mut STDERR_BUFFER_SPACE };
+//~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
 
 fn main() {}
diff --git a/tests/ui/consts/static_mut_containing_mut_ref.stderr b/tests/ui/consts/static_mut_containing_mut_ref.stderr
new file mode 100644
index 00000000000..56ceba41cf8
--- /dev/null
+++ b/tests/ui/consts/static_mut_containing_mut_ref.stderr
@@ -0,0 +1,17 @@
+warning: mutable reference of mutable static is discouraged
+  --> $DIR/static_mut_containing_mut_ref.rs:5:52
+   |
+LL | pub static mut STDERR_BUFFER: *mut [u8] = unsafe { &mut STDERR_BUFFER_SPACE };
+   |                                                    ^^^^^^^^^^^^^^^^^^^^^^^^ mutable reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
+   |
+LL | pub static mut STDERR_BUFFER: *mut [u8] = unsafe { addr_of_mut!(STDERR_BUFFER_SPACE) };
+   |                                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/consts/static_mut_containing_mut_ref2.mut_refs.stderr b/tests/ui/consts/static_mut_containing_mut_ref2.mut_refs.stderr
index 3d0de233569..bc32ecc2c35 100644
--- a/tests/ui/consts/static_mut_containing_mut_ref2.mut_refs.stderr
+++ b/tests/ui/consts/static_mut_containing_mut_ref2.mut_refs.stderr
@@ -1,9 +1,24 @@
+warning: mutable reference of mutable static is discouraged
+  --> $DIR/static_mut_containing_mut_ref2.rs:8:6
+   |
+LL |     *(&mut STDERR_BUFFER_SPACE) = 42;
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
+   |
+LL |     *addr_of_mut!(STDERR_BUFFER_SPACE) = 42;
+   |      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
 error[E0080]: could not evaluate static initializer
-  --> $DIR/static_mut_containing_mut_ref2.rs:7:45
+  --> $DIR/static_mut_containing_mut_ref2.rs:8:5
    |
-LL | pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; };
-   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ modifying a static's initial value from another static's initializer
+LL |     *(&mut STDERR_BUFFER_SPACE) = 42;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ modifying a static's initial value from another static's initializer
 
-error: aborting due to 1 previous error
+error: aborting due to 1 previous error; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/static_mut_containing_mut_ref2.rs b/tests/ui/consts/static_mut_containing_mut_ref2.rs
index 61368546083..fa79a78eab4 100644
--- a/tests/ui/consts/static_mut_containing_mut_ref2.rs
+++ b/tests/ui/consts/static_mut_containing_mut_ref2.rs
@@ -4,8 +4,12 @@
 
 static mut STDERR_BUFFER_SPACE: u8 = 0;
 
-pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; };
-//[mut_refs]~^ ERROR could not evaluate static initializer
-//[stock]~^^ ERROR mutable references are not allowed in statics
+pub static mut STDERR_BUFFER: () = unsafe {
+    *(&mut STDERR_BUFFER_SPACE) = 42;
+    //[mut_refs]~^ ERROR could not evaluate static initializer
+    //[stock]~^^ ERROR mutable references are not allowed in statics
+    //[mut_refs]~^^^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
+    //[stock]~^^^^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
+};
 
 fn main() {}
diff --git a/tests/ui/consts/static_mut_containing_mut_ref2.stock.stderr b/tests/ui/consts/static_mut_containing_mut_ref2.stock.stderr
index 3d5b012d42f..c6e5b07e3b7 100644
--- a/tests/ui/consts/static_mut_containing_mut_ref2.stock.stderr
+++ b/tests/ui/consts/static_mut_containing_mut_ref2.stock.stderr
@@ -1,12 +1,27 @@
+warning: mutable reference of mutable static is discouraged
+  --> $DIR/static_mut_containing_mut_ref2.rs:8:6
+   |
+LL |     *(&mut STDERR_BUFFER_SPACE) = 42;
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
+   |
+LL |     *addr_of_mut!(STDERR_BUFFER_SPACE) = 42;
+   |      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
 error[E0658]: mutable references are not allowed in statics
-  --> $DIR/static_mut_containing_mut_ref2.rs:7:46
+  --> $DIR/static_mut_containing_mut_ref2.rs:8:6
    |
-LL | pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; };
-   |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     *(&mut STDERR_BUFFER_SPACE) = 42;
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
 
-error: aborting due to 1 previous error
+error: aborting due to 1 previous error; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/drop/issue-23338-ensure-param-drop-order.rs b/tests/ui/drop/issue-23338-ensure-param-drop-order.rs
index a99f260dde3..52603744c45 100644
--- a/tests/ui/drop/issue-23338-ensure-param-drop-order.rs
+++ b/tests/ui/drop/issue-23338-ensure-param-drop-order.rs
@@ -13,38 +13,39 @@ pub fn main() {
     d::println("created empty log");
     test(&log);
 
-    assert_eq!(&log.borrow()[..],
-               [
-                   //                                    created empty log
-                   //    +-- Make D(da_0, 0)
-                   //    | +-- Make D(de_1, 1)
-                   //    | |                             calling foo
-                   //    | |                             entered foo
-                   //    | | +-- Make D(de_2, 2)
-                   //    | | | +-- Make D(da_1, 3)
-                   //    | | | | +-- Make D(de_3, 4)
-                   //    | | | | | +-- Make D(de_4, 5)
-                   3, // | | | +-- Drop D(da_1, 3)
-                   //    | | |   | |
-                   4, // | | |   +-- Drop D(de_3, 4)
-                   //    | | |     |
-                   //    | | |     |                     eval tail of foo
-                   //    | | | +-- Make D(de_5, 6)
-                   //    | | | | +-- Make D(de_6, 7)
-                   5, // | | | | | +-- Drop D(de_4, 5)
-                   //    | | | | |
-                   2, // | | +-- Drop D(de_2, 2)
-                   //    | |   | |
-                   6, // | |   +-- Drop D(de_5, 6)
-                   //    | |     |
-                   1, // | +-- Drop D(de_1, 1)
-                   //    |       |
-                   0, // +-- Drop D(da_0, 0)
-                   //            |
-                   //            |                       result D(de_6, 7)
-                   7 //          +-- Drop D(de_6, 7)
-
-                       ]);
+    assert_eq!(
+        &log.borrow()[..],
+        [
+            //                                    created empty log
+            //    +-- Make D(da_0, 0)
+            //    | +-- Make D(de_1, 1)
+            //    | |                             calling foo
+            //    | |                             entered foo
+            //    | | +-- Make D(de_2, 2)
+            //    | | | +-- Make D(da_1, 3)
+            //    | | | | +-- Make D(de_3, 4)
+            //    | | | | | +-- Make D(de_4, 5)
+            3, // | | | +-- Drop D(da_1, 3)
+            //    | | |   | |
+            4, // | | |   +-- Drop D(de_3, 4)
+            //    | | |     |
+            //    | | |     |                     eval tail of foo
+            //    | | | +-- Make D(de_5, 6)
+            //    | | | | +-- Make D(de_6, 7)
+            5, // | | | | | +-- Drop D(de_4, 5)
+            //    | | | | |
+            2, // | | +-- Drop D(de_2, 2)
+            //    | |   | |
+            6, // | |   +-- Drop D(de_5, 6)
+            //    | |     |
+            1, // | +-- Drop D(de_1, 1)
+            //    |       |
+            0, // +-- Drop D(da_0, 0)
+            //            |
+            //            |                       result D(de_6, 7)
+            7 //          +-- Drop D(de_6, 7)
+        ]
+    );
 }
 
 fn test<'a>(log: d::Log<'a>) {
@@ -57,13 +58,13 @@ fn test<'a>(log: d::Log<'a>) {
 
 fn foo<'a>(da0: D<'a>, de1: D<'a>) -> D<'a> {
     d::println("entered foo");
-    let de2 = de1.incr();      // creates D(de_2, 2)
+    let de2 = de1.incr(); // creates D(de_2, 2)
     let de4 = {
         let _da1 = da0.incr(); // creates D(da_1, 3)
-        de2.incr().incr()      // creates D(de_3, 4) and D(de_4, 5)
+        de2.incr().incr() // creates D(de_3, 4) and D(de_4, 5)
     };
     d::println("eval tail of foo");
-    de4.incr().incr()          // creates D(de_5, 6) and D(de_6, 7)
+    de4.incr().incr() // creates D(de_5, 6) and D(de_6, 7)
 }
 
 // This module provides simultaneous printouts of the dynamic extents
@@ -74,9 +75,9 @@ const PREF_INDENT: u32 = 16;
 
 pub mod d {
     #![allow(unused_parens)]
+    use std::cell::RefCell;
     use std::fmt;
     use std::mem;
-    use std::cell::RefCell;
 
     static mut counter: u32 = 0;
     static mut trails: u64 = 0;
@@ -89,7 +90,8 @@ pub mod d {
 
     pub fn max_width() -> u32 {
         unsafe {
-            (mem::size_of_val(&trails)*8) as u32
+            (mem::size_of_val(&trails) * 8) as u32
+            //~^ WARN shared reference of mutable static is discouraged [static_mut_ref]
         }
     }
 
@@ -123,7 +125,11 @@ pub mod d {
     }
 
     pub struct D<'a> {
-        name: &'static str, i: u32, uid: u32, trail: u32, log: Log<'a>
+        name: &'static str,
+        i: u32,
+        uid: u32,
+        trail: u32,
+        log: Log<'a>,
     }
 
     impl<'a> fmt::Display for D<'a> {
@@ -139,9 +145,7 @@ pub mod d {
                 let ctr = counter;
                 counter += 1;
                 trails |= (1 << trail);
-                let ret = D {
-                    name: name, i: i, log: log, uid: ctr, trail: trail
-                };
+                let ret = D { name: name, i: i, log: log, uid: ctr, trail: trail };
                 indent_println(trail, &format!("+-- Make {}", ret));
                 ret
             }
@@ -153,7 +157,9 @@ pub mod d {
 
     impl<'a> Drop for D<'a> {
         fn drop(&mut self) {
-            unsafe { trails &= !(1 << self.trail); };
+            unsafe {
+                trails &= !(1 << self.trail);
+            };
             self.log.borrow_mut().push(self.uid);
             indent_println(self.trail, &format!("+-- Drop {}", self));
             indent_println(::PREF_INDENT, "");
diff --git a/tests/ui/drop/issue-23338-ensure-param-drop-order.stderr b/tests/ui/drop/issue-23338-ensure-param-drop-order.stderr
new file mode 100644
index 00000000000..fd36ccbcbee
--- /dev/null
+++ b/tests/ui/drop/issue-23338-ensure-param-drop-order.stderr
@@ -0,0 +1,17 @@
+warning: shared reference of mutable static is discouraged
+  --> $DIR/issue-23338-ensure-param-drop-order.rs:93:31
+   |
+LL |             (mem::size_of_val(&trails) * 8) as u32
+   |                               ^^^^^^^ shared reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
+   |
+LL |             (mem::size_of_val(addr_of!(trails)) * 8) as u32
+   |                               ~~~~~~~~~~~~~~~~
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/error-codes/E0017.rs b/tests/ui/error-codes/E0017.rs
index c211ad1a2f8..9d3433fa543 100644
--- a/tests/ui/error-codes/E0017.rs
+++ b/tests/ui/error-codes/E0017.rs
@@ -3,12 +3,16 @@ const C: i32 = 2;
 static mut M: i32 = 3;
 
 const CR: &'static mut i32 = &mut C; //~ ERROR mutable references are not allowed
-                                     //~| WARN taking a mutable
+//~| WARN taking a mutable
+
 static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0658
-                                              //~| ERROR cannot borrow
-                                              //~| ERROR mutable references are not allowed
+//~| ERROR cannot borrow
+//~| ERROR mutable references are not allowed
 
 static CONST_REF: &'static mut i32 = &mut C; //~ ERROR mutable references are not allowed
-                                              //~| WARN taking a mutable
+//~| WARN taking a mutable
+
 static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M }; //~ ERROR mutable references are not
+//~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
+
 fn main() {}
diff --git a/tests/ui/error-codes/E0017.stderr b/tests/ui/error-codes/E0017.stderr
index 6e48f9582f1..ea6055da1c1 100644
--- a/tests/ui/error-codes/E0017.stderr
+++ b/tests/ui/error-codes/E0017.stderr
@@ -1,3 +1,18 @@
+warning: mutable reference of mutable static is discouraged
+  --> $DIR/E0017.rs:15:52
+   |
+LL | static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M };
+   |                                                    ^^^^^^ mutable reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
+   |
+LL | static STATIC_MUT_REF: &'static mut i32 = unsafe { addr_of_mut!(M) };
+   |                                                    ~~~~~~~~~~~~~~~
+
 warning: taking a mutable reference to a `const` item
   --> $DIR/E0017.rs:5:30
    |
@@ -20,7 +35,7 @@ LL | const CR: &'static mut i32 = &mut C;
    |                              ^^^^^^
 
 error[E0658]: mutation through a reference is not allowed in statics
-  --> $DIR/E0017.rs:7:39
+  --> $DIR/E0017.rs:8:39
    |
 LL | static STATIC_REF: &'static mut i32 = &mut X;
    |                                       ^^^^^^
@@ -29,19 +44,19 @@ LL | static STATIC_REF: &'static mut i32 = &mut X;
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
 
 error[E0764]: mutable references are not allowed in the final value of statics
-  --> $DIR/E0017.rs:7:39
+  --> $DIR/E0017.rs:8:39
    |
 LL | static STATIC_REF: &'static mut i32 = &mut X;
    |                                       ^^^^^^
 
 error[E0596]: cannot borrow immutable static item `X` as mutable
-  --> $DIR/E0017.rs:7:39
+  --> $DIR/E0017.rs:8:39
    |
 LL | static STATIC_REF: &'static mut i32 = &mut X;
    |                                       ^^^^^^ cannot borrow as mutable
 
 warning: taking a mutable reference to a `const` item
-  --> $DIR/E0017.rs:11:38
+  --> $DIR/E0017.rs:12:38
    |
 LL | static CONST_REF: &'static mut i32 = &mut C;
    |                                      ^^^^^^
@@ -55,18 +70,18 @@ LL | const C: i32 = 2;
    | ^^^^^^^^^^^^
 
 error[E0764]: mutable references are not allowed in the final value of statics
-  --> $DIR/E0017.rs:11:38
+  --> $DIR/E0017.rs:12:38
    |
 LL | static CONST_REF: &'static mut i32 = &mut C;
    |                                      ^^^^^^
 
 error[E0764]: mutable references are not allowed in the final value of statics
-  --> $DIR/E0017.rs:13:52
+  --> $DIR/E0017.rs:15:52
    |
 LL | static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M };
    |                                                    ^^^^^^
 
-error: aborting due to 6 previous errors; 2 warnings emitted
+error: aborting due to 6 previous errors; 3 warnings emitted
 
 Some errors have detailed explanations: E0596, E0658, E0764.
 For more information about an error, try `rustc --explain E0596`.
diff --git a/tests/ui/issues/issue-20616.rs b/tests/ui/impl-header-lifetime-elision/bare_type.rs
index 6c24d437272..9af98f870d2 100644
--- a/tests/ui/issues/issue-20616.rs
+++ b/tests/ui/impl-header-lifetime-elision/bare_type.rs
@@ -33,12 +33,11 @@ type TypeI<T,> = T;
 static STATIC: () = ();
 
 fn main() {
-
     // ensure token `>=` works fine
-    let _: TypeA<'static>= &STATIC;
-    let _: TypeA<'static,>= &STATIC;
+    let _: TypeA<'static> = &STATIC;
+    let _: TypeA<'static,> = &STATIC;
 
     // ensure token `>>=` works fine
-    let _: Box<TypeA<'static>>= Box::new(&STATIC);
-    let _: Box<TypeA<'static,>>= Box::new(&STATIC);
+    let _: Box<TypeA<'static>> = Box::new(&STATIC);
+    let _: Box<TypeA<'static,>> = Box::new(&STATIC);
 }
diff --git a/tests/ui/issues/issue-23611-enum-swap-in-drop.rs b/tests/ui/issues/issue-23611-enum-swap-in-drop.rs
index cdb130d600c..b967e6aecdd 100644
--- a/tests/ui/issues/issue-23611-enum-swap-in-drop.rs
+++ b/tests/ui/issues/issue-23611-enum-swap-in-drop.rs
@@ -37,11 +37,9 @@ pub fn main() {
             // | | | +-- Make D(g_b_5, 50000005)
             // | | | |                                 in g_B(b4b2) from GaspB::drop
             // | | | +-- Drop D(g_b_5, 50000005)
-            50000005,
-            // | | |
+            50000005, // | | |
             // | | +-- Drop D(GaspB::drop_3, 30000004)
-            30000004,
-            // | |
+            30000004, // | |
             // +-- Drop D(test_1, 10000000)
             10000000,
             //   |
@@ -49,15 +47,13 @@ pub fn main() {
             // | | +-- Make D(f_a_4, 40000007)
             // | | |                                   in f_A(a3a0) from GaspA::drop
             // | | +-- Drop D(f_a_4, 40000007)
-            40000007,
-            // | |
+            40000007, // | |
             // +-- Drop D(GaspA::drop_2, 20000006)
-            20000006,
-            //   |
+            20000006, //   |
             //   +-- Drop D(drop_6, 60000002)
-            60000002
-            //
-                ]);
+            60000002 //
+        ]
+    );
 
     // For reference purposes, the old (incorrect) behavior would produce the following
     // output, which you can compare to the above:
@@ -106,8 +102,8 @@ fn test<'a>(log: d::Log<'a>) {
     let _e = E::B(GaspB(g_b, 0xB4B0, log, D::new("test", 1, log)), true);
 }
 
-struct GaspA<'a>(for <'b> fn(u32, &'b str, d::Log<'a>), u32, d::Log<'a>, d::D<'a>);
-struct GaspB<'a>(for <'b> fn(u32, &'b str, d::Log<'a>), u32, d::Log<'a>, d::D<'a>);
+struct GaspA<'a>(for<'b> fn(u32, &'b str, d::Log<'a>), u32, d::Log<'a>, d::D<'a>);
+struct GaspB<'a>(for<'b> fn(u32, &'b str, d::Log<'a>), u32, d::Log<'a>, d::D<'a>);
 
 impl<'a> Drop for GaspA<'a> {
     fn drop(&mut self) {
@@ -124,7 +120,8 @@ impl<'a> Drop for GaspB<'a> {
 }
 
 enum E<'a> {
-    A(GaspA<'a>, bool), B(GaspB<'a>, bool),
+    A(GaspA<'a>, bool),
+    B(GaspB<'a>, bool),
 }
 
 fn f_a(x: u32, ctxt: &str, log: d::Log) {
@@ -174,9 +171,9 @@ const PREF_INDENT: u32 = 20;
 
 pub mod d {
     #![allow(unused_parens)]
+    use std::cell::RefCell;
     use std::fmt;
     use std::mem;
-    use std::cell::RefCell;
 
     static mut counter: u16 = 0;
     static mut trails: u64 = 0;
@@ -189,7 +186,8 @@ pub mod d {
 
     pub fn max_width() -> u32 {
         unsafe {
-            (mem::size_of_val(&trails)*8) as u32
+            (mem::size_of_val(&trails) * 8) as u32
+            //~^ WARN shared reference of mutable static is discouraged [static_mut_ref]
         }
     }
 
@@ -223,7 +221,11 @@ pub mod d {
     }
 
     pub struct D<'a> {
-        name: &'static str, i: u8, uid: u32, trail: u32, log: Log<'a>
+        name: &'static str,
+        i: u8,
+        uid: u32,
+        trail: u32,
+        log: Log<'a>,
     }
 
     impl<'a> fmt::Display for D<'a> {
@@ -239,9 +241,7 @@ pub mod d {
                 let ctr = ((i as u32) * 10_000_000) + (counter as u32);
                 counter += 1;
                 trails |= (1 << trail);
-                let ret = D {
-                    name: name, i: i, log: log, uid: ctr, trail: trail
-                };
+                let ret = D { name: name, i: i, log: log, uid: ctr, trail: trail };
                 indent_println(trail, &format!("+-- Make {}", ret));
                 ret
             }
@@ -250,7 +250,9 @@ pub mod d {
 
     impl<'a> Drop for D<'a> {
         fn drop(&mut self) {
-            unsafe { trails &= !(1 << self.trail); };
+            unsafe {
+                trails &= !(1 << self.trail);
+            };
             self.log.borrow_mut().push(self.uid);
             indent_println(self.trail, &format!("+-- Drop {}", self));
             indent_println(::PREF_INDENT, "");
diff --git a/tests/ui/issues/issue-23611-enum-swap-in-drop.stderr b/tests/ui/issues/issue-23611-enum-swap-in-drop.stderr
new file mode 100644
index 00000000000..14a986a3332
--- /dev/null
+++ b/tests/ui/issues/issue-23611-enum-swap-in-drop.stderr
@@ -0,0 +1,17 @@
+warning: shared reference of mutable static is discouraged
+  --> $DIR/issue-23611-enum-swap-in-drop.rs:189:31
+   |
+LL |             (mem::size_of_val(&trails) * 8) as u32
+   |                               ^^^^^^^ shared reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
+   |
+LL |             (mem::size_of_val(addr_of!(trails)) * 8) as u32
+   |                               ~~~~~~~~~~~~~~~~
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs
index 7d3b00dfc71..8eb544e8ab9 100644
--- a/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs
+++ b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs
@@ -14,9 +14,8 @@ struct S1 {
 
 impl S1 {
     fn new(_x: u64) -> S1 {
-        S1 {
-            a: unsafe { &mut X1 },
-        }
+        S1 { a: unsafe { &mut X1 } }
+        //~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
     }
 }
 
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
new file mode 100644
index 00000000000..17217cd5859
--- /dev/null
+++ b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr
@@ -0,0 +1,17 @@
+warning: mutable reference of mutable static is discouraged
+  --> $DIR/borrowck-thread-local-static-mut-borrow-outlives-fn.rs:17:26
+   |
+LL |         S1 { a: unsafe { &mut X1 } }
+   |                          ^^^^^^^ mutable reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
+   |
+LL |         S1 { a: unsafe { addr_of_mut!(X1) } }
+   |                          ~~~~~~~~~~~~~~~~
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/static/reference-of-mut-static-safe.e2021.stderr b/tests/ui/static/reference-of-mut-static-safe.e2021.stderr
index c38fe879063..16f47ace3a9 100644
--- a/tests/ui/static/reference-of-mut-static-safe.e2021.stderr
+++ b/tests/ui/static/reference-of-mut-static-safe.e2021.stderr
@@ -14,10 +14,10 @@ LL |     let _x = addr_of!(X);
    |              ~~~~~~~~~~~
 
 error[E0133]: use of mutable static is unsafe and requires unsafe function or block
-  --> $DIR/reference-of-mut-static-safe.rs:9:14
+  --> $DIR/reference-of-mut-static-safe.rs:9:15
    |
 LL |     let _x = &X;
-   |              ^^ use of mutable static
+   |               ^ use of mutable static
    |
    = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
 
diff --git a/tests/ui/static/safe-extern-statics-mut.rs b/tests/ui/static/safe-extern-statics-mut.rs
index 324fa443aa5..1c0662e0a6c 100644
--- a/tests/ui/static/safe-extern-statics-mut.rs
+++ b/tests/ui/static/safe-extern-statics-mut.rs
@@ -10,6 +10,8 @@ extern "C" {
 fn main() {
     let b = B; //~ ERROR use of mutable static is unsafe
     let rb = &B; //~ ERROR use of mutable static is unsafe
+    //~^ WARN shared reference of mutable static is discouraged [static_mut_ref]
     let xb = XB; //~ ERROR use of mutable static is unsafe
     let xrb = &XB; //~ ERROR use of mutable static is unsafe
+    //~^ WARN shared reference of mutable static is discouraged [static_mut_ref]
 }
diff --git a/tests/ui/static/safe-extern-statics-mut.stderr b/tests/ui/static/safe-extern-statics-mut.stderr
index e390625f20a..eda353ce673 100644
--- a/tests/ui/static/safe-extern-statics-mut.stderr
+++ b/tests/ui/static/safe-extern-statics-mut.stderr
@@ -1,3 +1,32 @@
+warning: shared reference of mutable static is discouraged
+  --> $DIR/safe-extern-statics-mut.rs:12:14
+   |
+LL |     let rb = &B;
+   |              ^^ shared reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
+   |
+LL |     let rb = addr_of!(B);
+   |              ~~~~~~~~~~~
+
+warning: shared reference of mutable static is discouraged
+  --> $DIR/safe-extern-statics-mut.rs:15:15
+   |
+LL |     let xrb = &XB;
+   |               ^^^ shared reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
+   |
+LL |     let xrb = addr_of!(XB);
+   |               ~~~~~~~~~~~~
+
 error[E0133]: use of mutable static is unsafe and requires unsafe function or block
   --> $DIR/safe-extern-statics-mut.rs:11:13
    |
@@ -15,7 +44,7 @@ LL |     let rb = &B;
    = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
 
 error[E0133]: use of mutable static is unsafe and requires unsafe function or block
-  --> $DIR/safe-extern-statics-mut.rs:13:14
+  --> $DIR/safe-extern-statics-mut.rs:14:14
    |
 LL |     let xb = XB;
    |              ^^ use of mutable static
@@ -23,13 +52,13 @@ LL |     let xb = XB;
    = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
 
 error[E0133]: use of mutable static is unsafe and requires unsafe function or block
-  --> $DIR/safe-extern-statics-mut.rs:14:16
+  --> $DIR/safe-extern-statics-mut.rs:15:16
    |
 LL |     let xrb = &XB;
    |                ^^ use of mutable static
    |
    = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
 
-error: aborting due to 4 previous errors
+error: aborting due to 4 previous errors; 2 warnings emitted
 
 For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/statics/issue-15261.rs b/tests/ui/statics/issue-15261.rs
index ec413f6d1d2..14422329b7d 100644
--- a/tests/ui/statics/issue-15261.rs
+++ b/tests/ui/statics/issue-15261.rs
@@ -6,6 +6,7 @@
 
 static mut n_mut: usize = 0;
 
-static n: &'static usize = unsafe{ &n_mut };
+static n: &'static usize = unsafe { &n_mut };
+//~^ WARN shared reference of mutable static is discouraged [static_mut_ref]
 
 fn main() {}
diff --git a/tests/ui/statics/issue-15261.stderr b/tests/ui/statics/issue-15261.stderr
new file mode 100644
index 00000000000..72d88ce1b38
--- /dev/null
+++ b/tests/ui/statics/issue-15261.stderr
@@ -0,0 +1,17 @@
+warning: shared reference of mutable static is discouraged
+  --> $DIR/issue-15261.rs:9:37
+   |
+LL | static n: &'static usize = unsafe { &n_mut };
+   |                                     ^^^^^^ shared reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
+   |
+LL | static n: &'static usize = unsafe { addr_of!(n_mut) };
+   |                                     ~~~~~~~~~~~~~~~
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/statics/static-mut-xc.rs b/tests/ui/statics/static-mut-xc.rs
index 1d172d26a59..2fc265e02ea 100644
--- a/tests/ui/statics/static-mut-xc.rs
+++ b/tests/ui/statics/static-mut-xc.rs
@@ -7,7 +7,6 @@
 
 // aux-build:static_mut_xc.rs
 
-
 extern crate static_mut_xc;
 
 unsafe fn static_bound(_: &'static isize) {}
@@ -27,7 +26,9 @@ unsafe fn run() {
     static_mut_xc::a = -3;
     assert_eq!(static_mut_xc::a, -3);
     static_bound(&static_mut_xc::a);
+    //~^ WARN shared reference of mutable static is discouraged [static_mut_ref]
     static_bound_set(&mut static_mut_xc::a);
+    //~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
 }
 
 pub fn main() {
diff --git a/tests/ui/statics/static-mut-xc.stderr b/tests/ui/statics/static-mut-xc.stderr
new file mode 100644
index 00000000000..37aa336bc50
--- /dev/null
+++ b/tests/ui/statics/static-mut-xc.stderr
@@ -0,0 +1,31 @@
+warning: shared reference of mutable static is discouraged
+  --> $DIR/static-mut-xc.rs:28:18
+   |
+LL |     static_bound(&static_mut_xc::a);
+   |                  ^^^^^^^^^^^^^^^^^ shared reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
+   |
+LL |     static_bound(addr_of!(static_mut_xc::a));
+   |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+warning: mutable reference of mutable static is discouraged
+  --> $DIR/static-mut-xc.rs:30:22
+   |
+LL |     static_bound_set(&mut static_mut_xc::a);
+   |                      ^^^^^^^^^^^^^^^^^^^^^ mutable reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
+   |
+LL |     static_bound_set(addr_of_mut!(static_mut_xc::a));
+   |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/statics/static-recursive.rs b/tests/ui/statics/static-recursive.rs
index 95dadc81f81..216beb0206d 100644
--- a/tests/ui/statics/static-recursive.rs
+++ b/tests/ui/statics/static-recursive.rs
@@ -1,36 +1,43 @@
 // run-pass
+
 static mut S: *const u8 = unsafe { &S as *const *const u8 as *const u8 };
+//~^ WARN shared reference of mutable static is discouraged [static_mut_ref]
 
 struct StaticDoubleLinked {
     prev: &'static StaticDoubleLinked,
     next: &'static StaticDoubleLinked,
     data: i32,
-    head: bool
+    head: bool,
 }
 
-static L1: StaticDoubleLinked = StaticDoubleLinked{prev: &L3, next: &L2, data: 1, head: true};
-static L2: StaticDoubleLinked = StaticDoubleLinked{prev: &L1, next: &L3, data: 2, head: false};
-static L3: StaticDoubleLinked = StaticDoubleLinked{prev: &L2, next: &L1, data: 3, head: false};
-
+static L1: StaticDoubleLinked = StaticDoubleLinked { prev: &L3, next: &L2, data: 1, head: true };
+static L2: StaticDoubleLinked = StaticDoubleLinked { prev: &L1, next: &L3, data: 2, head: false };
+static L3: StaticDoubleLinked = StaticDoubleLinked { prev: &L2, next: &L1, data: 3, head: false };
 
 pub fn main() {
-    unsafe { assert_eq!(S, *(S as *const *const u8)); }
+    unsafe {
+        assert_eq!(S, *(S as *const *const u8));
+    }
 
     let mut test_vec = Vec::new();
     let mut cur = &L1;
     loop {
         test_vec.push(cur.data);
         cur = cur.next;
-        if cur.head { break }
+        if cur.head {
+            break;
+        }
     }
-    assert_eq!(&test_vec, &[1,2,3]);
+    assert_eq!(&test_vec, &[1, 2, 3]);
 
     let mut test_vec = Vec::new();
     let mut cur = &L1;
     loop {
         cur = cur.prev;
         test_vec.push(cur.data);
-        if cur.head { break }
+        if cur.head {
+            break;
+        }
     }
-    assert_eq!(&test_vec, &[3,2,1]);
+    assert_eq!(&test_vec, &[3, 2, 1]);
 }
diff --git a/tests/ui/statics/static-recursive.stderr b/tests/ui/statics/static-recursive.stderr
new file mode 100644
index 00000000000..15888e5c68d
--- /dev/null
+++ b/tests/ui/statics/static-recursive.stderr
@@ -0,0 +1,17 @@
+warning: shared reference of mutable static is discouraged
+  --> $DIR/static-recursive.rs:3:36
+   |
+LL | static mut S: *const u8 = unsafe { &S as *const *const u8 as *const u8 };
+   |                                    ^^ shared reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
+   |
+LL | static mut S: *const u8 = unsafe { addr_of!(S) as *const *const u8 as *const u8 };
+   |                                    ~~~~~~~~~~~
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/thread-local/thread-local-static.rs b/tests/ui/thread-local/thread-local-static.rs
index e6cd4839dda..f5fb0984897 100644
--- a/tests/ui/thread-local/thread-local-static.rs
+++ b/tests/ui/thread-local/thread-local-static.rs
@@ -8,7 +8,8 @@ static mut STATIC_VAR_2: [u32; 8] = [4; 8];
 const fn g(x: &mut [u32; 8]) {
     //~^ ERROR mutable references are not allowed
     std::mem::swap(x, &mut STATIC_VAR_2)
-    //~^ ERROR thread-local statics cannot be accessed
+    //~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
+    //~^^ ERROR thread-local statics cannot be accessed
     //~| ERROR mutable references are not allowed
     //~| ERROR use of mutable static is unsafe
     //~| constant functions cannot refer to statics
diff --git a/tests/ui/thread-local/thread-local-static.stderr b/tests/ui/thread-local/thread-local-static.stderr
index c1777dd60db..b03f4580c2c 100644
--- a/tests/ui/thread-local/thread-local-static.stderr
+++ b/tests/ui/thread-local/thread-local-static.stderr
@@ -1,3 +1,18 @@
+warning: mutable reference of mutable static is discouraged
+  --> $DIR/thread-local-static.rs:10:23
+   |
+LL |     std::mem::swap(x, &mut STATIC_VAR_2)
+   |                       ^^^^^^^^^^^^^^^^^ mutable reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
+   |
+LL |     std::mem::swap(x, addr_of_mut!(STATIC_VAR_2))
+   |                       ~~~~~~~~~~~~~~~~~~~~~~~~~~
+
 error[E0133]: use of mutable static is unsafe and requires unsafe function or block
   --> $DIR/thread-local-static.rs:10:28
    |
@@ -38,7 +53,7 @@ LL |     std::mem::swap(x, &mut STATIC_VAR_2)
    = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
 
-error: aborting due to 5 previous errors
+error: aborting due to 5 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0013, E0133, E0625, E0658.
 For more information about an error, try `rustc --explain E0013`.
diff --git a/tests/ui/thread-local/thread-local-static.thir.stderr b/tests/ui/thread-local/thread-local-static.thir.stderr
new file mode 100644
index 00000000000..2043b268c09
--- /dev/null
+++ b/tests/ui/thread-local/thread-local-static.thir.stderr
@@ -0,0 +1,59 @@
+warning: mutable reference of mutable static is discouraged
+  --> $DIR/thread-local-static.rs:12:23
+   |
+LL |     std::mem::swap(x, &mut STATIC_VAR_2)
+   |                       ^^^^^^^^^^^^^^^^^ mutable reference of mutable static
+   |
+   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
+   = note: reference of mutable static is a hard error from 2024 edition
+   = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
+   = note: `#[warn(static_mut_ref)]` on by default
+help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
+   |
+LL |     std::mem::swap(x, addr_of_mut!(STATIC_VAR_2))
+   |                       ~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0658]: mutable references are not allowed in constant functions
+  --> $DIR/thread-local-static.rs:10:12
+   |
+LL | const fn g(x: &mut [u32; 8]) {
+   |            ^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
+error[E0625]: thread-local statics cannot be accessed at compile-time
+  --> $DIR/thread-local-static.rs:12:28
+   |
+LL |     std::mem::swap(x, &mut STATIC_VAR_2)
+   |                            ^^^^^^^^^^^^
+
+error[E0013]: constant functions cannot refer to statics
+  --> $DIR/thread-local-static.rs:12:28
+   |
+LL |     std::mem::swap(x, &mut STATIC_VAR_2)
+   |                            ^^^^^^^^^^^^
+   |
+   = help: consider extracting the value of the `static` to a `const`, and referring to that
+
+error[E0658]: mutable references are not allowed in constant functions
+  --> $DIR/thread-local-static.rs:12:23
+   |
+LL |     std::mem::swap(x, &mut STATIC_VAR_2)
+   |                       ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+  --> $DIR/thread-local-static.rs:12:23
+   |
+LL |     std::mem::swap(x, &mut STATIC_VAR_2)
+   |                       ^^^^^^^^^^^^^^^^^ use of mutable static
+   |
+   = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error: aborting due to 5 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0013, E0133, E0625, E0658.
+For more information about an error, try `rustc --explain E0013`.