mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
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:
commit
4a24b5bc05
@ -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",
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
22
compiler/rustc_error_codes/src/error_codes/E0796.md
Normal file
22
compiler/rustc_error_codes/src/error_codes/E0796.md
Normal 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.
|
@ -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" }
|
||||||
|
@ -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
|
||||||
|
97
compiler/rustc_hir_analysis/src/check/errs.rs
Normal file
97
compiler/rustc_hir_analysis/src/check/errs.rs
Normal 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 },
|
||||||
|
);
|
||||||
|
}
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -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`,
|
||||||
|
@ -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.
|
||||||
|
@ -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};
|
||||||
|
@ -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> {
|
||||||
|
@ -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> {
|
||||||
|
@ -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)
|
||||||
() => {};
|
() => {};
|
||||||
|
@ -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>>;
|
||||||
|
@ -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;
|
||||||
|
@ -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)]
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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() {
|
||||||
|
31
tests/ui/abi/statics/static-mut-foreign.stderr
Normal file
31
tests/ui/abi/statics/static-mut-foreign.stderr
Normal 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
|
||||||
|
|
@ -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]
|
||||||
|
@ -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`.
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
|
@ -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 {
|
||||||
|
@ -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`.
|
||||||
|
@ -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,));
|
||||||
|
@ -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`.
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
17
tests/ui/consts/const_let_assign2.stderr
Normal file
17
tests/ui/consts/const_let_assign2.stderr
Normal 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
|
||||||
|
|
@ -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() {}
|
||||||
|
@ -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`.
|
||||||
|
@ -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`.
|
||||||
|
@ -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`.
|
||||||
|
@ -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 {
|
||||||
|
@ -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() {}
|
||||||
|
17
tests/ui/consts/static_mut_containing_mut_ref.stderr
Normal file
17
tests/ui/consts/static_mut_containing_mut_ref.stderr
Normal 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
|
||||||
|
|
@ -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`.
|
||||||
|
@ -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() {}
|
||||||
|
@ -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`.
|
||||||
|
@ -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, "");
|
||||||
|
17
tests/ui/drop/issue-23338-ensure-param-drop-order.stderr
Normal file
17
tests/ui/drop/issue-23338-ensure-param-drop-order.stderr
Normal 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
|
||||||
|
|
@ -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() {}
|
||||||
|
@ -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`.
|
||||||
|
@ -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);
|
||||||
}
|
}
|
@ -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, "");
|
||||||
|
17
tests/ui/issues/issue-23611-enum-swap-in-drop.stderr
Normal file
17
tests/ui/issues/issue-23611-enum-swap-in-drop.stderr
Normal 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
|
||||||
|
|
@ -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]
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
26
tests/ui/static/reference-of-mut-static-safe.e2021.stderr
Normal file
26
tests/ui/static/reference-of-mut-static-safe.e2021.stderr
Normal 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`.
|
15
tests/ui/static/reference-of-mut-static-safe.e2024.stderr
Normal file
15
tests/ui/static/reference-of-mut-static-safe.e2024.stderr
Normal 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`.
|
13
tests/ui/static/reference-of-mut-static-safe.rs
Normal file
13
tests/ui/static/reference-of-mut-static-safe.rs
Normal 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]
|
||||||
|
}
|
23
tests/ui/static/reference-of-mut-static-unsafe-fn.rs
Normal file
23
tests/ui/static/reference-of-mut-static-unsafe-fn.rs
Normal 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) {}
|
63
tests/ui/static/reference-of-mut-static-unsafe-fn.stderr
Normal file
63
tests/ui/static/reference-of-mut-static-unsafe-fn.stderr
Normal 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`.
|
91
tests/ui/static/reference-of-mut-static.e2021.stderr
Normal file
91
tests/ui/static/reference-of-mut-static.e2021.stderr
Normal 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
|
||||||
|
|
75
tests/ui/static/reference-of-mut-static.e2024.stderr
Normal file
75
tests/ui/static/reference-of-mut-static.e2024.stderr
Normal 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`.
|
50
tests/ui/static/reference-of-mut-static.rs
Normal file
50
tests/ui/static/reference-of-mut-static.rs
Normal 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) {}
|
@ -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]
|
||||||
}
|
}
|
||||||
|
@ -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`.
|
||||||
|
@ -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() {}
|
||||||
|
17
tests/ui/statics/issue-15261.stderr
Normal file
17
tests/ui/statics/issue-15261.stderr
Normal 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
|
||||||
|
|
@ -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() {
|
||||||
|
31
tests/ui/statics/static-mut-xc.stderr
Normal file
31
tests/ui/statics/static-mut-xc.stderr
Normal 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
|
||||||
|
|
@ -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]);
|
||||||
}
|
}
|
||||||
|
17
tests/ui/statics/static-recursive.stderr
Normal file
17
tests/ui/statics/static-recursive.stderr
Normal 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
|
||||||
|
|
@ -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
|
||||||
|
@ -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`.
|
||||||
|
59
tests/ui/thread-local/thread-local-static.thir.stderr
Normal file
59
tests/ui/thread-local/thread-local-static.thir.stderr
Normal 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`.
|
Loading…
Reference in New Issue
Block a user