Skip to content

Commit b863a00

Browse files
authored
Merge pull request #2344 from HMPerson1/svar_to_cfn
Add lint to replace `const`s with `const fn`s
2 parents 7e21663 + 8505ee7 commit b863a00

File tree

4 files changed

+417
-0
lines changed

4 files changed

+417
-0
lines changed

clippy_lints/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ pub mod ptr;
150150
pub mod ranges;
151151
pub mod reference;
152152
pub mod regex;
153+
pub mod replace_consts;
153154
pub mod returns;
154155
pub mod serde_api;
155156
pub mod shadow;
@@ -361,6 +362,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
361362
reg.register_late_lint_pass(box types::ImplicitHasher);
362363
reg.register_early_lint_pass(box const_static_lifetime::StaticConst);
363364
reg.register_late_lint_pass(box fallible_impl_from::FallibleImplFrom);
365+
reg.register_late_lint_pass(box replace_consts::ReplaceConsts);
364366

365367
reg.register_lint_group("clippy_restrictions", vec![
366368
arithmetic::FLOAT_ARITHMETIC,
@@ -399,6 +401,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
399401
print::PRINT_STDOUT,
400402
print::USE_DEBUG,
401403
ranges::RANGE_PLUS_ONE,
404+
replace_consts::REPLACE_CONSTS,
402405
shadow::SHADOW_REUSE,
403406
shadow::SHADOW_SAME,
404407
shadow::SHADOW_UNRELATED,

clippy_lints/src/replace_consts.rs

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
use rustc::lint::*;
2+
use rustc::hir;
3+
use rustc::hir::def::Def;
4+
use utils::{match_def_path, span_lint_and_sugg};
5+
6+
/// **What it does:** Checks for usage of `ATOMIC_X_INIT`, `ONCE_INIT`, and
7+
/// `uX/iX::MIN/MAX`.
8+
///
9+
/// **Why is this bad?** `const fn`s exist
10+
///
11+
/// **Known problems:** None.
12+
///
13+
/// **Example:**
14+
/// ```rust
15+
/// static FOO: AtomicIsize = ATOMIC_ISIZE_INIT;
16+
/// ```
17+
///
18+
/// Could be written:
19+
///
20+
/// ```rust
21+
/// static FOO: AtomicIsize = AtomicIsize::new(0);
22+
/// ```
23+
declare_lint! {
24+
pub REPLACE_CONSTS,
25+
Allow,
26+
"Lint usages of standard library `const`s that could be replaced by `const fn`s"
27+
}
28+
29+
pub struct ReplaceConsts;
30+
31+
impl LintPass for ReplaceConsts {
32+
fn get_lints(&self) -> LintArray {
33+
lint_array!(REPLACE_CONSTS)
34+
}
35+
}
36+
37+
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ReplaceConsts {
38+
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
39+
if_chain! {
40+
if let hir::ExprPath(ref qp) = expr.node;
41+
if let Def::Const(def_id) = cx.tables.qpath_def(qp, expr.hir_id);
42+
then {
43+
for &(const_path, repl_snip) in REPLACEMENTS {
44+
if match_def_path(cx.tcx, def_id, const_path) {
45+
span_lint_and_sugg(
46+
cx,
47+
REPLACE_CONSTS,
48+
expr.span,
49+
&format!("using `{}`", const_path.last().expect("empty path")),
50+
"try this",
51+
repl_snip.to_string(),
52+
);
53+
return;
54+
}
55+
}
56+
}
57+
}
58+
}
59+
}
60+
61+
const REPLACEMENTS: &[(&[&str], &str)] = &[
62+
// Once
63+
(&["core", "sync", "ONCE_INIT"], "Once::new()"),
64+
// Atomic
65+
(&["core", "sync", "atomic", "ATOMIC_BOOL_INIT"], "AtomicBool::new(false)"),
66+
(&["core", "sync", "atomic", "ATOMIC_ISIZE_INIT"], "AtomicIsize::new(0)"),
67+
(&["core", "sync", "atomic", "ATOMIC_I8_INIT"], "AtomicI8::new(0)"),
68+
(&["core", "sync", "atomic", "ATOMIC_I16_INIT"], "AtomicI16::new(0)"),
69+
(&["core", "sync", "atomic", "ATOMIC_I32_INIT"], "AtomicI32::new(0)"),
70+
(&["core", "sync", "atomic", "ATOMIC_I64_INIT"], "AtomicI64::new(0)"),
71+
(&["core", "sync", "atomic", "ATOMIC_USIZE_INIT"], "AtomicUsize::new(0)"),
72+
(&["core", "sync", "atomic", "ATOMIC_U8_INIT"], "AtomicU8::new(0)"),
73+
(&["core", "sync", "atomic", "ATOMIC_U16_INIT"], "AtomicU16::new(0)"),
74+
(&["core", "sync", "atomic", "ATOMIC_U32_INIT"], "AtomicU32::new(0)"),
75+
(&["core", "sync", "atomic", "ATOMIC_U64_INIT"], "AtomicU64::new(0)"),
76+
// Min
77+
(&["core", "isize", "MIN"], "isize::min_value()"),
78+
(&["core", "i8", "MIN"], "i8::min_value()"),
79+
(&["core", "i16", "MIN"], "i16::min_value()"),
80+
(&["core", "i32", "MIN"], "i32::min_value()"),
81+
(&["core", "i64", "MIN"], "i64::min_value()"),
82+
(&["core", "i128", "MIN"], "i128::min_value()"),
83+
(&["core", "usize", "MIN"], "usize::min_value()"),
84+
(&["core", "u8", "MIN"], "u8::min_value()"),
85+
(&["core", "u16", "MIN"], "u16::min_value()"),
86+
(&["core", "u32", "MIN"], "u32::min_value()"),
87+
(&["core", "u64", "MIN"], "u64::min_value()"),
88+
(&["core", "u128", "MIN"], "u128::min_value()"),
89+
// Max
90+
(&["core", "isize", "MAX"], "isize::max_value()"),
91+
(&["core", "i8", "MAX"], "i8::max_value()"),
92+
(&["core", "i16", "MAX"], "i16::max_value()"),
93+
(&["core", "i32", "MAX"], "i32::max_value()"),
94+
(&["core", "i64", "MAX"], "i64::max_value()"),
95+
(&["core", "i128", "MAX"], "i128::max_value()"),
96+
(&["core", "usize", "MAX"], "usize::max_value()"),
97+
(&["core", "u8", "MAX"], "u8::max_value()"),
98+
(&["core", "u16", "MAX"], "u16::max_value()"),
99+
(&["core", "u32", "MAX"], "u32::max_value()"),
100+
(&["core", "u64", "MAX"], "u64::max_value()"),
101+
(&["core", "u128", "MAX"], "u128::max_value()"),
102+
];

tests/ui/replace_consts.rs

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#![feature(integer_atomics, i128, i128_type)]
2+
#![allow(blacklisted_name)]
3+
#![deny(replace_consts)]
4+
use std::sync::atomic::*;
5+
use std::sync::{ONCE_INIT, Once};
6+
7+
fn bad() {
8+
// Once
9+
{ let foo = ONCE_INIT; };
10+
// Atomic
11+
{ let foo = ATOMIC_BOOL_INIT; };
12+
{ let foo = ATOMIC_ISIZE_INIT; };
13+
{ let foo = ATOMIC_I8_INIT; };
14+
{ let foo = ATOMIC_I16_INIT; };
15+
{ let foo = ATOMIC_I32_INIT; };
16+
{ let foo = ATOMIC_I64_INIT; };
17+
{ let foo = ATOMIC_USIZE_INIT; };
18+
{ let foo = ATOMIC_U8_INIT; };
19+
{ let foo = ATOMIC_U16_INIT; };
20+
{ let foo = ATOMIC_U32_INIT; };
21+
{ let foo = ATOMIC_U64_INIT; };
22+
// Min
23+
{ let foo = std::isize::MIN; };
24+
{ let foo = std::i8::MIN; };
25+
{ let foo = std::i16::MIN; };
26+
{ let foo = std::i32::MIN; };
27+
{ let foo = std::i64::MIN; };
28+
{ let foo = std::i128::MIN; };
29+
{ let foo = std::usize::MIN; };
30+
{ let foo = std::u8::MIN; };
31+
{ let foo = std::u16::MIN; };
32+
{ let foo = std::u32::MIN; };
33+
{ let foo = std::u64::MIN; };
34+
{ let foo = std::u128::MIN; };
35+
// Max
36+
{ let foo = std::isize::MAX; };
37+
{ let foo = std::i8::MAX; };
38+
{ let foo = std::i16::MAX; };
39+
{ let foo = std::i32::MAX; };
40+
{ let foo = std::i64::MAX; };
41+
{ let foo = std::i128::MAX; };
42+
{ let foo = std::usize::MAX; };
43+
{ let foo = std::u8::MAX; };
44+
{ let foo = std::u16::MAX; };
45+
{ let foo = std::u32::MAX; };
46+
{ let foo = std::u64::MAX; };
47+
{ let foo = std::u128::MAX; };
48+
}
49+
50+
fn good() {
51+
// Once
52+
{ let foo = Once::new(); };
53+
// Atomic
54+
{ let foo = AtomicBool::new(false); };
55+
{ let foo = AtomicIsize::new(0); };
56+
{ let foo = AtomicI8::new(0); };
57+
{ let foo = AtomicI16::new(0); };
58+
{ let foo = AtomicI32::new(0); };
59+
{ let foo = AtomicI64::new(0); };
60+
{ let foo = AtomicUsize::new(0); };
61+
{ let foo = AtomicU8::new(0); };
62+
{ let foo = AtomicU16::new(0); };
63+
{ let foo = AtomicU32::new(0); };
64+
{ let foo = AtomicU64::new(0); };
65+
// Min
66+
{ let foo = isize::min_value(); };
67+
{ let foo = i8::min_value(); };
68+
{ let foo = i16::min_value(); };
69+
{ let foo = i32::min_value(); };
70+
{ let foo = i64::min_value(); };
71+
{ let foo = i128::min_value(); };
72+
{ let foo = usize::min_value(); };
73+
{ let foo = u8::min_value(); };
74+
{ let foo = u16::min_value(); };
75+
{ let foo = u32::min_value(); };
76+
{ let foo = u64::min_value(); };
77+
{ let foo = u128::min_value(); };
78+
// Max
79+
{ let foo = isize::max_value(); };
80+
{ let foo = i8::max_value(); };
81+
{ let foo = i16::max_value(); };
82+
{ let foo = i32::max_value(); };
83+
{ let foo = i64::max_value(); };
84+
{ let foo = i128::max_value(); };
85+
{ let foo = usize::max_value(); };
86+
{ let foo = u8::max_value(); };
87+
{ let foo = u16::max_value(); };
88+
{ let foo = u32::max_value(); };
89+
{ let foo = u64::max_value(); };
90+
{ let foo = u128::max_value(); };
91+
}
92+
93+
fn main() {
94+
bad();
95+
good();
96+
}

0 commit comments

Comments
 (0)