about summary refs log tree commit diff
diff options
context:
space:
mode:
authorflip1995 <philipp.krones@embecosm.com>2021-05-04 16:48:25 +0200
committerflip1995 <philipp.krones@embecosm.com>2021-05-04 16:48:43 +0200
commit0854f0caee1d6d16e57eb1d3f5abf539b3bee3f0 (patch)
tree672d38ee04108211408d3340dbc2f35a01796f5c
parent5e3160ca0bfa9e96ab81a0812a79ec41ad535d14 (diff)
downloadrust-0854f0caee1d6d16e57eb1d3f5abf539b3bee3f0.tar.gz
rust-0854f0caee1d6d16e57eb1d3f5abf539b3bee3f0.zip
Don't trigger `field_reassign_with_default` in macros
Producing a good suggestion for this lint is already hard when no macros
are involved. With macros the lint message and the suggestion are just
confusing. Since both, producing a good suggestion and figuring out if
this pattern can be re-written inside a macro is nearly impossible, just
bail out.
-rw-r--r--clippy_lints/src/default.rs3
-rw-r--r--tests/ui/field_reassign_with_default.rs20
-rw-r--r--tests/ui/field_reassign_with_default.stderr36
3 files changed, 39 insertions, 20 deletions
diff --git a/clippy_lints/src/default.rs b/clippy_lints/src/default.rs
index 7a53d390bb4..947479db8f5 100644
--- a/clippy_lints/src/default.rs
+++ b/clippy_lints/src/default.rs
@@ -7,7 +7,6 @@ use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::{Block, Expr, ExprKind, PatKind, QPath, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::symbol::{Ident, Symbol};
@@ -122,7 +121,7 @@ impl LateLintPass<'_> for Default {
                 if let StmtKind::Local(local) = stmt.kind;
                 if let Some(expr) = local.init;
                 if !any_parent_is_automatically_derived(cx.tcx, expr.hir_id);
-                if !in_external_macro(cx.tcx.sess, expr.span);
+                if !in_macro(expr.span);
                 // only take bindings to identifiers
                 if let PatKind::Binding(_, binding_id, ident, _) = local.pat.kind;
                 // only when assigning `... = Default::default()`
diff --git a/tests/ui/field_reassign_with_default.rs b/tests/ui/field_reassign_with_default.rs
index 1368c5d7984..787053fb000 100644
--- a/tests/ui/field_reassign_with_default.rs
+++ b/tests/ui/field_reassign_with_default.rs
@@ -29,6 +29,21 @@ struct C {
     i: Vec<i32>,
     j: i64,
 }
+
+#[derive(Default)]
+struct D {
+    a: Option<i32>,
+    b: Option<i32>,
+}
+
+macro_rules! m {
+    ($key:ident: $value:tt) => {{
+        let mut data = $crate::D::default();
+        data.$key = Some($value);
+        data
+    }};
+}
+
 /// Implements .next() that returns a different number each time.
 struct SideEffect(i32);
 
@@ -143,6 +158,11 @@ fn main() {
 
     let mut a: WrapperMulti<i32, i64> = Default::default();
     a.i = 42;
+
+    // Don't lint in macros
+    m! {
+        a: 42
+    };
 }
 
 mod m {
diff --git a/tests/ui/field_reassign_with_default.stderr b/tests/ui/field_reassign_with_default.stderr
index dd7c0360bb1..b56db08ec8a 100644
--- a/tests/ui/field_reassign_with_default.stderr
+++ b/tests/ui/field_reassign_with_default.stderr
@@ -1,108 +1,108 @@
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> $DIR/field_reassign_with_default.rs:48:5
+  --> $DIR/field_reassign_with_default.rs:63:5
    |
 LL |     a.i = 42;
    |     ^^^^^^^^^
    |
    = note: `-D clippy::field-reassign-with-default` implied by `-D warnings`
 note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments
-  --> $DIR/field_reassign_with_default.rs:47:5
+  --> $DIR/field_reassign_with_default.rs:62:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> $DIR/field_reassign_with_default.rs:88:5
+  --> $DIR/field_reassign_with_default.rs:103:5
    |
 LL |     a.j = 43;
    |     ^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { j: 43, i: 42 }` and removing relevant reassignments
-  --> $DIR/field_reassign_with_default.rs:87:5
+  --> $DIR/field_reassign_with_default.rs:102:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> $DIR/field_reassign_with_default.rs:93:5
+  --> $DIR/field_reassign_with_default.rs:108:5
    |
 LL |     a.i = 42;
    |     ^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { i: 42, j: 44 }` and removing relevant reassignments
-  --> $DIR/field_reassign_with_default.rs:92:5
+  --> $DIR/field_reassign_with_default.rs:107:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> $DIR/field_reassign_with_default.rs:99:5
+  --> $DIR/field_reassign_with_default.rs:114:5
    |
 LL |     a.i = 42;
    |     ^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments
-  --> $DIR/field_reassign_with_default.rs:98:5
+  --> $DIR/field_reassign_with_default.rs:113:5
    |
 LL |     let mut a = A::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> $DIR/field_reassign_with_default.rs:109:5
+  --> $DIR/field_reassign_with_default.rs:124:5
    |
 LL |     a.i = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { i: Default::default(), ..Default::default() }` and removing relevant reassignments
-  --> $DIR/field_reassign_with_default.rs:108:5
+  --> $DIR/field_reassign_with_default.rs:123:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> $DIR/field_reassign_with_default.rs:113:5
+  --> $DIR/field_reassign_with_default.rs:128:5
    |
 LL |     a.i = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { i: Default::default(), j: 45 }` and removing relevant reassignments
-  --> $DIR/field_reassign_with_default.rs:112:5
+  --> $DIR/field_reassign_with_default.rs:127:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> $DIR/field_reassign_with_default.rs:135:5
+  --> $DIR/field_reassign_with_default.rs:150:5
    |
 LL |     a.i = vec![1];
    |     ^^^^^^^^^^^^^^
    |
 note: consider initializing the variable with `C { i: vec![1], ..Default::default() }` and removing relevant reassignments
-  --> $DIR/field_reassign_with_default.rs:134:5
+  --> $DIR/field_reassign_with_default.rs:149:5
    |
 LL |     let mut a: C = C::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> $DIR/field_reassign_with_default.rs:142:5
+  --> $DIR/field_reassign_with_default.rs:157:5
    |
 LL |     a.i = true;
    |     ^^^^^^^^^^^
    |
 note: consider initializing the variable with `Wrapper::<bool> { i: true }` and removing relevant reassignments
-  --> $DIR/field_reassign_with_default.rs:141:5
+  --> $DIR/field_reassign_with_default.rs:156:5
    |
 LL |     let mut a: Wrapper<bool> = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> $DIR/field_reassign_with_default.rs:145:5
+  --> $DIR/field_reassign_with_default.rs:160:5
    |
 LL |     a.i = 42;
    |     ^^^^^^^^^
    |
 note: consider initializing the variable with `WrapperMulti::<i32, i64> { i: 42, ..Default::default() }` and removing relevant reassignments
-  --> $DIR/field_reassign_with_default.rs:144:5
+  --> $DIR/field_reassign_with_default.rs:159:5
    |
 LL |     let mut a: WrapperMulti<i32, i64> = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^