diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0796.md | 26 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/messages.ftl | 31 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/errs.rs | 28 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/errors.rs | 28 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/lib.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_lint_defs/src/builtin.rs | 8 |
8 files changed, 59 insertions, 71 deletions
diff --git a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs index 2a7b1107ffc..8b0b9123ac7 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs @@ -112,8 +112,8 @@ fn start<T: Termination + 'static>( static mut NUM: u8 = 6 * 7; -// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint -#[allow(static_mut_ref)] +// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_refs` lint +#[allow(static_mut_refs)] static NUM_REF: &'static u8 = unsafe { &NUM }; unsafe fn zeroed<T>() -> T { diff --git a/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs b/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs index 9827e299f2a..add77880716 100644 --- a/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs +++ b/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs @@ -99,8 +99,8 @@ fn start<T: Termination + 'static>( static mut NUM: u8 = 6 * 7; -// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint -#[allow(static_mut_ref)] +// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_refs` lint +#[allow(static_mut_refs)] static NUM_REF: &'static u8 = unsafe { &NUM }; macro_rules! assert { diff --git a/compiler/rustc_error_codes/src/error_codes/E0796.md b/compiler/rustc_error_codes/src/error_codes/E0796.md index cea18f8db85..7ac429e5215 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0796.md +++ b/compiler/rustc_error_codes/src/error_codes/E0796.md @@ -1,22 +1,26 @@ -Reference of mutable static. +You have created a reference to a 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 work() { + let _val = unsafe { X }; } -fn foo<'a>(_x: &'a i32) {} +let x_ref = unsafe { &mut X }; +work(); +// The next line has Undefined Behavior! +// `x_ref` is a mutable reference and allows no aliases, +// but `work` has been reading the reference between +// the moment `x_ref` was created and when it was used. +// This violates the uniqueness of `x_ref`. +*x_ref = 42; ``` -Mutable statics can be written to by multiple threads: aliasing violations or -data races will cause undefined behavior. +A reference to a mutable static has lifetime `'static`. This is very dangerous +as it is easy to accidentally overlap the lifetime of that reference with +other, conflicting accesses to the same static. -Reference of mutable static is a hard error from 2024 edition. +References to mutable statics are a hard error in the 2024 edition. diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index a61cfd0e4ce..202c5ba989a 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -373,19 +373,24 @@ 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_mut_ref = creating a {$shared} reference to a mutable static + .label = {$shared} reference to mutable static + .note = {$shared -> + [shared] this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior + *[mutable] this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior + } + .suggestion = use `addr_of!` instead to create a raw pointer + .suggestion_mut = use `addr_of_mut!` instead to create a raw pointer + +hir_analysis_static_mut_refs_lint = creating a {$shared} reference to mutable static is discouraged + .label = {$shared} reference to mutable static + .suggestion = use `addr_of!` instead to create a raw pointer + .suggestion_mut = use `addr_of_mut!` instead to create a raw pointer + .note = this will be a hard error in the 2024 edition + .why_note = {$shared -> + [shared] this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior + *[mutable] this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior + } hir_analysis_static_specialize = cannot specialize on `'static` lifetime diff --git a/compiler/rustc_hir_analysis/src/check/errs.rs b/compiler/rustc_hir_analysis/src/check/errs.rs index 87a1f3d3425..4a7ace274c5 100644 --- a/compiler/rustc_hir_analysis/src/check/errs.rs +++ b/compiler/rustc_hir_analysis/src/check/errs.rs @@ -1,6 +1,6 @@ use rustc_hir as hir; use rustc_hir_pretty::qpath_to_string; -use rustc_lint_defs::builtin::STATIC_MUT_REF; +use rustc_lint_defs::builtin::STATIC_MUT_REFS; use rustc_middle::ty::TyCtxt; use rustc_span::Span; use rustc_type_ir::Mutability; @@ -66,32 +66,24 @@ fn handle_static_mut_ref( hir_id: hir::HirId, ) { if e2024 { - let sugg = if mutable { - errors::StaticMutRefSugg::Mut { span, var } + let (sugg, shared) = if mutable { + (errors::StaticMutRefSugg::Mut { span, var }, "mutable") } else { - errors::StaticMutRefSugg::Shared { span, var } + (errors::StaticMutRefSugg::Shared { span, var }, "shared") }; - tcx.sess.parse_sess.dcx.emit_err(errors::StaticMutRef { span, sugg }); + tcx.sess.parse_sess.dcx.emit_err(errors::StaticMutRef { span, sugg, shared }); return; } - let (label, sugg, shared) = if mutable { - ( - errors::RefOfMutStaticLabel::Mut { span }, - errors::RefOfMutStaticSugg::Mut { span, var }, - "mutable ", - ) + let (sugg, shared) = if mutable { + (errors::RefOfMutStaticSugg::Mut { span, var }, "mutable") } else { - ( - errors::RefOfMutStaticLabel::Shared { span }, - errors::RefOfMutStaticSugg::Shared { span, var }, - "shared ", - ) + (errors::RefOfMutStaticSugg::Shared { span, var }, "shared") }; tcx.emit_node_span_lint( - STATIC_MUT_REF, + STATIC_MUT_REFS, hir_id, span, - errors::RefOfMutStatic { shared, why_note: (), label, sugg }, + errors::RefOfMutStatic { span, sugg, shared }, ); } diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 6a505b96197..a8fd311df43 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1455,12 +1455,13 @@ pub struct OnlyCurrentTraitsPointerSugg<'a> { #[derive(Diagnostic)] #[diag(hir_analysis_static_mut_ref, code = E0796)] #[note] -pub struct StaticMutRef { +pub struct StaticMutRef<'a> { #[primary_span] #[label] pub span: Span, #[subdiagnostic] pub sugg: StaticMutRefSugg, + pub shared: &'a str, } #[derive(Subdiagnostic)] @@ -1491,30 +1492,15 @@ pub enum StaticMutRefSugg { // STATIC_MUT_REF lint #[derive(LintDiagnostic)] -#[diag(hir_analysis_static_mut_ref_lint)] +#[diag(hir_analysis_static_mut_refs_lint)] #[note] +#[note(hir_analysis_why_note)] pub struct RefOfMutStatic<'a> { - pub shared: &'a str, - #[note(hir_analysis_why_note)] - pub why_note: (), - #[subdiagnostic] - pub label: RefOfMutStaticLabel, + #[label] + pub span: Span, #[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, - }, + pub shared: &'a str, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 85f9d3bd63e..e50f4ca338b 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -325,6 +325,7 @@ fn register_builtins(store: &mut LintStore) { store.register_renamed("or_patterns_back_compat", "rust_2021_incompatible_or_patterns"); store.register_renamed("non_fmt_panic", "non_fmt_panics"); store.register_renamed("unused_tuple_struct_fields", "dead_code"); + store.register_renamed("static_mut_ref", "static_mut_refs"); // These were moved to tool lints, but rustc still sees them when compiling normally, before // tool lints are registered, so `check_tool_name_for_backwards_compat` doesn't work. Use diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 6a2a2c1e48e..3f5d3c25971 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -89,7 +89,7 @@ declare_lint_pass! { SINGLE_USE_LIFETIMES, SOFT_UNSTABLE, STABLE_FEATURES, - STATIC_MUT_REF, + STATIC_MUT_REFS, SUSPICIOUS_AUTO_TRAIT_IMPLS, TEST_UNSTABLE_LINT, TEXT_DIRECTION_CODEPOINT_IN_COMMENT, @@ -1769,7 +1769,7 @@ declare_lint! { } declare_lint! { - /// The `static_mut_ref` lint checks for shared or mutable references + /// The `static_mut_refs` lint checks for shared or mutable references /// of mutable static inside `unsafe` blocks and `unsafe` functions. /// /// ### Example @@ -1807,9 +1807,9 @@ declare_lint! { /// 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 + /// This lint is "warn" by default on editions up to 2021, in 2024 there is /// a hard error instead. - pub STATIC_MUT_REF, + pub STATIC_MUT_REFS, Warn, "shared references or mutable references of mutable static is discouraged", @future_incompatible = FutureIncompatibleInfo { |
