Skip to content

Commit 92f2bbb

Browse files
committed
Fix macro issues with field_reassign_with_default
1 parent a8825e9 commit 92f2bbb

File tree

5 files changed

+73
-20
lines changed

5 files changed

+73
-20
lines changed

clippy_lints/src/default.rs

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_errors::Applicability;
88
use rustc_hir::def::Res;
99
use rustc_hir::{Block, Expr, ExprKind, PatKind, QPath, Stmt, StmtKind};
1010
use rustc_lint::{LateContext, LateLintPass};
11+
use rustc_middle::lint::in_external_macro;
1112
use rustc_middle::ty;
1213
use rustc_session::{declare_tool_lint, impl_lint_pass};
1314
use rustc_span::symbol::{Ident, Symbol};
@@ -120,6 +121,8 @@ impl LateLintPass<'_> for Default {
120121
// only take `let ...` statements
121122
if let StmtKind::Local(local) = stmt.kind;
122123
if let Some(expr) = local.init;
124+
if !any_parent_is_automatically_derived(cx.tcx, expr.hir_id);
125+
if !in_external_macro(cx.tcx.sess, expr.span);
123126
// only take bindings to identifiers
124127
if let PatKind::Binding(_, binding_id, ident, _) = local.pat.kind;
125128
// only when assigning `... = Default::default()`

tests/ui/auxiliary/macro_rules.rs

+16
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,19 @@ macro_rules! large_enum_variant {
9494
}
9595
};
9696
}
97+
98+
#[macro_export]
99+
macro_rules! field_reassign_with_default {
100+
() => {
101+
#[derive(Default)]
102+
struct A {
103+
pub i: i32,
104+
pub j: i64,
105+
}
106+
fn lint() {
107+
let mut a: A = Default::default();
108+
a.i = 42;
109+
a;
110+
}
111+
};
112+
}

tests/ui/auxiliary/proc_macro_derive.rs

+18
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#![crate_type = "proc-macro"]
55
#![feature(repr128, proc_macro_quote)]
66
#![allow(incomplete_features)]
7+
#![allow(clippy::field_reassign_with_default)]
78
#![allow(clippy::eq_op)]
89

910
extern crate proc_macro;
@@ -23,3 +24,20 @@ pub fn derive(_: TokenStream) -> TokenStream {
2324
};
2425
output
2526
}
27+
28+
#[proc_macro_derive(FieldReassignWithDefault)]
29+
pub fn derive_foo(_input: TokenStream) -> TokenStream {
30+
quote! {
31+
#[derive(Default)]
32+
struct A {
33+
pub i: i32,
34+
pub j: i64,
35+
}
36+
#[automatically_derived]
37+
fn lint() {
38+
let mut a: A = Default::default();
39+
a.i = 42;
40+
a;
41+
}
42+
}
43+
}

tests/ui/field_reassign_with_default.rs

+16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
1+
// aux-build:proc_macro_derive.rs
2+
// aux-build:macro_rules.rs
3+
14
#![warn(clippy::field_reassign_with_default)]
25

