Skip to content

Commit 260c542

Browse files
committed
Add separated_literal_suffix instead of style configuration
1 parent 2d964b2 commit 260c542

8 files changed

+148
-57
lines changed

clippy_lints/src/lib.register_lints.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ store.register_lints(&[
323323
misc_early::DUPLICATE_UNDERSCORE_ARGUMENT,
324324
misc_early::MIXED_CASE_HEX_LITERALS,
325325
misc_early::REDUNDANT_PATTERN,
326+
misc_early::SEPARATED_LITERAL_SUFFIX,
326327
misc_early::UNNEEDED_FIELD_PATTERN,
327328
misc_early::UNNEEDED_WILDCARD_PATTERN,
328329
misc_early::UNSEPARATED_LITERAL_SUFFIX,

clippy_lints/src/lib.register_restriction.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
3434
LintId::of(methods::GET_UNWRAP),
3535
LintId::of(methods::UNWRAP_USED),
3636
LintId::of(misc::FLOAT_CMP_CONST),
37+
LintId::of(misc_early::SEPARATED_LITERAL_SUFFIX),
3738
LintId::of(misc_early::UNNEEDED_FIELD_PATTERN),
3839
LintId::of(misc_early::UNSEPARATED_LITERAL_SUFFIX),
3940
LintId::of(missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS),
Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,18 @@
1-
use super::MiscEarlyLints;
21
use clippy_utils::diagnostics::span_lint;
32
use rustc_ast::ast::{Expr, ExprKind, UnOp};
43
use rustc_lint::EarlyContext;
54

65
use super::DOUBLE_NEG;
76

87
pub(super) fn check(cx: &EarlyContext<'_>, expr: &Expr) {
9-
match expr.kind {
10-
ExprKind::Unary(UnOp::Neg, ref inner) => {
11-
if let ExprKind::Unary(UnOp::Neg, _) = inner.kind {
12-
span_lint(
13-
cx,
14-
DOUBLE_NEG,
15-
expr.span,
16-
"`--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op",
17-
);
18-
}
19-
},
20-
ExprKind::Lit(ref lit) => MiscEarlyLints::check_lit(cx, lit),
21-
_ => (),
8+
if let ExprKind::Unary(UnOp::Neg, ref inner) = expr.kind {
9+
if let ExprKind::Unary(UnOp::Neg, _) = inner.kind {
10+
span_lint(
11+
cx,
12+
DOUBLE_NEG,
13+
expr.span,
14+
"`--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op",
15+
);
16+
}
2217
}
2318
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use clippy_utils::diagnostics::span_lint_and_sugg;
2+
use rustc_ast::ast::Lit;
3+
use rustc_errors::Applicability;
4+
use rustc_lint::EarlyContext;
5+
6+
use super::{SEPARATED_LITERAL_SUFFIX, UNSEPARATED_LITERAL_SUFFIX};
7+
8+
pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str, suffix: &str, sugg_type: &str) {
9+
let maybe_last_sep_idx = if let Some(val) = lit_snip.len().checked_sub(suffix.len() + 1) {
10+
val
11+
} else {
12+
return; // It's useless so shouldn't lint.
13+
};
14+
// Do not lint when literal is unsuffixed.
15+
if !suffix.is_empty() {
16+
if lit_snip.as_bytes()[maybe_last_sep_idx] == b'_' {
17+
span_lint_and_sugg(
18+
cx,
19+
SEPARATED_LITERAL_SUFFIX,
20+
lit.span,
21+
&format!("{} type suffix should not be separated by an underscore", sugg_type),
22+
"remove the underscore",
23+
format!("{}{}", &lit_snip[..=maybe_last_sep_idx], suffix),
24+
Applicability::MachineApplicable,
25+
);
26+
} else {
27+
span_lint_and_sugg(
28+
cx,
29+
UNSEPARATED_LITERAL_SUFFIX,
30+
lit.span,
31+
&format!("{} type suffix should be separated by an underscore", sugg_type),
32+
"add an underscore",
33+
format!("{}_{}", &lit_snip[..=maybe_last_sep_idx], suffix),
34+
Applicability::MachineApplicable,
35+
);
36+
}
37+
}
38+
}

clippy_lints/src/misc_early/mod.rs

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
mod builtin_type_shadow;
22
mod double_neg;
3+
mod literal_suffix;
34
mod mixed_case_hex_literals;
45
mod redundant_pattern;
56
mod unneeded_field_pattern;
67
mod unneeded_wildcard_pattern;
7-
mod unseparated_literal_suffix;
88
mod zero_prefixed_literal;
99

1010
use clippy_utils::diagnostics::span_lint;
1111
use clippy_utils::source::snippet_opt;
12-
use rustc_ast::ast::{Expr, Generics, Lit, LitFloatType, LitIntType, LitKind, NodeId, Pat, PatKind};
12+
use rustc_ast::ast::{Expr, ExprKind, Generics, Lit, LitFloatType, LitIntType, LitKind, NodeId, Pat, PatKind};
1313
use rustc_ast::visit::FnKind;
1414
use rustc_data_structures::fx::FxHashMap;
1515
use rustc_lint::{EarlyContext, EarlyLintPass};
@@ -115,9 +115,11 @@ declare_clippy_lint! {
115115
/// ### What it does
116116
/// Warns if literal suffixes are not separated by an
117117
/// underscore.
118+
/// To enforce unseparated literal suffix style,
119+
/// see `separated_literal_suffix` lint
118120
///
119121
/// ### Why is this bad?
120-
/// It is much less readable.
122+
/// Suffix style should be consistent.
121123
///
122124
/// ### Example
123125
/// ```rust
@@ -132,6 +134,28 @@ declare_clippy_lint! {
132134
"literals whose suffix is not separated by an underscore"
133135
}
134136

137+
declare_clippy_lint! {
138+
/// ### What it does
139+
/// Warns if literal suffixes are separated by an underscore.
140+
/// To enforce separated literal suffix style,
141+
/// see `unseparated_literal_suffix` lint
142+
///
143+
/// ### Why is this bad?
144+
/// Suffix style should be consistent.
145+
///
146+
/// ### Example
147+
/// ```rust
148+
/// // Bad
149+
/// let y = 123832_i32;
150+
///
151+
/// // Good
152+
/// let y = 123832i32;
153+
/// ```
154+
pub SEPARATED_LITERAL_SUFFIX,
155+
restriction,
156+
"literals whose suffix is separated by an underscore"
157+
}
158+
135159
declare_clippy_lint! {
136160
/// ### What it does
137161
/// Warns if an integral constant literal starts with `0`.
@@ -260,6 +284,7 @@ declare_lint_pass!(MiscEarlyLints => [
260284
DOUBLE_NEG,
261285
MIXED_CASE_HEX_LITERALS,
262286
UNSEPARATED_LITERAL_SUFFIX,
287+
SEPARATED_LITERAL_SUFFIX,
263288
ZERO_PREFIXED_LITERAL,
264289
BUILTIN_TYPE_SHADOW,
265290
REDUNDANT_PATTERN,
@@ -310,6 +335,10 @@ impl EarlyLintPass for MiscEarlyLints {
310335
if in_external_macro(cx.sess, expr.span) {
311336
return;
312337
}
338+
339+
if let ExprKind::Lit(ref lit) = expr.kind {
340+
MiscEarlyLints::check_lit(cx, lit);
341+
}
313342
double_neg::check(cx, expr);
314343
}
315344
}
@@ -332,7 +361,7 @@ impl MiscEarlyLints {
332361
LitIntType::Unsigned(ty) => ty.name_str(),
333362
LitIntType::Unsuffixed => "",
334363
};
335-
unseparated_literal_suffix::check(cx, lit, &lit_snip, suffix, "integer");
364+
literal_suffix::check(cx, lit, &lit_snip, suffix, "integer");
336365
if lit_snip.starts_with("0x") {
337366
mixed_case_hex_literals::check(cx, lit, suffix, &lit_snip);
338367
} else if lit_snip.starts_with("0b") || lit_snip.starts_with("0o") {
@@ -342,7 +371,7 @@ impl MiscEarlyLints {
342371
}
343372
} else if let LitKind::Float(_, LitFloatType::Suffixed(float_ty)) = lit.kind {
344373
let suffix = float_ty.name_str();
345-
unseparated_literal_suffix::check(cx, lit, &lit_snip, suffix, "float");
374+
literal_suffix::check(cx, lit, &lit_snip, suffix, "float");
346375
}
347376
}
348377
}

clippy_lints/src/misc_early/unseparated_literal_suffix.rs

Lines changed: 0 additions & 26 deletions
This file was deleted.

tests/ui/literals.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
#![warn(clippy::mixed_case_hex_literals)]
44
#![warn(clippy::zero_prefixed_literal)]
5-
#![allow(clippy::unseparated_literal_suffix)]
5+
#![warn(clippy::unseparated_literal_suffix)]
6+
#![warn(clippy::separated_literal_suffix)]
67
#![allow(dead_code)]
78

89
fn main() {

tests/ui/literals.stderr

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,65 @@
1+
error: integer type suffix should not be separated by an underscore
2+
--> $DIR/literals.rs:12:15
3+
|
4+
LL | let ok4 = 0xab_cd_i32;
5+
| ^^^^^^^^^^^ help: remove the underscore: `0xab_cd_i32`
6+
|
7+
= note: `-D clippy::separated-literal-suffix` implied by `-D warnings`
8+
9+
error: integer type suffix should not be separated by an underscore
10+
--> $DIR/literals.rs:13:15
11+
|
12+
LL | let ok5 = 0xAB_CD_u32;
13+
| ^^^^^^^^^^^ help: remove the underscore: `0xAB_CD_u32`
14+
15+
error: integer type suffix should not be separated by an underscore
16+
--> $DIR/literals.rs:14:15
17+
|
18+
LL | let ok5 = 0xAB_CD_isize;
19+
| ^^^^^^^^^^^^^ help: remove the underscore: `0xAB_CD_isize`
20+
121
error: inconsistent casing in hexadecimal literal
2-
--> $DIR/literals.rs:14:17
22+
--> $DIR/literals.rs:15:17
323
|
424
LL | let fail1 = 0xabCD;
525
| ^^^^^^
626
|
727
= note: `-D clippy::mixed-case-hex-literals` implied by `-D warnings`
828

29+
error: integer type suffix should not be separated by an underscore
30+
--> $DIR/literals.rs:16:17
31+
|
32+
LL | let fail2 = 0xabCD_u32;
33+
| ^^^^^^^^^^ help: remove the underscore: `0xabCD_u32`
34+
935
error: inconsistent casing in hexadecimal literal
10-
--> $DIR/literals.rs:15:17
36+
--> $DIR/literals.rs:16:17
1137
|
1238
LL | let fail2 = 0xabCD_u32;
1339
| ^^^^^^^^^^
1440

41+
error: integer type suffix should not be separated by an underscore
42+
--> $DIR/literals.rs:17:17
43+
|
44+
LL | let fail2 = 0xabCD_isize;
45+
| ^^^^^^^^^^^^ help: remove the underscore: `0xabCD_isize`
46+
1547
error: inconsistent casing in hexadecimal literal
16-
--> $DIR/literals.rs:16:17
48+
--> $DIR/literals.rs:17:17
1749
|
1850
LL | let fail2 = 0xabCD_isize;
1951
| ^^^^^^^^^^^^
2052

53+
error: integer type suffix should be separated by an underscore
54+
--> $DIR/literals.rs:18:27
55+
|
56+
LL | let fail_multi_zero = 000_123usize;
57+
| ^^^^^^^^^^^^ help: add an underscore: `000_123_usize`
58+
|
59+
= note: `-D clippy::unseparated-literal-suffix` implied by `-D warnings`
60+
2161
error: this is a decimal constant
22-
--> $DIR/literals.rs:17:27
62+
--> $DIR/literals.rs:18:27
2363
|
2464
LL | let fail_multi_zero = 000_123usize;
2565
| ^^^^^^^^^^^^
@@ -34,8 +74,14 @@ help: if you mean to use an octal constant, use `0o`
3474
LL | let fail_multi_zero = 0o123usize;
3575
| ~~~~~~~~~~
3676

77+
error: integer type suffix should not be separated by an underscore
78+
--> $DIR/literals.rs:21:16
79+
|
80+
LL | let ok10 = 0_i64;
81+
| ^^^^^ help: remove the underscore: `0_i64`
82+
3783
error: this is a decimal constant
38-
--> $DIR/literals.rs:21:17
84+
--> $DIR/literals.rs:22:17
3985
|
4086
LL | let fail8 = 0123;
4187
| ^^^^
@@ -49,39 +95,45 @@ help: if you mean to use an octal constant, use `0o`
4995
LL | let fail8 = 0o123;
5096
| ~~~~~
5197

98+
error: integer type suffix should not be separated by an underscore
99+
--> $DIR/literals.rs:31:16
100+
|
101+
LL | let ok17 = 0x123_4567_8901_usize;
102+
| ^^^^^^^^^^^^^^^^^^^^^ help: remove the underscore: `0x123_4567_8901_usize`
103+
52104
error: digits grouped inconsistently by underscores
53-
--> $DIR/literals.rs:33:18
105+
--> $DIR/literals.rs:34:18
54106
|
55107
LL | let fail19 = 12_3456_21;
56108
| ^^^^^^^^^^ help: consider: `12_345_621`
57109
|
58110
= note: `-D clippy::inconsistent-digit-grouping` implied by `-D warnings`
59111

60112
error: digits grouped inconsistently by underscores
61-
--> $DIR/literals.rs:34:18
113+
--> $DIR/literals.rs:35:18
62114
|
63115
LL | let fail22 = 3__4___23;
64116
| ^^^^^^^^^ help: consider: `3_423`
65117

66118
error: digits grouped inconsistently by underscores
67-
--> $DIR/literals.rs:35:18
119+
--> $DIR/literals.rs:36:18
68120
|
69121
LL | let fail23 = 3__16___23;
70122
| ^^^^^^^^^^ help: consider: `31_623`
71123

72124
error: digits of hex or binary literal not grouped by four
73-
--> $DIR/literals.rs:37:18
125+
--> $DIR/literals.rs:38:18
74126
|
75127
LL | let fail24 = 0xAB_ABC_AB;
76128
| ^^^^^^^^^^^ help: consider: `0x0ABA_BCAB`
77129
|
78130
= note: `-D clippy::unusual-byte-groupings` implied by `-D warnings`
79131

80132
error: digits of hex or binary literal not grouped by four
81-
--> $DIR/literals.rs:38:18
133+
--> $DIR/literals.rs:39:18
82134
|
83135
LL | let fail25 = 0b01_100_101;
84136
| ^^^^^^^^^^^^ help: consider: `0b0110_0101`
85137

86-
error: aborting due to 10 previous errors
138+
error: aborting due to 18 previous errors
87139

0 commit comments

Comments
 (0)