make needless_update ignore non_exhaustive structs

This commit is contained in:
Andrew Houts
2020-12-17 21:09:55 -06:00
parent 5c00931642
commit 1eb7608a2e
3 changed files with 31 additions and 3 deletions
+19 -2
View File
@@ -21,7 +21,14 @@
/// # 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 @@
/// 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 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
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,
+11
View File
@@ -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
}
+1 -1
View File
@@ -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 };
| ^^^^