@@ -82,6 +82,25 @@ declare_clippy_lint! {
82
82
"integer literals with digits grouped inconsistently"
83
83
}
84
84
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
+
85
104
declare_clippy_lint ! {
86
105
/// **What it does:** Warns if the digits of an integral or floating-point
87
106
/// constant are grouped into groups that
@@ -125,6 +144,7 @@ enum WarningType {
125
144
LargeDigitGroups ,
126
145
DecimalRepresentation ,
127
146
MistypedLiteralSuffix ,
147
+ UnusualByteGroupings ,
128
148
}
129
149
130
150
impl WarningType {
@@ -175,6 +195,15 @@ impl WarningType {
175
195
suggested_format,
176
196
Applicability :: MachineApplicable ,
177
197
) ,
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
+ ) ,
178
207
} ;
179
208
}
180
209
}
@@ -184,6 +213,7 @@ declare_lint_pass!(LiteralDigitGrouping => [
184
213
INCONSISTENT_DIGIT_GROUPING ,
185
214
LARGE_DIGIT_GROUPS ,
186
215
MISTYPED_LITERAL_SUFFIXES ,
216
+ UNUSUAL_BYTE_GROUPINGS ,
187
217
] ) ;
188
218
189
219
impl EarlyLintPass for LiteralDigitGrouping {
@@ -217,9 +247,9 @@ impl LiteralDigitGrouping {
217
247
218
248
let result = ( || {
219
249
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 ) ?;
221
251
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 ) ?;
223
253
224
254
let consistent = Self :: parts_consistent( integral_group_size,
225
255
fractional_group_size,
@@ -229,6 +259,7 @@ impl LiteralDigitGrouping {
229
259
return Err ( WarningType :: InconsistentDigitGrouping ) ;
230
260
} ;
231
261
}
262
+
232
263
Ok ( ( ) )
233
264
} ) ( ) ;
234
265
@@ -237,6 +268,7 @@ impl LiteralDigitGrouping {
237
268
let should_warn = match warning_type {
238
269
| WarningType :: UnreadableLiteral
239
270
| WarningType :: InconsistentDigitGrouping
271
+ | WarningType :: UnusualByteGroupings
240
272
| WarningType :: LargeDigitGroups => {
241
273
!in_macro( lit. span)
242
274
}
@@ -331,11 +363,15 @@ impl LiteralDigitGrouping {
331
363
332
364
/// Returns the size of the digit groups (or None if ungrouped) if successful,
333
365
/// 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 > {
335
367
let mut groups = groups. map ( str:: len) ;
336
368
337
369
let first = groups. next ( ) . expect ( "At least one group" ) ;
338
370
371
+ if ( radix == Radix :: Binary || radix == Radix :: Hexadecimal ) && groups. any ( |i| i != 4 && i != 2 ) {
372
+ return Err ( WarningType :: UnusualByteGroupings ) ;
373
+ }
374
+
339
375
if let Some ( second) = groups. next ( ) {
340
376
if !groups. all ( |x| x == second) || first > second {
341
377
Err ( WarningType :: InconsistentDigitGrouping )
0 commit comments