]> git.lizzy.rs Git - rust.git/commitdiff
Implement redundant field names lint #2244
authorTomasKralCZ <tomas@kral.hk>
Sat, 10 Feb 2018 20:13:17 +0000 (21:13 +0100)
committerTomasKralCZ <tomas@kral.hk>
Sat, 10 Feb 2018 21:52:31 +0000 (22:52 +0100)
clippy_lints/src/lib.rs
clippy_lints/src/redundant_field_names.rs [new file with mode: 0644]
tests/ui/no_effect.rs
tests/ui/no_effect.stderr
tests/ui/redundant_field_names.rs [new file with mode: 0644]
tests/ui/redundant_field_names.stderr [new file with mode: 0644]

index bec46ba180c62ca963fcd3139a0346d55b803420..1f78bee00e7c2e09d5aa7f903868b61b73c222e0 100644 (file)
@@ -152,6 +152,7 @@ macro_rules! declare_restriction_lint {
 pub mod question_mark;
 pub mod ranges;
 pub mod reference;
+pub mod redundant_field_names;
 pub mod regex;
 pub mod replace_consts;
 pub mod returns;
@@ -373,6 +374,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
     reg.register_late_lint_pass(box types::UnitArg);
     reg.register_late_lint_pass(box double_comparison::DoubleComparisonPass);
     reg.register_late_lint_pass(box question_mark::QuestionMarkPass);
+    reg.register_late_lint_pass(box redundant_field_names::RedundantFieldNames);
 
     reg.register_lint_group("clippy_restrictions", vec![
         arithmetic::FLOAT_ARITHMETIC,
@@ -591,6 +593,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
         ranges::ITERATOR_STEP_BY_ZERO,
         ranges::RANGE_MINUS_ONE,
         ranges::RANGE_ZIP_WITH_LEN,
+        redundant_field_names::REDUNDANT_FIELD_NAMES,
         reference::DEREF_ADDROF,
         regex::INVALID_REGEX,
         regex::REGEX_MACRO,
diff --git a/clippy_lints/src/redundant_field_names.rs b/clippy_lints/src/redundant_field_names.rs
new file mode 100644 (file)
index 0000000..d6164e2
--- /dev/null
@@ -0,0 +1,68 @@
+use rustc::lint::*;
+use rustc::hir::*;
+use utils::{span_lint_and_sugg};
+
+/// **What it does:** Checks for redundnat field names where shorthands
+/// can be used.
+/// 
+/// **Why is this bad?** If the field and variable names are the same,
+/// the field name is redundant.
+/// 
+/// **Known problems:** None.
+/// 
+/// **Example:**
+/// ```rust
+/// let bar: u8 = 123;
+/// 
+/// struct Foo {
+///     bar: u8,
+/// }
+/// 
+/// let foo = Foo{ bar: bar }
+/// ```
+declare_lint! {
+    pub REDUNDANT_FIELD_NAMES,
+    Warn,
+    "using same name for field and variable ,where shorthand can be used"
+}
+
+pub struct RedundantFieldNames;
+
+impl LintPass for RedundantFieldNames {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(REDUNDANT_FIELD_NAMES)
+    }
+}
+
+impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantFieldNames {
+    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
+        if let ExprStruct(_, ref fields, _) = expr.node {
+            for field in fields {
+                let name = field.name.node;
+                if let ExprPath(ref qpath) = field.expr.node {
+                    if let &QPath::Resolved(_, ref path) = qpath {
+                        let segments = &path.segments;
+
+                        if segments.len() == 1 {
+                            let expr_name = segments[0].name;
+
+                            if name == expr_name {
+                                span_lint_and_sugg(
+                                    cx,
+                                    REDUNDANT_FIELD_NAMES,
+                                    path.span,
+                                    "redundant field names in struct initialization",
+                                    &format!(
+                                        "replace '{0}: {0}' with '{0}'",
+                                        name,
+                                    ),
+                                    "".to_string()
+                                );
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
index a037ac3cf0e11cfe2d8c02654b97f5858aeba97f..a782063e3919d2af20030e28c9376c3d667f779f 100644 (file)
@@ -5,6 +5,7 @@
 #![allow(dead_code)]
 #![allow(path_statements)]
 #![allow(deref_addrof)]
+#![allow(redundant_field_names)]
 #![feature(untagged_unions)]
 
 struct Unit;
index 5bcab9f2b5e3329c8155d99f9775199fed093106..64c0267a8b80515792ece4a062ce7c9a898d3218 100644 (file)
 error: statement with no effect
-  --> $DIR/no_effect.rs:58:5
+  --> $DIR/no_effect.rs:59:5
    |
-58 |     0;
+59 |     0;
    |     ^^
    |
    = note: `-D no-effect` implied by `-D warnings`
 
-error: statement with no effect
-  --> $DIR/no_effect.rs:59:5
-   |
-59 |     s2;
-   |     ^^^
-
 error: statement with no effect
   --> $DIR/no_effect.rs:60:5
    |
-60 |     Unit;
-   |     ^^^^^
+60 |     s2;
+   |     ^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:61:5
    |
-61 |     Tuple(0);
-   |     ^^^^^^^^^
+61 |     Unit;
+   |     ^^^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:62:5
    |
-62 |     Struct { field: 0 };
-   |     ^^^^^^^^^^^^^^^^^^^^
+62 |     Tuple(0);
+   |     ^^^^^^^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:63:5
    |
-63 |     Struct { ..s };
-   |     ^^^^^^^^^^^^^^^
+63 |     Struct { field: 0 };
+   |     ^^^^^^^^^^^^^^^^^^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:64:5
    |
-64 |     Union { a: 0 };
+64 |     Struct { ..s };
    |     ^^^^^^^^^^^^^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:65:5
    |
-65 |     Enum::Tuple(0);
+65 |     Union { a: 0 };
    |     ^^^^^^^^^^^^^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:66:5
    |
-66 |     Enum::Struct { field: 0 };
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+66 |     Enum::Tuple(0);
+   |     ^^^^^^^^^^^^^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:67:5
    |
-67 |     5 + 6;
-   |     ^^^^^^
+67 |     Enum::Struct { field: 0 };
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:68:5
    |
-68 |     *&42;
-   |     ^^^^^
+68 |     5 + 6;
+   |     ^^^^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:69:5
    |
-69 |     &6;
-   |     ^^^
+69 |     *&42;
+   |     ^^^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:70:5
    |
-70 |     (5, 6, 7);
-   |     ^^^^^^^^^^
+70 |     &6;
+   |     ^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:71:5
    |
-71 |     box 42;
-   |     ^^^^^^^
+71 |     (5, 6, 7);
+   |     ^^^^^^^^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:72:5
    |
-72 |     ..;
-   |     ^^^
+72 |     box 42;
+   |     ^^^^^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:73:5
    |
-73 |     5..;
-   |     ^^^^
+73 |     ..;
+   |     ^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:74:5
    |
-74 |     ..5;
+74 |     5..;
    |     ^^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:75:5
    |
-75 |     5..6;
-   |     ^^^^^
+75 |     ..5;
+   |     ^^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:76:5
    |
-76 |     5..=6;
-   |     ^^^^^^
+76 |     5..6;
+   |     ^^^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:77:5
    |
-77 |     [42, 55];
-   |     ^^^^^^^^^
+77 |     5..=6;
+   |     ^^^^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:78:5
    |
-78 |     [42, 55][1];
-   |     ^^^^^^^^^^^^
+78 |     [42, 55];
+   |     ^^^^^^^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:79:5
    |
-79 |     (42, 55).1;
-   |     ^^^^^^^^^^^
+79 |     [42, 55][1];
+   |     ^^^^^^^^^^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:80:5
    |
-80 |     [42; 55];
-   |     ^^^^^^^^^
+80 |     (42, 55).1;
+   |     ^^^^^^^^^^^
 
 error: statement with no effect
   --> $DIR/no_effect.rs:81:5
    |
-81 |     [42; 55][13];
+81 |     [42; 55];
+   |     ^^^^^^^^^
+
+error: statement with no effect
+  --> $DIR/no_effect.rs:82:5
+   |
+82 |     [42; 55][13];
    |     ^^^^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:83:5
+  --> $DIR/no_effect.rs:84:5
    |
-83 |     || x += 5;
+84 |     || x += 5;
    |     ^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:85:5
+  --> $DIR/no_effect.rs:86:5
    |
-85 |     FooString { s: s };
+86 |     FooString { s: s };
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: statement can be reduced
-  --> $DIR/no_effect.rs:96:5
+  --> $DIR/no_effect.rs:97:5
    |
-96 |     Tuple(get_number());
+97 |     Tuple(get_number());
    |     ^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
    |
    = note: `-D unnecessary-operation` implied by `-D warnings`
 
-error: statement can be reduced
-  --> $DIR/no_effect.rs:97:5
-   |
-97 |     Struct { field: get_number() };
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
-
 error: statement can be reduced
   --> $DIR/no_effect.rs:98:5
    |
-98 |     Struct { ..get_struct() };
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_struct();`
+98 |     Struct { field: get_number() };
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
 
 error: statement can be reduced
   --> $DIR/no_effect.rs:99:5
    |
-99 |     Enum::Tuple(get_number());
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
+99 |     Struct { ..get_struct() };
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_struct();`
 
 error: statement can be reduced
    --> $DIR/no_effect.rs:100:5
     |
-100 |     Enum::Struct { field: get_number() };
-    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
+100 |     Enum::Tuple(get_number());
+    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
 
 error: statement can be reduced
    --> $DIR/no_effect.rs:101:5
     |
-101 |     5 + get_number();
-    |     ^^^^^^^^^^^^^^^^^ help: replace it with: `5;get_number();`
+101 |     Enum::Struct { field: get_number() };
+    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
 
 error: statement can be reduced
    --> $DIR/no_effect.rs:102:5
     |
-102 |     *&get_number();
-    |     ^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
+102 |     5 + get_number();
+    |     ^^^^^^^^^^^^^^^^^ help: replace it with: `5;get_number();`
 
 error: statement can be reduced
    --> $DIR/no_effect.rs:103:5
     |
-103 |     &get_number();
-    |     ^^^^^^^^^^^^^^ help: replace it with: `get_number();`
+103 |     *&get_number();
+    |     ^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
 
 error: statement can be reduced
    --> $DIR/no_effect.rs:104:5
     |
-104 |     (5, 6, get_number());
-    |     ^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `5;6;get_number();`
+104 |     &get_number();
+    |     ^^^^^^^^^^^^^^ help: replace it with: `get_number();`
 
 error: statement can be reduced
    --> $DIR/no_effect.rs:105:5
     |
-105 |     box get_number();
-    |     ^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
+105 |     (5, 6, get_number());
+    |     ^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `5;6;get_number();`
 
 error: statement can be reduced
    --> $DIR/no_effect.rs:106:5
     |
-106 |     get_number()..;
-    |     ^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
+106 |     box get_number();
+    |     ^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
 
 error: statement can be reduced
    --> $DIR/no_effect.rs:107:5
     |
-107 |     ..get_number();
+107 |     get_number()..;
     |     ^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
 
 error: statement can be reduced
    --> $DIR/no_effect.rs:108:5
     |
-108 |     5..get_number();
-    |     ^^^^^^^^^^^^^^^^ help: replace it with: `5;get_number();`
+108 |     ..get_number();
+    |     ^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
 
 error: statement can be reduced
    --> $DIR/no_effect.rs:109:5
     |
-109 |     [42, get_number()];
-    |     ^^^^^^^^^^^^^^^^^^^ help: replace it with: `42;get_number();`
+109 |     5..get_number();
+    |     ^^^^^^^^^^^^^^^^ help: replace it with: `5;get_number();`
 
 error: statement can be reduced
    --> $DIR/no_effect.rs:110:5
     |
-110 |     [42, 55][get_number() as usize];
-    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `[42, 55];get_number() as usize;`
+110 |     [42, get_number()];
+    |     ^^^^^^^^^^^^^^^^^^^ help: replace it with: `42;get_number();`
 
 error: statement can be reduced
    --> $DIR/no_effect.rs:111:5
     |
-111 |     (42, get_number()).1;
-    |     ^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `42;get_number();`
+111 |     [42, 55][get_number() as usize];
+    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `[42, 55];get_number() as usize;`
 
 error: statement can be reduced
    --> $DIR/no_effect.rs:112:5
     |
-112 |     [get_number(); 55];
-    |     ^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
+112 |     (42, get_number()).1;
+    |     ^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `42;get_number();`
 
 error: statement can be reduced
    --> $DIR/no_effect.rs:113:5
     |
-113 |     [42; 55][get_number() as usize];
-    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `[42; 55];get_number() as usize;`
+113 |     [get_number(); 55];
+    |     ^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
 
 error: statement can be reduced
    --> $DIR/no_effect.rs:114:5
     |
-114 |     {get_number()};
-    |     ^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
+114 |     [42; 55][get_number() as usize];
+    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `[42; 55];get_number() as usize;`
 
 error: statement can be reduced
    --> $DIR/no_effect.rs:115:5
     |
-115 |     FooString { s: String::from("blah"), };
+115 |     {get_number()};
+    |     ^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
+
+error: statement can be reduced
+   --> $DIR/no_effect.rs:116:5
+    |
+116 |     FooString { s: String::from("blah"), };
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `String::from("blah");`
 
 error: aborting due to 46 previous errors
diff --git a/tests/ui/redundant_field_names.rs b/tests/ui/redundant_field_names.rs
new file mode 100644 (file)
index 0000000..d562fa4
--- /dev/null
@@ -0,0 +1,28 @@
+#![warn(redundant_field_names)]
+#![allow(unused_variables)]
+
+mod foo {
+    pub const BAR: u8 = 0;
+}
+
+struct Person {
+    gender: u8,
+    age: u8,
+
+    buzz: u64,
+    foo: u8,
+}
+
+fn main() {
+    let gender: u8 = 42;
+    let age = 0;
+    let fizz: u64 = 0;
+
+    let me = Person {
+        gender: gender,
+        age: age,
+
+        buzz: fizz, //should be ok
+        foo: foo::BAR, //should be ok
+    };
+}
diff --git a/tests/ui/redundant_field_names.stderr b/tests/ui/redundant_field_names.stderr
new file mode 100644 (file)
index 0000000..594282d
--- /dev/null
@@ -0,0 +1,16 @@
+error: redundant field names in struct initialization
+  --> $DIR/redundant_field_names.rs:22:17
+   |
+22 |         gender: gender,
+   |                 ^^^^^^ help: replace 'gender: gender' with 'gender'
+   |
+   = note: `-D redundant-field-names` implied by `-D warnings`
+
+error: redundant field names in struct initialization
+  --> $DIR/redundant_field_names.rs:23:14
+   |
+23 |         age: age,
+   |              ^^^ help: replace 'age: age' with 'age'
+
+error: aborting due to 2 previous errors
+