Skip to content

Commit 8907903

Browse files
author
Henri Lunnikivi
committed
Also include calls to ::default via non-Default types
1 parent afcb3ee commit 8907903

File tree

3 files changed

+43
-31
lines changed

3 files changed

+43
-31
lines changed

clippy_lints/src/field_reassign_with_default.rs

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -91,43 +91,39 @@ impl LateLintPass<'_> for FieldReassignWithDefault {
9191
let stmt = &block.stmts[stmt_idx];
9292

9393
if let StmtKind::Local(preceding_local) = &stmt.kind {
94-
if let Some(ty) = &preceding_local.ty {
95-
96-
// if all fields of the struct are not assigned, add `.. Default::default()` to the suggestion.
97-
let ext_with_default = !fields_of_type(&binding_type).iter().all(|field| assigned_fields.contains_key(&field.name));
98-
99-
let ty_snippet = snippet(cx, ty.span, "_");
100-
101-
let field_list = assigned_fields
102-
.into_iter()
103-
.map(|(field, value)| format!("{}: {}", field, value))
104-
.collect::<Vec<String>>()
105-
.join(", ");
106-
107-
let sugg = if ext_with_default {
108-
format!("{} {{ {}, ..Default::default() }}", ty_snippet, field_list)
109-
} else {
110-
format!("{} {{ {} }}", ty_snippet, field_list)
111-
};
112-
113-
// span lint once per statement that binds default
114-
span_lint_and_note(
115-
cx,
116-
FIELD_REASSIGN_WITH_DEFAULT,
117-
first_assign.unwrap_or_else(|| unreachable!()).span,
118-
"field assignment outside of initializer for an instance created with Default::default()",
119-
Some(preceding_local.span),
120-
&format!("consider initializing the variable with `{}`", sugg),
121-
);
12294

123-
}
95+
// if all fields of the struct are not assigned, add `.. Default::default()` to the suggestion.
96+
let ext_with_default = !fields_of_type(&binding_type).iter().all(|field| assigned_fields.contains_key(&field.name));
97+
98+
let field_list = assigned_fields
99+
.into_iter()
100+
.map(|(field, value)| format!("{}: {}", field, value))
101+
.collect::<Vec<String>>()
102+
.join(", ");
103+
104+
let sugg = if ext_with_default {
105+
format!("{} {{ {}, ..Default::default() }}", binding_type, field_list)
106+
} else {
107+
format!("{} {{ {} }}", binding_type, field_list)
108+
};
109+
110+
// span lint once per statement that binds default
111+
span_lint_and_note(
112+
cx,
113+
FIELD_REASSIGN_WITH_DEFAULT,
114+
first_assign.unwrap_or_else(|| unreachable!()).span,
115+
"field assignment outside of initializer for an instance created with Default::default()",
116+
Some(preceding_local.span),
117+
&format!("consider initializing the variable with `{}`", sugg),
118+
);
119+
124120
}
125121
}
126122
}
127123
}
128124
}
129125

130-
/// Returns the indices, identifiers and types of bindings set as `Default::default()`.
126+
/// Returns the block indices, identifiers and types of bindings set as `Default::default()`.
131127
fn enumerate_bindings_using_default<'cx, 'hir>(cx: &LateContext<'cx>, block: &Block<'hir>) -> Vec<(usize, Symbol, &'cx TyS<'cx>)> {
132128
block
133129
.stmts

tests/ui/field_reassign_with_default.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,8 @@ fn main() {
6262
a.i = 42;
6363
a.j = 43;
6464
a.j = 44;
65+
66+
// wrong, produces fourth error in stderr
67+
let mut a = A::default();
68+
a.i = 42;
6569
}

tests/ui/field_reassign_with_default.stderr

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,17 @@ note: consider initializing the variable with `A { i: 42, j: 44 }`
3535
LL | let mut a: A = Default::default();
3636
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3737

38-
error: aborting due to 3 previous errors
38+
error: field assignment outside of initializer for an instance created with Default::default()
39+
--> $DIR/field_reassign_with_default.rs:68:5
40+
|
41+
LL | a.i = 42;
42+
| ^^^^^^^^^
43+
|
44+
note: consider initializing the variable with `A { i: 42, ..Default::default() }`
45+
--> $DIR/field_reassign_with_default.rs:67:5
46+
|
47+
LL | let mut a = A::default();
48+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
49+
50+
error: aborting due to 4 previous errors
3951

0 commit comments

Comments
 (0)