Skip to content

Commit 67ca1ca

Browse files
committed
wip
1 parent 78e2854 commit 67ca1ca

File tree

1 file changed

+20
-9
lines changed

1 file changed

+20
-9
lines changed

clippy_lints/src/unnecessary_struct_initialization.rs

+20-9
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,11 @@ impl LateLintPass<'_> for UnnecessaryStruct {
6363
// all fields match, no base given
6464
path.span
6565
},
66-
(Some(path), Some(base)) if base_is_suitable(cx, expr, base) && path_matches_base(path, base) => {
66+
(Some(path), Some(base)) if base_is_suitable(cx, expr, fields, base) && path_matches_base(path, base) => {
6767
// all fields match, has base: ensure that the path of the base matches
6868
base.span
6969
},
70-
(None, Some(base)) if fields.is_empty() && base_is_suitable(cx, expr, base) => {
70+
(None, Some(base)) if fields.is_empty() && base_is_suitable(cx, expr, fields, base) => {
7171
// just the base, no explicit fields
7272
base.span
7373
},
@@ -86,8 +86,8 @@ impl LateLintPass<'_> for UnnecessaryStruct {
8686
}
8787
}
8888

89-
fn base_is_suitable(cx: &LateContext<'_>, expr: &Expr<'_>, base: &Expr<'_>) -> bool {
90-
if !check_references(cx, expr, base) {
89+
fn base_is_suitable(cx: &LateContext<'_>, expr: &Expr<'_>, expr_fields: &[ExprField<'_>], base: &Expr<'_>) -> bool {
90+
if !check_references(cx, expr, expr_fields, base) {
9191
return false;
9292
}
9393

@@ -147,7 +147,7 @@ fn same_path_in_all_fields<'tcx>(
147147
}
148148

149149
if let Some((src_expr, src_path)) = found
150-
&& check_references(cx, expr, src_expr)
150+
&& check_references(cx, expr, fields, src_expr)
151151
{
152152
Some(src_path)
153153
} else {
@@ -165,14 +165,25 @@ fn is_mutable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
165165
}
166166
}
167167

168-
fn check_references(cx: &LateContext<'_>, expr_a: &Expr<'_>, expr_b: &Expr<'_>) -> bool {
168+
fn check_references(
169+
cx: &LateContext<'_>,
170+
expr_a: &Expr<'_>,
171+
expr_a_fields: &[ExprField<'_>],
172+
expr_b: &Expr<'_>,
173+
) -> bool {
169174
if let Some(parent) = get_parent_expr(cx, expr_a)
170175
&& let parent_ty = cx.typeck_results().expr_ty_adjusted(parent)
171176
&& parent_ty.is_any_ptr()
172177
{
173-
if is_copy(cx, cx.typeck_results().expr_ty(expr_a)) && path_to_local(expr_b).is_some() {
174-
// When the type implements `Copy`, a reference to the new struct works on the
175-
// copy. Using the original would borrow it.
178+
if expr_a_fields.iter().any(|f| {
179+
let ExprKind::Field(expr_f, _) = f.expr.kind else {
180+
return false;
181+
};
182+
is_copy(cx, cx.typeck_results().expr_ty(expr_f))
183+
}) && path_to_local(expr_b).is_some()
184+
{
185+
// When any of the fields of the struct implements `Copy`, a reference to
186+
// the new struct works on the copy. Using the original would borrow it.
176187
return false;
177188
}
178189

0 commit comments

Comments
 (0)