Rollup merge of #117556 - obeis:static-mut-ref-lint, r=davidtwco

Disallow reference to `static mut` and adding `static_mut_ref` lint

Closes #114447

r? `@scottmcm`
This commit is contained in:
Guillaume Gomez 2024-01-09 13:23:15 +01:00 committed by GitHub
commit 4a24b5bc05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
71 changed files with 1447 additions and 237 deletions

View File

@ -3876,6 +3876,7 @@ dependencies = [
"rustc_feature", "rustc_feature",
"rustc_fluent_macro", "rustc_fluent_macro",
"rustc_hir", "rustc_hir",
"rustc_hir_pretty",
"rustc_index", "rustc_index",
"rustc_infer", "rustc_infer",
"rustc_lint_defs", "rustc_lint_defs",

View File

@ -111,6 +111,9 @@ fn start<T: Termination + 'static>(
} }
static mut NUM: u8 = 6 * 7; 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 }; static NUM_REF: &'static u8 = unsafe { &NUM };
unsafe fn zeroed<T>() -> T { unsafe fn zeroed<T>() -> T {

View File

@ -98,6 +98,9 @@ fn start<T: Termination + 'static>(
} }
static mut NUM: u8 = 6 * 7; 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 }; static NUM_REF: &'static u8 = unsafe { &NUM };
macro_rules! assert { macro_rules! assert {

View File

@ -515,6 +515,7 @@ E0792: include_str!("./error_codes/E0792.md"),
E0793: include_str!("./error_codes/E0793.md"), E0793: include_str!("./error_codes/E0793.md"),
E0794: include_str!("./error_codes/E0794.md"), E0794: include_str!("./error_codes/E0794.md"),
E0795: include_str!("./error_codes/E0795.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 // Undocumented removed error codes. Note that many removed error codes are kept in the list above

View File

@ -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.

View File

@ -17,6 +17,7 @@ rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" } rustc_feature = { path = "../rustc_feature" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_hir = { path = "../rustc_hir" } rustc_hir = { path = "../rustc_hir" }
rustc_hir_pretty = { path = "../rustc_hir_pretty" }
rustc_index = { path = "../rustc_index" } rustc_index = { path = "../rustc_index" }
rustc_infer = { path = "../rustc_infer" } rustc_infer = { path = "../rustc_infer" }
rustc_lint_defs = { path = "../rustc_lint_defs" } rustc_lint_defs = { path = "../rustc_lint_defs" }

View File

@ -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]` 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]` .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_static_specialize = cannot specialize on `'static` lifetime
hir_analysis_substs_on_overridden_impl = could not resolve substs on overridden impl hir_analysis_substs_on_overridden_impl = could not resolve substs on overridden impl

View File

@ -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<String> {
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 },
);
}

View File

@ -66,6 +66,7 @@ mod check;
mod compare_impl_item; mod compare_impl_item;
pub mod dropck; pub mod dropck;
mod entry; mod entry;
mod errs;
pub mod intrinsic; pub mod intrinsic;
pub mod intrinsicck; pub mod intrinsicck;
mod region; mod region;

View File

@ -18,6 +18,8 @@ use rustc_middle::ty::TyCtxt;
use rustc_span::source_map; use rustc_span::source_map;
use rustc_span::Span; use rustc_span::Span;
use super::errs::{maybe_expr_static_mut, maybe_stmt_static_mut};
use std::mem; use std::mem;
#[derive(Debug, Copy, Clone)] #[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; let stmt_id = stmt.hir_id.local_id;
debug!("resolve_stmt(stmt.id={:?})", stmt_id); debug!("resolve_stmt(stmt.id={:?})", stmt_id);
maybe_stmt_static_mut(visitor.tcx, *stmt);
// Every statement will clean up the temporaries created during // Every statement will clean up the temporaries created during
// execution of that statement. Therefore each statement has an // execution of that statement. Therefore each statement has an
// associated destruction scope that represents the scope of the // 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>) { 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); debug!("resolve_expr - pre-increment {} expr = {:?}", visitor.expr_and_pat_count, expr);
maybe_expr_static_mut(visitor.tcx, *expr);
let prev_cx = visitor.cx; let prev_cx = visitor.cx;
visitor.enter_node_scope_with_dtor(expr.hir_id.local_id); visitor.enter_node_scope_with_dtor(expr.hir_id.local_id);

View File

@ -1410,3 +1410,94 @@ pub struct OnlyCurrentTraitsPointerSugg<'a> {
pub mut_key: &'a str, pub mut_key: &'a str,
pub ptr_ty: Ty<'a>, 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,
},
}

View File

