mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-10 15:14:29 +00:00
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:
commit
ba80e06537
4 changed files with 55 additions and 24 deletions
|
@ -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,
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue