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
@ -59,24 +59,22 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
||||
}
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user