@ -88,6 +88,7 @@ declare_lint_pass! {
SINGLE_USE_LIFETIMES, SINGLE_USE_LIFETIMES,
SOFT_UNSTABLE, SOFT_UNSTABLE,
STABLE_FEATURES, STABLE_FEATURES,
STATIC_MUT_REF,
SUSPICIOUS_AUTO_TRAIT_IMPLS, SUSPICIOUS_AUTO_TRAIT_IMPLS,
TEST_UNSTABLE_LINT, TEST_UNSTABLE_LINT,
TEXT_DIRECTION_CODEPOINT_IN_COMMENT, TEXT_DIRECTION_CODEPOINT_IN_COMMENT,
@ -1766,6 +1767,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 <https://github.com/rust-lang/rust/issues/114447>",
explain_reason: false,
};
}
declare_lint! { declare_lint! {
/// The `absolute_paths_not_starting_with_crate` lint detects fully /// The `absolute_paths_not_starting_with_crate` lint detects fully
/// qualified paths that start with a module name instead of `crate`, /// qualified paths that start with a module name instead of `crate`,

View File

@ -261,6 +261,8 @@ cfg_if::cfg_if! {
} }
} }
// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
#[cfg_attr(not(bootstrap), allow(static_mut_ref))]
pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 { pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
use core::intrinsics::atomic_store_seqcst; use core::intrinsics::atomic_store_seqcst;
@ -322,6 +324,8 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
_CxxThrowException(throw_ptr, &mut THROW_INFO as *mut _ as *mut _); _CxxThrowException(throw_ptr, &mut THROW_INFO as *mut _ as *mut _);
} }
// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
#[cfg_attr(not(bootstrap), allow(static_mut_ref))]
pub unsafe fn cleanup(payload: *mut u8) -> Box<dyn Any + Send> { pub unsafe fn cleanup(payload: *mut u8) -> Box<dyn Any + Send> {
// A null payload here means that we got here from the catch (...) of // 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. // __rust_try. This happens when a non-Rust foreign exception is caught.

View File

@ -337,6 +337,8 @@ pub mod panic_count {
#[doc(hidden)] #[doc(hidden)]
#[cfg(not(feature = "panic_immediate_abort"))] #[cfg(not(feature = "panic_immediate_abort"))]
#[unstable(feature = "update_panic_count", issue = "none")] #[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 { pub mod panic_count {
use crate::cell::Cell; use crate::cell::Cell;
use crate::sync::atomic::{AtomicUsize, Ordering}; use crate::sync::atomic::{AtomicUsize, Ordering};

View File

@ -13,6 +13,8 @@ pub macro thread_local_inner {
(@key $t:ty, const $init:expr) => {{ (@key $t:ty, const $init:expr) => {{
#[inline] #[inline]
#[deny(unsafe_op_in_unsafe_fn)] #[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( unsafe fn __getit(
_init: $crate::option::Option<&mut $crate::option::Option<$t>>, _init: $crate::option::Option<&mut $crate::option::Option<$t>>,
) -> $crate::option::Option<&'static $t> { ) -> $crate::option::Option<&'static $t> {

View File

@ -11,6 +11,8 @@ pub macro thread_local_inner {
(@key $t:ty, const $init:expr) => {{ (@key $t:ty, const $init:expr) => {{
#[inline] // see comments below #[inline] // see comments below
#[deny(unsafe_op_in_unsafe_fn)] #[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( unsafe fn __getit(
_init: $crate::option::Option<&mut $crate::option::Option<$t>>, _init: $crate::option::Option<&mut $crate::option::Option<$t>>,
) -> $crate::option::Option<&'static $t> { ) -> $crate::option::Option<&'static $t> {

View File

@ -180,6 +180,8 @@ impl<T: 'static> fmt::Debug for LocalKey<T> {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "thread_local_macro")] #[cfg_attr(not(test), rustc_diagnostic_item = "thread_local_macro")]
#[allow_internal_unstable(thread_local_internals)] #[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 { macro_rules! thread_local {
// empty (base case for the recursion) // empty (base case for the recursion)
() => {}; () => {};

View File

@ -15,6 +15,7 @@ static GROUP_DESCRIPTIONS: &[(&str, &str)] = &[
("future-incompatible", "Lints that detect code that has future-compatibility problems"), ("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-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-2021-compatibility", "Lints used to transition code from the 2018 edition to 2021"),
("rust-2024-compatibility", "Lints used to transition code from the 2021 edition to 2024"),
]; ];
type LintGroups = BTreeMap<String, BTreeSet<String>>; type LintGroups = BTreeMap<String, BTreeSet<String>>;

View File

@ -1,6 +1,8 @@
//! Ensure that thread-local statics get deallocated when the thread dies. //! Ensure that thread-local statics get deallocated when the thread dies.
#![feature(thread_local)] #![feature(thread_local)]
// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
#![allow(static_mut_ref)]
#[thread_local] #[thread_local]
static mut TLS: u8 = 0; static mut TLS: u8 = 0;

View File

@ -1,4 +1,7 @@
static mut FOO: i32 = 42; 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 _ }); static BAR: Foo = Foo(unsafe { &FOO as *const _ });
#[allow(dead_code)] #[allow(dead_code)]

View File

@ -8,6 +8,8 @@
//! test, we also check that thread-locals act as per-thread statics. //! test, we also check that thread-locals act as per-thread statics.
#![feature(thread_local)] #![feature(thread_local)]
// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
#![allow(static_mut_ref)]
use std::thread; use std::thread;

View File

@ -33,7 +33,9 @@ unsafe fn run() {
rust_dbg_static_mut = -3; rust_dbg_static_mut = -3;
assert_eq!(rust_dbg_static_mut, -3); assert_eq!(rust_dbg_static_mut, -3);
static_bound(&rust_dbg_static_mut); 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); static_bound_set(&mut rust_dbg_static_mut);
//~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
} }
pub fn main() { pub fn main() {

View File

@ -0,0 +1,31 @@
warning: shared reference of mutable static is discouraged
--> $DIR/static-mut-foreign.rs:35:18
|
LL | static_bound(&rust_dbg_static_mut);
| ^^^^^^^^^^^^^^^^^^^^ shared reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
|
LL | static_bound(addr_of!(rust_dbg_static_mut));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
warning: mutable reference of mutable static is discouraged
--> $DIR/static-mut-foreign.rs:37:22
|
LL | static_bound_set(&mut rust_dbg_static_mut);
| ^^^^^^^^^^^^^^^^^^^^^^^^ mutable reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | static_bound_set(addr_of_mut!(rust_dbg_static_mut));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
warning: 2 warnings emitted

View File

@ -1,21 +1,27 @@
static static_x : i32 = 1; static static_x: i32 = 1;
static mut static_x_mut : i32 = 1; static mut static_x_mut: i32 = 1;
fn main() { fn main() {
let x = 1; let x = 1;
let mut x_mut = 1; let mut x_mut = 1;
{ // borrow of local {
// borrow of local
let _y1 = &mut x; //~ ERROR [E0596] let _y1 = &mut x; //~ ERROR [E0596]
let _y2 = &mut x_mut; // No error let _y2 = &mut x_mut; // No error
} }
{ // borrow of static {
// borrow of static
let _y1 = &mut static_x; //~ ERROR [E0596] 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 box_x = Box::new(1);
let mut box_x_mut = 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 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 = &x;
let ref_x_mut = &mut x_mut; let ref_x_mut = &mut x_mut;
@ -31,9 +38,10 @@ fn main() {
let _y2 = &mut *ref_x_mut; // No error let _y2 = &mut *ref_x_mut; // No error
} }
{ // borrow of deref to pointer {
let ptr_x : *const _ = &x; // borrow of deref to pointer
let ptr_mut_x : *mut _ = &mut x_mut; let ptr_x: *const _ = &x;
let ptr_mut_x: *mut _ = &mut x_mut;
unsafe { unsafe {
let _y1 = &mut *ptr_x; //~ ERROR [E0596] 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 mut foo = Foo { f: &mut x_mut, g: &x };
let foo_ref = &foo; let foo_ref = &foo;
let _y = &mut *foo_ref.f; //~ ERROR [E0596] let _y = &mut *foo_ref.f; //~ ERROR [E0596]

View File

@ -1,5 +1,20 @@
warning: mutable reference of mutable static is discouraged
--> $DIR/borrowck-access-permissions.rs:18:23
|
LL | let _y2 = &mut static_x_mut;
| ^^^^^^^^^^^^^^^^^ mutable reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | let _y2 = addr_of_mut!(static_x_mut);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable 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; LL | let _y1 = &mut x;
| ^^^^^^ cannot borrow as mutable | ^^^^^^ cannot borrow as mutable
@ -10,13 +25,13 @@ LL | let mut x = 1;
| +++ | +++
error[E0596]: cannot borrow immutable static item `static_x` as mutable 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; LL | let _y1 = &mut static_x;
| ^^^^^^^^^^^^^ cannot borrow as mutable | ^^^^^^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `*box_x` as mutable, as `box_x` is not declared 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; LL | let _y1 = &mut *box_x;
| ^^^^^^^^^^^ cannot borrow as mutable | ^^^^^^^^^^^ 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 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; LL | let _y1 = &mut *ref_x;
| ^^^^^^^^^^^ `ref_x` is a `&` reference, so the data it refers to cannot be borrowed as mutable | ^^^^^^^^^^^ `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 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; LL | let _y1 = &mut *ptr_x;
| ^^^^^^^^^^^ `ptr_x` is a `*const` pointer, so the data it refers to cannot be borrowed as mutable | ^^^^^^^^^^^ `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 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 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; LL | let _y = &mut *foo_ref.f;
| ^^^^^^^^^^^^^^^ `foo_ref` is a `&` reference, so the data it refers to cannot be borrowed as mutable | ^^^^^^^^^^^^^^^ `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; 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`. For more information about this error, try `rustc --explain E0596`.

View File

@ -2,17 +2,22 @@
// Test file taken from issue 45129 (https://github.com/rust-lang/rust/issues/45129) // 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] }; static mut SFOO: Foo = Foo { x: [23, 32] };
impl Foo { impl Foo {
fn x(&mut self) -> &mut usize { &mut self.x[0] } fn x(&mut self) -> &mut usize {
&mut self.x[0]
}
} }
fn main() { fn main() {
unsafe { unsafe {
let sfoo: *mut Foo = &mut SFOO; let sfoo: *mut Foo = &mut SFOO;
//~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
let x = (*sfoo).x(); let x = (*sfoo).x();
(*sfoo).x[1] += 1; (*sfoo).x[1] += 1;
*x += 1; *x += 1;

View File

@ -0,0 +1,17 @@
warning: mutable reference of mutable static is discouraged
--> $DIR/borrowck-unsafe-static-mutable-borrows.rs:19:30
|
LL | let sfoo: *mut Foo = &mut SFOO;
| ^^^^^^^^^ mutable reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | let sfoo: *mut Foo = addr_of_mut!(SFOO);
| ~~~~~~~~~~~~~~~~~~
warning: 1 warning emitted

View File

@ -12,6 +12,7 @@ fn imm_ref() -> &'static T {
fn mut_ref() -> &'static mut T { fn mut_ref() -> &'static mut T {
unsafe { &mut GLOBAL_MUT_T } unsafe { &mut GLOBAL_MUT_T }
//~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
} }
fn mut_ptr() -> *mut T { fn mut_ptr() -> *mut T {

View File

@ -1,5 +1,20 @@
warning: mutable reference of mutable static is discouraged
--> $DIR/issue-20801.rs:14:14
|
LL | unsafe { &mut GLOBAL_MUT_T }
| ^^^^^^^^^^^^^^^^^ mutable reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | unsafe { addr_of_mut!(GLOBAL_MUT_T) }
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0507]: cannot move out of a mutable reference 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() }; LL | let a = unsafe { *mut_ref() };
| ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait | ^^^^^^^^^^ 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 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() }; LL | let b = unsafe { *imm_ref() };
| ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait | ^^^^^^^^^^ 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 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() }; LL | let c = unsafe { *mut_ptr() };
| ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait | ^^^^^^^^^^ 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 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() }; LL | let d = unsafe { *const_ptr() };
| ^^^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait | ^^^^^^^^^^^^ 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() }; 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`. For more information about this error, try `rustc --explain E0507`.

View File

@ -8,7 +8,10 @@ mod borrowck_closures_unique {
static mut Y: isize = 3; static mut Y: isize = 3;
let mut c1 = |y: &'static mut isize| x = y; let mut c1 = |y: &'static mut isize| x = y;
//~^ ERROR is not declared as mutable //~^ 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; static mut Z: isize = 3;
let mut c1 = |z: &'static mut isize| { let mut c1 = |z: &'static mut isize| {
let mut c2 = |y: &'static mut isize| x = y; let mut c2 = |y: &'static mut isize| x = y;
//~^ ERROR is not declared as mutable //~^ ERROR is not declared as mutable
c2(z); 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 // adapted from mutability_errors.rs
mod mutability_errors { mod mutability_errors {
pub fn capture_assign_whole(x: (i32,)) { 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,)) { 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,)) { 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,)) { 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() { fn main() {
static mut X: isize = 2; 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_whole((1000,));
mutability_errors::capture_assign_part((2000,)); mutability_errors::capture_assign_part((2000,));

View File

@ -1,3 +1,46 @@
warning: mutable reference of mutable static is discouraged
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:12:16
|
LL | c1(&mut Y);
| ^^^^^^ mutable reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | c1(addr_of_mut!(Y));
| ~~~~~~~~~~~~~~~
warning: mutable reference of mutable static is discouraged
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:27:16
|
LL | c1(&mut Z);
| ^^^^^^ mutable reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | c1(addr_of_mut!(Z));
| ~~~~~~~~~~~~~~~
warning: mutable reference of mutable static is discouraged
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:64:37
|
LL | borrowck_closures_unique::e(&mut X);
| ^^^^^^ mutable reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | borrowck_closures_unique::e(addr_of_mut!(X));
| ~~~~~~~~~~~~~~~
error[E0594]: cannot assign to `x`, as it is not declared as mutable error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:9:46 --> $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 | ^^^^^ cannot assign
error[E0594]: cannot assign to `x`, as it is not declared as mutable 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) { LL | pub fn ee(x: &'static mut isize) {
| - help: consider changing this to be mutable: `mut x` | - 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 | ^^^^^ cannot assign
error[E0594]: cannot assign to `x`, as it is not declared as mutable 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,)) { LL | pub fn capture_assign_whole(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x` | - help: consider changing this to be mutable: `mut x`
LL | || { x = (1,); }; LL | || {
| ^^^^^^^^ cannot assign LL | x = (1,);
| ^^^^^^^^ cannot assign
error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable 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,)) { LL | pub fn capture_assign_part(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x` | - help: consider changing this to be mutable: `mut x`
LL | || { x.0 = 1; }; LL | || {
| ^^^^^^^ cannot assign LL | x.0 = 1;
| ^^^^^^^ cannot assign
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable 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,)) { LL | pub fn capture_reborrow_whole(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x` | - help: consider changing this to be mutable: `mut x`
LL | || { &mut x; }; LL | || {
| ^^^^^^ cannot borrow as mutable LL | &mut x;
| ^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `x.0` as mutable, as `x` is not declared 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,)) { LL | pub fn capture_reborrow_part(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x` | - help: consider changing this to be mutable: `mut x`
LL | || { &mut x.0; }; LL | || {
| ^^^^^^^^ cannot borrow as mutable 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. Some errors have detailed explanations: E0594, E0596.
For more information about an error, try `rustc --explain E0594`. For more information about an error, try `rustc --explain E0594`.

View File

@ -16,6 +16,7 @@ static mut BB: AA = AA::new();
fn main() { fn main() {
let ptr = unsafe { &mut BB }; let ptr = unsafe { &mut BB };
//~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
for a in ptr.data.iter() { for a in ptr.data.iter() {
println!("{}", a); println!("{}", a);
} }

View File

@ -0,0 +1,17 @@
warning: mutable reference of mutable static is discouraged
--> $DIR/const_let_assign2.rs:18:24
|
LL | let ptr = unsafe { &mut BB };
| ^^^^^^^ mutable reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | let ptr = unsafe { addr_of_mut!(BB) };
| ~~~~~~~~~~~~~~~~
warning: 1 warning emitted

View File

@ -3,7 +3,8 @@ const C1: &'static mut [usize] = &mut [];
static mut S: usize = 3; static mut S: usize = 3;
const C2: &'static mut usize = unsafe { &mut S }; 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 //~| ERROR: constants cannot refer to statics
fn main() {} fn main() {}

View File

@ -1,3 +1,18 @@
warning: mutable reference of mutable static is discouraged
--> $DIR/issue-17718-const-bad-values.rs:5:41
|
LL | const C2: &'static mut usize = unsafe { &mut S };
| ^^^^^^ mutable reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | const C2: &'static mut usize = unsafe { addr_of_mut!(S) };
| ~~~~~~~~~~~~~~~
error[E0764]: mutable references are not allowed in the final value of constants error[E0764]: mutable references are not allowed in the final value of constants
--> $DIR/issue-17718-const-bad-values.rs:1:34 --> $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 = 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` = 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. Some errors have detailed explanations: E0013, E0764.
For more information about an error, try `rustc --explain E0013`. For more information about an error, try `rustc --explain E0013`.

View File

@ -1,3 +1,18 @@
warning: shared reference of mutable static is discouraged
--> $DIR/const_refers_to_static_cross_crate.rs:13:14
|
LL | unsafe { &static_cross_crate::ZERO }
| ^^^^^^^^^^^^^^^^^^^^^^^^^ shared reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
|
LL | unsafe { addr_of!(static_cross_crate::ZERO) }
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/const_refers_to_static_cross_crate.rs:10:1 --> $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 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, LL | SLICE_MUT => true,
| ^^^^^^^^^ | ^^^^^^^^^
error[E0080]: it is undefined behavior to use this value 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 = { LL | const U8_MUT: &u8 = {
| ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant | ^^^^^^^^^^^^^^^^^ 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 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, LL | U8_MUT => true,
| ^^^^^^ | ^^^^^^
error[E0080]: evaluation of constant value failed 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] } LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
error: could not evaluate constant pattern 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, LL | U8_MUT2 => true,
| ^^^^^^^ | ^^^^^^^
error[E0080]: evaluation of constant value failed 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!() } } LL | match static_cross_crate::OPT_ZERO {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
error: could not evaluate constant pattern 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, LL | U8_MUT3 => true,
| ^^^^^^^ | ^^^^^^^
@ -59,61 +74,61 @@ LL | U8_MUT3 => true,
warning: skipping const checks warning: skipping const checks
| |
help: skipping check that does not even have a feature gate 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 } LL | unsafe { &static_cross_crate::ZERO }
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate 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 } LL | unsafe { &static_cross_crate::ZERO }
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate 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] } LL | unsafe { &static_cross_crate::ZERO[0] }
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate 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] } LL | unsafe { &static_cross_crate::ZERO[0] }
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate 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] } LL | unsafe { &static_cross_crate::ZERO[0] }
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate 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] } LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate 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 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 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 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 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`. For more information about this error, try `rustc --explain E0080`.

View File

@ -1,3 +1,18 @@
warning: shared reference of mutable static is discouraged
--> $DIR/const_refers_to_static_cross_crate.rs:13:14
|
LL | unsafe { &static_cross_crate::ZERO }
| ^^^^^^^^^^^^^^^^^^^^^^^^^ shared reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
|
LL | unsafe { addr_of!(static_cross_crate::ZERO) }
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/const_refers_to_static_cross_crate.rs:10:1 --> $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 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, LL | SLICE_MUT => true,
| ^^^^^^^^^ | ^^^^^^^^^
error[E0080]: it is undefined behavior to use this value 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 = { LL | const U8_MUT: &u8 = {
| ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant | ^^^^^^^^^^^^^^^^^ 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 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, LL | U8_MUT => true,
| ^^^^^^ | ^^^^^^
error[E0080]: evaluation of constant value failed 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] } LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
error: could not evaluate constant pattern 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, LL | U8_MUT2 => true,
| ^^^^^^^ | ^^^^^^^
error[E0080]: evaluation of constant value failed 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!() } } LL | match static_cross_crate::OPT_ZERO {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
error: could not evaluate constant pattern 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, LL | U8_MUT3 => true,
| ^^^^^^^ | ^^^^^^^
@ -59,61 +74,61 @@ LL | U8_MUT3 => true,
warning: skipping const checks warning: skipping const checks
| |
help: skipping check that does not even have a feature gate 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 } LL | unsafe { &static_cross_crate::ZERO }
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate 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 } LL | unsafe { &static_cross_crate::ZERO }
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate 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] } LL | unsafe { &static_cross_crate::ZERO[0] }
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate 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] } LL | unsafe { &static_cross_crate::ZERO[0] }
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate 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] } LL | unsafe { &static_cross_crate::ZERO[0] }
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate 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] } LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate 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 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 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 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 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`. For more information about this error, try `rustc --explain E0080`.

View File

@ -7,13 +7,16 @@ extern crate static_cross_crate;
// Sneaky: reference to a mutable static. // Sneaky: reference to a mutable static.
// Allowing this would be a disaster for pattern matching, we could violate exhaustiveness checking! // 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 const SLICE_MUT: &[u8; 1] = {
//~| encountered a reference pointing to a static variable //~^ ERROR undefined behavior to use this value
//~| encountered a reference pointing to a static variable
unsafe { &static_cross_crate::ZERO } 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 const U8_MUT: &u8 = {
//~| encountered a reference pointing to a static variable //~^ ERROR undefined behavior to use this value
//~| encountered a reference pointing to a static variable
unsafe { &static_cross_crate::ZERO[0] } unsafe { &static_cross_crate::ZERO[0] }
}; };
@ -24,9 +27,14 @@ const U8_MUT2: &u8 = {
//~| constant accesses static //~| constant accesses static
}; };
const U8_MUT3: &u8 = { const U8_MUT3: &u8 = {
unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } unsafe {
//~^ ERROR evaluation of constant value failed match static_cross_crate::OPT_ZERO {
//~| constant accesses static //~^ ERROR evaluation of constant value failed
//~| constant accesses static
Some(ref u) => u,
None => panic!(),
}
}
}; };
pub fn test(x: &[u8; 1]) -> bool { pub fn test(x: &[u8; 1]) -> bool {

View File

@ -3,5 +3,6 @@
static mut STDERR_BUFFER_SPACE: [u8; 42] = [0u8; 42]; static mut STDERR_BUFFER_SPACE: [u8; 42] = [0u8; 42];
pub static mut STDERR_BUFFER: *mut [u8] = unsafe { &mut STDERR_BUFFER_SPACE }; 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() {} fn main() {}

View File

@ -0,0 +1,17 @@
warning: mutable reference of mutable static is discouraged
--> $DIR/static_mut_containing_mut_ref.rs:5:52
|
LL | pub static mut STDERR_BUFFER: *mut [u8] = unsafe { &mut STDERR_BUFFER_SPACE };
| ^^^^^^^^^^^^^^^^^^^^^^^^ mutable reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | pub static mut STDERR_BUFFER: *mut [u8] = unsafe { addr_of_mut!(STDERR_BUFFER_SPACE) };
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
warning: 1 warning emitted

View File

@ -1,9 +1,24 @@
error[E0080]: could not evaluate static initializer warning: mutable reference of mutable static is discouraged
--> $DIR/static_mut_containing_mut_ref2.rs:7:45 --> $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;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ modifying a static's initial value from another static's initializer | ^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | *addr_of_mut!(STDERR_BUFFER_SPACE) = 42;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 1 previous error error[E0080]: could not evaluate static initializer
--> $DIR/static_mut_containing_mut_ref2.rs:8:5
|
LL | *(&mut STDERR_BUFFER_SPACE) = 42;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ modifying a static's initial value from another static's initializer
error: aborting due to 1 previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0080`. For more information about this error, try `rustc --explain E0080`.

View File

@ -4,8 +4,12 @@
static mut STDERR_BUFFER_SPACE: u8 = 0; static mut STDERR_BUFFER_SPACE: u8 = 0;
pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; }; pub static mut STDERR_BUFFER: () = unsafe {
//[mut_refs]~^ ERROR could not evaluate static initializer *(&mut STDERR_BUFFER_SPACE) = 42;
//[stock]~^^ ERROR mutable references are not allowed in statics //[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() {} fn main() {}

View File

@ -1,12 +1,27 @@
error[E0658]: mutable references are not allowed in statics warning: mutable reference of mutable static is discouraged
--> $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;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | *addr_of_mut!(STDERR_BUFFER_SPACE) = 42;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0658]: mutable references are not allowed in statics
--> $DIR/static_mut_containing_mut_ref2.rs:8:6
|
LL | *(&mut STDERR_BUFFER_SPACE) = 42;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable = 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`. For more information about this error, try `rustc --explain E0658`.

View File

@ -13,38 +13,39 @@ pub fn main() {
d::println("created empty log"); d::println("created empty log");
test(&log); test(&log);
assert_eq!(&log.borrow()[..], assert_eq!(
[ &log.borrow()[..],
// created empty log [
// +-- Make D(da_0, 0) // created empty log
// | +-- Make D(de_1, 1) // +-- Make D(da_0, 0)
// | | calling foo // | +-- Make D(de_1, 1)
// | | entered foo // | | calling foo
// | | +-- Make D(de_2, 2) // | | entered foo
// | | | +-- Make D(da_1, 3) // | | +-- Make D(de_2, 2)
// | | | | +-- Make D(de_3, 4) // | | | +-- Make D(da_1, 3)
// | | | | | +-- Make D(de_4, 5) // | | | | +-- Make D(de_3, 4)
3, // | | | +-- Drop D(da_1, 3) // | | | | | +-- Make D(de_4, 5)
// | | | | | 3, // | | | +-- Drop D(da_1, 3)
4, // | | | +-- Drop D(de_3, 4) // | | | | |
// | | | | 4, // | | | +-- Drop D(de_3, 4)
// | | | | eval tail of foo // | | | |
// | | | +-- Make D(de_5, 6) // | | | | eval tail of foo
// | | | | +-- Make D(de_6, 7) // | | | +-- Make D(de_5, 6)
5, // | | | | | +-- Drop D(de_4, 5) // | | | | +-- Make D(de_6, 7)
// | | | | | 5, // | | | | | +-- Drop D(de_4, 5)
2, // | | +-- Drop D(de_2, 2) // | | | | |
// | | | | 2, // | | +-- Drop D(de_2, 2)
6, // | | +-- Drop D(de_5, 6) // | | | |
// | | | 6, // | | +-- Drop D(de_5, 6)
1, // | +-- Drop D(de_1, 1) // | | |
// | | 1, // | +-- Drop D(de_1, 1)
0, // +-- Drop D(da_0, 0) // | |
// | 0, // +-- Drop D(da_0, 0)
// | result D(de_6, 7) // |
7 // +-- Drop D(de_6, 7) // | result D(de_6, 7)
7 // +-- Drop D(de_6, 7)
]); ]
);
} }
fn test<'a>(log: d::Log<'a>) { 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> { fn foo<'a>(da0: D<'a>, de1: D<'a>) -> D<'a> {
d::println("entered foo"); 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 de4 = {
let _da1 = da0.incr(); // creates D(da_1, 3) 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"); 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 // This module provides simultaneous printouts of the dynamic extents
@ -74,9 +75,9 @@ const PREF_INDENT: u32 = 16;
pub mod d { pub mod d {
#![allow(unused_parens)] #![allow(unused_parens)]
use std::cell::RefCell;
use std::fmt; use std::fmt;
use std::mem; use std::mem;
use std::cell::RefCell;
static mut counter: u32 = 0; static mut counter: u32 = 0;
static mut trails: u64 = 0; static mut trails: u64 = 0;
@ -89,7 +90,8 @@ pub mod d {
pub fn max_width() -> u32 { pub fn max_width() -> u32 {
unsafe { 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> { 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> { impl<'a> fmt::Display for D<'a> {
@ -139,9 +145,7 @@ pub mod d {
let ctr = counter; let ctr = counter;
counter += 1; counter += 1;
trails |= (1 << trail); trails |= (1 << trail);
let ret = D { let ret = D { name: name, i: i, log: log, uid: ctr, trail: trail };
name: name, i: i, log: log, uid: ctr, trail: trail
};
indent_println(trail, &format!("+-- Make {}", ret)); indent_println(trail, &format!("+-- Make {}", ret));
ret ret
} }
@ -153,7 +157,9 @@ pub mod d {
impl<'a> Drop for D<'a> { impl<'a> Drop for D<'a> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { trails &= !(1 << self.trail); }; unsafe {
trails &= !(1 << self.trail);
};
self.log.borrow_mut().push(self.uid); self.log.borrow_mut().push(self.uid);
indent_println(self.trail, &format!("+-- Drop {}", self)); indent_println(self.trail, &format!("+-- Drop {}", self));
indent_println(::PREF_INDENT, ""); indent_println(::PREF_INDENT, "");

View File

@ -0,0 +1,17 @@
warning: shared reference of mutable static is discouraged
--> $DIR/issue-23338-ensure-param-drop-order.rs:93:31
|
LL | (mem::size_of_val(&trails) * 8) as u32
| ^^^^^^^ shared reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
|
LL | (mem::size_of_val(addr_of!(trails)) * 8) as u32
| ~~~~~~~~~~~~~~~~
warning: 1 warning emitted

View File

@ -3,12 +3,16 @@ const C: i32 = 2;
static mut M: i32 = 3; static mut M: i32 = 3;
const CR: &'static mut i32 = &mut C; //~ ERROR mutable references are not allowed 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 static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0658
//~| ERROR cannot borrow //~| ERROR cannot borrow
//~| ERROR mutable references are not allowed //~| ERROR mutable references are not allowed
static CONST_REF: &'static mut i32 = &mut C; //~ 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 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() {} fn main() {}

View File

@ -1,3 +1,18 @@
warning: mutable reference of mutable static is discouraged
--> $DIR/E0017.rs:15:52
|
LL | static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M };
| ^^^^^^ mutable reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | static STATIC_MUT_REF: &'static mut i32 = unsafe { addr_of_mut!(M) };
| ~~~~~~~~~~~~~~~
warning: taking a mutable reference to a `const` item warning: taking a mutable reference to a `const` item
--> $DIR/E0017.rs:5:30 --> $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 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; 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 = 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 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; LL | static STATIC_REF: &'static mut i32 = &mut X;
| ^^^^^^ | ^^^^^^
error[E0596]: cannot borrow immutable static item `X` as mutable 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; LL | static STATIC_REF: &'static mut i32 = &mut X;
| ^^^^^^ cannot borrow as mutable | ^^^^^^ cannot borrow as mutable
warning: taking a mutable reference to a `const` item 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; 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 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; LL | static CONST_REF: &'static mut i32 = &mut C;
| ^^^^^^ | ^^^^^^
error[E0764]: mutable references are not allowed in the final value of statics 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 }; 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. Some errors have detailed explanations: E0596, E0658, E0764.
For more information about an error, try `rustc --explain E0596`. For more information about an error, try `rustc --explain E0596`.

View File

@ -33,12 +33,11 @@ type TypeI<T,> = T;
static STATIC: () = (); static STATIC: () = ();
fn main() { fn main() {
// ensure token `>=` works fine // ensure token `>=` works fine
let _: TypeA<'static>= &STATIC; let _: TypeA<'static> = &STATIC;
let _: TypeA<'static,>= &STATIC; let _: TypeA<'static,> = &STATIC;
// ensure token `>>=` works fine // ensure token `>>=` works fine
let _: Box<TypeA<'static>>= Box::new(&STATIC); let _: Box<TypeA<'static>> = Box::new(&STATIC);
let _: Box<TypeA<'static,>>= Box::new(&STATIC); let _: Box<TypeA<'static,>> = Box::new(&STATIC);
} }

View File

@ -37,11 +37,9 @@ pub fn main() {
// | | | +-- Make D(g_b_5, 50000005) // | | | +-- Make D(g_b_5, 50000005)
// | | | | in g_B(b4b2) from GaspB::drop // | | | | in g_B(b4b2) from GaspB::drop
// | | | +-- Drop D(g_b_5, 50000005) // | | | +-- Drop D(g_b_5, 50000005)
50000005, 50000005, // | | |
// | | |
// | | +-- Drop D(GaspB::drop_3, 30000004) // | | +-- Drop D(GaspB::drop_3, 30000004)
30000004, 30000004, // | |
// | |
// +-- Drop D(test_1, 10000000) // +-- Drop D(test_1, 10000000)
10000000, 10000000,
// | // |
@ -49,15 +47,13 @@ pub fn main() {
// | | +-- Make D(f_a_4, 40000007) // | | +-- Make D(f_a_4, 40000007)
// | | | in f_A(a3a0) from GaspA::drop // | | | in f_A(a3a0) from GaspA::drop
// | | +-- Drop D(f_a_4, 40000007) // | | +-- Drop D(f_a_4, 40000007)
40000007, 40000007, // | |
// | |
// +-- Drop D(GaspA::drop_2, 20000006) // +-- Drop D(GaspA::drop_2, 20000006)
20000006, 20000006, // |
// |
// +-- Drop D(drop_6, 60000002) // +-- Drop D(drop_6, 60000002)
60000002 60000002 //
// ]
]); );
// For reference purposes, the old (incorrect) behavior would produce the following // For reference purposes, the old (incorrect) behavior would produce the following
// output, which you can compare to the above: // 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); 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 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 GaspB<'a>(for<'b> fn(u32, &'b str, d::Log<'a>), u32, d::Log<'a>, d::D<'a>);
impl<'a> Drop for GaspA<'a> { impl<'a> Drop for GaspA<'a> {
fn drop(&mut self) { fn drop(&mut self) {
@ -124,7 +120,8 @@ impl<'a> Drop for GaspB<'a> {
} }
enum E<'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) { fn f_a(x: u32, ctxt: &str, log: d::Log) {
@ -174,9 +171,9 @@ const PREF_INDENT: u32 = 20;
pub mod d { pub mod d {
#![allow(unused_parens)] #![allow(unused_parens)]
use std::cell::RefCell;
use std::fmt; use std::fmt;
use std::mem; use std::mem;
use std::cell::RefCell;
static mut counter: u16 = 0; static mut counter: u16 = 0;
static mut trails: u64 = 0; static mut trails: u64 = 0;
@ -189,7 +186,8 @@ pub mod d {
pub fn max_width() -> u32 { pub fn max_width() -> u32 {
unsafe { 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> { 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> { 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); let ctr = ((i as u32) * 10_000_000) + (counter as u32);
counter += 1; counter += 1;
trails |= (1 << trail); trails |= (1 << trail);
let ret = D { let ret = D { name: name, i: i, log: log, uid: ctr, trail: trail };
name: name, i: i, log: log, uid: ctr, trail: trail
};
indent_println(trail, &format!("+-- Make {}", ret)); indent_println(trail, &format!("+-- Make {}", ret));
ret ret
} }
@ -250,7 +250,9 @@ pub mod d {
impl<'a> Drop for D<'a> { impl<'a> Drop for D<'a> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { trails &= !(1 << self.trail); }; unsafe {
trails &= !(1 << self.trail);
};
self.log.borrow_mut().push(self.uid); self.log.borrow_mut().push(self.uid);
indent_println(self.trail, &format!("+-- Drop {}", self)); indent_println(self.trail, &format!("+-- Drop {}", self));
indent_println(::PREF_INDENT, ""); indent_println(::PREF_INDENT, "");

View File

@ -0,0 +1,17 @@
warning: shared reference of mutable static is discouraged
--> $DIR/issue-23611-enum-swap-in-drop.rs:189:31
|
LL | (mem::size_of_val(&trails) * 8) as u32
| ^^^^^^^ shared reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
|
LL | (mem::size_of_val(addr_of!(trails)) * 8) as u32
| ~~~~~~~~~~~~~~~~
warning: 1 warning emitted

View File

@ -14,9 +14,8 @@ struct S1 {
impl S1 { impl S1 {
fn new(_x: u64) -> S1 { fn new(_x: u64) -> S1 {
S1 { S1 { a: unsafe { &mut X1 } }
a: unsafe { &mut X1 }, //~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
}
} }
} }

View File

@ -0,0 +1,17 @@
warning: mutable reference of mutable static is discouraged
--> $DIR/borrowck-thread-local-static-mut-borrow-outlives-fn.rs:17:26
|
LL | S1 { a: unsafe { &mut X1 } }
| ^^^^^^^ mutable reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | S1 { a: unsafe { addr_of_mut!(X1) } }
| ~~~~~~~~~~~~~~~~
warning: 1 warning emitted

View File

@ -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 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
|
LL | let _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`.

View File

@ -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`.

View File

@ -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]
}

View File

@ -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) {}

View File

@ -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`.

View File

@ -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 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
note: 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 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | 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 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
|
LL | let 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 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
|
LL | let (_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 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
|
LL | let (_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 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
|
LL | foo(addr_of!(X));
| ~~~~~~~~~~~
error: aborting due to 6 previous errors

View File

@ -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`.

View File

@ -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) {}

View File

@ -10,6 +10,8 @@ extern "C" {
fn main() { fn main() {
let b = B; //~ ERROR use of mutable static is unsafe let b = B; //~ ERROR use of mutable static is unsafe
let rb = &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 xb = XB; //~ ERROR use of mutable static is unsafe
let xrb = &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]
} }

View File

@ -1,3 +1,32 @@
warning: shared reference of mutable static is discouraged
--> $DIR/safe-extern-statics-mut.rs:12:14
|
LL | let rb = &B;
| ^^ shared reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
|
LL | let rb = addr_of!(B);
| ~~~~~~~~~~~
warning: shared reference of mutable static is discouraged
--> $DIR/safe-extern-statics-mut.rs:15:15
|
LL | let xrb = &XB;
| ^^^ shared reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
|
LL | let xrb = addr_of!(XB);
| ~~~~~~~~~~~~
error[E0133]: use of mutable static is unsafe and requires unsafe function or block error[E0133]: use of mutable static is unsafe and requires unsafe function or block
--> $DIR/safe-extern-statics-mut.rs:11:13 --> $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 = 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 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; LL | let xb = XB;
| ^^ use of mutable static | ^^ 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 = 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 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; LL | let xrb = &XB;
| ^^ use of mutable static | ^^ use of mutable static
| |
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior = 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`. For more information about this error, try `rustc --explain E0133`.

View File

@ -6,6 +6,7 @@
static mut n_mut: usize = 0; 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() {} fn main() {}

View File

@ -0,0 +1,17 @@
warning: shared reference of mutable static is discouraged
--> $DIR/issue-15261.rs:9:37
|
LL | static n: &'static usize = unsafe { &n_mut };
| ^^^^^^ shared reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
|
LL | static n: &'static usize = unsafe { addr_of!(n_mut) };
| ~~~~~~~~~~~~~~~
warning: 1 warning emitted

View File

@ -7,7 +7,6 @@
// aux-build:static_mut_xc.rs // aux-build:static_mut_xc.rs
extern crate static_mut_xc; extern crate static_mut_xc;
unsafe fn static_bound(_: &'static isize) {} unsafe fn static_bound(_: &'static isize) {}
@ -27,7 +26,9 @@ unsafe fn run() {
static_mut_xc::a = -3; static_mut_xc::a = -3;
assert_eq!(static_mut_xc::a, -3); assert_eq!(static_mut_xc::a, -3);
static_bound(&static_mut_xc::a); 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); static_bound_set(&mut static_mut_xc::a);
//~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
} }
pub fn main() { pub fn main() {

View File

@ -0,0 +1,31 @@
warning: shared reference of mutable static is discouraged
--> $DIR/static-mut-xc.rs:28:18
|
LL | static_bound(&static_mut_xc::a);
| ^^^^^^^^^^^^^^^^^ shared reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
|
LL | static_bound(addr_of!(static_mut_xc::a));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
warning: mutable reference of mutable static is discouraged
--> $DIR/static-mut-xc.rs:30:22
|
LL | static_bound_set(&mut static_mut_xc::a);
| ^^^^^^^^^^^^^^^^^^^^^ mutable reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | static_bound_set(addr_of_mut!(static_mut_xc::a));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
warning: 2 warnings emitted

View File

@ -1,36 +1,43 @@
// run-pass // run-pass
static mut S: *const u8 = unsafe { &S as *const *const u8 as *const u8 }; 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 { struct StaticDoubleLinked {
prev: &'static StaticDoubleLinked, prev: &'static StaticDoubleLinked,
next: &'static StaticDoubleLinked, next: &'static StaticDoubleLinked,
data: i32, data: i32,
head: bool head: bool,
} }
static L1: StaticDoubleLinked = StaticDoubleLinked{prev: &L3, next: &L2, data: 1, head: true}; 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 L2: StaticDoubleLinked = StaticDoubleLinked { prev: &L1, next: &L3, data: 2, head: false };
static L3: StaticDoubleLinked = StaticDoubleLinked{prev: &L2, next: &L1, data: 3, head: false}; static L3: StaticDoubleLinked = StaticDoubleLinked { prev: &L2, next: &L1, data: 3, head: false };
pub fn main() { 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 test_vec = Vec::new();
let mut cur = &L1; let mut cur = &L1;
loop { loop {
test_vec.push(cur.data); test_vec.push(cur.data);
cur = cur.next; 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 test_vec = Vec::new();
let mut cur = &L1; let mut cur = &L1;
loop { loop {
cur = cur.prev; cur = cur.prev;
test_vec.push(cur.data); 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]);
} }

View File

@ -0,0 +1,17 @@
warning: shared reference of mutable static is discouraged
--> $DIR/static-recursive.rs:3:36
|
LL | static mut S: *const u8 = unsafe { &S as *const *const u8 as *const u8 };
| ^^ shared reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
|
LL | static mut S: *const u8 = unsafe { addr_of!(S) as *const *const u8 as *const u8 };
| ~~~~~~~~~~~
warning: 1 warning emitted

View File

@ -8,7 +8,8 @@ static mut STATIC_VAR_2: [u32; 8] = [4; 8];
const fn g(x: &mut [u32; 8]) { const fn g(x: &mut [u32; 8]) {
//~^ ERROR mutable references are not allowed //~^ ERROR mutable references are not allowed
std::mem::swap(x, &mut STATIC_VAR_2) 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 mutable references are not allowed
//~| ERROR use of mutable static is unsafe //~| ERROR use of mutable static is unsafe
//~| constant functions cannot refer to statics //~| constant functions cannot refer to statics

View File

@ -1,3 +1,18 @@
warning: mutable reference of mutable static is discouraged
--> $DIR/thread-local-static.rs:10:23
|
LL | std::mem::swap(x, &mut STATIC_VAR_2)
| ^^^^^^^^^^^^^^^^^ mutable reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | std::mem::swap(x, addr_of_mut!(STATIC_VAR_2))
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0133]: use of mutable static is unsafe and requires unsafe function or block error[E0133]: use of mutable static is unsafe and requires unsafe function or block
--> $DIR/thread-local-static.rs:10:28 --> $DIR/thread-local-static.rs:10:28
| |
@ -38,7 +53,7 @@ LL | std::mem::swap(x, &mut STATIC_VAR_2)
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable = 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. Some errors have detailed explanations: E0013, E0133, E0625, E0658.
For more information about an error, try `rustc --explain E0013`. For more information about an error, try `rustc --explain E0013`.

View File

@ -0,0 +1,59 @@
warning: mutable reference of mutable static is discouraged
--> $DIR/thread-local-static.rs:12:23
|
LL | std::mem::swap(x, &mut STATIC_VAR_2)
| ^^^^^^^^^^^^^^^^^ mutable reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | std::mem::swap(x, addr_of_mut!(STATIC_VAR_2))
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0658]: mutable references are not allowed in constant functions
--> $DIR/thread-local-static.rs:10:12
|
LL | const fn g(x: &mut [u32; 8]) {
| ^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
error[E0625]: thread-local statics cannot be accessed at compile-time
--> $DIR/thread-local-static.rs:12:28
|
LL | std::mem::swap(x, &mut STATIC_VAR_2)
| ^^^^^^^^^^^^
error[E0013]: constant functions cannot refer to statics
--> $DIR/thread-local-static.rs:12:28
|
LL | std::mem::swap(x, &mut STATIC_VAR_2)
| ^^^^^^^^^^^^
|
= help: consider extracting the value of the `static` to a `const`, and referring to that
error[E0658]: mutable references are not allowed in constant functions
--> $DIR/thread-local-static.rs:12:23
|
LL | std::mem::swap(x, &mut STATIC_VAR_2)
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
error[E0133]: use of mutable static is unsafe and requires unsafe function or block
--> $DIR/thread-local-static.rs:12:23
|
LL | std::mem::swap(x, &mut STATIC_VAR_2)
| ^^^^^^^^^^^^^^^^^ use of mutable static
|
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
error: aborting due to 5 previous errors; 1 warning emitted
Some errors have detailed explanations: E0013, E0133, E0625, E0658.
For more information about an error, try `rustc --explain E0013`.