]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/enum_variants.rs
Auto merge of #3946 - rchaser53:issue-3920, r=flip1995
[rust.git] / clippy_lints / src / enum_variants.rs
index 16d1e40484d0b7507923df7ab620d10208c22805..707fe93bd0c3c43d81b9ca9b1595f7edcc6fa578 100644 (file)
-// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-
 //! lint on enum variants that are prefixed or suffixed by the same characters
 
-use crate::rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass, Lint};
-use crate::rustc::{declare_tool_lint, lint_array};
-use crate::syntax::ast::*;
-use crate::syntax::source_map::Span;
-use crate::syntax::symbol::LocalInternedString;
-use crate::utils::{span_help_and_lint, span_lint};
 use crate::utils::{camel_case, in_macro};
+use crate::utils::{span_help_and_lint, span_lint};
+use rustc::lint::{EarlyContext, EarlyLintPass, Lint, LintArray, LintPass};
+use rustc::{declare_tool_lint, lint_array};
+use syntax::ast::*;
+use syntax::source_map::Span;
+use syntax::symbol::{InternedString, LocalInternedString};
 
-/// **What it does:** Detects enumeration variants that are prefixed or suffixed
-/// by the same characters.
-///
-/// **Why is this bad?** Enumeration variant names should specify their variant,
-/// not repeat the enumeration name.
-///
-/// **Known problems:** None.
-///
-/// **Example:**
-/// ```rust
-/// enum Cake {
-///     BlackForestCake,
-///     HummingbirdCake,
-///     BattenbergCake,
-/// }
-/// ```
 declare_clippy_lint! {
+    /// **What it does:** Detects enumeration variants that are prefixed or suffixed
+    /// by the same characters.
+    ///
+    /// **Why is this bad?** Enumeration variant names should specify their variant,
+    /// not repeat the enumeration name.
+    ///
+    /// **Known problems:** None.
+    ///
+    /// **Example:**
+    /// ```rust
+    /// enum Cake {
+    ///     BlackForestCake,
+    ///     HummingbirdCake,
+    ///     BattenbergCake,
+    /// }
+    /// ```
     pub ENUM_VARIANT_NAMES,
     style,
     "enums where all variants share a prefix/postfix"
 }
 
-/// **What it does:** Detects enumeration variants that are prefixed or suffixed
-/// by the same characters.
-///
-/// **Why is this bad?** Enumeration variant names should specify their variant,
-/// not repeat the enumeration name.
-///
-/// **Known problems:** None.
-///
-/// **Example:**
-/// ```rust
-/// enum Cake {
-///     BlackForestCake,
-///     HummingbirdCake,
-///     BattenbergCake,
-/// }
-/// ```
 declare_clippy_lint! {
+    /// **What it does:** Detects enumeration variants that are prefixed or suffixed
+    /// by the same characters.
+    ///
+    /// **Why is this bad?** Enumeration variant names should specify their variant,
+    /// not repeat the enumeration name.
+    ///
+    /// **Known problems:** None.
+    ///
+    /// **Example:**
+    /// ```rust
+    /// enum Cake {
+    ///     BlackForestCake,
+    ///     HummingbirdCake,
+    ///     BattenbergCake,
+    /// }
+    /// ```
     pub PUB_ENUM_VARIANT_NAMES,
     pedantic,
     "enums where all variants share a prefix/postfix"
 }
 
-/// **What it does:** Detects type names that are prefixed or suffixed by the
-/// containing module's name.
-///
-/// **Why is this bad?** It requires the user to type the module name twice.
-///
-/// **Known problems:** None.
-///
-/// **Example:**
-/// ```rust
-/// mod cake {
-///     struct BlackForestCake;
-/// }
-/// ```
 declare_clippy_lint! {
-    pub STUTTER,
+    /// **What it does:** Detects type names that are prefixed or suffixed by the
+    /// containing module's name.
+    ///
+    /// **Why is this bad?** It requires the user to type the module name twice.
+    ///
+    /// **Known problems:** None.
+    ///
+    /// **Example:**
+    /// ```rust
+    /// mod cake {
+    ///     struct BlackForestCake;
+    /// }
+    /// ```
+    pub MODULE_NAME_REPETITIONS,
     pedantic,
     "type names prefixed/postfixed with their containing module's name"
 }
 
