about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--clippy_lints/src/lib.register_lints.rs1
-rw-r--r--clippy_lints/src/lib.register_pedantic.rs1
-rw-r--r--clippy_lints/src/lib.register_restriction.rs2
-rw-r--r--clippy_lints/src/misc_early/double_neg.rs23
-rw-r--r--clippy_lints/src/misc_early/literal_suffix.rs38
-rw-r--r--clippy_lints/src/misc_early/mod.rs41
-rw-r--r--clippy_lints/src/misc_early/unseparated_literal_suffix.rs26
-rw-r--r--tests/ui/literals.rs3
-rw-r--r--tests/ui/literals.stderr74
10 files changed, 151 insertions, 59 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c78aa5908de..85a6a6be8b7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3123,6 +3123,7 @@ Released 2018-09-13
 [`self_named_constructors`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_named_constructors
 [`self_named_module_files`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_named_module_files
 [`semicolon_if_nothing_returned`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
+[`separated_literal_suffix`]: https://rust-lang.github.io/rust-clippy/master/index.html#separated_literal_suffix
 [`serde_api_misuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#serde_api_misuse
 [`shadow_reuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_reuse
 [`shadow_same`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_same
diff --git a/clippy_lints/src/lib.register_lints.rs b/clippy_lints/src/lib.register_lints.rs
index 9b210791574..2cb86418e3c 100644
--- a/clippy_lints/src/lib.register_lints.rs
+++ b/clippy_lints/src/lib.register_lints.rs
@@ -327,6 +327,7 @@ store.register_lints(&[
     misc_early::DUPLICATE_UNDERSCORE_ARGUMENT,
     misc_early::MIXED_CASE_HEX_LITERALS,
     misc_early::REDUNDANT_PATTERN,
+    misc_early::SEPARATED_LITERAL_SUFFIX,
     misc_early::UNNEEDED_FIELD_PATTERN,
     misc_early::UNNEEDED_WILDCARD_PATTERN,
     misc_early::UNSEPARATED_LITERAL_SUFFIX,
diff --git a/clippy_lints/src/lib.register_pedantic.rs b/clippy_lints/src/lib.register_pedantic.rs
index 63ab7f1ca6f..1008ca29e73 100644
--- a/clippy_lints/src/lib.register_pedantic.rs
+++ b/clippy_lints/src/lib.register_pedantic.rs
@@ -66,7 +66,6 @@ store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), vec![
     LintId::of(methods::MAP_UNWRAP_OR),
     LintId::of(misc::FLOAT_CMP),
     LintId::of(misc::USED_UNDERSCORE_BINDING),
-    LintId::of(misc_early::UNSEPARATED_LITERAL_SUFFIX),
     LintId::of(mut_mut::MUT_MUT),
     LintId::of(needless_bitwise_bool::NEEDLESS_BITWISE_BOOL),
     LintId::of(needless_borrow::REF_BINDING_TO_REFERENCE),
diff --git a/clippy_lints/src/lib.register_restriction.rs b/clippy_lints/src/lib.register_restriction.rs
index 4929bbecde0..bd416a4979b 100644
--- a/clippy_lints/src/lib.register_restriction.rs
+++ b/clippy_lints/src/lib.register_restriction.rs
@@ -35,7 +35,9 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
     LintId::of(methods::GET_UNWRAP),
     LintId::of(methods::UNWRAP_USED),
     LintId::of(misc::FLOAT_CMP_CONST),
+    LintId::of(misc_early::SEPARATED_LITERAL_SUFFIX),
     LintId::of(misc_early::UNNEEDED_FIELD_PATTERN),
+    LintId::of(misc_early::UNSEPARATED_LITERAL_SUFFIX),
     LintId::of(missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS),
     LintId::of(missing_enforced_import_rename::MISSING_ENFORCED_IMPORT_RENAMES),
     LintId::of(missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS),
diff --git a/clippy_lints/src/misc_early/double_neg.rs b/clippy_lints/src/misc_early/double_neg.rs
index 6f65778e119..06ba968fa4e 100644
--- a/clippy_lints/src/misc_early/double_neg.rs
+++ b/clippy_lints/src/misc_early/double_neg.rs
@@ -1,4 +1,3 @@
-use super::MiscEarlyLints;
 use clippy_utils::diagnostics::span_lint;
 use rustc_ast::ast::{Expr, ExprKind, UnOp};
 use rustc_lint::EarlyContext;
@@ -6,18 +5,14 @@ use rustc_lint::EarlyContext;
 use super::DOUBLE_NEG;
 
 pub(super) fn check(cx: &EarlyContext<'_>, expr: &Expr) {
-    match expr.kind {
-        ExprKind::Unary(UnOp::Neg, ref inner) => {
-            if let ExprKind::Unary(UnOp::Neg, _) = inner.kind {
-                span_lint(
-                    cx,
-                    DOUBLE_NEG,
-                    expr.span,
-                    "`--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op",
-                );
-            }
-        },
-        ExprKind::Lit(ref lit) => MiscEarlyLints::check_lit(cx, lit),
-        _ => (),
+    if let ExprKind::Unary(UnOp::Neg, ref inner) = expr.kind {
+        if let ExprKind::Unary(UnOp::Neg, _) = inner.kind {
+            span_lint(
+                cx,
+                DOUBLE_NEG,
+                expr.span,
+                "`--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op",
+            );
+        }
     }
 }
diff --git a/clippy_lints/src/misc_early/literal_suffix.rs b/clippy_lints/src/misc_early/literal_suffix.rs
new file mode 100644
index 00000000000..1165c19a0cf
--- /dev/null
+++ b/clippy_lints/src/misc_early/literal_suffix.rs
@@ -0,0 +1,38 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use rustc_ast::ast::Lit;
+use rustc_errors::Applicability;
+use rustc_lint::EarlyContext;
+
+use super::{SEPARATED_LITERAL_SUFFIX, UNSEPARATED_LITERAL_SUFFIX};
+
+pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str, suffix: &str, sugg_type: &str) {
+    let maybe_last_sep_idx = if let Some(val) = lit_snip.len().checked_sub(suffix.len() + 1) {
+        val
+    } else {
+        return; // It's useless so shouldn't lint.
+    };
+    // Do not lint when literal is unsuffixed.
+    if !suffix.is_empty() {
+        if lit_snip.as_bytes()[maybe_last_sep_idx] == b'_' {
+            span_lint_and_sugg(
+                cx,
+                SEPARATED_LITERAL_SUFFIX,
+                lit.span,
+                &format!("{} type suffix should not be separated by an underscore", sugg_type),
+                "remove the underscore",
+                format!("{}{}", &lit_snip[..maybe_last_sep_idx], suffix),
+                Applicability::MachineApplicable,
+            );
+        } else {
+            span_lint_and_sugg(
+                cx,
+                UNSEPARATED_LITERAL_SUFFIX,
+                lit.span,
+                &format!("{} type suffix should be separated by an underscore", sugg_type),
+                "add an underscore",
+                format!("{}_{}", &lit_snip[..=maybe_last_sep_idx], suffix),
+                Applicability::MachineApplicable,
+            );
+        }
+    }
+}
diff --git a/clippy_lints/src/misc_early/mod.rs b/clippy_lints/src/misc_early/mod.rs
index b32feab4ee3..7c3f5f22ade 100644
--- a/clippy_lints/src/misc_early/mod.rs
+++ b/clippy_lints/src/misc_early/mod.rs
@@ -1,15 +1,15 @@
 mod builtin_type_shadow;
 mod double_neg;
+mod literal_suffix;
 mod mixed_case_hex_literals;
 mod redundant_pattern;
 mod unneeded_field_pattern;
 mod unneeded_wildcard_pattern;
-mod unseparated_literal_suffix;
 mod zero_prefixed_literal;
 
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::source::snippet_opt;
-use rustc_ast::ast::{Expr, Generics, Lit, LitFloatType, LitIntType, LitKind, NodeId, Pat, PatKind};
+use rustc_ast::ast::{Expr, ExprKind, Generics, Lit, LitFloatType, LitIntType, LitKind, NodeId, Pat, PatKind};
 use rustc_ast::visit::FnKind;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_lint::{EarlyContext, EarlyLintPass};
@@ -115,9 +115,11 @@ declare_clippy_lint! {
     /// ### What it does
     /// Warns if literal suffixes are not separated by an
     /// underscore.
+    /// To enforce unseparated literal suffix style,
+    /// see the `separated_literal_suffix` lint.
     ///
     /// ### Why is this bad?
-    /// It is much less readable.
+    /// Suffix style should be consistent.
     ///
     /// ### Example
     /// ```rust
@@ -128,12 +130,34 @@ declare_clippy_lint! {
     /// let y = 123832_i32;
     /// ```
     pub UNSEPARATED_LITERAL_SUFFIX,
-    pedantic,
+    restriction,
     "literals whose suffix is not separated by an underscore"
 }
 
 declare_clippy_lint! {
     /// ### What it does
+    /// Warns if literal suffixes are separated by an underscore.
+    /// To enforce separated literal suffix style,
+    /// see the `unseparated_literal_suffix` lint.
+    ///
+    /// ### Why is this bad?
+    /// Suffix style should be consistent.
+    ///
+    /// ### Example
+    /// ```rust
+    /// // Bad
+    /// let y = 123832_i32;
+    ///
+    /// // Good
+    /// let y = 123832i32;
+    /// ```
+    pub SEPARATED_LITERAL_SUFFIX,
+    restriction,
+    "literals whose suffix is separated by an underscore"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
     /// Warns if an integral constant literal starts with `0`.
     ///
     /// ### Why is this bad?
@@ -260,6 +284,7 @@ declare_lint_pass!(MiscEarlyLints => [
     DOUBLE_NEG,
     MIXED_CASE_HEX_LITERALS,
     UNSEPARATED_LITERAL_SUFFIX,
+    SEPARATED_LITERAL_SUFFIX,
     ZERO_PREFIXED_LITERAL,
     BUILTIN_TYPE_SHADOW,
     REDUNDANT_PATTERN,
@@ -310,6 +335,10 @@ impl EarlyLintPass for MiscEarlyLints {
         if in_external_macro(cx.sess, expr.span) {
             return;
         }
+
+        if let ExprKind::Lit(ref lit) = expr.kind {
+            MiscEarlyLints::check_lit(cx, lit);
+        }
         double_neg::check(cx, expr);
     }
 }
@@ -332,7 +361,7 @@ impl MiscEarlyLints {
                 LitIntType::Unsigned(ty) => ty.name_str(),
                 LitIntType::Unsuffixed => "",
             };
-            unseparated_literal_suffix::check(cx, lit, &lit_snip, suffix, "integer");
+            literal_suffix::check(cx, lit, &lit_snip, suffix, "integer");
             if lit_snip.starts_with("0x") {
                 mixed_case_hex_literals::check(cx, lit, suffix, &lit_snip);
             } else if lit_snip.starts_with("0b") || lit_snip.starts_with("0o") {
@@ -342,7 +371,7 @@ impl MiscEarlyLints {
             }
         } else if let LitKind::Float(_, LitFloatType::Suffixed(float_ty)) = lit.kind {
             let suffix = float_ty.name_str();
-            unseparated_literal_suffix::check(cx, lit, &lit_snip, suffix, "float");
+            literal_suffix::check(cx, lit, &lit_snip, suffix, "float");
         }
     }
 }
diff --git a/clippy_lints/src/misc_early/unseparated_literal_suffix.rs b/clippy_lints/src/misc_early/unseparated_literal_suffix.rs
deleted file mode 100644
index 2018aa6184a..00000000000
--- a/clippy_lints/src/misc_early/unseparated_literal_suffix.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use rustc_ast::ast::Lit;
-use rustc_errors::Applicability;
-use rustc_lint::EarlyContext;
-
-use super::UNSEPARATED_LITERAL_SUFFIX;
-
-pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str, suffix: &str, sugg_type: &str) {
-    let maybe_last_sep_idx = if let Some(val) = lit_snip.len().checked_sub(suffix.len() + 1) {
-        val
-    } else {
-        return; // It's useless so shouldn't lint.
-    };
-    // Do not lint when literal is unsuffixed.
-    if !suffix.is_empty() && lit_snip.as_bytes()[maybe_last_sep_idx] != b'_' {
-        span_lint_and_sugg(
-            cx,
-            UNSEPARATED_LITERAL_SUFFIX,
-            lit.span,
-            &format!("{} type suffix should be separated by an underscore", sugg_type),
-            "add an underscore",
-            format!("{}_{}", &lit_snip[..=maybe_last_sep_idx], suffix),
-            Applicability::MachineApplicable,
-        );
-    }
-}
diff --git a/tests/ui/literals.rs b/tests/ui/literals.rs
index a72a74b9131..e60ce8492fc 100644
--- a/tests/ui/literals.rs
+++ b/tests/ui/literals.rs
@@ -2,7 +2,8 @@
 
 #![warn(clippy::mixed_case_hex_literals)]
 #![warn(clippy::zero_prefixed_literal)]
-#![allow(clippy::unseparated_literal_suffix)]
+#![warn(clippy::unseparated_literal_suffix)]
+#![warn(clippy::separated_literal_suffix)]
 #![allow(dead_code)]
 
 fn main() {
diff --git a/tests/ui/literals.stderr b/tests/ui/literals.stderr
index 99542e20f78..365b2407473 100644
--- a/tests/ui/literals.stderr
+++ b/tests/ui/literals.stderr
@@ -1,25 +1,65 @@
+error: integer type suffix should not be separated by an underscore
+  --> $DIR/literals.rs:12:15
+   |
+LL |     let ok4 = 0xab_cd_i32;
+   |               ^^^^^^^^^^^ help: remove the underscore: `0xab_cdi32`
+   |
+   = note: `-D clippy::separated-literal-suffix` implied by `-D warnings`
+
+error: integer type suffix should not be separated by an underscore
+  --> $DIR/literals.rs:13:15
+   |
+LL |     let ok5 = 0xAB_CD_u32;
+   |               ^^^^^^^^^^^ help: remove the underscore: `0xAB_CDu32`
+
+error: integer type suffix should not be separated by an underscore
+  --> $DIR/literals.rs:14:15
+   |
+LL |     let ok5 = 0xAB_CD_isize;
+   |               ^^^^^^^^^^^^^ help: remove the underscore: `0xAB_CDisize`
+
 error: inconsistent casing in hexadecimal literal
-  --> $DIR/literals.rs:14:17
+  --> $DIR/literals.rs:15:17
    |
 LL |     let fail1 = 0xabCD;
    |                 ^^^^^^
    |
    = note: `-D clippy::mixed-case-hex-literals` implied by `-D warnings`
 
+error: integer type suffix should not be separated by an underscore
+  --> $DIR/literals.rs:16:17
+   |
+LL |     let fail2 = 0xabCD_u32;
+   |                 ^^^^^^^^^^ help: remove the underscore: `0xabCDu32`
+
 error: inconsistent casing in hexadecimal literal
-  --> $DIR/literals.rs:15:17
+  --> $DIR/literals.rs:16:17
    |
 LL |     let fail2 = 0xabCD_u32;
    |                 ^^^^^^^^^^
 
+error: integer type suffix should not be separated by an underscore
+  --> $DIR/literals.rs:17:17
+   |
+LL |     let fail2 = 0xabCD_isize;
+   |                 ^^^^^^^^^^^^ help: remove the underscore: `0xabCDisize`
+
 error: inconsistent casing in hexadecimal literal
-  --> $DIR/literals.rs:16:17
+  --> $DIR/literals.rs:17:17
    |
 LL |     let fail2 = 0xabCD_isize;
    |                 ^^^^^^^^^^^^
 
+error: integer type suffix should be separated by an underscore
+  --> $DIR/literals.rs:18:27
+   |
+LL |     let fail_multi_zero = 000_123usize;
+   |                           ^^^^^^^^^^^^ help: add an underscore: `000_123_usize`
+   |
+   = note: `-D clippy::unseparated-literal-suffix` implied by `-D warnings`
+
 error: this is a decimal constant
-  --> $DIR/literals.rs:17:27
+  --> $DIR/literals.rs:18:27
    |
 LL |     let fail_multi_zero = 000_123usize;
    |                           ^^^^^^^^^^^^
@@ -34,8 +74,14 @@ help: if you mean to use an octal constant, use `0o`
 LL |     let fail_multi_zero = 0o123usize;
    |                           ~~~~~~~~~~
 
+error: integer type suffix should not be separated by an underscore
+  --> $DIR/literals.rs:21:16
+   |
+LL |     let ok10 = 0_i64;
+   |                ^^^^^ help: remove the underscore: `0i64`
+
 error: this is a decimal constant
-  --> $DIR/literals.rs:21:17
+  --> $DIR/literals.rs:22:17
    |
 LL |     let fail8 = 0123;
    |                 ^^^^
@@ -49,8 +95,14 @@ help: if you mean to use an octal constant, use `0o`
 LL |     let fail8 = 0o123;
    |                 ~~~~~
 
+error: integer type suffix should not be separated by an underscore
+  --> $DIR/literals.rs:31:16
+   |
+LL |     let ok17 = 0x123_4567_8901_usize;
+   |                ^^^^^^^^^^^^^^^^^^^^^ help: remove the underscore: `0x123_4567_8901usize`
+
 error: digits grouped inconsistently by underscores
-  --> $DIR/literals.rs:33:18
+  --> $DIR/literals.rs:34:18
    |
 LL |     let fail19 = 12_3456_21;
    |                  ^^^^^^^^^^ help: consider: `12_345_621`
@@ -58,19 +110,19 @@ LL |     let fail19 = 12_3456_21;
    = note: `-D clippy::inconsistent-digit-grouping` implied by `-D warnings`
 
 error: digits grouped inconsistently by underscores
-  --> $DIR/literals.rs:34:18
+  --> $DIR/literals.rs:35:18
    |
 LL |     let fail22 = 3__4___23;
    |                  ^^^^^^^^^ help: consider: `3_423`
 
 error: digits grouped inconsistently by underscores
-  --> $DIR/literals.rs:35:18
+  --> $DIR/literals.rs:36:18
    |
 LL |     let fail23 = 3__16___23;
    |                  ^^^^^^^^^^ help: consider: `31_623`
 
 error: digits of hex or binary literal not grouped by four
-  --> $DIR/literals.rs:37:18
+  --> $DIR/literals.rs:38:18
    |
 LL |     let fail24 = 0xAB_ABC_AB;
    |                  ^^^^^^^^^^^ help: consider: `0x0ABA_BCAB`
@@ -78,10 +130,10 @@ LL |     let fail24 = 0xAB_ABC_AB;
    = note: `-D clippy::unusual-byte-groupings` implied by `-D warnings`
 
 error: digits of hex or binary literal not grouped by four
-  --> $DIR/literals.rs:38:18
+  --> $DIR/literals.rs:39:18
    |
 LL |     let fail25 = 0b01_100_101;
    |                  ^^^^^^^^^^^^ help: consider: `0b0110_0101`
 
-error: aborting due to 10 previous errors
+error: aborting due to 18 previous errors