@@ -63,11 +63,11 @@ impl LateLintPass<'_> for UnnecessaryStruct {
63
63
// all fields match, no base given
64
64
path. span
65
65
} ,
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) => {
67
67
// all fields match, has base: ensure that the path of the base matches
68
68
base. span
69
69
} ,
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) => {
71
71
// just the base, no explicit fields
72
72
base. span
73
73
} ,
@@ -86,8 +86,8 @@ impl LateLintPass<'_> for UnnecessaryStruct {
86
86
}
87
87
}
88
88
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) {
91
91
return false ;
92
92
}
93
93
@@ -147,7 +147,7 @@ fn same_path_in_all_fields<'tcx>(
147
147
}
148
148
149
149
if let Some ( ( src_expr, src_path) ) = found
150
- && check_references ( cx, expr, src_expr)
150
+ && check_references ( cx, expr, fields , src_expr)
151
151
{
152
152
Some ( src_path)
153
153
} else {
@@ -165,14 +165,25 @@ fn is_mutable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
165
165
}
166
166
}
167
167
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 {
169
174
if let Some ( parent) = get_parent_expr ( cx, expr_a)
170
175
&& let parent_ty = cx. typeck_results ( ) . expr_ty_adjusted ( parent)
171
176
&& parent_ty. is_any_ptr ( )
172
177
{
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.
176
187
return false ;
177
188
}
178
189
0 commit comments