-/// **What it does:** Checks for modules that have the same name as their
-/// parent module
-///
-/// **Why is this bad?** A typical beginner mistake is to have `mod foo;` and
-/// again `mod foo { ..
-/// }` in `foo.rs`.
-/// The expectation is that items inside the inner `mod foo { .. }` are then
-/// available
-/// through `foo::x`, but they are only available through
-/// `foo::foo::x`.
-/// If this is done on purpose, it would be better to choose a more
-/// representative module name.
-///
-/// **Known problems:** None.
-///
-/// **Example:**
-/// ```rust
-/// // lib.rs
-/// mod foo;
-/// // foo.rs
-/// mod foo {
-///     ...
-/// }
-/// ```
 declare_clippy_lint! {
+    /// **What it does:** Checks for modules that have the same name as their
+    /// parent module
+    ///
+    /// **Why is this bad?** A typical beginner mistake is to have `mod foo;` and
+    /// again `mod foo { ..
+    /// }` in `foo.rs`.
+    /// The expectation is that items inside the inner `mod foo { .. }` are then
+    /// available
+    /// through `foo::x`, but they are only available through
+    /// `foo::foo::x`.
+    /// If this is done on purpose, it would be better to choose a more
+    /// representative module name.
+    ///
+    /// **Known problems:** None.
+    ///
+    /// **Example:**
+    /// ```ignore
+    /// // lib.rs
+    /// mod foo;
+    /// // foo.rs
+    /// mod foo {
+    ///     ...
+    /// }
+    /// ```
     pub MODULE_INCEPTION,
     style,
     "modules that have the same name as their parent module"
 }
 
 pub struct EnumVariantNames {
-    modules: Vec<(LocalInternedString, String)>,
+    modules: Vec<(InternedString, String)>,
     threshold: u64,
 }
 
@@ -127,7 +117,16 @@ pub fn new(threshold: u64) -> Self {
 
 impl LintPass for EnumVariantNames {
     fn get_lints(&self) -> LintArray {
-        lint_array!(ENUM_VARIANT_NAMES, PUB_ENUM_VARIANT_NAMES, STUTTER, MODULE_INCEPTION)
+        lint_array!(
+            ENUM_VARIANT_NAMES,
+            PUB_ENUM_VARIANT_NAMES,
+            MODULE_NAME_REPETITIONS,
+            MODULE_INCEPTION
+        )
+    }
+
+    fn name(&self) -> &'static str {
+        "EnumVariantNames"
     }
 }
 
@@ -139,10 +138,7 @@ fn var2str(var: &Variant) -> LocalInternedString {
 fn partial_match(pre: &str, name: &str) -> usize {
     let mut name_iter = name.chars();
     let _ = name_iter.next_back(); // make sure the name is never fully matched
-    pre.chars()
-        .zip(name_iter)
-        .take_while(|&(l, r)| l == r)
-        .count()
+    pre.chars().zip(name_iter).take_while(|&(l, r)| l == r).count()
 }
 
 /// Returns the number of chars that match from the end
@@ -156,8 +152,6 @@ fn partial_rmatch(post: &str, name: &str) -> usize {
         .count()
 }
 
-// FIXME: #600
-#[allow(clippy::while_let_on_iterator)]
 fn check_variant(
     cx: &EarlyContext<'_>,
     threshold: u64,
@@ -173,9 +167,7 @@ fn check_variant(
     for var in &def.variants {
         let name = var2str(var);
         if partial_match(item_name, &name) == item_name_chars
-            && name.chars()
-                .nth(item_name_chars)
-                .map_or(false, |c| !c.is_lowercase())
+            && name.chars().nth(item_name_chars).map_or(false, |c| !c.is_lowercase())
         {
             span_lint(cx, lint, var.span, "Variant name starts with the enum's name");
         }
@@ -279,19 +271,26 @@ fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
                         let rmatching = partial_rmatch(mod_camel, &item_camel);
                         let nchars = mod_camel.chars().count();
 
-                        let is_word_beginning = |c: char| {
-                            c == '_' || c.is_uppercase() || c.is_numeric()
-                        };
+                        let is_word_beginning = |c: char| c == '_' || c.is_uppercase() || c.is_numeric();
 
                         if matching == nchars {
                             match item_camel.chars().nth(nchars) {
-                                Some(c) if is_word_beginning(c) =>
-                                    span_lint(cx, STUTTER, item.span, "item name starts with its containing module's name"),
-                                _ => ()
+                                Some(c) if is_word_beginning(c) => span_lint(
+                                    cx,
+                                    MODULE_NAME_REPETITIONS,
+                                    item.span,
+                                    "item name starts with its containing module's name",
+                                ),
+                                _ => (),
                             }
                         }
                         if rmatching == nchars {
-                            span_lint(cx, STUTTER, item.span, "item name ends with its containing module's name");
+                            span_lint(
+                                cx,
+                                MODULE_NAME_REPETITIONS,
+                                item.span,
+                                "item name ends with its containing module's name",
+                            );
                         }
                     }
                 }
@@ -304,6 +303,6 @@ fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
             };
             check_variant(cx, self.threshold, def, &item_name, item_name_chars, item.span, lint);
         }
-        self.modules.push((item_name, item_camel));
+        self.modules.push((item_name.as_interned_str(), item_camel));
     }
 }