@@ -65,13 +65,12 @@ fn check_addr_of_expr(
65
65
if let Some ( parent) = get_parent_expr( cx, expr) ;
66
66
if let ExprKind :: AddrOf ( BorrowKind :: Ref , Mutability :: Not , _) = parent. kind;
67
67
let adjustments = cx. typeck_results( ) . expr_adjustments( parent) . iter( ) . collect:: <Vec <_>>( ) ;
68
- if let Some ( target_ty) = match adjustments[ ..]
69
- {
68
+ if let
70
69
// For matching uses of `Cow::from`
71
70
[
72
71
Adjustment {
73
72
kind: Adjust :: Deref ( None ) ,
74
- ..
73
+ target : referent_ty ,
75
74
} ,
76
75
Adjustment {
77
76
kind: Adjust :: Borrow ( _) ,
@@ -82,7 +81,7 @@ fn check_addr_of_expr(
82
81
| [
83
82
Adjustment {
84
83
kind: Adjust :: Deref ( None ) ,
85
- ..
84
+ target : referent_ty ,
86
85
} ,
87
86
Adjustment {
88
87
kind: Adjust :: Borrow ( _) ,
@@ -97,7 +96,7 @@ fn check_addr_of_expr(
97
96
| [
98
97
Adjustment {
99
98
kind: Adjust :: Deref ( None ) ,
100
- ..
99
+ target : referent_ty ,
101
100
} ,
102
101
Adjustment {
103
102
kind: Adjust :: Deref ( Some ( OverloadedDeref { .. } ) ) ,
@@ -107,17 +106,24 @@ fn check_addr_of_expr(
107
106
kind: Adjust :: Borrow ( _) ,
108
107
target: target_ty,
109
108
} ,
110
- ] => Some ( target_ty) ,
111
- _ => None ,
112
- } ;
109
+ ] = adjustments[ ..] ;
113
110
let receiver_ty = cx. typeck_results( ) . expr_ty( receiver) ;
114
- // Only flag cases where the receiver is copyable or the method is `Cow::into_owned`. This
115
- // restriction is to ensure there is not overlap between `redundant_clone` and this lint.
116
- if is_copy( cx, receiver_ty) || is_cow_into_owned( cx, method_name, method_def_id) ;
111
+ let ( target_ty, n_target_refs) = peel_mid_ty_refs( * target_ty) ;
112
+ let ( receiver_ty, n_receiver_refs) = peel_mid_ty_refs( receiver_ty) ;
113
+ // Only flag cases satisfying at least one of the following three conditions:
114
+ // * the referent and receiver types are distinct
115
+ // * the referent/receiver type is a copyable array
116
+ // * the method is `Cow::into_owned`
117
+ // This restriction is to ensure there is no overlap between `redundant_clone` and this
118
+ // lint. It also avoids the following false positive:
119
+ // https://github.com/rust-lang/rust-clippy/issues/8759
120
+ // Arrays are a bit of a corner case. Non-copyable arrays are handled by
121
+ // `redundant_clone`, but copyable arrays are not.
122
+ if * referent_ty != receiver_ty
123
+ || ( matches!( referent_ty. kind( ) , ty:: Array ( ..) ) && is_copy( cx, * referent_ty) )
124
+ || is_cow_into_owned( cx, method_name, method_def_id) ;
117
125
if let Some ( receiver_snippet) = snippet_opt( cx, receiver. span) ;
118
126
then {
119
- let ( target_ty, n_target_refs) = peel_mid_ty_refs( * target_ty) ;
120
- let ( receiver_ty, n_receiver_refs) = peel_mid_ty_refs( receiver_ty) ;
121
127
if receiver_ty == target_ty && n_target_refs >= n_receiver_refs {
122
128
span_lint_and_sugg(
123
129
cx,
@@ -207,7 +213,11 @@ fn check_into_iter_call_arg(
207
213
if unnecessary_iter_cloned:: check_for_loop_iter( cx, parent, method_name, receiver, true ) {
208
214
return true ;
209
215
}
210
- let cloned_or_copied = if is_copy( cx, item_ty) && meets_msrv( msrv, & msrvs:: ITERATOR_COPIED ) { "copied" } else { "cloned" } ;
216
+ let cloned_or_copied = if is_copy( cx, item_ty) && meets_msrv( msrv, & msrvs:: ITERATOR_COPIED ) {
217
+ "copied"
218
+ } else {
219
+ "cloned"
220
+ } ;
211
221
// The next suggestion may be incorrect because the removal of the `to_owned`-like
212
222
// function could cause the iterator to hold a reference to a resource that is used
213
223
// mutably. See https://github.com/rust-lang/rust-clippy/issues/8148.
0 commit comments