From 1eb7608a2e7284eff2d0ba80705f1cf28a1117e5 Mon Sep 17 00:00:00 2001 From: Andrew Houts Date: Thu, 17 Dec 2020 21:09:55 -0600 Subject: [PATCH 1/2] make needless_update ignore non_exhaustive structs --- clippy_lints/src/needless_update.rs | 21 +++++++++++++++++++-- tests/ui/needless_update.rs | 11 +++++++++++ tests/ui/needless_update.stderr | 2 +- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/needless_update.rs b/clippy_lints/src/needless_update.rs index 98e9078094a22..1e387b518c3ad 100644 --- a/clippy_lints/src/needless_update.rs +++ b/clippy_lints/src/needless_update.rs @@ -21,7 +21,14 @@ declare_clippy_lint! { /// # z: i32, /// # } /// # let zero_point = Point { x: 0, y: 0, z: 0 }; - /// + /// # + /// # #[non_exhaustive] + /// # struct Options { + /// # a: bool, + /// # b: i32, + /// # } + /// # let default_options = Options { a: false, b: 0 }; + /// # /// // Bad /// Point { /// x: 1, @@ -36,6 +43,14 @@ declare_clippy_lint! { /// y: 1, /// ..zero_point /// }; + /// + /// // this lint is not applied to structs marked with [non_exhaustive](https://doc.rust-lang.org/reference/attributes/type_system.html) + /// // Ok + /// Options { + /// a: true, + /// b: 321, + /// ..default_options + /// }; /// ``` pub NEEDLESS_UPDATE, complexity, @@ -49,7 +64,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessUpdate { if let ExprKind::Struct(_, ref fields, Some(ref base)) = expr.kind { let ty = cx.typeck_results().expr_ty(expr); if let ty::Adt(def, _) = ty.kind() { - if fields.len() == def.non_enum_variant().fields.len() { + if fields.len() == def.non_enum_variant().fields.len() + && !def.variants[0_usize.into()].is_field_list_non_exhaustive() + { span_lint( cx, NEEDLESS_UPDATE, diff --git a/tests/ui/needless_update.rs b/tests/ui/needless_update.rs index bfa005a19f910..b93ff048a62f2 100644 --- a/tests/ui/needless_update.rs +++ b/tests/ui/needless_update.rs @@ -6,9 +6,20 @@ struct S { pub b: i32, } +#[non_exhaustive] +struct T { + pub x: i32, + pub y: i32, +} + fn main() { let base = S { a: 0, b: 0 }; S { ..base }; // no error S { a: 1, ..base }; // no error S { a: 1, b: 1, ..base }; + + let base = T { x: 0, y: 0 }; + T { ..base }; // no error + T { x: 1, ..base }; // no error + T { x: 1, y: 1, ..base }; // no error } diff --git a/tests/ui/needless_update.stderr b/tests/ui/needless_update.stderr index 133c834880dd9..b154b3b306ddc 100644 --- a/tests/ui/needless_update.stderr +++ b/tests/ui/needless_update.stderr @@ -1,5 +1,5 @@ error: struct update has no effect, all the fields in the struct have already been specified - --> $DIR/needless_update.rs:13:23 + --> $DIR/needless_update.rs:19:23 | LL | S { a: 1, b: 1, ..base }; | ^^^^ From a24c6f14fa89dafc879ad76a185f43bc50f0bbb9 Mon Sep 17 00:00:00 2001 From: Andrew Houts Date: Fri, 18 Dec 2020 19:15:05 -0600 Subject: [PATCH 2/2] remove example --- clippy_lints/src/needless_update.rs | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/clippy_lints/src/needless_update.rs b/clippy_lints/src/needless_update.rs index 1e387b518c3ad..41cf541ecf5ef 100644 --- a/clippy_lints/src/needless_update.rs +++ b/clippy_lints/src/needless_update.rs @@ -8,6 +8,9 @@ declare_clippy_lint! { /// **What it does:** Checks for needlessly including a base struct on update /// when all fields are changed anyway. /// + /// This lint is not applied to structs marked with + /// [non_exhaustive](https://doc.rust-lang.org/reference/attributes/type_system.html). + /// /// **Why is this bad?** This will cost resources (because the base has to be /// somewhere), and make the code less readable. /// @@ -21,14 +24,7 @@ declare_clippy_lint! { /// # z: i32, /// # } /// # let zero_point = Point { x: 0, y: 0, z: 0 }; - /// # - /// # #[non_exhaustive] - /// # struct Options { - /// # a: bool, - /// # b: i32, - /// # } - /// # let default_options = Options { a: false, b: 0 }; - /// # + /// /// // Bad /// Point { /// x: 1, @@ -43,14 +39,6 @@ declare_clippy_lint! { /// y: 1, /// ..zero_point /// }; - /// - /// // this lint is not applied to structs marked with [non_exhaustive](https://doc.rust-lang.org/reference/attributes/type_system.html) - /// // Ok - /// Options { - /// a: true, - /// b: 321, - /// ..default_options - /// }; /// ``` pub NEEDLESS_UPDATE, complexity,