Skip to content

Commit 6edd598

Browse files
committed
Added a lint-fraction-readability flag to the configuration
1 parent 13c1a01 commit 6edd598

File tree

10 files changed

+118
-37
lines changed

10 files changed

+118
-37
lines changed

clippy_lints/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1138,7 +1138,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
11381138
store.register_late_pass(|| box cargo_common_metadata::CargoCommonMetadata);
11391139
store.register_late_pass(|| box multiple_crate_versions::MultipleCrateVersions);
11401140
store.register_late_pass(|| box wildcard_dependencies::WildcardDependencies);
1141-
store.register_early_pass(|| box literal_representation::LiteralDigitGrouping);
1141+
let literal_representation_lint_fraction_readability = conf.lint_fraction_readability;
1142+
store.register_early_pass(move || box literal_representation::LiteralDigitGrouping::new(literal_representation_lint_fraction_readability));
11421143
let literal_representation_threshold = conf.literal_representation_threshold;
11431144
store.register_early_pass(move || box literal_representation::DecimalLiteralRepresentation::new(literal_representation_threshold));
11441145
let enum_variant_name_threshold = conf.enum_variant_name_threshold;

clippy_lints/src/literal_representation.rs

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_ast::ast::{Expr, ExprKind, Lit, LitKind};
1111
use rustc_errors::Applicability;
1212
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
1313
use rustc_middle::lint::in_external_macro;
14-
use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
14+
use rustc_session::{declare_tool_lint, impl_lint_pass};
1515

