Auto merge of #124895 - obeis:static-mut-hidden-ref, r=compiler-errors

Disallow hidden references to mutable static

Closes #123060

Tracking:
- https://github.com/rust-lang/rust/issues/123758
This commit is contained in:
bors 2024-09-20 17:25:34 +00:00
commit 5ba6db1b64
124 changed files with 1006 additions and 877 deletions

View File

@ -35,6 +35,8 @@ fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
} }
/// Signal handler installed for SIGSEGV /// Signal handler installed for SIGSEGV
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#[allow(static_mut_refs)]
extern "C" fn print_stack_trace(_: libc::c_int) { extern "C" fn print_stack_trace(_: libc::c_int) {
const MAX_FRAMES: usize = 256; const MAX_FRAMES: usize = 256;
// Reserve data segment so we don't have to malloc in a signal handler, which might fail // Reserve data segment so we don't have to malloc in a signal handler, which might fail

View File

@ -1,14 +1,14 @@
#### Note: this error code is no longer emitted by the compiler.
You have created a reference to a mutable static. You have created a reference to a mutable static.
Erroneous code example: Erroneous code example:
```compile_fail,edition2024,E0796 ```
static mut X: i32 = 23; static mut X: i32 = 23;
fn work() { fn work() {
let _val = unsafe { X }; let _val = unsafe { X };
} }
let x_ref = unsafe { &mut X }; let x_ref = unsafe { &mut X };
work(); work();
// The next line has Undefined Behavior! // The next line has Undefined Behavior!

View File

@ -681,3 +681,4 @@ macro_rules! error_codes {
// E0723, // unstable feature in `const` context // E0723, // unstable feature in `const` context
// E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`. // E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
// E0744, // merged into E0728 // E0744, // merged into E0728
// E0796, // unused error code. We use `static_mut_refs` lint instead.

View File

@ -467,25 +467,6 @@ 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 = creating a {$shared} reference to a mutable static
.label = {$shared} reference to mutable static
.note = {$shared ->
[shared] this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
*[mutable] this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
}
.suggestion = use `addr_of!` instead to create a raw pointer
.suggestion_mut = use `addr_of_mut!` instead to create a raw pointer
hir_analysis_static_mut_refs_lint = creating a {$shared} reference to mutable static is discouraged
.label = {$shared} reference to mutable static
.suggestion = use `addr_of!` instead to create a raw pointer
.suggestion_mut = use `addr_of_mut!` instead to create a raw pointer
.note = this will be a hard error in the 2024 edition
.why_note = {$shared ->
[shared] this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
*[mutable] this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
}
hir_analysis_static_specialize = cannot specialize on `'static` lifetime hir_analysis_static_specialize = cannot specialize on `'static` lifetime
hir_analysis_tait_forward_compat = item constrains opaque type that is not in its signature hir_analysis_tait_forward_compat = item constrains opaque type that is not in its signature

View File

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

View File

@ -20,8 +20,6 @@
use rustc_span::source_map; use rustc_span::source_map;
use tracing::debug; use tracing::debug;
use super::errs::{maybe_expr_static_mut, maybe_stmt_static_mut};
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
struct Context { struct Context {
/// The scope that contains any new variables declared, plus its depth in /// The scope that contains any new variables declared, plus its depth in
@ -229,8 +227,6 @@ 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
@ -249,8 +245,6 @@ fn resolve_stmt<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, stmt: &'tcx h
fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx hir::Expr<'tcx>) { fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
debug!("resolve_expr - pre-increment {} expr = {:?}", visitor.expr_and_pat_count, expr); debug!("resolve_expr - pre-increment {} expr = {:?}", visitor.expr_and_pat_count, expr);
maybe_expr_static_mut(visitor.tcx, *expr);
let prev_cx = visitor.cx; let prev_cx = visitor.cx;
visitor.enter_node_scope_with_dtor(expr.hir_id.local_id); visitor.enter_node_scope_with_dtor(expr.hir_id.local_id);

View File

@ -1522,57 +1522,6 @@ pub(crate) struct OnlyCurrentTraitsPointerSugg<'a> {
pub ptr_ty: Ty<'a>, pub ptr_ty: Ty<'a>,
} }
#[derive(Diagnostic)]
#[diag(hir_analysis_static_mut_ref, code = E0796)]
#[note]
pub(crate) struct StaticMutRef<'a> {
#[primary_span]
#[label]
pub span: Span,
#[subdiagnostic]
pub sugg: MutRefSugg,
pub shared: &'a str,
}
#[derive(Subdiagnostic)]
pub(crate) enum MutRefSugg {
#[multipart_suggestion(
hir_analysis_suggestion,
style = "verbose",
applicability = "maybe-incorrect"
)]
Shared {
#[suggestion_part(code = "addr_of!(")]
lo: Span,
#[suggestion_part(code = ")")]
hi: Span,
},
#[multipart_suggestion(
hir_analysis_suggestion_mut,
style = "verbose",
applicability = "maybe-incorrect"
)]
Mut {
#[suggestion_part(code = "addr_of_mut!(")]
lo: Span,
#[suggestion_part(code = ")")]
hi: Span,
},
}
// STATIC_MUT_REF lint
#[derive(LintDiagnostic)]
#[diag(hir_analysis_static_mut_refs_lint)]
#[note]
#[note(hir_analysis_why_note)]
pub(crate) struct RefOfMutStatic<'a> {
#[label]
pub span: Span,
#[subdiagnostic]
pub sugg: MutRefSugg,
pub shared: &'a str,
}
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(hir_analysis_not_supported_delegation)] #[diag(hir_analysis_not_supported_delegation)]
pub(crate) struct UnsupportedDelegation<'a> { pub(crate) struct UnsupportedDelegation<'a> {

View File

@ -769,6 +769,13 @@ lint_single_use_lifetime = lifetime parameter `{$ident}` only used once
lint_span_use_eq_ctxt = use `.eq_ctxt()` instead of `.ctxt() == .ctxt()` lint_span_use_eq_ctxt = use `.eq_ctxt()` instead of `.ctxt() == .ctxt()`
lint_static_mut_refs_lint = creating a {$shared_label}reference to mutable static is discouraged
.label = {$shared_label}reference to mutable static
.suggestion = use `&raw const` instead to create a raw pointer
.suggestion_mut = use `&raw mut` instead to create a raw pointer
.shared_note = shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
.mut_note = mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
lint_supertrait_as_deref_target = this `Deref` implementation is covered by an implicit supertrait coercion lint_supertrait_as_deref_target = this `Deref` implementation is covered by an implicit supertrait coercion
.label = `{$self_ty}` implements `Deref<Target = dyn {$target_principal}>` which conflicts with supertrait `{$supertrait_principal}` .label = `{$self_ty}` implements `Deref<Target = dyn {$target_principal}>` which conflicts with supertrait `{$supertrait_principal}`
.label2 = target type is a supertrait of `{$self_ty}` .label2 = target type is a supertrait of `{$self_ty}`

View File

@ -81,6 +81,7 @@
mod redundant_semicolon; mod redundant_semicolon;
mod reference_casting; mod reference_casting;
mod shadowed_into_iter; mod shadowed_into_iter;
mod static_mut_refs;
mod tail_expr_drop_order; mod tail_expr_drop_order;
mod traits; mod traits;
mod types; mod types;
@ -120,6 +121,7 @@
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use shadowed_into_iter::ShadowedIntoIter; use shadowed_into_iter::ShadowedIntoIter;
pub use shadowed_into_iter::{ARRAY_INTO_ITER, BOXED_SLICE_INTO_ITER}; pub use shadowed_into_iter::{ARRAY_INTO_ITER, BOXED_SLICE_INTO_ITER};
use static_mut_refs::*;
use tail_expr_drop_order::TailExprDropOrder; use tail_expr_drop_order::TailExprDropOrder;
use traits::*; use traits::*;
use types::*; use types::*;
@ -246,6 +248,7 @@ fn lint_mod(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
ImplTraitOvercaptures: ImplTraitOvercaptures, ImplTraitOvercaptures: ImplTraitOvercaptures,
TailExprDropOrder: TailExprDropOrder, TailExprDropOrder: TailExprDropOrder,
IfLetRescope: IfLetRescope::default(), IfLetRescope: IfLetRescope::default(),
StaticMutRefs: StaticMutRefs,
] ]
] ]
); );

View File

@ -3061,3 +3061,35 @@ pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion {
pub(crate) struct OutOfScopeMacroCalls { pub(crate) struct OutOfScopeMacroCalls {
pub path: String, pub path: String,
} }
#[derive(LintDiagnostic)]
#[diag(lint_static_mut_refs_lint)]
pub(crate) struct RefOfMutStatic<'a> {
#[label]
pub span: Span,
#[subdiagnostic]
pub sugg: Option<MutRefSugg>,
pub shared_label: &'a str,
#[note(lint_shared_note)]
pub shared_note: bool,
#[note(lint_mut_note)]
pub mut_note: bool,
}
#[derive(Subdiagnostic)]
pub(crate) enum MutRefSugg {
#[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")]
Shared {
#[suggestion_part(code = "&raw const ")]
span: Span,
},
#[multipart_suggestion(
lint_suggestion_mut,
style = "verbose",
applicability = "maybe-incorrect"
)]
Mut {
#[suggestion_part(code = "&raw mut ")]
span: Span,
},
}

View File

@ -0,0 +1,154 @@
use rustc_hir as hir;
use rustc_hir::{Expr, Stmt};
use rustc_middle::ty::{Mutability, TyKind};
use rustc_session::lint::FutureIncompatibilityReason;
use rustc_session::{declare_lint, declare_lint_pass};
use rustc_span::edition::Edition;
use rustc_span::Span;
use crate::lints::{MutRefSugg, RefOfMutStatic};
use crate::{LateContext, LateLintPass, LintContext};
declare_lint! {
/// The `static_mut_refs` 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, in 2024 is "deny".
pub STATIC_MUT_REFS,
Warn,
"shared references or mutable references of mutable static is discouraged",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>",
explain_reason: false,
};
@edition Edition2024 => Deny;
}
declare_lint_pass!(StaticMutRefs => [STATIC_MUT_REFS]);
impl<'tcx> LateLintPass<'tcx> for StaticMutRefs {
#[allow(rustc::usage_of_ty_tykind)]
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
let err_span = expr.span;
match expr.kind {
hir::ExprKind::AddrOf(borrow_kind, m, ex)
if matches!(borrow_kind, hir::BorrowKind::Ref)
&& let Some(err_span) = path_is_static_mut(ex, err_span) =>
{
emit_static_mut_refs(
cx,
err_span,
err_span.with_hi(ex.span.lo()),
m,
!expr.span.from_expansion(),
);
}
hir::ExprKind::MethodCall(_, e, _, _)
if let Some(err_span) = path_is_static_mut(e, expr.span)
&& let typeck = cx.typeck_results()
&& let Some(method_def_id) = typeck.type_dependent_def_id(expr.hir_id)
&& let inputs =
cx.tcx.fn_sig(method_def_id).skip_binder().inputs().skip_binder()
&& let Some(receiver) = inputs.get(0)
&& let TyKind::Ref(_, _, m) = receiver.kind() =>
{
emit_static_mut_refs(cx, err_span, err_span.shrink_to_lo(), *m, false);
}
_ => {}
}
}
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &Stmt<'_>) {
if let hir::StmtKind::Let(loc) = stmt.kind
&& let hir::PatKind::Binding(ba, _, _, _) = loc.pat.kind
&& let hir::ByRef::Yes(m) = ba.0
&& let Some(init) = loc.init
&& let Some(err_span) = path_is_static_mut(init, init.span)
{
emit_static_mut_refs(cx, err_span, err_span.shrink_to_lo(), m, false);
}
}
}
fn path_is_static_mut(mut expr: &hir::Expr<'_>, mut err_span: Span) -> Option<Span> {
if err_span.from_expansion() {
err_span = expr.span;
}
while let hir::ExprKind::Field(e, _) = expr.kind {
expr = e;
}
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 { safety: _, mutability: Mutability::Mut, nested: false } =
def_kind
{
return Some(err_span);
}
None
}
fn emit_static_mut_refs(
cx: &LateContext<'_>,
span: Span,
sugg_span: Span,
mutable: Mutability,
suggest_addr_of: bool,
) {
let (shared_label, shared_note, mut_note, sugg) = match mutable {
Mutability::Mut => {
let sugg =
if suggest_addr_of { Some(MutRefSugg::Mut { span: sugg_span }) } else { None };
("mutable ", false, true, sugg)
}
Mutability::Not => {
let sugg =
if suggest_addr_of { Some(MutRefSugg::Shared { span: sugg_span }) } else { None };
("shared ", true, false, sugg)
}
};
cx.emit_span_lint(
STATIC_MUT_REFS,
span,
RefOfMutStatic { span, sugg, shared_label, shared_note, mut_note },
);
}

