Skip to content

Commit eceebc3

Browse files
committed
Auto merge of #6183 - cgm616:hex_bin_digit_grouping, r=flip1995
Hex bin digit grouping This revives and updates an old pr (#3391) for the current API. Closes #2538. --- *Please keep the line below* changelog: Add [`unusual_byte_groupings`] lint.
2 parents 4242ef8 + 312bbff commit eceebc3

11 files changed

+97
-17
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -2017,6 +2017,7 @@ Released 2018-09-13
20172017
[`unused_label`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_label
20182018
[`unused_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_self
20192019
[`unused_unit`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_unit
2020+
[`unusual_byte_groupings`]: https://rust-lang.github.io/rust-clippy/master/index.html#unusual_byte_groupings
20202021
[`unwrap_in_result`]: https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_in_result
20212022
[`unwrap_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used
20222023
[`use_debug`]: https://rust-lang.github.io/rust-clippy/master/index.html#use_debug

clippy_lints/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
623623
&literal_representation::LARGE_DIGIT_GROUPS,
624624
&literal_representation::MISTYPED_LITERAL_SUFFIXES,
625625
&literal_representation::UNREADABLE_LITERAL,
626+
&literal_representation::UNUSUAL_BYTE_GROUPINGS,
626627
&loops::EMPTY_LOOP,
627628
&loops::EXPLICIT_COUNTER_LOOP,
628629
&loops::EXPLICIT_INTO_ITER_LOOP,
@@ -1365,6 +1366,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
13651366
LintId::of(&lifetimes::NEEDLESS_LIFETIMES),
13661367
LintId::of(&literal_representation::INCONSISTENT_DIGIT_GROUPING),
13671368
LintId::of(&literal_representation::MISTYPED_LITERAL_SUFFIXES),
1369+
LintId::of(&literal_representation::UNUSUAL_BYTE_GROUPINGS),
13681370
LintId::of(&loops::EMPTY_LOOP),
13691371
LintId::of(&loops::EXPLICIT_COUNTER_LOOP),
13701372
LintId::of(&loops::FOR_KV_MAP),
@@ -1587,6 +1589,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
15871589
LintId::of(&len_zero::LEN_WITHOUT_IS_EMPTY),
15881590
LintId::of(&len_zero::LEN_ZERO),
15891591
LintId::of(&literal_representation::INCONSISTENT_DIGIT_GROUPING),
1592+
LintId::of(&literal_representation::UNUSUAL_BYTE_GROUPINGS),
15901593
LintId::of(&loops::EMPTY_LOOP),
15911594
LintId::of(&loops::FOR_KV_MAP),
15921595
LintId::of(&loops::NEEDLESS_RANGE_LOOP),

clippy_lints/src/literal_representation.rs

+39-3
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,25 @@ declare_clippy_lint! {
8282
"integer literals with digits grouped inconsistently"
8383
}
8484

85+
declare_clippy_lint! {
86+
/// **What it does:** Warns if hexadecimal or binary literals are not grouped
87+
/// by nibble or byte.
88+
///
89+
/// **Why is this bad?** Negatively impacts readability.
90+
///
91+
/// **Known problems:** None.
92+
///
93+
/// **Example:**
94+
///
95+
/// ```rust
96+
/// let x: u32 = 0xFFF_FFF;
97+
/// let y: u8 = 0b01_011_101;
98+
/// ```
99+
pub UNUSUAL_BYTE_GROUPINGS,
100+
style,
101+
"binary or hex literals that aren't grouped by four"
102+
}
103+
85104
declare_clippy_lint! {
86105
/// **What it does:** Warns if the digits of an integral or floating-point
87106
/// constant are grouped into groups that
@@ -125,6 +144,7 @@ enum WarningType {
125144
LargeDigitGroups,
126145
DecimalRepresentation,
127146
MistypedLiteralSuffix,
147+
UnusualByteGroupings,
128148
}
129149

130150
impl WarningType {
@@ -175,6 +195,15 @@ impl WarningType {
175195
suggested_format,
176196
Applicability::MachineApplicable,
177197
),
198+
Self::UnusualByteGroupings => span_lint_and_sugg(
199+
cx,
200+
UNUSUAL_BYTE_GROUPINGS,
201+
span,
202+
"digits of hex or binary literal not grouped by four",
203+
"consider",
204+
suggested_format,
205+
Applicability::MachineApplicable,
206+
),
178207
};
179208
}
180209
}
@@ -184,6 +213,7 @@ declare_lint_pass!(LiteralDigitGrouping => [
184213
INCONSISTENT_DIGIT_GROUPING,
185214
LARGE_DIGIT_GROUPS,
186215
MISTYPED_LITERAL_SUFFIXES,
216+
UNUSUAL_BYTE_GROUPINGS,
187217
]);
188218

189219
impl EarlyLintPass for LiteralDigitGrouping {
@@ -217,9 +247,9 @@ impl LiteralDigitGrouping {
217247

218248
let result = (|| {
219249

220-
let integral_group_size = Self::get_group_size(num_lit.integer.split('_'))?;
250+
let integral_group_size = Self::get_group_size(num_lit.integer.split('_'), num_lit.radix)?;
221251
if let Some(fraction) = num_lit.fraction {
222-
let fractional_group_size = Self::get_group_size(fraction.rsplit('_'))?;
252+
let fractional_group_size = Self::get_group_size(fraction.rsplit('_'), num_lit.radix)?;
223253

224254
let consistent = Self::parts_consistent(integral_group_size,
225255
fractional_group_size,
@@ -229,6 +259,7 @@ impl LiteralDigitGrouping {
229259
return Err(WarningType::InconsistentDigitGrouping);
230260
};
231261
}
262+
232263
Ok(())
233264
})();
234265

@@ -237,6 +268,7 @@ impl LiteralDigitGrouping {
237268
let should_warn = match warning_type {
238269
| WarningType::UnreadableLiteral
239270
| WarningType::InconsistentDigitGrouping
271+
| WarningType::UnusualByteGroupings
240272
| WarningType::LargeDigitGroups => {
241273
!in_macro(lit.span)
242274
}
@@ -331,11 +363,15 @@ impl LiteralDigitGrouping {
331363

332364
/// Returns the size of the digit groups (or None if ungrouped) if successful,
333365
/// otherwise returns a `WarningType` for linting.
334-
fn get_group_size<'a>(groups: impl Iterator<Item = &'a str>) -> Result<Option<usize>, WarningType> {
366+
fn get_group_size<'a>(groups: impl Iterator<Item = &'a str>, radix: Radix) -> Result<Option<usize>, WarningType> {
335367
let mut groups = groups.map(str::len);
336368

337369
let first = groups.next().expect("At least one group");
338370

371+
if (radix == Radix::Binary || radix == Radix::Hexadecimal) && groups.any(|i| i != 4 && i != 2) {
372+
return Err(WarningType::UnusualByteGroupings);
373+
}
374+
339375
if let Some(second) = groups.next() {
340376
if !groups.all(|x| x == second) || first > second {
341377
Err(WarningType::InconsistentDigitGrouping)

clippy_lints/src/utils/numeric_literal.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_ast::ast::{Lit, LitFloatType, LitIntType, LitKind};
22

3-
#[derive(Debug, PartialEq)]
3+
#[derive(Debug, PartialEq, Copy, Clone)]
44
pub enum Radix {
55
Binary,
66
Octal,
@@ -11,8 +11,8 @@ pub enum Radix {
1111
impl Radix {
1212
/// Returns a reasonable digit group size for this radix.
1313
#[must_use]
14-
fn suggest_grouping(&self) -> usize {
15-
match *self {
14+
fn suggest_grouping(self) -> usize {
15+
match self {
1616
Self::Binary | Self::Hexadecimal => 4,
1717
Self::Octal | Self::Decimal => 3,
1818
}

src/lintlist/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -2643,6 +2643,13 @@ vec![
26432643
deprecation: None,
26442644
module: "unused_unit",
26452645
},
2646+
Lint {
2647+
name: "unusual_byte_groupings",
2648+
group: "style",
2649+
desc: "binary or hex literals that aren\'t grouped by four",
2650+
deprecation: None,
2651+
module: "literal_representation",
2652+
},
26462653
Lint {
26472654
name: "unwrap_in_result",
26482655
group: "restriction",

tests/ui/large_digit_groups.fixed

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ fn main() {
1111
let _good = (
1212
0b1011_i64,
1313
0o1_234_u32,
14-
0x1_234_567,
14+
0x0123_4567,
1515
1_2345_6789,
1616
1234_f32,
1717
1_234.12_f32,

tests/ui/large_digit_groups.stderr

+13-7
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,30 @@
1-
error: digit groups should be smaller
1+
error: digits of hex or binary literal not grouped by four
2+
--> $DIR/large_digit_groups.rs:14:9
3+
|
4+
LL | 0x1_234_567,
5+
| ^^^^^^^^^^^ help: consider: `0x0123_4567`
6+
|
7+
= note: `-D clippy::unusual-byte-groupings` implied by `-D warnings`
8+
9+
error: digits of hex or binary literal not grouped by four
210
--> $DIR/large_digit_groups.rs:22:9
311
|
412
LL | 0b1_10110_i64,
513
| ^^^^^^^^^^^^^ help: consider: `0b11_0110_i64`
6-
|
7-
= note: `-D clippy::large-digit-groups` implied by `-D warnings`
814

9-
error: digits grouped inconsistently by underscores
15+
error: digits of hex or binary literal not grouped by four
1016
--> $DIR/large_digit_groups.rs:23:9
1117
|
1218
LL | 0xd_e_adbee_f_usize,
1319
| ^^^^^^^^^^^^^^^^^^^ help: consider: `0xdead_beef_usize`
14-
|
15-
= note: `-D clippy::inconsistent-digit-grouping` implied by `-D warnings`
1620

1721
error: digit groups should be smaller
1822
--> $DIR/large_digit_groups.rs:24:9
1923
|
2024
LL | 1_23456_f32,
2125
| ^^^^^^^^^^^ help: consider: `123_456_f32`
26+
|
27+
= note: `-D clippy::large-digit-groups` implied by `-D warnings`
2228

2329
error: digit groups should be smaller
2430
--> $DIR/large_digit_groups.rs:25:9
@@ -38,5 +44,5 @@ error: digit groups should be smaller
3844
LL | 1_23456.12345_6_f64,
3945
| ^^^^^^^^^^^^^^^^^^^ help: consider: `123_456.123_456_f64`
4046

41-
error: aborting due to 6 previous errors
47+
error: aborting due to 7 previous errors
4248

tests/ui/literals.rs

+5
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,9 @@ fn main() {
3333
let fail19 = 12_3456_21;
3434
let fail22 = 3__4___23;
3535
let fail23 = 3__16___23;
36+
37+
let fail24 = 0xAB_ABC_AB;
38+
let fail25 = 0b01_100_101;
39+
let ok26 = 0x6_A0_BF;
40+
let ok27 = 0b1_0010_0101;
3641
}

tests/ui/literals.stderr

+15-1
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,19 @@ error: digits grouped inconsistently by underscores
6969
LL | let fail23 = 3__16___23;
7070
| ^^^^^^^^^^ help: consider: `31_623`
7171

72-
error: aborting due to 8 previous errors
72+
error: digits of hex or binary literal not grouped by four
73+
--> $DIR/literals.rs:37:18
74+
|
75+
LL | let fail24 = 0xAB_ABC_AB;
76+
| ^^^^^^^^^^^ help: consider: `0x0ABA_BCAB`
77+
|
78+
= note: `-D clippy::unusual-byte-groupings` implied by `-D warnings`
79+
80+
error: digits of hex or binary literal not grouped by four
81+
--> $DIR/literals.rs:38:18
82+
|
83+
LL | let fail25 = 0b01_100_101;
84+
| ^^^^^^^^^^^^ help: consider: `0b0110_0101`
85+
86+
error: aborting due to 10 previous errors
7387

tests/ui/unreadable_literal.fixed

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ fn main() {
1414
let _good = (
1515
0b1011_i64,
1616
0o1_234_u32,
17-
0x1_234_567,
17+
0x0123_4567,
1818
65536,
1919
1_2345_6789,
2020
1234_f32,

tests/ui/unreadable_literal.stderr

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
error: digits of hex or binary literal not grouped by four
2+
--> $DIR/unreadable_literal.rs:17:9
3+
|
4+
LL | 0x1_234_567,
5+
| ^^^^^^^^^^^ help: consider: `0x0123_4567`
6+
|
7+
= note: `-D clippy::unusual-byte-groupings` implied by `-D warnings`
8+
19
error: long literal lacking separators
210
--> $DIR/unreadable_literal.rs:25:17
311
|
@@ -54,5 +62,5 @@ error: long literal lacking separators
5462
LL | let _fail12: i128 = 0xabcabcabcabcabcabc;
5563
| ^^^^^^^^^^^^^^^^^^^^ help: consider: `0x00ab_cabc_abca_bcab_cabc`
5664

57-
error: aborting due to 9 previous errors
65+
error: aborting due to 10 previous errors
5866

0 commit comments

Comments
 (0)