1616
declare_clippy_lint! {
1717
/// **What it does:** Warns if a long integral or floating-point constant does
@@ -32,7 +32,7 @@ declare_clippy_lint! {
3232
/// ```
3333
pub UNREADABLE_LITERAL,
3434
pedantic,
35-
"long integer literal without underscores"
35+
"long literal without underscores"
3636
}
3737

3838
declare_clippy_lint! {
@@ -208,7 +208,13 @@ impl WarningType {
208208
}
209209
}
210210

211-
declare_lint_pass!(LiteralDigitGrouping => [
211+
#[allow(clippy::module_name_repetitions)]
212+
#[derive(Copy, Clone)]
213+
pub struct LiteralDigitGrouping {
214+
lint_fraction_readability: bool,
215+
}
216+
217+
impl_lint_pass!(LiteralDigitGrouping => [
212218
UNREADABLE_LITERAL,
213219
INCONSISTENT_DIGIT_GROUPING,
214220
LARGE_DIGIT_GROUPS,
@@ -223,7 +229,7 @@ impl EarlyLintPass for LiteralDigitGrouping {
223229
}
224230

225231
if let ExprKind::Lit(ref lit) = expr.kind {
226-
Self::check_lit(cx, lit)
232+
self.check_lit(cx, lit)
227233
}
228234
}
229235
}
@@ -232,7 +238,13 @@ impl EarlyLintPass for LiteralDigitGrouping {
232238
const UUID_GROUP_LENS: [usize; 5] = [8, 4, 4, 4, 12];
233239

234240
impl LiteralDigitGrouping {
235-
fn check_lit(cx: &EarlyContext<'_>, lit: &Lit) {
241+
pub fn new(lint_fraction_readability: bool) -> Self {
242+
Self {
243+
lint_fraction_readability,
244+
}
245+
}
246+
247+
fn check_lit(&self, cx: &EarlyContext<'_>, lit: &Lit) {
236248
if_chain! {
237249
if let Some(src) = snippet_opt(cx, lit.span);
238250
if let Some(mut num_lit) = NumericLiteral::from_lit(&src, &lit);
@@ -247,9 +259,12 @@ impl LiteralDigitGrouping {
247259

248260
let result = (|| {
249261

250-
let integral_group_size = Self::get_group_size(num_lit.integer.split('_'), num_lit.radix)?;
262+
let integral_group_size = Self::get_group_size(num_lit.integer.split('_'), num_lit.radix, true)?;
251263
if let Some(fraction) = num_lit.fraction {
252-
let fractional_group_size = Self::get_group_size(fraction.rsplit('_'), num_lit.radix)?;
264+
let fractional_group_size = Self::get_group_size(
265+
fraction.rsplit('_'),
266+
num_lit.radix,
267+
self.lint_fraction_readability)?;
253268

254269
let consistent = Self::parts_consistent(integral_group_size,
255270
fractional_group_size,
@@ -363,7 +378,11 @@ impl LiteralDigitGrouping {
363378

364379
/// Returns the size of the digit groups (or None if ungrouped) if successful,
365380
/// otherwise returns a `WarningType` for linting.
366-
fn get_group_size<'a>(groups: impl Iterator<Item = &'a str>, radix: Radix) -> Result<Option<usize>, WarningType> {
381+
fn get_group_size<'a>(
382+
groups: impl Iterator<Item = &'a str>,
383+
radix: Radix,
384+
lint_unreadable: bool,
385+
) -> Result<Option<usize>, WarningType> {
367386
let mut groups = groups.map(str::len);
368387

369388
let first = groups.next().expect("At least one group");
@@ -380,7 +399,7 @@ impl LiteralDigitGrouping {
380399
} else {
381400
Ok(Some(second))
382401
}
383-
} else if first > 5 {
402+
} else if first > 5 && lint_unreadable {
384403
Err(WarningType::UnreadableLiteral)
385404
} else {
386405
Ok(None)

clippy_lints/src/utils/conf.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ define_Conf! {
170170
(warn_on_all_wildcard_imports, "warn_on_all_wildcard_imports": bool, false),
171171
/// Lint: DISALLOWED_METHOD. The list of blacklisted methods to lint about. NB: `bar` is not here since it has legitimate uses
172172
(disallowed_methods, "disallowed_methods": Vec<String>, Vec::<String>::new()),
173+
/// Lint: UNREADABLE_LITERAL. Should the fraction of a decimal be linted to include separators.
174+
(lint_fraction_readability, "lint_fraction_readability": bool, true),
173175
}
174176

175177
impl Default for Conf {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
lint-fraction-readability = false
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#[deny(clippy::unreadable_literal)]
2+
3+
fn allow_inconsistent_digit_grouping() {
4+
#![allow(clippy::inconsistent_digit_grouping)]
5+
let _pass1 = 100_200_300.123456789;
6+
}
7+
8+
fn main() {
9+
allow_inconsistent_digit_grouping();
10+
11+
let _pass1 = 100_200_300.100_200_300;
12+
let _pass2 = 1.123456789;
13+
let _pass3 = 1.0;
14+
let _pass4 = 10000.00001;
15+
let _pass5 = 1.123456789e1;
16+
17+
// due to clippy::inconsistent-digit-grouping
18+
let _fail1 = 100_200_300.123456789;
19+
20+
// fail due to the integer part
21+
let _fail2 = 100200300.300200100;
22+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: digits grouped inconsistently by underscores
2+
--> $DIR/test.rs:18:18
3+
|
4+
LL | let _fail1 = 100_200_300.123456789;
5+
| ^^^^^^^^^^^^^^^^^^^^^ help: consider: `100_200_300.123_456_789`
6+
|
7+
= note: `-D clippy::inconsistent-digit-grouping` implied by `-D warnings`
8+
9+
error: aborting due to previous error
10+
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `msrv`, `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `pass-by-value-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `disallowed-methods`, `third-party` at line 5 column 1
1+
error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `msrv`, `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `pass-by-value-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `disallowed-methods`, `lint-fraction-readability`, `third-party` at line 5 column 1
22

33
error: aborting due to previous error
44

tests/ui/unreadable_literal.fixed

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ macro_rules! foo {
1010
};
1111
}
1212

13+
struct Bar(f32);
14+
15+
macro_rules! bar {
16+
() => {
17+
Bar(100200300400.100200300400500)
18+
};
19+
}
20+
1321
fn main() {
1422
let _good = (
1523
0b1011_i64,
@@ -26,10 +34,12 @@ fn main() {
2634
let _good_sci = 1.1234e1;
2735
let _bad_sci = 1.123_456e1;
2836

29-
let _fail9 = 0x00ab_cdef;
30-
let _fail10: u32 = 0xBAFE_BAFE;
31-
let _fail11 = 0x0abc_deff;
32-
let _fail12: i128 = 0x00ab_cabc_abca_bcab_cabc;
37+
let _fail1 = 0x00ab_cdef;
38+
let _fail2: u32 = 0xBAFE_BAFE;
39+
let _fail3 = 0x0abc_deff;
40+
let _fail4: i128 = 0x00ab_cabc_abca_bcab_cabc;
41+
let _fail5 = 1.100_300_400;
3342

3443
let _ = foo!();
44+
let _ = bar!();
3545
}

tests/ui/unreadable_literal.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ macro_rules! foo {
1010
};
1111
}
1212

13+
struct Bar(f32);
14+
15+
macro_rules! bar {
16+
() => {
17+
Bar(100200300400.100200300400500)
18+
};
19+
}
20+
1321
fn main() {
1422
let _good = (
1523
0b1011_i64,
@@ -26,10 +34,12 @@ fn main() {
2634
let _good_sci = 1.1234e1;
2735
let _bad_sci = 1.123456e1;
2836

29-
let _fail9 = 0xabcdef;
30-
let _fail10: u32 = 0xBAFEBAFE;
31-
let _fail11 = 0xabcdeff;
32-
let _fail12: i128 = 0xabcabcabcabcabcabc;
37+
let _fail1 = 0xabcdef;
38+
let _fail2: u32 = 0xBAFEBAFE;
39+
let _fail3 = 0xabcdeff;
40+
let _fail4: i128 = 0xabcabcabcabcabcabc;
41+
let _fail5 = 1.100300400;
3342

3443
let _ = foo!();
44+
let _ = bar!();
3545
}

tests/ui/unreadable_literal.stderr

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,72 @@
11
error: digits of hex or binary literal not grouped by four
2-
--> $DIR/unreadable_literal.rs:17:9
2+
--> $DIR/unreadable_literal.rs:25:9
33
|
44
LL | 0x1_234_567,
55
| ^^^^^^^^^^^ help: consider: `0x0123_4567`
66
|
77
= note: `-D clippy::unusual-byte-groupings` implied by `-D warnings`
88

99
error: long literal lacking separators
10-
--> $DIR/unreadable_literal.rs:25:17
10+
--> $DIR/unreadable_literal.rs:33:17
1111
|
1212
LL | let _bad = (0b110110_i64, 0xcafebabe_usize, 123456_f32, 1.234567_f32);
1313
| ^^^^^^^^^^^^ help: consider: `0b11_0110_i64`
1414
|
1515
= note: `-D clippy::unreadable-literal` implied by `-D warnings`
1616

1717
error: long literal lacking separators
18-
--> $DIR/unreadable_literal.rs:25:31
18+
--> $DIR/unreadable_literal.rs:33:31
1919
|
2020
LL | let _bad = (0b110110_i64, 0xcafebabe_usize, 123456_f32, 1.234567_f32);
2121
| ^^^^^^^^^^^^^^^^ help: consider: `0xcafe_babe_usize`
2222

2323
error: long literal lacking separators
24-
--> $DIR/unreadable_literal.rs:25:49
24+
--> $DIR/unreadable_literal.rs:33:49
2525
|
2626
LL | let _bad = (0b110110_i64, 0xcafebabe_usize, 123456_f32, 1.234567_f32);
2727
| ^^^^^^^^^^ help: consider: `123_456_f32`
2828

2929
error: long literal lacking separators
30-
--> $DIR/unreadable_literal.rs:25:61
30+
--> $DIR/unreadable_literal.rs:33:61
3131
|
3232
LL | let _bad = (0b110110_i64, 0xcafebabe_usize, 123456_f32, 1.234567_f32);
3333
| ^^^^^^^^^^^^ help: consider: `1.234_567_f32`
3434

3535
error: long literal lacking separators
36-
--> $DIR/unreadable_literal.rs:27:20
36+
--> $DIR/unreadable_literal.rs:35:20
3737
|
3838
LL | let _bad_sci = 1.123456e1;
3939
| ^^^^^^^^^^ help: consider: `1.123_456e1`
4040

4141
error: long literal lacking separators
42-
--> $DIR/unreadable_literal.rs:29:18
42+
--> $DIR/unreadable_literal.rs:37:18
4343
|
44-
LL | let _fail9 = 0xabcdef;
44+
LL | let _fail1 = 0xabcdef;
4545
| ^^^^^^^^ help: consider: `0x00ab_cdef`
4646

4747
error: long literal lacking separators
48-
--> $DIR/unreadable_literal.rs:30:24
48+
--> $DIR/unreadable_literal.rs:38:23
4949
|
50-
LL | let _fail10: u32 = 0xBAFEBAFE;
51-
| ^^^^^^^^^^ help: consider: `0xBAFE_BAFE`
50+
LL | let _fail2: u32 = 0xBAFEBAFE;
51+
| ^^^^^^^^^^ help: consider: `0xBAFE_BAFE`
5252

5353
error: long literal lacking separators
54-
--> $DIR/unreadable_literal.rs:31:19
54+
--> $DIR/unreadable_literal.rs:39:18
5555
|
56-
LL | let _fail11 = 0xabcdeff;
57-
| ^^^^^^^^^ help: consider: `0x0abc_deff`
56+
LL | let _fail3 = 0xabcdeff;
57+
| ^^^^^^^^^ help: consider: `0x0abc_deff`
5858

5959
error: long literal lacking separators
60-
--> $DIR/unreadable_literal.rs:32:25
60+
--> $DIR/unreadable_literal.rs:40:24
6161
|
62-
LL | let _fail12: i128 = 0xabcabcabcabcabcabc;
63-
| ^^^^^^^^^^^^^^^^^^^^ help: consider: `0x00ab_cabc_abca_bcab_cabc`
62+
LL | let _fail4: i128 = 0xabcabcabcabcabcabc;
63+
| ^^^^^^^^^^^^^^^^^^^^ help: consider: `0x00ab_cabc_abca_bcab_cabc`
6464

65-
error: aborting due to 10 previous errors
65+
error: long literal lacking separators
66+
--> $DIR/unreadable_literal.rs:41:18
67+
|
68+
LL | let _fail5 = 1.100300400;
69+
| ^^^^^^^^^^^ help: consider: `1.100_300_400`
70+
71+
error: aborting due to 11 previous errors
6672

0 commit comments

Comments
 (0)