diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index bec46ba18..1f78bee00 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -152,6 +152,7 @@ pub mod ptr; 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 index 000000000..d6164e211 --- /dev/null +++ b/clippy_lints/src/redundant_field_names.rs @@ -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() + ); + } + } + } + } + } + } + } +} diff --git a/tests/ui/no_effect.rs b/tests/ui/no_effect.rs index a037ac3cf..a782063e3 100644 --- a/tests/ui/no_effect.rs +++ b/tests/ui/no_effect.rs @@ -5,6 +5,7 @@ #![allow(dead_code)] #![allow(path_statements)] #![allow(deref_addrof)] +#![allow(redundant_field_names)] #![feature(untagged_unions)] struct Unit; diff --git a/tests/ui/no_effect.stderr b/tests/ui/no_effect.stderr index 5bcab9f2b..64c0267a8 100644 --- a/tests/ui/no_effect.stderr +++ b/tests/ui/no_effect.stderr @@ -1,281 +1,281 @@ 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 index 000000000..d562fa44f --- /dev/null +++ b/tests/ui/redundant_field_names.rs @@ -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 index 000000000..594282d23 --- /dev/null +++ b/tests/ui/redundant_field_names.stderr @@ -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 +