View File

@ -99,7 +99,6 @@
SINGLE_USE_LIFETIMES, SINGLE_USE_LIFETIMES,
SOFT_UNSTABLE, SOFT_UNSTABLE,
STABLE_FEATURES, STABLE_FEATURES,
STATIC_MUT_REFS,
TEST_UNSTABLE_LINT, TEST_UNSTABLE_LINT,
TEXT_DIRECTION_CODEPOINT_IN_COMMENT, TEXT_DIRECTION_CODEPOINT_IN_COMMENT,
TRIVIAL_CASTS, TRIVIAL_CASTS,
@ -1927,57 +1926,6 @@
}; };
} }
declare_lint! {
/// The `static_mut_refs` 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, in 2024 there is
/// a hard error instead.
pub STATIC_MUT_REFS,
Warn,
"shared references or mutable references of mutable static is discouraged",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
reference: "issue #114447 <https://github.com/rust-lang/rust/issues/114447>",
explain_reason: false,
};
}
declare_lint! { declare_lint! {
/// The `absolute_paths_not_starting_with_crate` lint detects fully /// The `absolute_paths_not_starting_with_crate` lint detects fully
/// qualified paths that start with a module name instead of `crate`, /// qualified paths that start with a module name instead of `crate`,

View File

@ -12,7 +12,7 @@
use rustc_hir::def::Namespace; use rustc_hir::def::Namespace;
use rustc_hir::{HashStableContext, HirId, MissingLifetimeKind}; use rustc_hir::{HashStableContext, HirId, MissingLifetimeKind};
use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_span::edition::Edition; pub use rustc_span::edition::Edition;
use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent}; use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent};
use rustc_span::{sym, Span, Symbol}; use rustc_span::{sym, Span, Symbol};
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;

View File

@ -1,3 +1,6 @@
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
use std::panic::{catch_unwind, AssertUnwindSafe}; use std::panic::{catch_unwind, AssertUnwindSafe};
use std::thread; use std::thread;

View File

@ -1,3 +1,6 @@
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
use core::iter::TrustedLen; use core::iter::TrustedLen;
use super::*; use super::*;

View File

@ -1,4 +1,6 @@
#![deny(warnings)] #![deny(warnings)]
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
use std::cell::RefCell; use std::cell::RefCell;
use std::fmt::{self, Write}; use std::fmt::{self, Write};

View File

@ -1,3 +1,6 @@
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
use core::alloc::{Allocator, Layout}; use core::alloc::{Allocator, Layout};
use core::num::NonZero; use core::num::NonZero;
use core::ptr::NonNull; use core::ptr::NonNull;
@ -1284,6 +1287,8 @@ fn test_from_iter_specialization_panic_during_iteration_drops() {
#[test] #[test]
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#[cfg_attr(not(bootstrap), allow(static_mut_refs))]
fn test_from_iter_specialization_panic_during_drop_doesnt_leak() { fn test_from_iter_specialization_panic_during_drop_doesnt_leak() {
static mut DROP_COUNTER_OLD: [usize; 5] = [0; 5]; static mut DROP_COUNTER_OLD: [usize; 5] = [0; 5];
static mut DROP_COUNTER_NEW: [usize; 2] = [0; 2]; static mut DROP_COUNTER_NEW: [usize; 2] = [0; 2];

View File

@ -1,3 +1,6 @@
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
use core::num::NonZero; use core::num::NonZero;
use std::assert_matches::assert_matches; use std::assert_matches::assert_matches;
use std::collections::vec_deque::Drain; use std::collections::vec_deque::Drain;

View File

@ -228,6 +228,8 @@ fn static_init() {
} }
#[test] #[test]
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#[cfg_attr(not(bootstrap), allow(static_mut_refs))]
fn atomic_access_bool() { fn atomic_access_bool() {
static mut ATOMIC: AtomicBool = AtomicBool::new(false); static mut ATOMIC: AtomicBool = AtomicBool::new(false);

View File

@ -291,6 +291,8 @@ macro_rules! define_cleanup {
} }
} }
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#[allow(static_mut_refs)]
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;

View File

@ -9,6 +9,9 @@
//! Consider the following code, operating on some global static variables: //! Consider the following code, operating on some global static variables:
//! //!
//! ```rust //! ```rust
//! // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
//! #![allow(static_mut_refs)]
//!
//! static mut A: u32 = 0; //! static mut A: u32 = 0;
//! static mut B: u32 = 0; //! static mut B: u32 = 0;
//! static mut C: u32 = 0; //! static mut C: u32 = 0;

View File

@ -16,6 +16,9 @@
//! The crate itself provides a global allocator which on wasm has no //! The crate itself provides a global allocator which on wasm has no
//! synchronization as there are no threads! //! synchronization as there are no threads!
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
use crate::alloc::{GlobalAlloc, Layout, System}; use crate::alloc::{GlobalAlloc, Layout, System};
static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::Dlmalloc::new(); static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::Dlmalloc::new();

View File

@ -103,6 +103,9 @@ fn run(key: &'static LocalKey<UnsafeCell<Option<NotifyOnDrop>>>) {
#[test] #[test]
fn circular() { fn circular() {
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
struct S1(&'static LocalKey<UnsafeCell<Option<S1>>>, &'static LocalKey<UnsafeCell<Option<S2>>>); struct S1(&'static LocalKey<UnsafeCell<Option<S1>>>, &'static LocalKey<UnsafeCell<Option<S2>>>);
struct S2(&'static LocalKey<UnsafeCell<Option<S1>>>, &'static LocalKey<UnsafeCell<Option<S2>>>); struct S2(&'static LocalKey<UnsafeCell<Option<S1>>>, &'static LocalKey<UnsafeCell<Option<S2>>>);
thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell::new(None)); thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell::new(None));

View File

@ -236,5 +236,16 @@ LL | if result.is_ok() {
LL | result.as_mut().unwrap(); LL | result.as_mut().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 25 previous errors error: creating a shared reference to mutable static is discouraged
--> tests/ui/checked_unwrap/simple_conditionals.rs:174:12
|
LL | if X.is_some() {
| ^^^^^^^^^^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
= note: `-D static-mut-refs` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(static_mut_refs)]`
error: aborting due to 26 previous errors

View File

@ -4,6 +4,7 @@
#![allow(deref_nullptr)] #![allow(deref_nullptr)]
#![allow(clippy::unnecessary_operation)] #![allow(clippy::unnecessary_operation)]
#![allow(dropping_copy_types)] #![allow(dropping_copy_types)]
#![allow(clippy::assign_op_pattern)]
#![warn(clippy::multiple_unsafe_ops_per_block)] #![warn(clippy::multiple_unsafe_ops_per_block)]
extern crate proc_macros; extern crate proc_macros;

View File

@ -1,5 +1,5 @@
error: this `unsafe` block contains 2 unsafe operations, expected only one error: this `unsafe` block contains 2 unsafe operations, expected only one
--> tests/ui/multiple_unsafe_ops_per_block.rs:37:5 --> tests/ui/multiple_unsafe_ops_per_block.rs:38:5
| |
LL | / unsafe { LL | / unsafe {
LL | | STATIC += 1; LL | | STATIC += 1;
@ -8,12 +8,12 @@ LL | | }
| |_____^ | |_____^
| |
note: modification of a mutable static occurs here note: modification of a mutable static occurs here
--> tests/ui/multiple_unsafe_ops_per_block.rs:38:9 --> tests/ui/multiple_unsafe_ops_per_block.rs:39:9
| |
LL | STATIC += 1; LL | STATIC += 1;
| ^^^^^^^^^^^ | ^^^^^^^^^^^
note: unsafe function call occurs here note: unsafe function call occurs here
--> tests/ui/multiple_unsafe_ops_per_block.rs:39:9 --> tests/ui/multiple_unsafe_ops_per_block.rs:40:9
| |
LL | not_very_safe(); LL | not_very_safe();
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
@ -21,7 +21,7 @@ LL | not_very_safe();
= help: to override `-D warnings` add `#[allow(clippy::multiple_unsafe_ops_per_block)]` = help: to override `-D warnings` add `#[allow(clippy::multiple_unsafe_ops_per_block)]`
error: this `unsafe` block contains 2 unsafe operations, expected only one error: this `unsafe` block contains 2 unsafe operations, expected only one
--> tests/ui/multiple_unsafe_ops_per_block.rs:46:5 --> tests/ui/multiple_unsafe_ops_per_block.rs:47:5
| |
LL | / unsafe { LL | / unsafe {
LL | | drop(u.u); LL | | drop(u.u);
@ -30,18 +30,18 @@ LL | | }
| |_____^ | |_____^
| |
note: union field access occurs here note: union field access occurs here
--> tests/ui/multiple_unsafe_ops_per_block.rs:47:14 --> tests/ui/multiple_unsafe_ops_per_block.rs:48:14
| |
LL | drop(u.u); LL | drop(u.u);
| ^^^ | ^^^
note: raw pointer dereference occurs here note: raw pointer dereference occurs here
--> tests/ui/multiple_unsafe_ops_per_block.rs:48:9 --> tests/ui/multiple_unsafe_ops_per_block.rs:49:9
| |
LL | *raw_ptr(); LL | *raw_ptr();
| ^^^^^^^^^^ | ^^^^^^^^^^
error: this `unsafe` block contains 3 unsafe operations, expected only one error: this `unsafe` block contains 3 unsafe operations, expected only one
--> tests/ui/multiple_unsafe_ops_per_block.rs:53:5 --> tests/ui/multiple_unsafe_ops_per_block.rs:54:5
| |
LL | / unsafe { LL | / unsafe {
LL | | asm!("nop"); LL | | asm!("nop");
@ -51,23 +51,23 @@ LL | | }
| |_____^ | |_____^
| |
note: inline assembly used here note: inline assembly used here
--> tests/ui/multiple_unsafe_ops_per_block.rs:54:9 --> tests/ui/multiple_unsafe_ops_per_block.rs:55:9
| |
LL | asm!("nop"); LL | asm!("nop");
| ^^^^^^^^^^^ | ^^^^^^^^^^^
note: unsafe method call occurs here note: unsafe method call occurs here
--> tests/ui/multiple_unsafe_ops_per_block.rs:55:9 --> tests/ui/multiple_unsafe_ops_per_block.rs:56:9
| |
LL | sample.not_very_safe(); LL | sample.not_very_safe();
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^
note: modification of a mutable static occurs here note: modification of a mutable static occurs here
--> tests/ui/multiple_unsafe_ops_per_block.rs:56:9 --> tests/ui/multiple_unsafe_ops_per_block.rs:57:9
| |
LL | STATIC = 0; LL | STATIC = 0;
| ^^^^^^^^^^ | ^^^^^^^^^^
error: this `unsafe` block contains 6 unsafe operations, expected only one error: this `unsafe` block contains 6 unsafe operations, expected only one
--> tests/ui/multiple_unsafe_ops_per_block.rs:62:5 --> tests/ui/multiple_unsafe_ops_per_block.rs:63:5
| |
LL | / unsafe { LL | / unsafe {
LL | | drop(u.u); LL | | drop(u.u);
@ -79,55 +79,55 @@ LL | | }
| |_____^ | |_____^
| |
note: union field access occurs here note: union field access occurs here
--> tests/ui/multiple_unsafe_ops_per_block.rs:63:14 --> tests/ui/multiple_unsafe_ops_per_block.rs:64:14
| |
LL | drop(u.u); LL | drop(u.u);
| ^^^ | ^^^
note: access of a mutable static occurs here note: access of a mutable static occurs here
--> tests/ui/multiple_unsafe_ops_per_block.rs:64:14 --> tests/ui/multiple_unsafe_ops_per_block.rs:65:14
| |
LL | drop(STATIC); LL | drop(STATIC);
| ^^^^^^ | ^^^^^^
note: unsafe method call occurs here note: unsafe method call occurs here
--> tests/ui/multiple_unsafe_ops_per_block.rs:65:9 --> tests/ui/multiple_unsafe_ops_per_block.rs:66:9
| |
LL | sample.not_very_safe(); LL | sample.not_very_safe();
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^
note: unsafe function call occurs here note: unsafe function call occurs here
--> tests/ui/multiple_unsafe_ops_per_block.rs:66:9 --> tests/ui/multiple_unsafe_ops_per_block.rs:67:9
| |
LL | not_very_safe(); LL | not_very_safe();
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
note: raw pointer dereference occurs here note: raw pointer dereference occurs here
--> tests/ui/multiple_unsafe_ops_per_block.rs:67:9 --> tests/ui/multiple_unsafe_ops_per_block.rs:68:9
| |
LL | *raw_ptr(); LL | *raw_ptr();
| ^^^^^^^^^^ | ^^^^^^^^^^
note: inline assembly used here note: inline assembly used here
--> tests/ui/multiple_unsafe_ops_per_block.rs:68:9 --> tests/ui/multiple_unsafe_ops_per_block.rs:69:9
| |
LL | asm!("nop"); LL | asm!("nop");
| ^^^^^^^^^^^ | ^^^^^^^^^^^
error: this `unsafe` block contains 2 unsafe operations, expected only one error: this `unsafe` block contains 2 unsafe operations, expected only one
--> tests/ui/multiple_unsafe_ops_per_block.rs:106:5 --> tests/ui/multiple_unsafe_ops_per_block.rs:107:5
| |
LL | unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) } LL | unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
note: unsafe function call occurs here note: unsafe function call occurs here
--> tests/ui/multiple_unsafe_ops_per_block.rs:106:14 --> tests/ui/multiple_unsafe_ops_per_block.rs:107:14
| |
LL | unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) } LL | unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: raw pointer dereference occurs here note: raw pointer dereference occurs here
--> tests/ui/multiple_unsafe_ops_per_block.rs:106:39 --> tests/ui/multiple_unsafe_ops_per_block.rs:107:39
| |
LL | unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) } LL | unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) }
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
error: this `unsafe` block contains 2 unsafe operations, expected only one error: this `unsafe` block contains 2 unsafe operations, expected only one
--> tests/ui/multiple_unsafe_ops_per_block.rs:124:5 --> tests/ui/multiple_unsafe_ops_per_block.rs:125:5
| |
LL | / unsafe { LL | / unsafe {
LL | | x(); LL | | x();
@ -136,18 +136,18 @@ LL | | }
| |_____^ | |_____^
| |
note: unsafe function call occurs here note: unsafe function call occurs here
--> tests/ui/multiple_unsafe_ops_per_block.rs:125:9 --> tests/ui/multiple_unsafe_ops_per_block.rs:126:9
| |
LL | x(); LL | x();
| ^^^ | ^^^
note: unsafe function call occurs here note: unsafe function call occurs here
--> tests/ui/multiple_unsafe_ops_per_block.rs:126:9 --> tests/ui/multiple_unsafe_ops_per_block.rs:127:9
| |
LL | x(); LL | x();
| ^^^ | ^^^
error: this `unsafe` block contains 2 unsafe operations, expected only one error: this `unsafe` block contains 2 unsafe operations, expected only one
--> tests/ui/multiple_unsafe_ops_per_block.rs:135:9 --> tests/ui/multiple_unsafe_ops_per_block.rs:136:9
| |
LL | / unsafe { LL | / unsafe {
LL | | T::X(); LL | | T::X();
@ -156,18 +156,18 @@ LL | | }
| |_________^ | |_________^
| |
note: unsafe function call occurs here note: unsafe function call occurs here
--> tests/ui/multiple_unsafe_ops_per_block.rs:136:13 --> tests/ui/multiple_unsafe_ops_per_block.rs:137:13
| |
LL | T::X(); LL | T::X();
| ^^^^^^ | ^^^^^^
note: unsafe function call occurs here note: unsafe function call occurs here
--> tests/ui/multiple_unsafe_ops_per_block.rs:137:13 --> tests/ui/multiple_unsafe_ops_per_block.rs:138:13
| |
LL | T::X(); LL | T::X();
| ^^^^^^ | ^^^^^^
error: this `unsafe` block contains 2 unsafe operations, expected only one error: this `unsafe` block contains 2 unsafe operations, expected only one
--> tests/ui/multiple_unsafe_ops_per_block.rs:145:5 --> tests/ui/multiple_unsafe_ops_per_block.rs:146:5
| |
LL | / unsafe { LL | / unsafe {
LL | | x.0(); LL | | x.0();
@ -176,12 +176,12 @@ LL | | }
| |_____^ | |_____^
| |
note: unsafe function call occurs here note: unsafe function call occurs here
--> tests/ui/multiple_unsafe_ops_per_block.rs:146:9 --> tests/ui/multiple_unsafe_ops_per_block.rs:147:9
| |
LL | x.0(); LL | x.0();
| ^^^^^ | ^^^^^
note: unsafe function call occurs here note: unsafe function call occurs here
--> tests/ui/multiple_unsafe_ops_per_block.rs:147:9 --> tests/ui/multiple_unsafe_ops_per_block.rs:148:9
| |
LL | x.0(); LL | x.0();
| ^^^^^ | ^^^^^

View File

@ -1,5 +1,10 @@
#![feature(never_type)] #![feature(never_type)]
#![allow(unused_mut, clippy::redundant_allocation, clippy::needless_pass_by_ref_mut)] #![allow(
unused_mut,
clippy::redundant_allocation,
clippy::needless_pass_by_ref_mut,
static_mut_refs
)]
#![warn(clippy::must_use_candidate)] #![warn(clippy::must_use_candidate)]
use std::rc::Rc; use std::rc::Rc;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};