6+
#[macro_use]
7+
extern crate proc_macro_derive;
8+
#[macro_use]
9+
extern crate macro_rules;
10+
11+
// Don't lint on derives that derive `Default`
12+
// See https://github.com/rust-lang/rust-clippy/issues/6545
13+
#[derive(FieldReassignWithDefault)]
14+
struct DerivedStruct;
15+
316
#[derive(Default)]
417
struct A {
518
i: i32,
@@ -120,6 +133,9 @@ fn main() {
120133
// don't expand macros in the suggestion (#6522)
121134
let mut a: C = C::default();
122135
a.i = vec![1];
136+
137+
// Don't lint in external macros
138+
field_reassign_with_default!();
123139
}
124140

125141
mod m {

tests/ui/field_reassign_with_default.stderr

+20-20
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,84 @@
11
error: field assignment outside of initializer for an instance created with Default::default()
2-
--> $DIR/field_reassign_with_default.rs:35:5
2+
--> $DIR/field_reassign_with_default.rs:48:5
33
|
44
LL | a.i = 42;
55
| ^^^^^^^^^
66
|
77
= note: `-D clippy::field-reassign-with-default` implied by `-D warnings`
8-
note: consider initializing the variable with `A { i: 42, ..Default::default() }` and removing relevant reassignments
9-
--> $DIR/field_reassign_with_default.rs:34:5
8+
note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments
9+
--> $DIR/field_reassign_with_default.rs:47:5
1010
|
1111
LL | let mut a: A = Default::default();
1212
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1313

1414
error: field assignment outside of initializer for an instance created with Default::default()
15-
--> $DIR/field_reassign_with_default.rs:75:5
15+
--> $DIR/field_reassign_with_default.rs:88:5
1616
|
1717
LL | a.j = 43;
1818
| ^^^^^^^^^
1919
|
20-
note: consider initializing the variable with `A { j: 43, i: 42 }` and removing relevant reassignments
21-
--> $DIR/field_reassign_with_default.rs:74:5
20+
note: consider initializing the variable with `main::A { j: 43, i: 42 }` and removing relevant reassignments
21+
--> $DIR/field_reassign_with_default.rs:87:5
2222
|
2323
LL | let mut a: A = Default::default();
2424
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2525

2626
error: field assignment outside of initializer for an instance created with Default::default()
27-
--> $DIR/field_reassign_with_default.rs:80:5
27+
--> $DIR/field_reassign_with_default.rs:93:5
2828
|
2929
LL | a.i = 42;
3030
| ^^^^^^^^^
3131
|
32-
note: consider initializing the variable with `A { i: 42, j: 44 }` and removing relevant reassignments
33-
--> $DIR/field_reassign_with_default.rs:79:5
32+
note: consider initializing the variable with `main::A { i: 42, j: 44 }` and removing relevant reassignments
33+
--> $DIR/field_reassign_with_default.rs:92:5
3434
|
3535
LL | let mut a: A = Default::default();
3636
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3737

3838
error: field assignment outside of initializer for an instance created with Default::default()
39-
--> $DIR/field_reassign_with_default.rs:86:5
39+
--> $DIR/field_reassign_with_default.rs:99:5
4040
|
4141
LL | a.i = 42;
4242
| ^^^^^^^^^
4343
|
44-
note: consider initializing the variable with `A { i: 42, ..Default::default() }` and removing relevant reassignments
45-
--> $DIR/field_reassign_with_default.rs:85:5
44+
note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments
45+
--> $DIR/field_reassign_with_default.rs:98:5
4646
|
4747
LL | let mut a = A::default();
4848
| ^^^^^^^^^^^^^^^^^^^^^^^^^
4949

5050
error: field assignment outside of initializer for an instance created with Default::default()
51-
--> $DIR/field_reassign_with_default.rs:96:5
51+
--> $DIR/field_reassign_with_default.rs:109:5
5252
|
5353
LL | a.i = Default::default();
5454
| ^^^^^^^^^^^^^^^^^^^^^^^^^
5555
|
56-
note: consider initializing the variable with `A { i: Default::default(), ..Default::default() }` and removing relevant reassignments
57-
--> $DIR/field_reassign_with_default.rs:95:5
56+
note: consider initializing the variable with `main::A { i: Default::default(), ..Default::default() }` and removing relevant reassignments
57+
--> $DIR/field_reassign_with_default.rs:108:5
5858
|
5959
LL | let mut a: A = Default::default();
6060
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6161

6262
error: field assignment outside of initializer for an instance created with Default::default()
63-
--> $DIR/field_reassign_with_default.rs:100:5
63+
--> $DIR/field_reassign_with_default.rs:113:5
6464
|
6565
LL | a.i = Default::default();
6666
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6767
|
68-
note: consider initializing the variable with `A { i: Default::default(), j: 45 }` and removing relevant reassignments
69-
--> $DIR/field_reassign_with_default.rs:99:5
68+
note: consider initializing the variable with `main::A { i: Default::default(), j: 45 }` and removing relevant reassignments
69+
--> $DIR/field_reassign_with_default.rs:112:5
7070
|
7171
LL | let mut a: A = Default::default();
7272
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7373

7474
error: field assignment outside of initializer for an instance created with Default::default()
75-
--> $DIR/field_reassign_with_default.rs:122:5
75+
--> $DIR/field_reassign_with_default.rs:135:5
7676
|
7777
LL | a.i = vec![1];
7878
| ^^^^^^^^^^^^^^
7979
|
8080
note: consider initializing the variable with `C { i: vec![1], ..Default::default() }` and removing relevant reassignments
81-
--> $DIR/field_reassign_with_default.rs:121:5
81+
--> $DIR/field_reassign_with_default.rs:134:5
8282
|
8383
LL | let mut a: C = C::default();
8484
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

0 commit comments

Comments
 (0)