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
This commit is contained in:
bors 2024-03-07 13:56:36 +00:00
commit ba80e06537
4 changed files with 55 additions and 24 deletions

View file

@ -59,24 +59,22 @@ impl EarlyLintPass for RedundantFieldNames {
} }
if let ExprKind::Struct(ref se) = expr.kind { if let ExprKind::Struct(ref se) = expr.kind {
for field in &se.fields { for field in &se.fields {
if field.is_shorthand { if !field.is_shorthand
continue; && let ExprKind::Path(None, path) = &field.expr.kind
} && let [segment] = path.segments.as_slice()
if let ExprKind::Path(None, path) = &field.expr.kind { && segment.args.is_none()
if path.segments.len() == 1 && segment.ident == field.ident
&& path.segments[0].ident == field.ident && field.span.eq_ctxt(field.ident.span)
&& path.segments[0].args.is_none() {
{ span_lint_and_sugg(
span_lint_and_sugg( cx,
cx, REDUNDANT_FIELD_NAMES,
REDUNDANT_FIELD_NAMES, field.span,
field.span, "redundant field names in struct initialization",
"redundant field names in struct initialization", "replace it with",
"replace it with", field.ident.to_string(),
field.ident.to_string(), Applicability::MachineApplicable,
Applicability::MachineApplicable, );
);
}
} }
} }
} }

View file

@ -20,7 +20,7 @@ struct Person {
} }
pub struct S { pub struct S {
v: String, v: usize,
} }
fn main() { fn main() {
@ -59,11 +59,22 @@ fn main() {
let _ = RangeToInclusive { end }; let _ = RangeToInclusive { end };
external! { external! {
let v = String::new(); let v = 1;
let _ = S { let _ = S {
v: v 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() { fn issue_3476() {

View file

@ -20,7 +20,7 @@ struct Person {
} }
pub struct S { pub struct S {
v: String, v: usize,
} }
fn main() { fn main() {
@ -59,11 +59,22 @@ fn main() {
let _ = RangeToInclusive { end: end }; let _ = RangeToInclusive { end: end };
external! { external! {
let v = String::new(); let v = 1;
let _ = S { let _ = S {
v: v 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() { fn issue_3476() {

View file

@ -44,10 +44,21 @@ LL | let _ = RangeToInclusive { end: end };
| ^^^^^^^^ help: replace it with: `end` | ^^^^^^^^ help: replace it with: `end`
error: redundant field names in struct initialization 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 }; LL | let _ = RangeFrom { start: start };
| ^^^^^^^^^^^^ help: replace it with: `start` | ^^^^^^^^^^^^ help: replace it with: `start`
error: aborting due to 8 previous errors error: aborting due to 9 previous errors