@@ -9,12 +9,12 @@ mod zero_prefixed_literal;
9
9
10
10
use clippy_utils:: diagnostics:: span_lint;
11
11
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 } ;
13
13
use rustc_ast:: visit:: FnKind ;
14
14
use rustc_data_structures:: fx:: FxHashMap ;
15
15
use rustc_lint:: { EarlyContext , EarlyLintPass } ;
16
16
use rustc_middle:: lint:: in_external_macro;
17
- use rustc_session:: { declare_lint_pass , declare_tool_lint } ;
17
+ use rustc_session:: { declare_tool_lint , impl_lint_pass } ;
18
18
use rustc_span:: source_map:: Span ;
19
19
20
20
declare_clippy_lint ! {
@@ -113,20 +113,35 @@ declare_clippy_lint! {
113
113
114
114
declare_clippy_lint ! {
115
115
/// ### What it does
116
- /// Warns if literal suffixes are not separated by an
117
- /// underscore.
116
+ /// If `literal-suffix-stylle` = "separated", warns literal suffixes that are not separated by an
117
+ /// underscore
118
+ /// e.g `123i32`
118
119
///
119
- /// ### Why is this bad?
120
- /// It is much less readable.
120
+ /// If `literal-suffix-style` = "unseparated", warns literal suffixes that are separated by an
121
+ /// underscore
122
+ /// e.g. `123_i32`
123
+ ///
124
+ /// else, any style of literal_suffix is allowed
121
125
///
122
126
/// ### Example
127
+ ///
128
+ /// #### "separated"
123
129
/// ```rust
124
130
/// // Bad
125
131
/// let y = 123832i32;
126
132
///
127
133
/// // Good
128
134
/// let y = 123832_i32;
129
135
/// ```
136
+ ///
137
+ /// #### "unseparated"
138
+ /// ```rust
139
+ /// // Bad
140
+ /// let y = 123832_i32;
141
+ ///
142
+ /// // Good
143
+ /// let y = 123832i32;
144
+ /// ```
130
145
pub UNSEPARATED_LITERAL_SUFFIX ,
131
146
restriction,
132
147
"literals whose suffix is not separated by an underscore"
@@ -254,7 +269,12 @@ declare_clippy_lint! {
254
269
"tuple patterns with a wildcard pattern (`_`) is next to a rest pattern (`..`)"
255
270
}
256
271
257
- declare_lint_pass ! ( MiscEarlyLints => [
272
+ #[ allow( clippy:: module_name_repetitions) ]
273
+ pub struct MiscEarlyLints {
274
+ literal_suffix_style : Option < LiteralSuffixStyle > ,
275
+ }
276
+
277
+ impl_lint_pass ! ( MiscEarlyLints => [
258
278
UNNEEDED_FIELD_PATTERN ,
259
279
DUPLICATE_UNDERSCORE_ARGUMENT ,
260
280
DOUBLE_NEG ,
@@ -310,12 +330,29 @@ impl EarlyLintPass for MiscEarlyLints {
310
330
if in_external_macro ( cx. sess , expr. span ) {
311
331
return ;
312
332
}
333
+
334
+ if let ExprKind :: Lit ( ref lit) = expr. kind {
335
+ self . check_lit ( cx, lit) ;
336
+ }
313
337
double_neg:: check ( cx, expr) ;
314
338
}
315
339
}
316
340
317
341
impl MiscEarlyLints {
318
- fn check_lit ( cx : & EarlyContext < ' _ > , lit : & Lit ) {
342
+ pub fn new ( suffix_style : Option < String > ) -> Self {
343
+ let literal_suffix_style = match suffix_style {
344
+ Some ( style) => match style. as_str ( ) {
345
+ "unseparated" => Some ( LiteralSuffixStyle :: Unseparated ) ,
346
+ "separated" => Some ( LiteralSuffixStyle :: Separated ) ,
347
+ _ => None ,
348
+ } ,
349
+ _ => None ,
350
+ } ;
351
+
352
+ Self { literal_suffix_style }
353
+ }
354
+
355
+ fn check_lit ( & self , cx : & EarlyContext < ' _ > , lit : & Lit ) {
319
356
// We test if first character in snippet is a number, because the snippet could be an expansion
320
357
// from a built-in macro like `line!()` or a proc-macro like `#[wasm_bindgen]`.
321
358
// Note that this check also covers special case that `line!()` is eagerly expanded by compiler.
@@ -332,7 +369,7 @@ impl MiscEarlyLints {
332
369
LitIntType :: Unsigned ( ty) => ty. name_str ( ) ,
333
370
LitIntType :: Unsuffixed => "" ,
334
371
} ;
335
- unseparated_literal_suffix:: check ( cx, lit, & lit_snip, suffix, "integer" ) ;
372
+ unseparated_literal_suffix:: check ( cx, lit, & lit_snip, suffix, "integer" , self . literal_suffix_style ) ;
336
373
if lit_snip. starts_with ( "0x" ) {
337
374
mixed_case_hex_literals:: check ( cx, lit, suffix, & lit_snip) ;
338
375
} else if lit_snip. starts_with ( "0b" ) || lit_snip. starts_with ( "0o" ) {
@@ -342,7 +379,13 @@ impl MiscEarlyLints {
342
379
}
343
380
} else if let LitKind :: Float ( _, LitFloatType :: Suffixed ( float_ty) ) = lit. kind {
344
381
let suffix = float_ty. name_str ( ) ;
345
- unseparated_literal_suffix:: check ( cx, lit, & lit_snip, suffix, "float" ) ;
382
+ unseparated_literal_suffix:: check ( cx, lit, & lit_snip, suffix, "float" , self . literal_suffix_style ) ;
346
383
}
347
384
}
348
385
}
386
+
387
+ #[ derive( Copy , Clone ) ]
388
+ enum LiteralSuffixStyle {
389
+ Unseparated ,
390
+ Separated ,
391
+ }
0 commit comments