Skip to content

Commit a300b0e

Browse files
committed
Auto merge of #7144 - rust-lang:while_immutable_mut_cond, r=flip1995
while_immutable_cond: check condition for mutation This fixes #6689 by also checking the bindings mutated in the condition, whereas it was previously only checked in the loop body. --- changelog: Fix FP in [`while_immutable_cond`] where mutation in the loop variable wasn't picked up.
2 parents 5e49c4b + 63425de commit a300b0e

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

clippy_lints/src/loops/while_immutable_condition.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,14 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, expr: &'
2828
return;
2929
}
3030
let used_in_condition = &var_visitor.ids;
31-
let no_cond_variable_mutated = if let Some(used_mutably) = mutated_variables(expr, cx) {
32-
used_in_condition.is_disjoint(&used_mutably)
33-
} else {
34-
return;
35-
};
31+
let mutated_in_body = mutated_variables(expr, cx);
32+
let mutated_in_condition = mutated_variables(cond, cx);
33+
let no_cond_variable_mutated =
34+
if let (Some(used_mutably_body), Some(used_mutably_cond)) = (mutated_in_body, mutated_in_condition) {
35+
used_in_condition.is_disjoint(&used_mutably_body) && used_in_condition.is_disjoint(&used_mutably_cond)
36+
} else {
37+
return;
38+
};
3639
let mutable_static_in_cond = var_visitor.def_ids.iter().any(|(_, v)| *v);
3740

3841
let mut has_break_or_return_visitor = HasBreakOrReturnVisitor {

tests/ui/infinite_loop.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,23 @@ fn while_loop_with_break_and_return() {
192192
}
193193
}
194194

195+
fn immutable_condition_false_positive(mut n: u64) -> u32 {
196+
let mut count = 0;
197+
while {
198+
n >>= 1;
199+
n != 0
200+
} {
201+
count += 1;
202+
}
203+
count
204+
}
205+
195206
fn main() {
196207
immutable_condition();
197208
unused_var();
198209
used_immutable();
199210
internally_mutable();
211+
immutable_condition_false_positive(5);
200212

201213
let mut c = Counter { count: 0 };
202214
c.inc_n(5);

0 commit comments

Comments
 (0)