From 94dc2f567ab7cd84a1d200749ca376eb7a5d96ec Mon Sep 17 00:00:00 2001 From: Florian Hartwig Date: Thu, 26 Nov 2015 00:09:01 +0100 Subject: [PATCH] Suppress explicit_counter_loop lint if loop variable is used after the loop --- src/loops.rs | 25 +++++++++++++++++-------- tests/compile-fail/for_loop.rs | 9 ++++----- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/loops.rs b/src/loops.rs index 92dff3a7d931..cfde17417159 100644 --- a/src/loops.rs +++ b/src/loops.rs @@ -150,7 +150,8 @@ impl LateLintPass for LoopsPass { for (id, _) in visitor.states.iter().filter( |&(_,v)| *v == VarState::IncrOnce) { let mut visitor2 = InitializeVisitor { cx: cx, end_expr: expr, var_id: id.clone(), state: VarState::IncrOnce, name: None, - depth: 0, done: false }; + depth: 0, + past_loop: false }; walk_block(&mut visitor2, block); if visitor2.state == VarState::Warn { @@ -502,7 +503,7 @@ struct InitializeVisitor<'v, 't: 'v> { state: VarState, name: Option, depth: u32, // depth of conditional expressions - done: bool + past_loop: bool } impl<'v, 't> Visitor<'v> for InitializeVisitor<'v, 't> { @@ -530,12 +531,16 @@ impl<'v, 't> Visitor<'v> for InitializeVisitor<'v, 't> { } fn visit_expr(&mut self, expr: &'v Expr) { - if self.state == VarState::DontWarn || expr == self.end_expr { - self.done = true; + if self.state == VarState::DontWarn { + return; + } + if expr == self.end_expr { + self.past_loop = true; + return; } // No need to visit expressions before the variable is - // declared or after we've rejected it. - if self.state == VarState::IncrOnce || self.done { + // declared + if self.state == VarState::IncrOnce { return; } @@ -556,11 +561,15 @@ impl<'v, 't> Visitor<'v> for InitializeVisitor<'v, 't> { _ => () } } + + if self.past_loop { + self.state = VarState::DontWarn; + return; + } } // If there are other loops between the declaration and the target loop, give up - else if is_loop(expr) { + else if !self.past_loop && is_loop(expr) { self.state = VarState::DontWarn; - self.done = true; return; } // Keep track of whether we're inside a conditional expression diff --git a/tests/compile-fail/for_loop.rs b/tests/compile-fail/for_loop.rs index 02c8cc560838..3d19bd66094a 100644 --- a/tests/compile-fail/for_loop.rs +++ b/tests/compile-fail/for_loop.rs @@ -132,11 +132,6 @@ fn main() { _index = 0; for _v in &vec { _index += 1 } //~ERROR the variable `_index` is used as a loop counter - let mut _index; - _index = 0; - for _v in &vec { _index += 1 } //~ERROR the variable `_index` is used as a loop counter - for _v in &vec { _index += 1 } // But this does not warn - // Potential false positives let mut _index = 0; _index = 1; @@ -187,4 +182,8 @@ fn main() { let mut _index = 0; { let mut _x = &mut _index; } for _v in &vec { _index += 1 } + + let mut index = 0; + for _v in &vec { index += 1 } + println!("index: {}", index); }