@@ -18,7 +18,7 @@ pub fn check(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, method_name: Symbol
18
18
if let Some ( callee_def_id) = fn_def_id( cx, parent) ;
19
19
if is_into_iter( cx, callee_def_id) ;
20
20
then {
21
- check_for_loop_iter( cx, parent, method_name, receiver)
21
+ check_for_loop_iter( cx, parent, method_name, receiver, false )
22
22
} else {
23
23
false
24
24
}
@@ -34,6 +34,7 @@ pub fn check_for_loop_iter(
34
34
expr : & ' tcx Expr < ' tcx > ,
35
35
method_name : Symbol ,
36
36
receiver : & ' tcx Expr < ' tcx > ,
37
+ cloned_before_iter : bool ,
37
38
) -> bool {
38
39
if_chain ! {
39
40
if let Some ( grandparent) = get_parent_expr( cx, expr) . and_then( |parent| get_parent_expr( cx, parent) ) ;
@@ -70,12 +71,22 @@ pub fn check_for_loop_iter(
70
71
expr. span,
71
72
& format!( "unnecessary use of `{}`" , method_name) ,
72
73
|diag| {
73
- diag. span_suggestion( expr. span, "use" , snippet, Applicability :: MachineApplicable ) ;
74
+ // If `check_into_iter_call_arg` called `check_for_loop_iter` because a call to
75
+ // a `to_owned`-like function was removed, then the next suggestion may be
76
+ // incorrect. This is because the iterator that results from the call's removal
77
+ // could hold a reference to a resource that is used mutably. See
78
+ // https://github.com/rust-lang/rust-clippy/issues/8148.
79
+ let applicability = if cloned_before_iter {
80
+ Applicability :: MaybeIncorrect
81
+ } else {
82
+ Applicability :: MachineApplicable
83
+ } ;
84
+ diag. span_suggestion( expr. span, "use" , snippet, applicability) ;
74
85
for addr_of_expr in addr_of_exprs {
75
86
match addr_of_expr. kind {
76
87
ExprKind :: AddrOf ( _, _, referent) => {
77
88
let span = addr_of_expr. span. with_hi( referent. span. lo( ) ) ;
78
- diag. span_suggestion( span, "remove this `&`" , String :: new( ) , Applicability :: MachineApplicable ) ;
89
+ diag. span_suggestion( span, "remove this `&`" , String :: new( ) , applicability ) ;
79
90
}
80
91
_ => unreachable!( ) ,
81
92
}
0 commit comments