Skip to content

Commit

Permalink
Add static_mut lint
Browse files Browse the repository at this point in the history
Fixes #12896
  • Loading branch information
lolbinarycat committed Jun 12, 2024
1 parent aaade2d commit 3dbaa0c
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5820,6 +5820,7 @@ Released 2018-09-13
[`skip_while_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#skip_while_next
[`slow_vector_initialization`]: https://rust-lang.github.io/rust-clippy/master/index.html#slow_vector_initialization
[`stable_sort_primitive`]: https://rust-lang.github.io/rust-clippy/master/index.html#stable_sort_primitive
[`static_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#static_mut
[`std_instead_of_alloc`]: https://rust-lang.github.io/rust-clippy/master/index.html#std_instead_of_alloc
[`std_instead_of_core`]: https://rust-lang.github.io/rust-clippy/master/index.html#std_instead_of_core
[`str_split_at_newline`]: https://rust-lang.github.io/rust-clippy/master/index.html#str_split_at_newline
Expand Down
1 change: 1 addition & 0 deletions clippy_lints/src/declared_lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT_INFO,
crate::size_of_ref::SIZE_OF_REF_INFO,
crate::slow_vector_initialization::SLOW_VECTOR_INITIALIZATION_INFO,
crate::static_mut::STATIC_MUT_INFO,
crate::std_instead_of_core::ALLOC_INSTEAD_OF_CORE_INFO,
crate::std_instead_of_core::STD_INSTEAD_OF_ALLOC_INFO,
crate::std_instead_of_core::STD_INSTEAD_OF_CORE_INFO,
Expand Down
2 changes: 2 additions & 0 deletions clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ mod single_range_in_vec_init;
mod size_of_in_element_count;
mod size_of_ref;
mod slow_vector_initialization;
mod static_mut;
mod std_instead_of_core;
mod string_patterns;
mod strings;
Expand Down Expand Up @@ -1169,6 +1170,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
})
});
store.register_late_pass(|_| Box::new(string_patterns::StringPatterns));
store.register_early_pass(|| Box::new(static_mut::StaticMut));
// add lints here, do not remove this comment, it's used in `new_lint`
}

Expand Down
60 changes: 60 additions & 0 deletions clippy_lints/src/static_mut.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use clippy_utils::diagnostics::span_lint_and_help;
use rustc_ast::ast::{Item, ItemKind, Mutability, StaticItem};
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::declare_lint_pass;

declare_clippy_lint! {
/// ### What it does
/// Produces warnings when a `static mut` is declared.
///
/// ### Why is this bad?
/// `static mut` can [easily produce undefined behavior][1] and
/// [may be removed in the future][2].
///
/// ### Example
/// ```no_run
/// static mut GLOBAL_INT: u8 = 0;
/// ```
/// Use instead:
/// ```no_run
/// use std::sync::RwLock;
///
/// static GLOBAL_INT: RwLock<u8> = RwLock::new(0);
/// ```
///
/// [1]: https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-reference.html
/// [2]: https://github.com/rust-lang/rfcs/pull/3560
#[clippy::version = "1.80.0"]
pub STATIC_MUT,
nursery,
"detect mutable static definitions"
}

declare_lint_pass!(StaticMut => [STATIC_MUT]);

impl EarlyLintPass for StaticMut {
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
if in_external_macro(cx.sess(), item.span) {
return;
};
let ItemKind::Static(ref static_item_box) = item.kind else {
return;
};
let StaticItem {
mutability: Mutability::Mut,
..
} = static_item_box.as_ref()
else {
return;
};
span_lint_and_help(
cx,
STATIC_MUT,
item.span,
"declaration of static mut",
None,
"remove the `mut` and use a type with interior mutibability that implements `Sync`, such as `std::sync::Mutex`",
);
}
}
3 changes: 3 additions & 0 deletions tests/ui/static_mut.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#![warn(clippy::static_mut)]

static mut NUMBER: u8 = 3;
12 changes: 12 additions & 0 deletions tests/ui/static_mut.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error: declaration of static mut
--> tests/ui/static_mut.rs:3:1
|
LL | static mut NUMBER: u8 = 3;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: remove the `mut` and use a type with interior mutibability that implements `Sync`, such as `std::sync::Mutex`
= note: `-D clippy::static-mut` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::static_mut)]`

error: aborting due to 1 previous error

0 comments on commit 3dbaa0c

Please sign in to comment.