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:
commit
5ba6db1b64
@ -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
|
||||||
|
@ -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!
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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> {
|
||||||
|
@ -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}`
|
||||||
|
@ -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,
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
@ -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,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
154
compiler/rustc_lint/src/static_mut_refs.rs
Normal file
154
compiler/rustc_lint/src/static_mut_refs.rs
Normal 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 },
|
||||||
|
);
|
||||||
|
}
|
@ -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`,
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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::*;
|
||||||
|
@ -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};
|
||||||
|
@ -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];
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
@ -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));
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -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};
|
||||||
|
@ -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};
|
||||||
|
@ -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`
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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`
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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,
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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() {
|
||||||
|
@ -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];
|
||||||
|
@ -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();
|
||||||
|
@ -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::*,
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![allow(static_mut_refs)]
|
||||||
|
|
||||||
trait Foo {}
|
trait Foo {}
|
||||||
|
|
||||||
struct Bar;
|
struct Bar;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![allow(static_mut_refs)]
|
||||||
|
|
||||||
struct Bar;
|
struct Bar;
|
||||||
|
|
||||||
static mut DROP_COUNT: usize = 0;
|
static mut DROP_COUNT: usize = 0;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![allow(static_mut_refs)]
|
||||||
|
|
||||||
struct Bar;
|
struct Bar;
|
||||||
|
|
||||||
static mut DROP_COUNT: usize = 0;
|
static mut DROP_COUNT: usize = 0;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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() {
|
||||||
|
@ -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
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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};
|
||||||
|
|
||||||
|
@ -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];
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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`.
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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`.
|
||||||
|
@ -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,));
|
||||||
|
@ -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`.
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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];
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
|
||||||
|
|
@ -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]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
@ -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;
|
||||||
|
@ -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};
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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()));
|
||||||
|
17
tests/ui/issues/issue-39367.stderr
Normal file
17
tests/ui/issues/issue-39367.stderr
Normal 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
|
||||||
|
|
@ -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 }
|
||||||
|
@ -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]
|
|
||||||
}
|
}
|
||||||
|
@ -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`.
|
||||||
|
@ -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 }
|
||||||
|
@ -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;
|
||||||
|
@ -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"]
|
||||||
|
@ -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]
|
||||||
|
@ -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"]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
143
tests/ui/lint/static-mut-refs.e2021.stderr
Normal file
143
tests/ui/lint/static-mut-refs.e2021.stderr
Normal 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
|
||||||
|
|
143
tests/ui/lint/static-mut-refs.e2024.stderr
Normal file
143
tests/ui/lint/static-mut-refs.e2024.stderr
Normal 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
|
||||||
|
|
95
tests/ui/lint/static-mut-refs.rs
Normal file
95
tests/ui/lint/static-mut-refs.rs
Normal 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) {}
|
@ -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;
|
||||||
|
@ -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)]
|
||||||
|
@ -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)]
|
||||||
|
@ -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);
|
||||||
|
@ -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
Loading…
Reference in New Issue
Block a user