@@ -56,51 +56,39 @@ pub fn check_for_loop_iter(
56
56
}
57
57
}
58
58
59
- if let Some ( caller) = if let ExprKind :: Call ( _, [ child, ..] ) = expr. kind {
60
- // filter first layer of iterator
61
- let mut child = child;
62
- // get inner real caller requests for clone
63
- while let ExprKind :: MethodCall ( _, caller, _, _) = child. kind {
64
- child = caller;
65
- }
66
- Some ( child)
67
- } else {
68
- None
69
- } && is_mutable ( cx, caller)
70
- {
71
- // all clones get from explicit function call
72
- // the suggestions out of this scope will handle for immutable caller
73
- // only check for mutable caller here
74
- // if caller is mutable and caller or its fields are changed
75
- // the lint should not execute
76
- if if let ExprKind :: Block ( block, ..) = body. kind {
77
- let mut no_change = true ;
78
- // check whether caller is mutable and caller or its fields are changed in this loop
59
+ fn is_caller_or_fields_changed ( cx : & LateContext < ' _ > , body : & Expr < ' _ > , caller : & Expr < ' _ > ) -> bool {
60
+ if let ExprKind :: Block ( block, ..) = body. kind {
79
61
for stmt in block. stmts {
80
62
if let StmtKind :: Semi ( e) = stmt. kind {
81
- // dont check `is_mutable` for `lhs` here because assign to an immutable variable is an error
82
- if let Some ( lhs ) = match e . kind {
83
- ExprKind :: Assign ( lhs , _ , _ ) => Some ( lhs ) ,
84
- ExprKind :: AssignOp ( _, lhs , _) => Some ( lhs ) ,
63
+ // dont check `is_mutable` for `lhs` here because
64
+ // assign to an immutable variable is an error
65
+ if let Some ( assignee ) = match e . kind {
66
+ ExprKind :: Assign ( assignee , _ , _ ) | ExprKind :: AssignOp ( _, assignee , _) => Some ( assignee ) ,
85
67
_ => None ,
86
68
} {
87
- no_change = can_mut_borrow_both ( cx, caller, lhs) ;
88
- }
89
- if !no_change {
90
- // if one change occurs, stop the loop
91
- break ;
69
+ if !can_mut_borrow_both ( cx, caller, assignee) {
70
+ return true ;
71
+ }
92
72
}
93
73
}
94
74
}
95
- !no_change
96
- } else {
97
- false
98
- } {
99
- // skip this lint
100
- return true ;
101
75
}
76
+ false
102
77
}
103
78
79
+ if let ExprKind :: Call ( _, [ child, ..] ) = expr. kind {
80
+ // filter first layer of iterator
81
+ let mut child = child;
82
+ // get inner real caller requests for clone
83
+ while let ExprKind :: MethodCall ( _, caller, _, _) = child. kind {
84
+ child = caller;
85
+ }
86
+ if is_mutable ( cx, child) && is_caller_or_fields_changed ( cx, body, child) {
87
+ // skip lint
88
+ return true ;
89
+ }
90
+ } ;
91
+
104
92
// the lint should not be executed if no violation happens
105
93
let snippet = if let ExprKind :: MethodCall ( maybe_iter_method_name, collection, [ ] , _) = receiver. kind
106
94
&& maybe_iter_method_name. ident . name == sym:: iter
0 commit comments