View File

@ -1,5 +1,10 @@
#![feature(never_type)] #![feature(never_type)]
#![allow(unused_mut, clippy::redundant_allocation, clippy::needless_pass_by_ref_mut)] #![allow(
unused_mut,
clippy::redundant_allocation,
clippy::needless_pass_by_ref_mut,
static_mut_refs
)]
#![warn(clippy::must_use_candidate)] #![warn(clippy::must_use_candidate)]
use std::rc::Rc; use std::rc::Rc;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};

View File

@ -1,5 +1,5 @@
error: this function could have a `#[must_use]` attribute error: this function could have a `#[must_use]` attribute
--> tests/ui/must_use_candidates.rs:11:1 --> tests/ui/must_use_candidates.rs:16:1
| |
LL | pub fn pure(i: u8) -> u8 { LL | pub fn pure(i: u8) -> u8 {
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn pure(i: u8) -> u8` | ^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn pure(i: u8) -> u8`
@ -8,25 +8,25 @@ LL | pub fn pure(i: u8) -> u8 {
= help: to override `-D warnings` add `#[allow(clippy::must_use_candidate)]` = help: to override `-D warnings` add `#[allow(clippy::must_use_candidate)]`
error: this method could have a `#[must_use]` attribute error: this method could have a `#[must_use]` attribute
--> tests/ui/must_use_candidates.rs:16:5 --> tests/ui/must_use_candidates.rs:21:5
| |
LL | pub fn inherent_pure(&self) -> u8 { LL | pub fn inherent_pure(&self) -> u8 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn inherent_pure(&self) -> u8` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn inherent_pure(&self) -> u8`
error: this function could have a `#[must_use]` attribute error: this function could have a `#[must_use]` attribute
--> tests/ui/must_use_candidates.rs:47:1 --> tests/ui/must_use_candidates.rs:52:1
| |
LL | pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool { LL | pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool`
error: this function could have a `#[must_use]` attribute error: this function could have a `#[must_use]` attribute
--> tests/ui/must_use_candidates.rs:59:1 --> tests/ui/must_use_candidates.rs:64:1
| |
LL | pub fn rcd(_x: Rc<u32>) -> bool { LL | pub fn rcd(_x: Rc<u32>) -> bool {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn rcd(_x: Rc<u32>) -> bool` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn rcd(_x: Rc<u32>) -> bool`
error: this function could have a `#[must_use]` attribute error: this function could have a `#[must_use]` attribute
--> tests/ui/must_use_candidates.rs:67:1 --> tests/ui/must_use_candidates.rs:72:1
| |
LL | pub fn arcd(_x: Arc<u32>) -> bool { LL | pub fn arcd(_x: Arc<u32>) -> bool {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn arcd(_x: Arc<u32>) -> bool` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn arcd(_x: Arc<u32>) -> bool`

View File

@ -1,4 +1,6 @@
#![allow(unused)] #![allow(unused)]
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
#[derive(Debug)] #[derive(Debug)]
struct Foo; struct Foo;

View File

@ -1,4 +1,6 @@
#![allow(unused)] #![allow(unused)]
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
#[derive(Debug)] #[derive(Debug)]
struct Foo; struct Foo;

View File

@ -1,5 +1,5 @@
error: constants have by default a `'static` lifetime error: constants have by default a `'static` lifetime
--> tests/ui/redundant_static_lifetimes.rs:6:17 --> tests/ui/redundant_static_lifetimes.rs:8:17
| |
LL | const VAR_ONE: &'static str = "Test constant #1"; // ERROR: Consider removing 'static. LL | const VAR_ONE: &'static str = "Test constant #1"; // ERROR: Consider removing 'static.
| -^^^^^^^---- help: consider removing `'static`: `&str` | -^^^^^^^---- help: consider removing `'static`: `&str`
@ -8,103 +8,103 @@ LL | const VAR_ONE: &'static str = "Test constant #1"; // ERROR: Consider removi
= help: to override `-D warnings` add `#[allow(clippy::redundant_static_lifetimes)]` = help: to override `-D warnings` add `#[allow(clippy::redundant_static_lifetimes)]`
error: constants have by default a `'static` lifetime error: constants have by default a `'static` lifetime
--> tests/ui/redundant_static_lifetimes.rs:10:21 --> tests/ui/redundant_static_lifetimes.rs:12:21
| |
LL | const VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR: Consider removing 'static LL | const VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR: Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str` | -^^^^^^^---- help: consider removing `'static`: `&str`
error: constants have by default a `'static` lifetime error: constants have by default a `'static` lifetime
--> tests/ui/redundant_static_lifetimes.rs:12:32 --> tests/ui/redundant_static_lifetimes.rs:14:32
| |
LL | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static LL | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str` | -^^^^^^^---- help: consider removing `'static`: `&str`
error: constants have by default a `'static` lifetime error: constants have by default a `'static` lifetime
--> tests/ui/redundant_static_lifetimes.rs:12:47 --> tests/ui/redundant_static_lifetimes.rs:14:47
| |
LL | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static LL | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str` | -^^^^^^^---- help: consider removing `'static`: `&str`
error: constants have by default a `'static` lifetime error: constants have by default a `'static` lifetime
--> tests/ui/redundant_static_lifetimes.rs:14:17 --> tests/ui/redundant_static_lifetimes.rs:16:17
| |
LL | const VAR_SIX: &'static u8 = &5; LL | const VAR_SIX: &'static u8 = &5;
| -^^^^^^^--- help: consider removing `'static`: `&u8` | -^^^^^^^--- help: consider removing `'static`: `&u8`
error: constants have by default a `'static` lifetime error: constants have by default a `'static` lifetime
--> tests/ui/redundant_static_lifetimes.rs:16:20 --> tests/ui/redundant_static_lifetimes.rs:18:20
| |
LL | const VAR_HEIGHT: &'static Foo = &Foo {}; LL | const VAR_HEIGHT: &'static Foo = &Foo {};
| -^^^^^^^---- help: consider removing `'static`: `&Foo` | -^^^^^^^---- help: consider removing `'static`: `&Foo`
error: constants have by default a `'static` lifetime error: constants have by default a `'static` lifetime
--> tests/ui/redundant_static_lifetimes.rs:18:19 --> tests/ui/redundant_static_lifetimes.rs:20:19
| |
LL | const VAR_SLICE: &'static [u8] = b"Test constant #1"; // ERROR: Consider removing 'static. LL | const VAR_SLICE: &'static [u8] = b"Test constant #1"; // ERROR: Consider removing 'static.
| -^^^^^^^----- help: consider removing `'static`: `&[u8]` | -^^^^^^^----- help: consider removing `'static`: `&[u8]`
error: constants have by default a `'static` lifetime error: constants have by default a `'static` lifetime
--> tests/ui/redundant_static_lifetimes.rs:20:19 --> tests/ui/redundant_static_lifetimes.rs:22:19
| |
LL | const VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR: Consider removing 'static. LL | const VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR: Consider removing 'static.
| -^^^^^^^--------- help: consider removing `'static`: `&(u8, u8)` | -^^^^^^^--------- help: consider removing `'static`: `&(u8, u8)`
error: constants have by default a `'static` lifetime error: constants have by default a `'static` lifetime
--> tests/ui/redundant_static_lifetimes.rs:22:19 --> tests/ui/redundant_static_lifetimes.rs:24:19
| |
LL | const VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR: Consider removing 'static. LL | const VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR: Consider removing 'static.
| -^^^^^^^-------- help: consider removing `'static`: `&[u8; 1]` | -^^^^^^^-------- help: consider removing `'static`: `&[u8; 1]`
error: statics have by default a `'static` lifetime error: statics have by default a `'static` lifetime
--> tests/ui/redundant_static_lifetimes.rs:24:25 --> tests/ui/redundant_static_lifetimes.rs:26:25
| |
LL | static STATIC_VAR_ONE: &'static str = "Test static #1"; // ERROR: Consider removing 'static. LL | static STATIC_VAR_ONE: &'static str = "Test static #1"; // ERROR: Consider removing 'static.
| -^^^^^^^---- help: consider removing `'static`: `&str` | -^^^^^^^---- help: consider removing `'static`: `&str`
error: statics have by default a `'static` lifetime error: statics have by default a `'static` lifetime
--> tests/ui/redundant_static_lifetimes.rs:28:29 --> tests/ui/redundant_static_lifetimes.rs:30:29
| |
LL | static STATIC_VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR: Consider removing 'static LL | static STATIC_VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR: Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str` | -^^^^^^^---- help: consider removing `'static`: `&str`
error: statics have by default a `'static` lifetime error: statics have by default a `'static` lifetime
--> tests/ui/redundant_static_lifetimes.rs:30:25 --> tests/ui/redundant_static_lifetimes.rs:32:25
| |
LL | static STATIC_VAR_SIX: &'static u8 = &5; LL | static STATIC_VAR_SIX: &'static u8 = &5;
| -^^^^^^^--- help: consider removing `'static`: `&u8` | -^^^^^^^--- help: consider removing `'static`: `&u8`
error: statics have by default a `'static` lifetime error: statics have by default a `'static` lifetime
--> tests/ui/redundant_static_lifetimes.rs:32:28 --> tests/ui/redundant_static_lifetimes.rs:34:28
| |
LL | static STATIC_VAR_HEIGHT: &'static Foo = &Foo {}; LL | static STATIC_VAR_HEIGHT: &'static Foo = &Foo {};
| -^^^^^^^---- help: consider removing `'static`: `&Foo` | -^^^^^^^---- help: consider removing `'static`: `&Foo`
error: statics have by default a `'static` lifetime error: statics have by default a `'static` lifetime
--> tests/ui/redundant_static_lifetimes.rs:34:27 --> tests/ui/redundant_static_lifetimes.rs:36:27
| |
LL | static STATIC_VAR_SLICE: &'static [u8] = b"Test static #3"; // ERROR: Consider removing 'static. LL | static STATIC_VAR_SLICE: &'static [u8] = b"Test static #3"; // ERROR: Consider removing 'static.
| -^^^^^^^----- help: consider removing `'static`: `&[u8]` | -^^^^^^^----- help: consider removing `'static`: `&[u8]`
error: statics have by default a `'static` lifetime error: statics have by default a `'static` lifetime
--> tests/ui/redundant_static_lifetimes.rs:36:27 --> tests/ui/redundant_static_lifetimes.rs:38:27
| |
LL | static STATIC_VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR: Consider removing 'static. LL | static STATIC_VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR: Consider removing 'static.
| -^^^^^^^--------- help: consider removing `'static`: `&(u8, u8)` | -^^^^^^^--------- help: consider removing `'static`: `&(u8, u8)`
error: statics have by default a `'static` lifetime error: statics have by default a `'static` lifetime
--> tests/ui/redundant_static_lifetimes.rs:38:27 --> tests/ui/redundant_static_lifetimes.rs:40:27
| |
LL | static STATIC_VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR: Consider removing 'static. LL | static STATIC_VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR: Consider removing 'static.
| -^^^^^^^-------- help: consider removing `'static`: `&[u8; 1]` | -^^^^^^^-------- help: consider removing `'static`: `&[u8; 1]`
error: statics have by default a `'static` lifetime error: statics have by default a `'static` lifetime
--> tests/ui/redundant_static_lifetimes.rs:40:31 --> tests/ui/redundant_static_lifetimes.rs:42:31
| |
LL | static mut STATIC_MUT_SLICE: &'static mut [u32] = &mut [0]; LL | static mut STATIC_MUT_SLICE: &'static mut [u32] = &mut [0];
| -^^^^^^^---------- help: consider removing `'static`: `&mut [u32]` | -^^^^^^^---------- help: consider removing `'static`: `&mut [u32]`
error: statics have by default a `'static` lifetime error: statics have by default a `'static` lifetime
--> tests/ui/redundant_static_lifetimes.rs:69:16 --> tests/ui/redundant_static_lifetimes.rs:71:16
| |
LL | static V: &'static u8 = &17; LL | static V: &'static u8 = &17;
| -^^^^^^^--- help: consider removing `'static`: `&u8` | -^^^^^^^--- help: consider removing `'static`: `&u8`

View File

@ -1,5 +1,7 @@
#![deny(clippy::useless_conversion)] #![deny(clippy::useless_conversion)]
#![allow(clippy::needless_if, clippy::unnecessary_wraps)] #![allow(clippy::needless_if, clippy::unnecessary_wraps)]
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
fn test_generic<T: Copy>(val: T) -> T { fn test_generic<T: Copy>(val: T) -> T {
let _ = val; let _ = val;

View File

@ -1,5 +1,7 @@
#![deny(clippy::useless_conversion)] #![deny(clippy::useless_conversion)]
#![allow(clippy::needless_if, clippy::unnecessary_wraps)] #![allow(clippy::needless_if, clippy::unnecessary_wraps)]
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
fn test_generic<T: Copy>(val: T) -> T { fn test_generic<T: Copy>(val: T) -> T {
let _ = T::from(val); let _ = T::from(val);

View File

@ -1,5 +1,5 @@
error: useless conversion to the same type: `T` error: useless conversion to the same type: `T`
--> tests/ui/useless_conversion.rs:5:13 --> tests/ui/useless_conversion.rs:7:13
| |
LL | let _ = T::from(val); LL | let _ = T::from(val);
| ^^^^^^^^^^^^ help: consider removing `T::from()`: `val` | ^^^^^^^^^^^^ help: consider removing `T::from()`: `val`
@ -11,217 +11,217 @@ LL | #![deny(clippy::useless_conversion)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: useless conversion to the same type: `T` error: useless conversion to the same type: `T`
--> tests/ui/useless_conversion.rs:6:5 --> tests/ui/useless_conversion.rs:8:5
| |
LL | val.into() LL | val.into()
| ^^^^^^^^^^ help: consider removing `.into()`: `val` | ^^^^^^^^^^ help: consider removing `.into()`: `val`
error: useless conversion to the same type: `i32` error: useless conversion to the same type: `i32`
--> tests/ui/useless_conversion.rs:18:22 --> tests/ui/useless_conversion.rs:20:22
| |
LL | let _: i32 = 0i32.into(); LL | let _: i32 = 0i32.into();
| ^^^^^^^^^^^ help: consider removing `.into()`: `0i32` | ^^^^^^^^^^^ help: consider removing `.into()`: `0i32`
error: useless conversion to the same type: `std::str::Lines<'_>` error: useless conversion to the same type: `std::str::Lines<'_>`
--> tests/ui/useless_conversion.rs:48:22 --> tests/ui/useless_conversion.rs:50:22
| |
LL | if Some("ok") == lines.into_iter().next() {} LL | if Some("ok") == lines.into_iter().next() {}
| ^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `lines` | ^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `lines`
error: useless conversion to the same type: `std::str::Lines<'_>` error: useless conversion to the same type: `std::str::Lines<'_>`
--> tests/ui/useless_conversion.rs:53:21 --> tests/ui/useless_conversion.rs:55:21
| |
LL | let mut lines = text.lines().into_iter(); LL | let mut lines = text.lines().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `text.lines()` | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `text.lines()`
error: useless conversion to the same type: `std::str::Lines<'_>` error: useless conversion to the same type: `std::str::Lines<'_>`
--> tests/ui/useless_conversion.rs:59:22 --> tests/ui/useless_conversion.rs:61:22
| |
LL | if Some("ok") == text.lines().into_iter().next() {} LL | if Some("ok") == text.lines().into_iter().next() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `text.lines()` | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `text.lines()`
error: useless conversion to the same type: `std::ops::Range<i32>` error: useless conversion to the same type: `std::ops::Range<i32>`
--> tests/ui/useless_conversion.rs:65:13 --> tests/ui/useless_conversion.rs:67:13
| |
LL | let _ = NUMBERS.into_iter().next(); LL | let _ = NUMBERS.into_iter().next();
| ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `NUMBERS` | ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `NUMBERS`
error: useless conversion to the same type: `std::ops::Range<i32>` error: useless conversion to the same type: `std::ops::Range<i32>`
--> tests/ui/useless_conversion.rs:70:17 --> tests/ui/useless_conversion.rs:72:17
| |
LL | let mut n = NUMBERS.into_iter(); LL | let mut n = NUMBERS.into_iter();
| ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `NUMBERS` | ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `NUMBERS`
error: useless conversion to the same type: `std::string::String` error: useless conversion to the same type: `std::string::String`
--> tests/ui/useless_conversion.rs:132:21 --> tests/ui/useless_conversion.rs:134:21
| |
LL | let _: String = "foo".to_string().into(); LL | let _: String = "foo".to_string().into();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `"foo".to_string()` | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `"foo".to_string()`
error: useless conversion to the same type: `std::string::String` error: useless conversion to the same type: `std::string::String`
--> tests/ui/useless_conversion.rs:133:21 --> tests/ui/useless_conversion.rs:135:21
| |
LL | let _: String = From::from("foo".to_string()); LL | let _: String = From::from("foo".to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `From::from()`: `"foo".to_string()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `From::from()`: `"foo".to_string()`
error: useless conversion to the same type: `std::string::String` error: useless conversion to the same type: `std::string::String`
--> tests/ui/useless_conversion.rs:134:13 --> tests/ui/useless_conversion.rs:136:13
| |
LL | let _ = String::from("foo".to_string()); LL | let _ = String::from("foo".to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `"foo".to_string()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `"foo".to_string()`
error: useless conversion to the same type: `std::string::String` error: useless conversion to the same type: `std::string::String`
--> tests/ui/useless_conversion.rs:135:13 --> tests/ui/useless_conversion.rs:137:13
| |
LL | let _ = String::from(format!("A: {:04}", 123)); LL | let _ = String::from(format!("A: {:04}", 123));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `format!("A: {:04}", 123)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `format!("A: {:04}", 123)`
error: useless conversion to the same type: `std::str::Lines<'_>` error: useless conversion to the same type: `std::str::Lines<'_>`
--> tests/ui/useless_conversion.rs:136:13 --> tests/ui/useless_conversion.rs:138:13
| |
LL | let _ = "".lines().into_iter(); LL | let _ = "".lines().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `"".lines()` | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `"".lines()`
error: useless conversion to the same type: `std::vec::IntoIter<i32>` error: useless conversion to the same type: `std::vec::IntoIter<i32>`
--> tests/ui/useless_conversion.rs:137:13 --> tests/ui/useless_conversion.rs:139:13
| |
LL | let _ = vec![1, 2, 3].into_iter().into_iter(); LL | let _ = vec![1, 2, 3].into_iter().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2, 3].into_iter()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2, 3].into_iter()`
error: useless conversion to the same type: `std::string::String` error: useless conversion to the same type: `std::string::String`
--> tests/ui/useless_conversion.rs:138:21 --> tests/ui/useless_conversion.rs:140:21
| |
LL | let _: String = format!("Hello {}", "world").into(); LL | let _: String = format!("Hello {}", "world").into();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `format!("Hello {}", "world")` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `format!("Hello {}", "world")`
error: useless conversion to the same type: `i32` error: useless conversion to the same type: `i32`
--> tests/ui/useless_conversion.rs:143:13 --> tests/ui/useless_conversion.rs:145:13
| |
LL | let _ = i32::from(a + b) * 3; LL | let _ = i32::from(a + b) * 3;
| ^^^^^^^^^^^^^^^^ help: consider removing `i32::from()`: `(a + b)` | ^^^^^^^^^^^^^^^^ help: consider removing `i32::from()`: `(a + b)`
error: useless conversion to the same type: `Foo<'a'>` error: useless conversion to the same type: `Foo<'a'>`
--> tests/ui/useless_conversion.rs:149:23 --> tests/ui/useless_conversion.rs:151:23
| |
LL | let _: Foo<'a'> = s2.into(); LL | let _: Foo<'a'> = s2.into();
| ^^^^^^^^^ help: consider removing `.into()`: `s2` | ^^^^^^^^^ help: consider removing `.into()`: `s2`
error: useless conversion to the same type: `Foo<'a'>` error: useless conversion to the same type: `Foo<'a'>`
--> tests/ui/useless_conversion.rs:151:13 --> tests/ui/useless_conversion.rs:153:13
| |
LL | let _ = Foo::<'a'>::from(s3); LL | let _ = Foo::<'a'>::from(s3);
| ^^^^^^^^^^^^^^^^^^^^ help: consider removing `Foo::<'a'>::from()`: `s3` | ^^^^^^^^^^^^^^^^^^^^ help: consider removing `Foo::<'a'>::from()`: `s3`
error: useless conversion to the same type: `std::vec::IntoIter<Foo<'a'>>` error: useless conversion to the same type: `std::vec::IntoIter<Foo<'a'>>`
--> tests/ui/useless_conversion.rs:153:13 --> tests/ui/useless_conversion.rs:155:13
| |
LL | let _ = vec![s4, s4, s4].into_iter().into_iter(); LL | let _ = vec![s4, s4, s4].into_iter().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![s4, s4, s4].into_iter()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![s4, s4, s4].into_iter()`
error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
--> tests/ui/useless_conversion.rs:185:7 --> tests/ui/useless_conversion.rs:187:7
| |
LL | b(vec![1, 2].into_iter()); LL | b(vec![1, 2].into_iter());
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]` | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]`
| |
note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
--> tests/ui/useless_conversion.rs:175:13 --> tests/ui/useless_conversion.rs:177:13
| |
LL | fn b<T: IntoIterator<Item = i32>>(_: T) {} LL | fn b<T: IntoIterator<Item = i32>>(_: T) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
--> tests/ui/useless_conversion.rs:186:7 --> tests/ui/useless_conversion.rs:188:7
| |
LL | c(vec![1, 2].into_iter()); LL | c(vec![1, 2].into_iter());
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]` | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]`
| |
note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
--> tests/ui/useless_conversion.rs:176:18 --> tests/ui/useless_conversion.rs:178:18
| |
LL | fn c(_: impl IntoIterator<Item = i32>) {} LL | fn c(_: impl IntoIterator<Item = i32>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
--> tests/ui/useless_conversion.rs:187:7 --> tests/ui/useless_conversion.rs:189:7
| |
LL | d(vec![1, 2].into_iter()); LL | d(vec![1, 2].into_iter());
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]` | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]`
| |
note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
--> tests/ui/useless_conversion.rs:179:12 --> tests/ui/useless_conversion.rs:181:12
| |
LL | T: IntoIterator<Item = i32>, LL | T: IntoIterator<Item = i32>,
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
--> tests/ui/useless_conversion.rs:190:7 --> tests/ui/useless_conversion.rs:192:7
| |
LL | b(vec![1, 2].into_iter().into_iter()); LL | b(vec![1, 2].into_iter().into_iter());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`s: `vec![1, 2]` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`s: `vec![1, 2]`
| |
note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
--> tests/ui/useless_conversion.rs:175:13 --> tests/ui/useless_conversion.rs:177:13
| |
LL | fn b<T: IntoIterator<Item = i32>>(_: T) {} LL | fn b<T: IntoIterator<Item = i32>>(_: T) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
--> tests/ui/useless_conversion.rs:191:7 --> tests/ui/useless_conversion.rs:193:7
| |
LL | b(vec![1, 2].into_iter().into_iter().into_iter()); LL | b(vec![1, 2].into_iter().into_iter().into_iter());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`s: `vec![1, 2]` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`s: `vec![1, 2]`
| |
note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
--> tests/ui/useless_conversion.rs:175:13 --> tests/ui/useless_conversion.rs:177:13
| |
LL | fn b<T: IntoIterator<Item = i32>>(_: T) {} LL | fn b<T: IntoIterator<Item = i32>>(_: T) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
--> tests/ui/useless_conversion.rs:237:24 --> tests/ui/useless_conversion.rs:239:24
| |
LL | foo2::<i32, _>([1, 2, 3].into_iter()); LL | foo2::<i32, _>([1, 2, 3].into_iter());
| ^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2, 3]` | ^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2, 3]`
| |
note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
--> tests/ui/useless_conversion.rs:216:12 --> tests/ui/useless_conversion.rs:218:12
| |
LL | I: IntoIterator<Item = i32> + Helper<X>, LL | I: IntoIterator<Item = i32> + Helper<X>,
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
--> tests/ui/useless_conversion.rs:245:14 --> tests/ui/useless_conversion.rs:247:14
| |
LL | foo3([1, 2, 3].into_iter()); LL | foo3([1, 2, 3].into_iter());
| ^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2, 3]` | ^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2, 3]`
| |
note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
--> tests/ui/useless_conversion.rs:225:12 --> tests/ui/useless_conversion.rs:227:12
| |
LL | I: IntoIterator<Item = i32>, LL | I: IntoIterator<Item = i32>,
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
--> tests/ui/useless_conversion.rs:254:16 --> tests/ui/useless_conversion.rs:256:16
| |
LL | S1.foo([1, 2].into_iter()); LL | S1.foo([1, 2].into_iter());
| ^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2]` | ^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2]`
| |
note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
--> tests/ui/useless_conversion.rs:251:27 --> tests/ui/useless_conversion.rs:253:27
| |
LL | pub fn foo<I: IntoIterator>(&self, _: I) {} LL | pub fn foo<I: IntoIterator>(&self, _: I) {}
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
--> tests/ui/useless_conversion.rs:273:44 --> tests/ui/useless_conversion.rs:275:44
| |
LL | v0.into_iter().interleave_shortest(v1.into_iter()); LL | v0.into_iter().interleave_shortest(v1.into_iter());
| ^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `v1` | ^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `v1`
| |
note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
--> tests/ui/useless_conversion.rs:260:20 --> tests/ui/useless_conversion.rs:262:20
| |
LL | J: IntoIterator, LL | J: IntoIterator,
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^

View File

@ -1,6 +1,9 @@
//@only-target: linux //@only-target: linux
//@compile-flags: -Zmiri-disable-isolation //@compile-flags: -Zmiri-disable-isolation
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
use std::ptr::{self, addr_of}; use std::ptr::{self, addr_of};
use std::sync::atomic::AtomicI32; use std::sync::atomic::AtomicI32;

View File

@ -5,6 +5,9 @@
//! the fallback path in `guard::key::enable`, which uses a *single* pthread_key //! the fallback path in `guard::key::enable`, which uses a *single* pthread_key
//! to manage a thread-local list of dtors to call. //! to manage a thread-local list of dtors to call.
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
use std::mem; use std::mem;
use std::ptr; use std::ptr;

View File

@ -2,6 +2,9 @@
// test_race depends on a deterministic schedule. // test_race depends on a deterministic schedule.
//@compile-flags: -Zmiri-preemption-rate=0 //@compile-flags: -Zmiri-preemption-rate=0
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
use std::thread; use std::thread;
fn main() { fn main() {

View File

@ -72,6 +72,8 @@ fn test_pipe_threaded() {
thread2.join().unwrap(); thread2.join().unwrap();
} }
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#[allow(static_mut_refs)]
fn test_race() { fn test_race() {
static mut VAL: u8 = 0; static mut VAL: u8 = 0;
let mut fds = [-1, -1]; let mut fds = [-1, -1];

View File

@ -1,6 +1,10 @@
//@ignore-target: windows # No libc socketpair on Windows //@ignore-target: windows # No libc socketpair on Windows
// test_race depends on a deterministic schedule. // test_race depends on a deterministic schedule.
//@compile-flags: -Zmiri-preemption-rate=0 //@compile-flags: -Zmiri-preemption-rate=0
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
use std::thread; use std::thread;
fn main() { fn main() {
test_socketpair(); test_socketpair();

View File

@ -1,7 +1,11 @@
//@revisions: stack tree //@revisions: stack tree
//@[tree]compile-flags: -Zmiri-tree-borrows //@[tree]compile-flags: -Zmiri-tree-borrows
//@compile-flags: -Zmiri-strict-provenance //@compile-flags: -Zmiri-strict-provenance
#![feature(strict_provenance, strict_provenance_atomic_ptr)] #![feature(strict_provenance, strict_provenance_atomic_ptr)]
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
use std::sync::atomic::{ use std::sync::atomic::{
compiler_fence, fence, AtomicBool, AtomicIsize, AtomicPtr, AtomicU64, Ordering::*, compiler_fence, fence, AtomicBool, AtomicIsize, AtomicPtr, AtomicU64, Ordering::*,
}; };

View File

@ -1,3 +1,5 @@
#![allow(static_mut_refs)]
struct Bar(u16); // ZSTs are tested separately struct Bar(u16); // ZSTs are tested separately
static mut DROP_COUNT: usize = 0; static mut DROP_COUNT: usize = 0;

View File

@ -1,3 +1,5 @@
#![allow(static_mut_refs)]
trait Foo {} trait Foo {}
struct Bar; struct Bar;

View File

@ -1,3 +1,5 @@
#![allow(static_mut_refs)]
struct Bar; struct Bar;
static mut DROP_COUNT: usize = 0; static mut DROP_COUNT: usize = 0;

View File

@ -1,3 +1,5 @@
#![allow(static_mut_refs)]
struct Bar; struct Bar;
static mut DROP_COUNT: usize = 0; static mut DROP_COUNT: usize = 0;

View File

@ -1,3 +1,6 @@
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
static mut X: usize = 5; static mut X: usize = 5;

View File

@ -1,3 +1,6 @@
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
use std::ptr::addr_of; use std::ptr::addr_of;
static mut FOO: i32 = 42; static mut FOO: i32 = 42;

View File

@ -7,6 +7,8 @@
//! dereferencing the pointer on `t2` resolves to `t1`'s thread-local. In this //! dereferencing the pointer on `t2` resolves to `t1`'s thread-local. In this
//! test, we also check that thread-locals act as per-thread statics. //! test, we also check that thread-locals act as per-thread statics.
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
#![feature(thread_local)] #![feature(thread_local)]
use std::ptr::addr_of_mut; use std::ptr::addr_of_mut;

View File

@ -1649,7 +1649,6 @@ ui/issues/issue-17068.rs
ui/issues/issue-17121.rs ui/issues/issue-17121.rs
ui/issues/issue-17216.rs ui/issues/issue-17216.rs
ui/issues/issue-17252.rs ui/issues/issue-17252.rs
ui/issues/issue-17302.rs
ui/issues/issue-17322.rs ui/issues/issue-17322.rs
ui/issues/issue-17336.rs ui/issues/issue-17336.rs
ui/issues/issue-17337.rs ui/issues/issue-17337.rs

View File

@ -3,6 +3,9 @@
// statics cannot. This ensures that there's some form of error if this is // statics cannot. This ensures that there's some form of error if this is
// attempted. // attempted.
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
use std::ffi::c_int; use std::ffi::c_int;
#[link(name = "rust_test_helpers", kind = "static")] #[link(name = "rust_test_helpers", kind = "static")]
@ -29,9 +32,7 @@ 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 to mutable static is discouraged [static_mut_refs]
static_bound_set(&mut rust_dbg_static_mut); static_bound_set(&mut rust_dbg_static_mut);
//~^ WARN mutable reference to mutable static is discouraged [static_mut_refs]
} }
pub fn main() { pub fn main() {

View File

@ -1,31 +0,0 @@
warning: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-foreign.rs:31:18
|
LL | static_bound(&rust_dbg_static_mut);
| ^^^^^^^^^^^^^^^^^^^^ shared reference to mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: this will be a hard error in the 2024 edition
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
= note: `#[warn(static_mut_refs)]` on by default
help: use `addr_of!` instead to create a raw pointer
|
LL | static_bound(addr_of!(rust_dbg_static_mut));
| ~~~~~~~~~ +
warning: creating a mutable reference to mutable static is discouraged
--> $DIR/static-mut-foreign.rs:33:22
|
LL | static_bound_set(&mut rust_dbg_static_mut);
| ^^^^^^^^^^^^^^^^^^^^^^^^ mutable reference to mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: this will be a hard error in the 2024 edition
= note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
help: use `addr_of_mut!` instead to create a raw pointer
|
LL | static_bound_set(addr_of_mut!(rust_dbg_static_mut));
| ~~~~~~~~~~~~~ +
warning: 2 warnings emitted

View File

@ -5,6 +5,8 @@
// Test that if a slicing expr[..] fails, the correct cleanups happen. // Test that if a slicing expr[..] fails, the correct cleanups happen.
// FIXME(static_mut_refs): this could use an atomic
#![allow(static_mut_refs)]
use std::thread; use std::thread;

View File

@ -5,6 +5,8 @@
// Test that if a slicing expr[..] fails, the correct cleanups happen. // Test that if a slicing expr[..] fails, the correct cleanups happen.
// FIXME(static_mut_refs): this could use an atomic
#![allow(static_mut_refs)]
use std::thread; use std::thread;

View File

@ -3,6 +3,9 @@
// Test slicing sugar. // Test slicing sugar.
// FIXME(static_mut_refs): this could use an atomic
#![allow(static_mut_refs)]
extern crate core; extern crate core;
use core::ops::{Index, IndexMut, Range, RangeTo, RangeFrom, RangeFull}; use core::ops::{Index, IndexMut, Range, RangeTo, RangeFrom, RangeFull};

View File

@ -2,6 +2,8 @@
//@ edition:2018 //@ edition:2018
#![feature(if_let_guard)] #![feature(if_let_guard)]
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
static mut A: [i32; 5] = [1, 2, 3, 4, 5]; static mut A: [i32; 5] = [1, 2, 3, 4, 5];

View File

@ -5,6 +5,8 @@
// in ORDER matching up to when it ran. // in ORDER matching up to when it ran.
// Correct order is: matched, inner, outer // Correct order is: matched, inner, outer
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
static mut ORDER: [usize; 3] = [0, 0, 0]; static mut ORDER: [usize; 3] = [0, 0, 0];
static mut INDEX: usize = 0; static mut INDEX: usize = 0;

View File

@ -16,7 +16,6 @@ fn main() {
let _y1 = &mut static_x; //~ ERROR [E0596] let _y1 = &mut static_x; //~ ERROR [E0596]
unsafe { unsafe {
let _y2 = &mut static_x_mut; let _y2 = &mut static_x_mut;
//~^ WARN mutable reference to mutable static is discouraged [static_mut_refs]
} }
} }

View File

@ -1,18 +1,3 @@
warning: creating a mutable reference to mutable static is discouraged
--> $DIR/borrowck-access-permissions.rs:18:23
|
LL | let _y2 = &mut static_x_mut;
| ^^^^^^^^^^^^^^^^^ mutable reference to mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: this will be a hard error in the 2024 edition
= note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
= note: `#[warn(static_mut_refs)]` on by default
help: 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:10:19 --> $DIR/borrowck-access-permissions.rs:10:19
| |
@ -31,7 +16,7 @@ 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:28:19 --> $DIR/borrowck-access-permissions.rs:27:19
| |
LL | let _y1 = &mut *box_x; LL | let _y1 = &mut *box_x;
| ^^^^^^^^^^^ cannot borrow as mutable | ^^^^^^^^^^^ cannot borrow as mutable
@ -42,7 +27,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:37:19 --> $DIR/borrowck-access-permissions.rs:36: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
@ -53,7 +38,7 @@ 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:47:23 --> $DIR/borrowck-access-permissions.rs:46: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
@ -64,7 +49,7 @@ 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:60:18 --> $DIR/borrowck-access-permissions.rs:59: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
@ -74,6 +59,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; 1 warning emitted error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0596`. For more information about this error, try `rustc --explain E0596`.

View File

@ -4,14 +4,13 @@ warning: creating a mutable reference to mutable static is discouraged
LL | let sfoo: *mut Foo = &mut SFOO; LL | let sfoo: *mut Foo = &mut SFOO;
| ^^^^^^^^^ mutable reference to mutable static | ^^^^^^^^^ mutable reference to mutable static
| |
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447> = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: this will be a hard error in the 2024 edition = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
= note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
= note: `#[warn(static_mut_refs)]` on by default = note: `#[warn(static_mut_refs)]` on by default
help: use `addr_of_mut!` instead to create a raw pointer help: use `&raw mut` instead to create a raw pointer
| |
LL | let sfoo: *mut Foo = addr_of_mut!(SFOO); LL | let sfoo: *mut Foo = &raw mut SFOO;
| ~~~~~~~~~~~~~ + | ~~~~~~~~
warning: 1 warning emitted warning: 1 warning emitted

View File

@ -12,7 +12,6 @@ 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 to mutable static is discouraged [static_mut_refs]
} }
fn mut_ptr() -> *mut T { fn mut_ptr() -> *mut T {

View File

@ -1,20 +1,5 @@
warning: creating a mutable reference to mutable static is discouraged
--> $DIR/issue-20801.rs:14:14
|
LL | unsafe { &mut GLOBAL_MUT_T }
| ^^^^^^^^^^^^^^^^^ mutable reference to mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: this will be a hard error in the 2024 edition
= note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
= note: `#[warn(static_mut_refs)]` on by default
help: 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:27:22 --> $DIR/issue-20801.rs:26: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
@ -34,7 +19,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:30:22 --> $DIR/issue-20801.rs:29: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
@ -54,7 +39,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:33:22 --> $DIR/issue-20801.rs:32: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
@ -69,7 +54,7 @@ LL | let c = unsafe { *mut_ptr() };
| ---------- you could clone this value | ---------- you could clone this value
error[E0507]: cannot move out of a raw pointer error[E0507]: cannot move out of a raw pointer
--> $DIR/issue-20801.rs:36:22 --> $DIR/issue-20801.rs:35: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
@ -83,6 +68,6 @@ LL | struct T(u8);
LL | let d = unsafe { *const_ptr() }; LL | let d = unsafe { *const_ptr() };
| ------------ you could clone this value | ------------ you could clone this value
error: aborting due to 4 previous errors; 1 warning emitted error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0507`. For more information about this error, try `rustc --explain E0507`.

View File

@ -10,7 +10,6 @@ pub fn e(x: &'static mut isize) {
//~^ ERROR is not declared as mutable //~^ ERROR is not declared as mutable
unsafe { unsafe {
c1(&mut Y); c1(&mut Y);
//~^ WARN mutable reference to mutable static is discouraged [static_mut_refs]
} }
} }
} }
@ -25,7 +24,6 @@ pub fn ee(x: &'static mut isize) {
}; };
unsafe { unsafe {
c1(&mut Z); c1(&mut Z);
//~^ WARN mutable reference to mutable static is discouraged [static_mut_refs]
} }
} }
} }
@ -62,7 +60,6 @@ fn main() {
static mut X: isize = 2; static mut X: isize = 2;
unsafe { unsafe {
borrowck_closures_unique::e(&mut X); borrowck_closures_unique::e(&mut X);
//~^ WARN mutable reference to mutable static is discouraged [static_mut_refs]
} }
mutability_errors::capture_assign_whole((1000,)); mutability_errors::capture_assign_whole((1000,));

View File

@ -1,46 +1,3 @@
warning: creating a mutable reference to mutable static is discouraged
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:12:16
|
LL | c1(&mut Y);
| ^^^^^^ mutable reference to mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: this will be a hard error in the 2024 edition
= note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
= note: `#[warn(static_mut_refs)]` on by default
help: use `addr_of_mut!` instead to create a raw pointer
|
LL | c1(addr_of_mut!(Y));
| ~~~~~~~~~~~~~ +
warning: creating a mutable reference to mutable static is discouraged
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:27:16
|
LL | c1(&mut Z);
| ^^^^^^ mutable reference to mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: this will be a hard error in the 2024 edition
= note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
help: use `addr_of_mut!` instead to create a raw pointer
|
LL | c1(addr_of_mut!(Z));
| ~~~~~~~~~~~~~ +
warning: creating a mutable reference to mutable static is discouraged
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:64:37
|
LL | borrowck_closures_unique::e(&mut X);
| ^^^^^^ mutable reference to mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: this will be a hard error in the 2024 edition
= note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
help: 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
| |
@ -53,7 +10,7 @@ LL | pub fn e(mut x: &'static mut isize) {
| +++ | +++
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:22:50 --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:21:50
| |
LL | let mut c2 = |y: &'static mut isize| x = y; LL | let mut c2 = |y: &'static mut isize| x = y;
| ^^^^^ cannot assign | ^^^^^ cannot assign
@ -64,7 +21,7 @@ LL | pub fn ee(mut x: &'static mut isize) {
| +++ | +++
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:37:13 --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:35:13
| |
LL | x = (1,); LL | x = (1,);
| ^^^^^^^^ cannot assign | ^^^^^^^^ cannot assign
@ -75,7 +32,7 @@ LL | pub fn capture_assign_whole(mut x: (i32,)) {
| +++ | +++
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:43:13 --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:41:13
| |
LL | x.0 = 1; LL | x.0 = 1;
| ^^^^^^^ cannot assign | ^^^^^^^ cannot assign
@ -86,7 +43,7 @@ LL | pub fn capture_assign_part(mut x: (i32,)) {
| +++ | +++
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:49:13 --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:47:13
| |
LL | &mut x; LL | &mut x;
| ^^^^^^ cannot borrow as mutable | ^^^^^^ cannot borrow as mutable
@ -97,7 +54,7 @@ LL | pub fn capture_reborrow_whole(mut x: (i32,)) {
| +++ | +++
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:55:13 --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:53:13
| |
LL | &mut x.0; LL | &mut x.0;
| ^^^^^^^^ cannot borrow as mutable | ^^^^^^^^ cannot borrow as mutable
@ -107,7 +64,7 @@ help: consider changing this to be mutable
LL | pub fn capture_reborrow_part(mut x: (i32,)) { LL | pub fn capture_reborrow_part(mut x: (i32,)) {
| +++ | +++
error: aborting due to 6 previous errors; 3 warnings emitted error: aborting due to 6 previous errors
Some errors have detailed explanations: E0594, E0596. Some errors have detailed explanations: E0594, E0596.
For more information about an error, try `rustc --explain E0594`. For more information about an error, try `rustc --explain E0594`.

View File

@ -4,14 +4,13 @@ warning: creating a mutable reference to mutable static is discouraged
LL | let ptr = unsafe { &mut BB }; LL | let ptr = unsafe { &mut BB };
| ^^^^^^^ mutable reference to mutable static | ^^^^^^^ mutable reference to mutable static
| |
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447> = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: this will be a hard error in the 2024 edition = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
= note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
= note: `#[warn(static_mut_refs)]` on by default = note: `#[warn(static_mut_refs)]` on by default
help: use `addr_of_mut!` instead to create a raw pointer help: use `&raw mut` instead to create a raw pointer
| |
LL | let ptr = unsafe { addr_of_mut!(BB) }; LL | let ptr = unsafe { &raw mut BB };
| ~~~~~~~~~~~~~ + | ~~~~~~~~
warning: 1 warning emitted warning: 1 warning emitted

View File

@ -1,6 +1,9 @@
//@ run-pass //@ run-pass
#![allow(dead_code)] #![allow(dead_code)]
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
// Checks that mutable static items can have mutable slices and other references // Checks that mutable static items can have mutable slices and other references

View File

@ -1,6 +1,8 @@
//@ build-pass //@ build-pass
#![feature(coroutines, stmt_expr_attributes)] #![feature(coroutines, stmt_expr_attributes)]
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
static mut A: [i32; 5] = [1, 2, 3, 4, 5]; static mut A: [i32; 5] = [1, 2, 3, 4, 5];

View File

@ -5,6 +5,9 @@
// Test that destructor on a struct runs successfully after the struct // Test that destructor on a struct runs successfully after the struct
// is boxed and converted to an object. // is boxed and converted to an object.
// FIXME(static_mut_refs): this could use an atomic
#![allow(static_mut_refs)]
static mut value: usize = 0; static mut value: usize = 0;
struct Cat { struct Cat {

View File

@ -1,5 +1,5 @@
warning: method `get` is never used warning: method `get` is never used
--> $DIR/drop-struct-as-object.rs:15:8 --> $DIR/drop-struct-as-object.rs:18:8
| |
LL | trait Dummy { LL | trait Dummy {
| ----- method in this trait | ----- method in this trait

View File

@ -1,5 +1,7 @@
//@ run-pass //@ run-pass
#![allow(non_upper_case_globals)] #![allow(non_upper_case_globals)]
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
// This test is ensuring that parameters are indeed dropped after // This test is ensuring that parameters are indeed dropped after
// temporaries in a fn body. // temporaries in a fn body.
@ -91,7 +93,6 @@ pub fn current_width() -> u32 {
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 to mutable static is discouraged [static_mut_refs]
} }
} }

View File

@ -1,17 +0,0 @@
warning: creating a shared reference to 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 to mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: this will be a hard error in the 2024 edition
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
= note: `#[warn(static_mut_refs)]` on by default
help: use `addr_of!` instead to create a raw pointer
|
LL | (mem::size_of_val(addr_of!(trails)) * 8) as u32
| ~~~~~~~~~ +
warning: 1 warning emitted

View File

@ -1,5 +1,7 @@
//@ run-pass //@ run-pass
#![allow(non_upper_case_globals)] #![allow(non_upper_case_globals)]
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
// Issue 23611: this test is ensuring that, for an instance `X` of the // Issue 23611: this test is ensuring that, for an instance `X` of the
// enum `E`, if you swap in a different variant during the execution // enum `E`, if you swap in a different variant during the execution
@ -187,7 +189,6 @@ pub fn current_width() -> u32 {
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 to mutable static is discouraged [static_mut_refs]
} }
} }

View File

@ -1,17 +0,0 @@
warning: creating a shared reference to 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 to mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: this will be a hard error in the 2024 edition
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
= note: `#[warn(static_mut_refs)]` on by default
help: use `addr_of!` instead to create a raw pointer
|
LL | (mem::size_of_val(addr_of!(trails)) * 8) as u32
| ~~~~~~~~~ +
warning: 1 warning emitted

View File

@ -1,6 +1,9 @@
//@ run-pass //@ run-pass
#![allow(unused_must_use)] #![allow(unused_must_use)]
// Test that we are able to reinitialize box with moved referent // Test that we are able to reinitialize box with moved referent
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
static mut ORDER: [usize; 3] = [0, 0, 0]; static mut ORDER: [usize; 3] = [0, 0, 0];
static mut INDEX: usize = 0; static mut INDEX: usize = 0;

View File

@ -3,6 +3,9 @@
#![allow(dropping_references, dropping_copy_types)] #![allow(dropping_references, dropping_copy_types)]
// FIXME(static_mut_refs): this could use an atomic
#![allow(static_mut_refs)]
static mut CHECK: usize = 0; static mut CHECK: usize = 0;
struct DropChecker(usize); struct DropChecker(usize);

View File

@ -1,5 +1,8 @@
//@ run-pass //@ run-pass
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
static mut DROPPED: [bool; 2] = [false, false]; static mut DROPPED: [bool; 2] = [false, false];
struct A(usize); struct A(usize);

View File

@ -2,6 +2,9 @@
// This test verifies that temporaries created for `while`'s and `if` // This test verifies that temporaries created for `while`'s and `if`
// conditions are dropped after the condition is evaluated. // conditions are dropped after the condition is evaluated.
// FIXME(static_mut_refs): this could use an atomic
#![allow(static_mut_refs)]
struct Temporary; struct Temporary;
static mut DROPPED: isize = 0; static mut DROPPED: isize = 0;

View File

@ -2,6 +2,10 @@
// The `foo` module attempts to maintains an invariant that each `S` // The `foo` module attempts to maintains an invariant that each `S`
// has a unique `u64` id. // has a unique `u64` id.
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
use self::foo::S; use self::foo::S;
mod foo { mod foo {
use std::cell::{UnsafeCell}; use std::cell::{UnsafeCell};

View File

@ -1,5 +1,5 @@
error[E0451]: field `secret_uid` of struct `S` is private error[E0451]: field `secret_uid` of struct `S` is private
--> $DIR/functional-struct-update-respects-privacy.rs:28:49 --> $DIR/functional-struct-update-respects-privacy.rs:32:49
| |
LL | let s_2 = foo::S { b: format!("ess two"), ..s_1 }; // FRU ... LL | let s_2 = foo::S { b: format!("ess two"), ..s_1 }; // FRU ...
| ^^^ field `secret_uid` is private | ^^^ field `secret_uid` is private

View File

@ -1,6 +1,9 @@
//@ run-pass //@ run-pass
#![allow(non_upper_case_globals)] #![allow(non_upper_case_globals)]
// FIXME(static_mut_refs): this could use an atomic
#![allow(static_mut_refs)]
static mut drop_count: usize = 0; static mut drop_count: usize = 0;
struct Foo { struct Foo {

View File

@ -1,4 +1,6 @@
//@ run-pass //@ run-pass
// FIXME(static_mut_refs): this could use an atomic
#![allow(static_mut_refs)]
static mut DROP_RAN: bool = false; static mut DROP_RAN: bool = false;
trait Bar { trait Bar {

View File

@ -1,5 +1,5 @@
warning: method `do_something` is never used warning: method `do_something` is never used
--> $DIR/issue-15858.rs:5:8 --> $DIR/issue-15858.rs:7:8
| |
LL | trait Bar { LL | trait Bar {
| --- method in this trait | --- method in this trait

View File

@ -1,5 +1,8 @@
//@ run-pass //@ run-pass
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
use std::mem; use std::mem;
static mut DROP_COUNT: usize = 0; static mut DROP_COUNT: usize = 0;

View File

@ -20,6 +20,7 @@ unsafe fn __stability() -> &'static ArenaSet<Vec<u8>> {
static mut ONCE: Once = Once::new(); static mut ONCE: Once = Once::new();
ONCE.call_once(|| { ONCE.call_once(|| {
//~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs]
DATA = transmute DATA = transmute
::<Box<ArenaSet<Vec<u8>>>, *const ArenaSet<Vec<u8>>> ::<Box<ArenaSet<Vec<u8>>>, *const ArenaSet<Vec<u8>>>
(Box::new(__static_ref_initialize())); (Box::new(__static_ref_initialize()));

View File

@ -0,0 +1,17 @@
warning: creating a shared reference to mutable static is discouraged
--> $DIR/issue-39367.rs:22:13
|
LL | / ONCE.call_once(|| {
LL | |
LL | | DATA = transmute
LL | | ::<Box<ArenaSet<Vec<u8>>>, *const ArenaSet<Vec<u8>>>
LL | | (Box::new(__static_ref_initialize()));
LL | | });
| |______________^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
= note: `#[warn(static_mut_refs)]` on by default
warning: 1 warning emitted

View File

@ -3,7 +3,8 @@
// Ensures that destructors are run for expressions of the form "e;" where // Ensures that destructors are run for expressions of the form "e;" where
// `e` is a type which requires a destructor. // `e` is a type which requires a destructor.
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
#![allow(path_statements)] #![allow(path_statements)]
struct A { n: isize } struct A { n: isize }

View File

@ -5,5 +5,4 @@
fn main() { fn main() {
println!("{:p}", unsafe { &symbol }); println!("{:p}", unsafe { &symbol });
//~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs]
} }

View File

@ -6,21 +6,6 @@ LL | pub static mut symbol: [i8];
| |
= help: the trait `Sized` is not implemented for `[i8]` = help: the trait `Sized` is not implemented for `[i8]`
warning: creating a shared reference to mutable static is discouraged error: aborting due to 1 previous error
--> $DIR/issue-54410.rs:7:31
|
LL | println!("{:p}", unsafe { &symbol });
| ^^^^^^^ shared reference to mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: this will be a hard error in the 2024 edition
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
= note: `#[warn(static_mut_refs)]` on by default
help: use `addr_of!` instead to create a raw pointer
|
LL | println!("{:p}", unsafe { addr_of!(symbol) });
| ~~~~~~~~~ +
error: aborting due to 1 previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0277`. For more information about this error, try `rustc --explain E0277`.

View File

@ -3,6 +3,8 @@
// Ensures that destructors are run for expressions of the form "let _ = e;" // Ensures that destructors are run for expressions of the form "let _ = e;"
// where `e` is a type which requires a destructor. // where `e` is a type which requires a destructor.
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
struct Foo; struct Foo;
struct Bar { x: isize } struct Bar { x: isize }

View File

@ -1,4 +1,6 @@
//@ run-pass //@ run-pass
// FIXME(static_mut_refs): this could use an atomic
#![allow(static_mut_refs)]
#![allow(dead_code)] #![allow(dead_code)]
static mut DROP: isize = 0; static mut DROP: isize = 0;

View File

@ -1,5 +1,8 @@
//@ run-pass //@ run-pass
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
#![allow(non_upper_case_globals)] #![allow(non_upper_case_globals)]
#[cfg(not(target_vendor = "apple"))] #[cfg(not(target_vendor = "apple"))]
#[link_section = ".moretext"] #[link_section = ".moretext"]

View File

@ -2,6 +2,8 @@
//! them at runtime, so deny mutable statics with #[linkage]. //! them at runtime, so deny mutable statics with #[linkage].
#![feature(linkage)] #![feature(linkage)]
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
fn main() { fn main() {
#[rustfmt::skip] #[rustfmt::skip]

View File

@ -1,5 +1,5 @@
error: extern mutable statics are not allowed with `#[linkage]` error: extern mutable statics are not allowed with `#[linkage]`
--> $DIR/linkage-attr-mutable-static.rs:9:9 --> $DIR/linkage-attr-mutable-static.rs:11:9
| |
LL | #[linkage = "extern_weak"] LL | #[linkage = "extern_weak"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -0,0 +1,143 @@
warning: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:39:18
|
LL | let _y = &X;
| ^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
= note: `#[warn(static_mut_refs)]` on by default
help: use `&raw const` instead to create a raw pointer
|
LL | let _y = &raw const X;
| ~~~~~~~~~~
warning: creating a mutable reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:43:18
|
LL | let _y = &mut X;
| ^^^^^^ mutable reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
help: use `&raw mut` instead to create a raw pointer
|
LL | let _y = &raw mut X;
| ~~~~~~~~
warning: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:51:22
|
LL | let ref _a = X;
| ^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
warning: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:55:25
|
LL | let (_b, _c) = (&X, &Y);
| ^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
LL | let (_b, _c) = (&raw const X, &Y);
| ~~~~~~~~~~
warning: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:55:29
|
LL | let (_b, _c) = (&X, &Y);
| ^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
LL | let (_b, _c) = (&X, &raw const Y);
| ~~~~~~~~~~
warning: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:61:13
|
LL | foo(&X);
| ^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
LL | foo(&raw const X);
| ~~~~~~~~~~
warning: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:67:17
|
LL | let _ = Z.len();
| ^^^^^^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
warning: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:73:33
|
LL | let _ = format!("{:?}", Z);
| ^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
warning: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:77:18
|
LL | let _v = &A.value;
| ^^^^^^^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
LL | let _v = &raw const A.value;
| ~~~~~~~~~~
warning: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:81:18
|
LL | let _s = &A.s.value;
| ^^^^^^^^^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
LL | let _s = &raw const A.s.value;
| ~~~~~~~~~~
warning: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:85:22
|
LL | let ref _v = A.value;
| ^^^^^^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
warning: creating a mutable reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:15:14
|
LL | &mut ($x.0)
| ^^^^^^ mutable reference to mutable static
...
LL | let _x = bar!(FOO);
| --------- in this macro invocation
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
= note: this warning originates in the macro `bar` (in Nightly builds, run with -Z macro-backtrace for more info)
warning: 12 warnings emitted

View File

@ -0,0 +1,143 @@
error: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:39:18
|
LL | let _y = &X;
| ^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
= note: `#[deny(static_mut_refs)]` on by default
help: use `&raw const` instead to create a raw pointer
|
LL | let _y = &raw const X;
| ~~~~~~~~~~
error: creating a mutable reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:43:18
|
LL | let _y = &mut X;
| ^^^^^^ mutable reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
help: use `&raw mut` instead to create a raw pointer
|
LL | let _y = &raw mut X;
| ~~~~~~~~
error: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:51:22
|
LL | let ref _a = X;
| ^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
error: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:55:25
|
LL | let (_b, _c) = (&X, &Y);
| ^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
LL | let (_b, _c) = (&raw const X, &Y);
| ~~~~~~~~~~
error: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:55:29
|
LL | let (_b, _c) = (&X, &Y);
| ^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
LL | let (_b, _c) = (&X, &raw const Y);
| ~~~~~~~~~~
error: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:61:13
|
LL | foo(&X);
| ^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
LL | foo(&raw const X);
| ~~~~~~~~~~
error: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:67:17
|
LL | let _ = Z.len();
| ^^^^^^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
error: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:73:33
|
LL | let _ = format!("{:?}", Z);
| ^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
error: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:77:18
|
LL | let _v = &A.value;
| ^^^^^^^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
LL | let _v = &raw const A.value;
| ~~~~~~~~~~
error: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:81:18
|
LL | let _s = &A.s.value;
| ^^^^^^^^^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
LL | let _s = &raw const A.s.value;
| ~~~~~~~~~~
error: creating a shared reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:85:22
|
LL | let ref _v = A.value;
| ^^^^^^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
error: creating a mutable reference to mutable static is discouraged
--> $DIR/static-mut-refs.rs:15:14
|
LL | &mut ($x.0)
| ^^^^^^ mutable reference to mutable static
...
LL | let _x = bar!(FOO);
| --------- in this macro invocation
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
= note: this error originates in the macro `bar` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 12 previous errors

View File

@ -0,0 +1,95 @@
// Test `static_mut_refs` lint.
//@ revisions: e2021 e2024
//@ [e2021] edition:2021
//@ [e2021] run-pass
//@ [e2024] edition:2024
//@ [e2024] compile-flags: -Zunstable-options
static mut FOO: (u32, u32) = (1, 2);
macro_rules! bar {
($x:expr) => {
&mut ($x.0)
//[e2021]~^ WARN creating a mutable reference to mutable static is discouraged [static_mut_refs]
//[e2024]~^^ ERROR creating a mutable reference to mutable static is discouraged [static_mut_refs]
};
}
static mut STATIC: i64 = 1;
fn main() {
static mut X: i32 = 1;
static mut Y: i32 = 1;
struct TheStruct {
pub value: i32,
}
struct MyStruct {
pub value: i32,
pub s: TheStruct,
}
static mut A: MyStruct = MyStruct { value: 1, s: TheStruct { value: 2 } };
unsafe {
let _y = &X;
//[e2021]~^ WARN shared reference to mutable static is discouraged [static_mut_refs]
//[e2024]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs]
let _y = &mut X;
//[e2021]~^ WARN mutable reference to mutable static is discouraged [static_mut_refs]
//[e2024]~^^ ERROR mutable reference to mutable static is discouraged [static_mut_refs]
let _z = &raw mut X;
let _p = &raw const X;
let ref _a = X;
//[e2021]~^ WARN shared reference to mutable static is discouraged [static_mut_refs]
//[e2024]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs]
let (_b, _c) = (&X, &Y);
//[e2021]~^ WARN shared reference to mutable static is discouraged [static_mut_refs]
//[e2024]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs]
//[e2021]~^^^ WARN shared reference to mutable static is discouraged [static_mut_refs]
//[e2024]~^^^^ ERROR shared reference to mutable static is discouraged [static_mut_refs]
foo(&X);
//[e2021]~^ WARN shared reference to mutable static is discouraged [static_mut_refs]
//[e2024]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs]
static mut Z: &[i32; 3] = &[0, 1, 2];
let _ = Z.len();
//[e2021]~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs]
//[e2024]~^^ ERROR creating a shared reference to mutable static is discouraged [static_mut_refs]
let _ = Z[0];
let _ = format!("{:?}", Z);
//[e2021]~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs]
//[e2024]~^^ ERROR creating a shared reference to mutable static is discouraged [static_mut_refs]
let _v = &A.value;
//[e2021]~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs]
//[e2024]~^^ ERROR creating a shared reference to mutable static is discouraged [static_mut_refs]
let _s = &A.s.value;
//[e2021]~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs]
//[e2024]~^^ ERROR creating a shared reference to mutable static is discouraged [static_mut_refs]
let ref _v = A.value;
//[e2021]~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs]
//[e2024]~^^ ERROR creating a shared reference to mutable static is discouraged [static_mut_refs]
let _x = bar!(FOO);
STATIC += 1;
}
}
fn foo<'a>(_x: &'a i32) {}

View File

@ -3,6 +3,9 @@
//@ no-prefer-dynamic //@ no-prefer-dynamic
//@ needs-threads //@ needs-threads
// FIXME(static_mut_refs): this could use an atomic
#![allow(static_mut_refs)]
use std::thread; use std::thread;
static mut HIT: usize = 0; static mut HIT: usize = 0;

View File

@ -1,6 +1,9 @@
//@ run-pass //@ run-pass
// Test method calls with self as an argument // Test method calls with self as an argument
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
static mut COUNT: u64 = 1; static mut COUNT: u64 = 1;
#[derive(Copy, Clone)] #[derive(Copy, Clone)]

View File

@ -1,6 +1,9 @@
//@ run-pass //@ run-pass
// Test method calls with self as an argument // Test method calls with self as an argument
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]
static mut COUNT: usize = 1; static mut COUNT: usize = 1;
#[derive(Copy, Clone)] #[derive(Copy, Clone)]

View File

@ -1,5 +1,7 @@
//@ run-pass //@ run-pass
#![allow(unused_variables)] #![allow(unused_variables)]
// FIXME(static_mut_refs): this could use an atomic
#![allow(static_mut_refs)]
static mut DROP: bool = false; static mut DROP: bool = false;
struct ConnWrap(Conn); struct ConnWrap(Conn);

View File

@ -4,14 +4,13 @@ warning: creating a mutable reference to mutable static is discouraged
LL | S1 { a: unsafe { &mut X1 } } LL | S1 { a: unsafe { &mut X1 } }
| ^^^^^^^ mutable reference to mutable static | ^^^^^^^ mutable reference to mutable static
| |
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447> = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: this will be a hard error in the 2024 edition = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
= note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
= note: `#[warn(static_mut_refs)]` on by default = note: `#[warn(static_mut_refs)]` on by default
help: use `addr_of_mut!` instead to create a raw pointer help: use `&raw mut` instead to create a raw pointer
| |
LL | S1 { a: unsafe { addr_of_mut!(X1) } } LL | S1 { a: unsafe { &raw mut X1 } }
| ~~~~~~~~~~~~~ + | ~~~~~~~~
warning: 1 warning emitted warning: 1 warning emitted

Some files were not shown because too many files have changed in this diff Show More