diff options
| author | bors <bors@rust-lang.org> | 2021-04-30 15:08:27 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-04-30 15:08:27 +0000 |
| commit | a300b0e66ce819833c4de4439ea3044a4c89eda3 (patch) | |
| tree | b2d1f7727897bb8bd95d8716ce053ac6ac4a8425 | |
| parent | 5e49c4bd67d69131265cb414a29d5489a9eb35a1 (diff) | |
| parent | 63425de77db7f4dee55cfceeed7e174bfe986b0d (diff) | |
| download | rust-a300b0e66ce819833c4de4439ea3044a4c89eda3.tar.gz rust-a300b0e66ce819833c4de4439ea3044a4c89eda3.zip | |
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.
| -rw-r--r-- | clippy_lints/src/loops/while_immutable_condition.rs | 13 | ||||
| -rw-r--r-- | tests/ui/infinite_loop.rs | 12 |
2 files changed, 20 insertions, 5 deletions
diff --git a/clippy_lints/src/loops/while_immutable_condition.rs b/clippy_lints/src/loops/while_immutable_condition.rs index de267cc77d2..55404b87ec9 100644 --- a/clippy_lints/src/loops/while_immutable_condition.rs +++ b/clippy_lints/src/loops/while_immutable_condition.rs @@ -28,11 +28,14 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, expr: &' return; } let used_in_condition = &var_visitor.ids; - let no_cond_variable_mutated = if let Some(used_mutably) = mutated_variables(expr, cx) { - used_in_condition.is_disjoint(&used_mutably) - } else { - return; - }; + let mutated_in_body = mutated_variables(expr, cx); + let mutated_in_condition = mutated_variables(cond, cx); + let no_cond_variable_mutated = + if let (Some(used_mutably_body), Some(used_mutably_cond)) = (mutated_in_body, mutated_in_condition) { + used_in_condition.is_disjoint(&used_mutably_body) && used_in_condition.is_disjoint(&used_mutably_cond) + } else { + return; + }; let mutable_static_in_cond = var_visitor.def_ids.iter().any(|(_, v)| *v); let mut has_break_or_return_visitor = HasBreakOrReturnVisitor { diff --git a/tests/ui/infinite_loop.rs b/tests/ui/infinite_loop.rs index 72591f12baf..3d8fb8507e5 100644 --- a/tests/ui/infinite_loop.rs +++ b/tests/ui/infinite_loop.rs @@ -192,11 +192,23 @@ fn while_loop_with_break_and_return() { } } +fn immutable_condition_false_positive(mut n: u64) -> u32 { + let mut count = 0; + while { + n >>= 1; + n != 0 + } { + count += 1; + } + count +} + fn main() { immutable_condition(); unused_var(); used_immutable(); internally_mutable(); + immutable_condition_false_positive(5); let mut c = Counter { count: 0 }; c.inc_n(5); |
