diff --git a/Cargo.lock b/Cargo.lock index b8192e333fe91..1d6f7ea1e27ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3877,6 +3877,7 @@ dependencies = [ "rustc_feature", "rustc_fluent_macro", "rustc_hir", + "rustc_hir_pretty", "rustc_index", "rustc_infer", "rustc_lint_defs", 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 a1cdf31c68a00..2a7b1107ffcaa 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( } 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 { 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 40a1ad22c0e13..9827e299f2a31 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( } 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/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index 1028d43f9c5ba..a1391cceb7128 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -515,6 +515,7 @@ E0792: include_str!("./error_codes/E0792.md"), E0793: include_str!("./error_codes/E0793.md"), E0794: include_str!("./error_codes/E0794.md"), E0795: include_str!("./error_codes/E0795.md"), +E0796: include_str!("./error_codes/E0796.md"), } // Undocumented removed error codes. Note that many removed error codes are kept in the list above diff --git a/compiler/rustc_error_codes/src/error_codes/E0796.md b/compiler/rustc_error_codes/src/error_codes/E0796.md new file mode 100644 index 0000000000000..cea18f8db851f --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0796.md @@ -0,0 +1,22 @@ +Reference of mutable static. + +Erroneous code example: + +```compile_fail,edition2024,E0796 +static mut X: i32 = 23; +static mut Y: i32 = 24; + +unsafe { + let y = &X; + let ref x = X; + let (x, y) = (&X, &Y); + foo(&X); +} + +fn foo<'a>(_x: &'a i32) {} +``` + +Mutable statics can be written to by multiple threads: aliasing violations or +data races will cause undefined behavior. + +Reference of mutable static is a hard error from 2024 edition. diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml index b671bebeb0503..b5ebc1fab765d 100644 --- a/compiler/rustc_hir_analysis/Cargo.toml +++ b/compiler/rustc_hir_analysis/Cargo.toml @@ -17,6 +17,7 @@ rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } +rustc_hir_pretty = { path = "../rustc_hir_pretty" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } rustc_lint_defs = { path = "../rustc_lint_defs" } diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index d8b6b9a1272fb..6a17668ad17f8 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -346,6 +346,20 @@ hir_analysis_start_not_target_feature = `#[start]` function is not allowed to ha hir_analysis_start_not_track_caller = `#[start]` function is not allowed to be `#[track_caller]` .label = `#[start]` function is not allowed to be `#[track_caller]` +hir_analysis_static_mut_ref = reference of mutable static is disallowed + .label = reference of mutable static + .note = mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior + .suggestion = 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 + .suggestion_mut = 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 + +hir_analysis_static_mut_ref_lint = {$shared}reference of mutable static is discouraged + .label = shared reference of mutable static + .label_mut = mutable reference of mutable static + .suggestion = 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 + .suggestion_mut = 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 + .note = reference of mutable static is a hard error from 2024 edition + .why_note = mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior + hir_analysis_static_specialize = cannot specialize on `'static` lifetime hir_analysis_substs_on_overridden_impl = could not resolve substs on overridden impl diff --git a/compiler/rustc_hir_analysis/src/check/errs.rs b/compiler/rustc_hir_analysis/src/check/errs.rs new file mode 100644 index 0000000000000..27bb2c57a5cb7 --- /dev/null +++ b/compiler/rustc_hir_analysis/src/check/errs.rs @@ -0,0 +1,97 @@ +use rustc_hir as hir; +use rustc_hir_pretty::qpath_to_string; +use rustc_lint_defs::builtin::STATIC_MUT_REF; +use rustc_middle::ty::TyCtxt; +use rustc_span::Span; +use rustc_type_ir::Mutability; + +use crate::errors; + +/// Check for shared or mutable references of `static mut` inside expression +pub fn maybe_expr_static_mut(tcx: TyCtxt<'_>, expr: hir::Expr<'_>) { + let span = expr.span; + let hir_id = expr.hir_id; + if let hir::ExprKind::AddrOf(borrow_kind, m, expr) = expr.kind + && matches!(borrow_kind, hir::BorrowKind::Ref) + && let Some(var) = is_path_static_mut(*expr) + { + handle_static_mut_ref( + tcx, + span, + var, + span.edition().at_least_rust_2024(), + matches!(m, Mutability::Mut), + hir_id, + ); + } +} + +/// Check for shared or mutable references of `static mut` inside statement +pub fn maybe_stmt_static_mut(tcx: TyCtxt<'_>, stmt: hir::Stmt<'_>) { + if let hir::StmtKind::Local(loc) = stmt.kind + && let hir::PatKind::Binding(ba, _, _, _) = loc.pat.kind + && matches!(ba.0, rustc_ast::ByRef::Yes) + && let Some(init) = loc.init + && let Some(var) = is_path_static_mut(*init) + { + handle_static_mut_ref( + tcx, + init.span, + var, + loc.span.edition().at_least_rust_2024(), + matches!(ba.1, Mutability::Mut), + stmt.hir_id, + ); + } +} + +fn is_path_static_mut(expr: hir::Expr<'_>) -> Option { + if let hir::ExprKind::Path(qpath) = expr.kind + && let hir::QPath::Resolved(_, path) = qpath + && let hir::def::Res::Def(def_kind, _) = path.res + && let hir::def::DefKind::Static(mt) = def_kind + && matches!(mt, Mutability::Mut) + { + return Some(qpath_to_string(&qpath)); + } + None +} + +fn handle_static_mut_ref( + tcx: TyCtxt<'_>, + span: Span, + var: String, + e2024: bool, + mutable: bool, + hir_id: hir::HirId, +) { + if e2024 { + let sugg = if mutable { + errors::StaticMutRefSugg::Mut { span, var } + } else { + errors::StaticMutRefSugg::Shared { span, var } + }; + tcx.sess.parse_sess.dcx.emit_err(errors::StaticMutRef { span, sugg }); + return; + } + + let (label, sugg, shared) = if mutable { + ( + errors::RefOfMutStaticLabel::Mut { span }, + errors::RefOfMutStaticSugg::Mut { span, var }, + "mutable ", + ) + } else { + ( + errors::RefOfMutStaticLabel::Shared { span }, + errors::RefOfMutStaticSugg::Shared { span, var }, + "shared ", + ) + }; + tcx.emit_spanned_lint( + STATIC_MUT_REF, + hir_id, + span, + errors::RefOfMutStatic { shared, why_note: (), label, sugg }, + ); +} diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index f60d6950670d9..ac0c715c6b308 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -66,6 +66,7 @@ mod check; mod compare_impl_item; pub mod dropck; mod entry; +mod errs; pub mod intrinsic; pub mod intrinsicck; mod region; diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index 542e69a6c34de..5d5a4789734a7 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -18,6 +18,8 @@ use rustc_middle::ty::TyCtxt; use rustc_span::source_map; use rustc_span::Span; +use super::errs::{maybe_expr_static_mut, maybe_stmt_static_mut}; + use std::mem; #[derive(Debug, Copy, Clone)] @@ -224,6 +226,8 @@ fn resolve_stmt<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, stmt: &'tcx h let stmt_id = stmt.hir_id.local_id; debug!("resolve_stmt(stmt.id={:?})", stmt_id); + maybe_stmt_static_mut(visitor.tcx, *stmt); + // Every statement will clean up the temporaries created during // execution of that statement. Therefore each statement has an // associated destruction scope that represents the scope of the @@ -242,6 +246,8 @@ fn resolve_stmt<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, stmt: &'tcx h fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx hir::Expr<'tcx>) { debug!("resolve_expr - pre-increment {} expr = {:?}", visitor.expr_and_pat_count, expr); + maybe_expr_static_mut(visitor.tcx, *expr); + let prev_cx = visitor.cx; visitor.enter_node_scope_with_dtor(expr.hir_id.local_id); diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 9124d50211056..4f22da4ba3b98 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1410,3 +1410,94 @@ pub struct OnlyCurrentTraitsPointerSugg<'a> { pub mut_key: &'a str, pub ptr_ty: Ty<'a>, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_static_mut_ref, code = "E0796")] +#[note] +pub struct StaticMutRef { + #[primary_span] + #[label] + pub span: Span, + #[subdiagnostic] + pub sugg: StaticMutRefSugg, +} + +#[derive(Subdiagnostic)] +pub enum StaticMutRefSugg { + #[suggestion( + hir_analysis_suggestion, + style = "verbose", + code = "addr_of!({var})", + applicability = "maybe-incorrect" + )] + Shared { + #[primary_span] + span: Span, + var: String, + }, + #[suggestion( + hir_analysis_suggestion_mut, + style = "verbose", + code = "addr_of_mut!({var})", + applicability = "maybe-incorrect" + )] + Mut { + #[primary_span] + span: Span, + var: String, + }, +} + +// STATIC_MUT_REF lint +#[derive(LintDiagnostic)] +#[diag(hir_analysis_static_mut_ref_lint)] +#[note] +pub struct RefOfMutStatic<'a> { + pub shared: &'a str, + #[note(hir_analysis_why_note)] + pub why_note: (), + #[subdiagnostic] + pub label: RefOfMutStaticLabel, + #[subdiagnostic] + pub sugg: RefOfMutStaticSugg, +} + +#[derive(Subdiagnostic)] +pub enum RefOfMutStaticLabel { + #[label(hir_analysis_label)] + Shared { + #[primary_span] + span: Span, + }, + #[label(hir_analysis_label_mut)] + Mut { + #[primary_span] + span: Span, + }, +} + +#[derive(Subdiagnostic)] +pub enum RefOfMutStaticSugg { + #[suggestion( + hir_analysis_suggestion, + style = "verbose", + code = "addr_of!({var})", + applicability = "maybe-incorrect" + )] + Shared { + #[primary_span] + span: Span, + var: String, + }, + #[suggestion( + hir_analysis_suggestion_mut, + style = "verbose", + code = "addr_of_mut!({var})", + applicability = "maybe-incorrect" + )] + Mut { + #[primary_span] + span: Span, + var: String, + }, +} diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 19da51b7dcfa3..cfba6780a66fa 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -89,6 +89,7 @@ declare_lint_pass! { SINGLE_USE_LIFETIMES, SOFT_UNSTABLE, STABLE_FEATURES, + STATIC_MUT_REF, SUSPICIOUS_AUTO_TRAIT_IMPLS, TEST_UNSTABLE_LINT, TEXT_DIRECTION_CODEPOINT_IN_COMMENT, @@ -1767,6 +1768,57 @@ declare_lint! { }; } +declare_lint! { + /// The `static_mut_ref` lint checks for shared or mutable references + /// of mutable static inside `unsafe` blocks and `unsafe` functions. + /// + /// ### Example + /// + /// ```rust,edition2021 + /// fn main() { + /// static mut X: i32 = 23; + /// static mut Y: i32 = 24; + /// + /// unsafe { + /// let y = &X; + /// let ref x = X; + /// let (x, y) = (&X, &Y); + /// foo(&X); + /// } + /// } + /// + /// unsafe fn _foo() { + /// static mut X: i32 = 23; + /// static mut Y: i32 = 24; + /// + /// let y = &X; + /// let ref x = X; + /// let (x, y) = (&X, &Y); + /// foo(&X); + /// } + /// + /// fn foo<'a>(_x: &'a i32) {} + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Shared or mutable references of mutable static are almost always a mistake and + /// can lead to undefined behavior and various other problems in your code. + /// + /// This lint is "warn" by default on editions up to 2021, from 2024 there is + /// a hard error instead. + pub STATIC_MUT_REF, + Warn, + "shared references or mutable references of mutable static is discouraged", + @future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024), + reference: "issue #114447 ", + explain_reason: false, + }; +} + declare_lint! { /// The `absolute_paths_not_starting_with_crate` lint detects fully /// qualified paths that start with a module name instead of `crate`, diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs index 99db00e549066..ccae406cc286c 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) -> u32 { use core::intrinsics::atomic_store_seqcst; @@ -322,6 +324,8 @@ pub unsafe fn panic(data: Box) -> 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 { // 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 66b4ec37c8ec5..c80f15d8a611b 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 c0a9619bf7bfa..9206588be064e 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 5cb6c541a0ec5..51cba66fad76d 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 9cf37b0e6347c..338567777f753 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -180,6 +180,8 @@ impl fmt::Debug for LocalKey { #[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 5be8ef7996bb2..c5cd30ccc3437 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>; 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 d5e6d37226ab3..762a8d85314f2 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 218b02525bd55..c1e58b70adb0b 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 fc4c8a283ddb2..9be00af47aa35 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 ecd8ee94a01e3..eb732e7c2c31f 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 0000000000000..144ac056f87e4 --- /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 + = 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 + = 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 469ad508b0e77..1638644103ba4 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 c161e2d95b43a..93d92295dd9b6 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 + = 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 adc7dfd541f48..1bf079e24cae4 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 0000000000000..7a3824f79a4c2 --- /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 + = 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 c3f136f2876b6..ec83af5d5dfc6 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 215bf01006369..b2bee2d880394 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 + = 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 b3cce1b3a0611..9b172b4131911 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 4c299cdc455ac..e4e4947fce1c1 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 + = 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 + = 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 + = 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 28265c85dd1f1..1c7afe0e3d6cb 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 0000000000000..2764153a8a590 --- /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 + = 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 62bbb3b569c37..4fedc48452bec 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 405c2195dec4f..2dc91f52669e7 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 + = 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 7960648ce3a19..ed9db67542641 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 + = 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 6ae0b2d1bfef7..275323bc286c0 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 + = 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 bbaa32ddfd1bd..3eafa58d9f9fd 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 df09c76c5584d..874aa59df0bb6 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 0000000000000..56ceba41cf88c --- /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 + = 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 3d0de233569c9..bc32ecc2c35ff 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 + = 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 61368546083db..fa79a78eab424 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 3d5b012d42f37..c6e5b07e3b70a 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 + = 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 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 a99f260dde3b2..52603744c45fc 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 0000000000000..fd36ccbcbee47 --- /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 + = 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 c211ad1a2f8f6..9d3433fa543fd 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 6e48f9582f1c0..ea6055da1c1fe 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 + = 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 similarity index 82% rename from tests/ui/issues/issue-20616.rs rename to tests/ui/impl-header-lifetime-elision/bare_type.rs index 6c24d437272e4..9af98f870d2d5 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; 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>= Box::new(&STATIC); - let _: Box>= Box::new(&STATIC); + let _: Box> = Box::new(&STATIC); + let _: Box> = 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 cdb130d600c5e..b967e6aecdd43 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 0000000000000..14a986a333264 --- /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 + = 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 7d3b00dfc7163..8eb544e8ab9d2 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 0000000000000..17217cd5859d0 --- /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 + = 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 new file mode 100644 index 0000000000000..16f47ace3a930 --- /dev/null +++ b/tests/ui/static/reference-of-mut-static-safe.e2021.stderr @@ -0,0 +1,26 @@ +warning: shared reference of mutable static is discouraged + --> $DIR/reference-of-mut-static-safe.rs:9:14 + | +LL | let _x = &X; + | ^^ shared reference of mutable static + | + = note: for more information, see issue #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 _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:15 + | +LL | let _x = &X; + | ^ 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 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/static/reference-of-mut-static-safe.e2024.stderr b/tests/ui/static/reference-of-mut-static-safe.e2024.stderr new file mode 100644 index 0000000000000..53f81179de55a --- /dev/null +++ b/tests/ui/static/reference-of-mut-static-safe.e2024.stderr @@ -0,0 +1,15 @@ +error[E0796]: reference of mutable static is disallowed + --> $DIR/reference-of-mut-static-safe.rs:9:14 + | +LL | let _x = &X; + | ^^ reference of mutable static + | + = 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 _x = addr_of!(X); + | ~~~~~~~~~~~ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0796`. diff --git a/tests/ui/static/reference-of-mut-static-safe.rs b/tests/ui/static/reference-of-mut-static-safe.rs new file mode 100644 index 0000000000000..5cb1a03bef512 --- /dev/null +++ b/tests/ui/static/reference-of-mut-static-safe.rs @@ -0,0 +1,13 @@ +// revisions: e2021 e2024 + +// [e2021] edition:2021 +// [e2024] compile-flags: --edition 2024 -Z unstable-options + +fn main() { + static mut X: i32 = 1; + + let _x = &X; + //[e2024]~^ reference of mutable static is disallowed [E0796] + //[e2021]~^^ use of mutable static is unsafe and requires unsafe function or block [E0133] + //[e2021]~^^^ shared reference of mutable static is discouraged [static_mut_ref] +} diff --git a/tests/ui/static/reference-of-mut-static-unsafe-fn.rs b/tests/ui/static/reference-of-mut-static-unsafe-fn.rs new file mode 100644 index 0000000000000..6b1e77850e50d --- /dev/null +++ b/tests/ui/static/reference-of-mut-static-unsafe-fn.rs @@ -0,0 +1,23 @@ +// compile-flags: --edition 2024 -Z unstable-options + +fn main() {} + +unsafe fn _foo() { + static mut X: i32 = 1; + static mut Y: i32 = 1; + + let _y = &X; + //~^ ERROR reference of mutable static is disallowed + + let ref _a = X; + //~^ ERROR reference of mutable static is disallowed + + let (_b, _c) = (&X, &Y); + //~^ ERROR reference of mutable static is disallowed + //~^^ ERROR reference of mutable static is disallowed + + foo(&X); + //~^ ERROR reference of mutable static is disallowed +} + +fn foo<'a>(_x: &'a i32) {} diff --git a/tests/ui/static/reference-of-mut-static-unsafe-fn.stderr b/tests/ui/static/reference-of-mut-static-unsafe-fn.stderr new file mode 100644 index 0000000000000..5c6fdedfa96f7 --- /dev/null +++ b/tests/ui/static/reference-of-mut-static-unsafe-fn.stderr @@ -0,0 +1,63 @@ +error[E0796]: reference of mutable static is disallowed + --> $DIR/reference-of-mut-static-unsafe-fn.rs:9:14 + | +LL | let _y = &X; + | ^^ reference of mutable static + | + = 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 _y = addr_of!(X); + | ~~~~~~~~~~~ + +error[E0796]: reference of mutable static is disallowed + --> $DIR/reference-of-mut-static-unsafe-fn.rs:12:18 + | +LL | let ref _a = X; + | ^ reference of mutable static + | + = 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 ref _a = addr_of!(X); + | ~~~~~~~~~~~ + +error[E0796]: reference of mutable static is disallowed + --> $DIR/reference-of-mut-static-unsafe-fn.rs:15:21 + | +LL | let (_b, _c) = (&X, &Y); + | ^^ reference of mutable static + | + = 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 (_b, _c) = (addr_of!(X), &Y); + | ~~~~~~~~~~~ + +error[E0796]: reference of mutable static is disallowed + --> $DIR/reference-of-mut-static-unsafe-fn.rs:15:25 + | +LL | let (_b, _c) = (&X, &Y); + | ^^ reference of mutable static + | + = 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 (_b, _c) = (&X, addr_of!(Y)); + | ~~~~~~~~~~~ + +error[E0796]: reference of mutable static is disallowed + --> $DIR/reference-of-mut-static-unsafe-fn.rs:19:9 + | +LL | foo(&X); + | ^^ reference of mutable static + | + = 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 | foo(addr_of!(X)); + | ~~~~~~~~~~~ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0796`. diff --git a/tests/ui/static/reference-of-mut-static.e2021.stderr b/tests/ui/static/reference-of-mut-static.e2021.stderr new file mode 100644 index 0000000000000..77a6b3d304bdb --- /dev/null +++ b/tests/ui/static/reference-of-mut-static.e2021.stderr @@ -0,0 +1,91 @@ +error: shared reference of mutable static is discouraged + --> $DIR/reference-of-mut-static.rs:16:18 + | +LL | let _y = &X; + | ^^ shared reference of mutable static + | + = note: for more information, see issue #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: the lint level is defined here + --> $DIR/reference-of-mut-static.rs:6:9 + | +LL | #![deny(static_mut_ref)] + | ^^^^^^^^^^^^^^ +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 _y = addr_of!(X); + | ~~~~~~~~~~~ + +error: mutable reference of mutable static is discouraged + --> $DIR/reference-of-mut-static.rs:20:18 + | +LL | let _y = &mut X; + | ^^^^^^ mutable reference of mutable static + | + = note: for more information, see issue #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 | let _y = addr_of_mut!(X); + | ~~~~~~~~~~~~~~~ + +error: shared reference of mutable static is discouraged + --> $DIR/reference-of-mut-static.rs:28:22 + | +LL | let ref _a = X; + | ^ shared reference of mutable static + | + = note: for more information, see issue #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 ref _a = addr_of!(X); + | ~~~~~~~~~~~ + +error: shared reference of mutable static is discouraged + --> $DIR/reference-of-mut-static.rs:32:25 + | +LL | let (_b, _c) = (&X, &Y); + | ^^ shared reference of mutable static + | + = note: for more information, see issue #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 (_b, _c) = (addr_of!(X), &Y); + | ~~~~~~~~~~~ + +error: shared reference of mutable static is discouraged + --> $DIR/reference-of-mut-static.rs:32:29 + | +LL | let (_b, _c) = (&X, &Y); + | ^^ shared reference of mutable static + | + = note: for more information, see issue #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 (_b, _c) = (&X, addr_of!(Y)); + | ~~~~~~~~~~~ + +error: shared reference of mutable static is discouraged + --> $DIR/reference-of-mut-static.rs:38:13 + | +LL | foo(&X); + | ^^ shared reference of mutable static + | + = note: for more information, see issue #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 | foo(addr_of!(X)); + | ~~~~~~~~~~~ + +error: aborting due to 6 previous errors + diff --git a/tests/ui/static/reference-of-mut-static.e2024.stderr b/tests/ui/static/reference-of-mut-static.e2024.stderr new file mode 100644 index 0000000000000..f445ec65a5d24 --- /dev/null +++ b/tests/ui/static/reference-of-mut-static.e2024.stderr @@ -0,0 +1,75 @@ +error[E0796]: reference of mutable static is disallowed + --> $DIR/reference-of-mut-static.rs:16:18 + | +LL | let _y = &X; + | ^^ reference of mutable static + | + = 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 _y = addr_of!(X); + | ~~~~~~~~~~~ + +error[E0796]: reference of mutable static is disallowed + --> $DIR/reference-of-mut-static.rs:20:18 + | +LL | let _y = &mut X; + | ^^^^^^ reference of mutable static + | + = 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 | let _y = addr_of_mut!(X); + | ~~~~~~~~~~~~~~~ + +error[E0796]: reference of mutable static is disallowed + --> $DIR/reference-of-mut-static.rs:28:22 + | +LL | let ref _a = X; + | ^ reference of mutable static + | + = 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 ref _a = addr_of!(X); + | ~~~~~~~~~~~ + +error[E0796]: reference of mutable static is disallowed + --> $DIR/reference-of-mut-static.rs:32:25 + | +LL | let (_b, _c) = (&X, &Y); + | ^^ reference of mutable static + | + = 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 (_b, _c) = (addr_of!(X), &Y); + | ~~~~~~~~~~~ + +error[E0796]: reference of mutable static is disallowed + --> $DIR/reference-of-mut-static.rs:32:29 + | +LL | let (_b, _c) = (&X, &Y); + | ^^ reference of mutable static + | + = 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 (_b, _c) = (&X, addr_of!(Y)); + | ~~~~~~~~~~~ + +error[E0796]: reference of mutable static is disallowed + --> $DIR/reference-of-mut-static.rs:38:13 + | +LL | foo(&X); + | ^^ reference of mutable static + | + = 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 | foo(addr_of!(X)); + | ~~~~~~~~~~~ + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0796`. diff --git a/tests/ui/static/reference-of-mut-static.rs b/tests/ui/static/reference-of-mut-static.rs new file mode 100644 index 0000000000000..01a3b1fbd9b51 --- /dev/null +++ b/tests/ui/static/reference-of-mut-static.rs @@ -0,0 +1,50 @@ +// revisions: e2021 e2024 + +// [e2021] edition:2021 +// [e2024] compile-flags: --edition 2024 -Z unstable-options + +#![deny(static_mut_ref)] + +use std::ptr::{addr_of, addr_of_mut}; + +fn main() { + static mut X: i32 = 1; + + static mut Y: i32 = 1; + + unsafe { + let _y = &X; + //[e2024]~^ ERROR reference of mutable static is disallowed + //[e2021]~^^ ERROR shared reference of mutable static is discouraged [static_mut_ref] + + let _y = &mut X; + //[e2024]~^ ERROR reference of mutable static is disallowed + //[e2021]~^^ ERROR mutable reference of mutable static is discouraged [static_mut_ref] + + let _z = addr_of_mut!(X); + + let _p = addr_of!(X); + + let ref _a = X; + //[e2024]~^ ERROR reference of mutable static is disallowed + //[e2021]~^^ ERROR shared reference of mutable static is discouraged [static_mut_ref] + + let (_b, _c) = (&X, &Y); + //[e2024]~^ ERROR reference of mutable static is disallowed + //[e2021]~^^ ERROR shared reference of mutable static is discouraged [static_mut_ref] + //[e2024]~^^^ ERROR reference of mutable static is disallowed + //[e2021]~^^^^ ERROR shared reference of mutable static is discouraged [static_mut_ref] + + foo(&X); + //[e2024]~^ ERROR reference of mutable static is disallowed + //[e2021]~^^ ERROR shared reference of mutable static is discouraged [static_mut_ref] + + static mut Z: &[i32; 3] = &[0, 1, 2]; + + let _ = Z.len(); + let _ = Z[0]; + let _ = format!("{:?}", Z); + } +} + +fn foo<'a>(_x: &'a i32) {} diff --git a/tests/ui/static/safe-extern-statics-mut.rs b/tests/ui/static/safe-extern-statics-mut.rs index 324fa443aa50e..1c0662e0a6cec 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 e390625f20a98..eda353ce6736f 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 + = 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 + = 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 ec413f6d1d2be..14422329b7dc8 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 0000000000000..72d88ce1b3832 --- /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 + = 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 1d172d26a5949..2fc265e02eaa3 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 0000000000000..37aa336bc50f7 --- /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 + = 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 + = 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 95dadc81f811d..216beb0206d9c 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 0000000000000..15888e5c68d84 --- /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 + = 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 e6cd4839dda7e..f5fb098489746 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 c1777dd60db68..b03f4580c2cf1 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 + = 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 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 0000000000000..2043b268c090c --- /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 + = 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 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 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`.