about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-03-07 13:56:36 +0000
committerbors <bors@rust-lang.org>2024-03-07 13:56:36 +0000
commitba80e06537f7c07da33dacdc8efa87c2ea32b6c5 (patch)
treee204b9305a8b5bd6e1e7f2d873e2464a4f371a9d
parenta79db2aa5173edcda81c7e571bd21d4097e8eb73 (diff)
parentac643a278bdfd408519da6f092e64a6a839db314 (diff)
downloadrust-ba80e06537f7c07da33dacdc8efa87c2ea32b6c5.tar.gz
rust-ba80e06537f7c07da33dacdc8efa87c2ea32b6c5.zip
Auto merge of #12429 - Alexendoo:redundant-field-names-macro-ctxt, r=Manishearth
Don't lint `redundant_field_names` across macro boundaries

Fixes #12426

The `field.span.eq_ctxt(field.ident.span)` addition is the relevant line for the bugfix

The current implementation checks that the field's name and the path are in the same context by comparing the idents, but not that the two are in the same context as the entire field itself, so in local macros `SomeStruct { $ident: $ident }` would get linted

changelog: none
-rw-r--r--clippy_lints/src/redundant_field_names.rs34
-rw-r--r--tests/ui/redundant_field_names.fixed15
-rw-r--r--tests/ui/redundant_field_names.rs15
-rw-r--r--tests/ui/redundant_field_names.stderr15
4 files changed, 55 insertions, 24 deletions
diff --git a/clippy_lints/src/redundant_field_names.rs b/clippy_lints/src/redundant_field_names.rs
index fb000cd7184..17b031d5f01 100644
--- a/clippy_lints/src/redundant_field_names.rs
+++ b/clippy_lints/src/redundant_field_names.rs
@@ -59,24 +59,22 @@ impl EarlyLintPass for RedundantFieldNames {
         }
         if let ExprKind::Struct(ref se) = expr.kind {
             for field in &se.fields {
-                if field.is_shorthand {
-                    continue;
-                }
-                if let ExprKind::Path(None, path) = &field.expr.kind {
-                    if path.segments.len() == 1
-                        && path.segments[0].ident == field.ident
-                        && path.segments[0].args.is_none()
-                    {
-                        span_lint_and_sugg(
-                            cx,
-                            REDUNDANT_FIELD_NAMES,
-                            field.span,
-                            "redundant field names in struct initialization",
-                            "replace it with",
-                            field.ident.to_string(),
-                            Applicability::MachineApplicable,
-                        );
-                    }
+                if !field.is_shorthand
+                    && let ExprKind::Path(None, path) = &field.expr.kind
+                    && let [segment] = path.segments.as_slice()
+                    && segment.args.is_none()
+                    && segment.ident == field.ident
+                    && field.span.eq_ctxt(field.ident.span)
+                {
+                    span_lint_and_sugg(
+                        cx,
+                        REDUNDANT_FIELD_NAMES,
+                        field.span,
+                        "redundant field names in struct initialization",
+                        "replace it with",
+                        field.ident.to_string(),
+                        Applicability::MachineApplicable,
+                    );
                 }
             }
         }
diff --git a/tests/ui/redundant_field_names.fixed b/tests/ui/redundant_field_names.fixed
index c578e786426..72fc4cb7333 100644
--- a/tests/ui/redundant_field_names.fixed
+++ b/tests/ui/redundant_field_names.fixed
@@ -20,7 +20,7 @@ struct Person {
 }
 
 pub struct S {
-    v: String,
+    v: usize,
 }
 
 fn main() {
@@ -59,11 +59,22 @@ fn main() {
     let _ = RangeToInclusive { end };
 
     external! {
-        let v = String::new();
+        let v = 1;
         let _ = S {
             v: v
         };
     }
+
+    let v = 2;
+    macro_rules! internal {
+        ($i:ident) => {
+            let _ = S { v };
+            let _ = S { $i: v };
+            let _ = S { v: $i };
+            let _ = S { $i: $i };
+        };
+    }
+    internal!(v);
 }
 
 fn issue_3476() {
diff --git a/tests/ui/redundant_field_names.rs b/tests/ui/redundant_field_names.rs
index d8c2286d5ad..2617d7e7283 100644
--- a/tests/ui/redundant_field_names.rs
+++ b/tests/ui/redundant_field_names.rs
@@ -20,7 +20,7 @@ struct Person {
 }
 
 pub struct S {
-    v: String,
+    v: usize,
 }
 
 fn main() {
@@ -59,11 +59,22 @@ fn main() {
     let _ = RangeToInclusive { end: end };
 
     external! {
-        let v = String::new();
+        let v = 1;
         let _ = S {
             v: v
         };
     }
+
+    let v = 2;
+    macro_rules! internal {
+        ($i:ident) => {
+            let _ = S { v: v };
+            let _ = S { $i: v };
+            let _ = S { v: $i };
+            let _ = S { $i: $i };
+        };
+    }
+    internal!(v);
 }
 
 fn issue_3476() {
diff --git a/tests/ui/redundant_field_names.stderr b/tests/ui/redundant_field_names.stderr
index 53234736207..38c021fdba3 100644
--- a/tests/ui/redundant_field_names.stderr
+++ b/tests/ui/redundant_field_names.stderr
@@ -44,10 +44,21 @@ LL |     let _ = RangeToInclusive { end: end };
    |                                ^^^^^^^^ help: replace it with: `end`
 
 error: redundant field names in struct initialization
-  --> tests/ui/redundant_field_names.rs:88:25
+  --> tests/ui/redundant_field_names.rs:71:25
+   |
+LL |             let _ = S { v: v };
+   |                         ^^^^ help: replace it with: `v`
+...
+LL |     internal!(v);
+   |     ------------ in this macro invocation
+   |
+   = note: this error originates in the macro `internal` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: redundant field names in struct initialization
+  --> tests/ui/redundant_field_names.rs:99:25
    |
 LL |     let _ = RangeFrom { start: start };
    |                         ^^^^^^^^^^^^ help: replace it with: `start`
 
-error: aborting due to 8 previous errors
+error: aborting due to 9 previous errors