]> git.lizzy.rs Git - rust.git/commitdiff
Lint literal suffixes not separated by underscores (see #703)
authorGeorg Brandl <georg@python.org>
Fri, 5 Aug 2016 16:50:02 +0000 (18:50 +0200)
committerGeorg Brandl <georg@python.org>
Fri, 5 Aug 2016 16:50:23 +0000 (18:50 +0200)
CHANGELOG.md
README.md
clippy_lints/src/lib.rs
clippy_lints/src/misc_early.rs
tests/compile-fail/doc.rs [changed mode: 0755->0644]
tests/compile-fail/entry.rs [changed mode: 0755->0644]
tests/compile-fail/filter_methods.rs
tests/compile-fail/if_not_else.rs [changed mode: 0755->0644]
tests/compile-fail/literals.rs [changed mode: 0755->0644]
tests/compile-fail/shadow.rs

index 4081d3d25c057bba63c9058e627a2b39582be4bf..d83611f1fd30d2c3c11972c555e7f198d77895a1 100644 (file)
@@ -281,6 +281,7 @@ All notable changes to this project will be documented in this file.
 [`unnecessary_operation`]: https://github.com/Manishearth/rust-clippy/wiki#unnecessary_operation
 [`unneeded_field_pattern`]: https://github.com/Manishearth/rust-clippy/wiki#unneeded_field_pattern
 [`unsafe_removed_from_name`]: https://github.com/Manishearth/rust-clippy/wiki#unsafe_removed_from_name
+[`unseparated_literal_suffix`]: https://github.com/Manishearth/rust-clippy/wiki#unseparated_literal_suffix
 [`unstable_as_mut_slice`]: https://github.com/Manishearth/rust-clippy/wiki#unstable_as_mut_slice
 [`unstable_as_slice`]: https://github.com/Manishearth/rust-clippy/wiki#unstable_as_slice
 [`unused_collect`]: https://github.com/Manishearth/rust-clippy/wiki#unused_collect
index 7edb751fb449f667c12c71283fbf2b9839851fea..0c8e391121984f06be79b32f06e3896c22f9c3e8 100644 (file)
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ Table of contents:
 
 ## Lints
 
-There are 161 lints included in this crate:
+There are 162 lints included in this crate:
 
 name                                                                                                                 | default | meaning
 ---------------------------------------------------------------------------------------------------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -166,6 +166,7 @@ name
 [unnecessary_operation](https://github.com/Manishearth/rust-clippy/wiki#unnecessary_operation)                       | warn    | outer expressions with no effect
 [unneeded_field_pattern](https://github.com/Manishearth/rust-clippy/wiki#unneeded_field_pattern)                     | warn    | Struct fields are bound to a wildcard instead of using `..`
 [unsafe_removed_from_name](https://github.com/Manishearth/rust-clippy/wiki#unsafe_removed_from_name)                 | warn    | unsafe removed from name
+[unseparated_literal_suffix](https://github.com/Manishearth/rust-clippy/wiki#unseparated_literal_suffix)             | allow   | literal suffixes should be separated with an underscore
 [unused_collect](https://github.com/Manishearth/rust-clippy/wiki#unused_collect)                                     | warn    | `collect()`ing an iterator without using the result; this is usually better written as a for loop
 [unused_label](https://github.com/Manishearth/rust-clippy/wiki#unused_label)                                         | warn    | unused label
 [unused_lifetimes](https://github.com/Manishearth/rust-clippy/wiki#unused_lifetimes)                                 | warn    | unused lifetimes in function definitions
index eaac42c5c175ddff20ec4fcf0a2b5628659531a0..08f5e6b242db9450702767e741906ec472b4555e 100644 (file)
@@ -277,6 +277,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
         methods::RESULT_UNWRAP_USED,
         methods::WRONG_PUB_SELF_CONVENTION,
         misc::USED_UNDERSCORE_BINDING,
+        misc_early::UNSEPARATED_LITERAL_SUFFIX,
         mut_mut::MUT_MUT,
         mutex_atomic::MUTEX_INTEGER,
         non_expressive_names::SIMILAR_NAMES,
index 2d6b0a357da55b64a48bc6ddb182b521f74952ae..2c058f3bcc293306ad561c9fdd51ff67c3efc05a 100644 (file)
@@ -1,5 +1,6 @@
 use rustc::lint::*;
 use std::collections::HashMap;
+use std::char;
 use syntax::ast::*;
 use syntax::codemap::Span;
 use syntax::visit::FnKind;
     "letter digits in hex literals should be either completely upper- or lowercased"
 }
 
+/// **What it does:** Warns if literal suffixes are not separated by an underscore.
+///
+/// **Why is this bad?** It is much less readable.
+///
+/// **Known problems:** None.
+///
+/// **Example:**
+/// ```rust
+/// let y = 123832i32;
+/// ```
+declare_lint! {
+    pub UNSEPARATED_LITERAL_SUFFIX, Allow,
+    "literal suffixes should be separated with an underscore"
+}
+
 
 #[derive(Copy, Clone)]
 pub struct MiscEarly;
 impl LintPass for MiscEarly {
     fn get_lints(&self) -> LintArray {
         lint_array!(UNNEEDED_FIELD_PATTERN, DUPLICATE_UNDERSCORE_ARGUMENT, REDUNDANT_CLOSURE_CALL,
-                    DOUBLE_NEG, MIXED_CASE_HEX_LITERALS)
+                    DOUBLE_NEG, MIXED_CASE_HEX_LITERALS, UNSEPARATED_LITERAL_SUFFIX)
     }
 }
 
@@ -196,20 +212,52 @@ fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) {
                 if_let_chain! {[
                     let LitKind::Int(..) = lit.node,
                     let Some(src) = snippet_opt(cx, lit.span),
-                    src.starts_with("0x")
+                    let Some(firstch) = src.chars().next(),
+                    char::to_digit(firstch, 10).is_some()
                 ], {
-                    let mut seen = (false, false);
+                    let mut prev = '\0';
                     for ch in src.chars() {
-                        match ch {
-                            'a' ... 'f' => seen.0 = true,
-                            'A' ... 'F' => seen.1 = true,
-                            'i' | 'u'   => break,   // start of suffix already
-                            _ => ()
+                        if ch == 'i' || ch == 'u' {
+                            if prev != '_' {
+                                span_lint(cx, UNSEPARATED_LITERAL_SUFFIX, lit.span,
+                                          "integer type suffix should be separated by an underscore");
+                            }
+                            break;
                         }
+                        prev = ch;
                     }
-                    if seen.0 && seen.1 {
-                        span_lint(cx, MIXED_CASE_HEX_LITERALS, lit.span,
-                                  "inconsistent casing in hexadecimal literal");
+                    if src.starts_with("0x") {
+                        let mut seen = (false, false);
+                        for ch in src.chars() {
+                            match ch {
+                                'a' ... 'f' => seen.0 = true,
+                                'A' ... 'F' => seen.1 = true,
+                                'i' | 'u'   => break,   // start of suffix already
+                                _ => ()
+                            }
+                        }
+                        if seen.0 && seen.1 {
+                            span_lint(cx, MIXED_CASE_HEX_LITERALS, lit.span,
+                                      "inconsistent casing in hexadecimal literal");
+                        }
+                    }
+                }}
+                if_let_chain! {[
+                    let LitKind::Float(..) = lit.node,
+                    let Some(src) = snippet_opt(cx, lit.span),
+                    let Some(firstch) = src.chars().next(),
+                    char::to_digit(firstch, 10).is_some()
+                ], {
+                    let mut prev = '\0';
+                    for ch in src.chars() {
+                        if ch == 'f' {
+                            if prev != '_' {
+                                span_lint(cx, UNSEPARATED_LITERAL_SUFFIX, lit.span,
+                                          "float type suffix should be separated by an underscore");
+                            }
+                            break;
+                        }
+                        prev = ch;
                     }
                 }}
             }
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index 743c3c15aeb82cbbf83693c2947c796861e1cf1c..bee9688f58144c5bc5209f40daf348d2d139d5fa 100644 (file)
@@ -8,17 +8,17 @@ fn main() {
                               .map(|x| x * 2)
                               .collect();
 
-    let _: Vec<_> = vec![5i8; 6].into_iter() //~ERROR called `filter(p).flat_map(q)` on an `Iterator`
+    let _: Vec<_> = vec![5_i8; 6].into_iter() //~ERROR called `filter(p).flat_map(q)` on an `Iterator`
                                 .filter(|&x| x == 0)
                                 .flat_map(|x| x.checked_mul(2))
                                 .collect();
 
-    let _: Vec<_> = vec![5i8; 6].into_iter() //~ERROR called `filter_map(p).flat_map(q)` on an `Iterator`
+    let _: Vec<_> = vec![5_i8; 6].into_iter() //~ERROR called `filter_map(p).flat_map(q)` on an `Iterator`
                                 .filter_map(|x| x.checked_mul(2))
                                 .flat_map(|x| x.checked_mul(2))
                                 .collect();
 
-    let _: Vec<_> = vec![5i8; 6].into_iter() //~ERROR called `filter_map(p).map(q)` on an `Iterator`
+    let _: Vec<_> = vec![5_i8; 6].into_iter() //~ERROR called `filter_map(p).map(q)` on an `Iterator`
                                 .filter_map(|x| x.checked_mul(2))
                                 .map(|x| x.checked_mul(2))
                                 .collect();
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index fb031ea..7645fb5
@@ -1,6 +1,7 @@
 #![feature(plugin)]
 #![plugin(clippy)]
 #![deny(mixed_case_hex_literals)]
+#![deny(unseparated_literal_suffix)]
 #![allow(dead_code)]
 
 fn main() {
@@ -12,4 +13,13 @@ fn main() {
     let fail1 = 0xabCD;       //~ERROR inconsistent casing in hexadecimal literal
     let fail2 = 0xabCD_u32;   //~ERROR inconsistent casing in hexadecimal literal
     let fail2 = 0xabCD_isize; //~ERROR inconsistent casing in hexadecimal literal
+
+    let ok6 = 1234_i32;
+    let ok7 = 1234_f32;
+    let ok8 = 1234_isize;
+    let fail3 = 1234i32;      //~ERROR integer type suffix should be separated
+    let fail4 = 1234u32;      //~ERROR integer type suffix should be separated
+    let fail5 = 1234isize;    //~ERROR integer type suffix should be separated
+    let fail6 = 1234usize;    //~ERROR integer type suffix should be separated
+    let fail7 = 1.5f32;       //~ERROR float type suffix should be separated
 }
index 1cfcff74a44c091b33851f2dee10782838f38019..1200e25cdbcea4689505d08a66bee2da2119649c 100644 (file)
@@ -20,7 +20,7 @@ fn main() {
     let y = 1;
     let x = y; //~ERROR `x` is shadowed by `y`
 
-    let o = Some(1u8);
+    let o = Some(1_u8);
 
     if let Some(p) = o { assert_eq!(1, p); }
     match o {