Merge pull request #1847 from Manishearth/nested_while_let
don't lint while_let_on_iterator on nested loops
This commit is contained in:
@@ -251,7 +251,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
|
|||||||
reg.register_late_lint_pass(box shadow::Pass);
|
reg.register_late_lint_pass(box shadow::Pass);
|
||||||
reg.register_late_lint_pass(box types::LetPass);
|
reg.register_late_lint_pass(box types::LetPass);
|
||||||
reg.register_late_lint_pass(box types::UnitCmp);
|
reg.register_late_lint_pass(box types::UnitCmp);
|
||||||
reg.register_late_lint_pass(box loops::Pass);
|
reg.register_late_lint_pass(box loops::Pass::default());
|
||||||
reg.register_late_lint_pass(box lifetimes::LifetimePass);
|
reg.register_late_lint_pass(box lifetimes::LifetimePass);
|
||||||
reg.register_late_lint_pass(box entry::HashMapLint);
|
reg.register_late_lint_pass(box entry::HashMapLint);
|
||||||
reg.register_late_lint_pass(box ranges::StepByZero);
|
reg.register_late_lint_pass(box ranges::StepByZero);
|
||||||
|
|||||||
@@ -304,8 +304,10 @@ declare_lint! {
|
|||||||
"any loop that will always `break` or `return`"
|
"any loop that will always `break` or `return`"
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone, Default)]
|
||||||
pub struct Pass;
|
pub struct Pass {
|
||||||
|
loop_count : usize,
|
||||||
|
}
|
||||||
|
|
||||||
impl LintPass for Pass {
|
impl LintPass for Pass {
|
||||||
fn get_lints(&self) -> LintArray {
|
fn get_lints(&self) -> LintArray {
|
||||||
@@ -327,6 +329,13 @@ impl LintPass for Pass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||||
|
fn check_expr_post(&mut self, _: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||||
|
match expr.node {
|
||||||
|
ExprWhile(..) | ExprLoop(..) => { self.loop_count -= 1; }
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||||
if let Some((pat, arg, body)) = higher::for_loop(expr) {
|
if let Some((pat, arg, body)) = higher::for_loop(expr) {
|
||||||
check_for_loop(cx, pat, arg, body, expr);
|
check_for_loop(cx, pat, arg, body, expr);
|
||||||
@@ -336,6 +345,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||||||
match expr.node {
|
match expr.node {
|
||||||
ExprWhile(_, ref block, _) |
|
ExprWhile(_, ref block, _) |
|
||||||
ExprLoop(ref block, _, _) => {
|
ExprLoop(ref block, _, _) => {
|
||||||
|
self.loop_count += 1;
|
||||||
if never_loop(block, &expr.id) {
|
if never_loop(block, &expr.id) {
|
||||||
span_lint(cx, NEVER_LOOP, expr.span, "this loop never actually loops");
|
span_lint(cx, NEVER_LOOP, expr.span, "this loop never actually loops");
|
||||||
}
|
}
|
||||||
@@ -398,7 +408,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||||||
&ExprMethodCall(method_name, _, ref method_args)) = (pat, &match_expr.node) {
|
&ExprMethodCall(method_name, _, ref method_args)) = (pat, &match_expr.node) {
|
||||||
let iter_expr = &method_args[0];
|
let iter_expr = &method_args[0];
|
||||||
let lhs_constructor = last_path_segment(qpath);
|
let lhs_constructor = last_path_segment(qpath);
|
||||||
if method_name.node == "next" && match_trait_method(cx, match_expr, &paths::ITERATOR) &&
|
if self.loop_count < 2 && method_name.node == "next" &&
|
||||||
|
match_trait_method(cx, match_expr, &paths::ITERATOR) &&
|
||||||
lhs_constructor.name == "Some" && !is_refutable(cx, &pat_args[0]) &&
|
lhs_constructor.name == "Some" && !is_refutable(cx, &pat_args[0]) &&
|
||||||
!is_iterator_used_after_while_let(cx, iter_expr) {
|
!is_iterator_used_after_while_let(cx, iter_expr) {
|
||||||
let iterator = snippet(cx, method_args[0].span, "_");
|
let iterator = snippet(cx, method_args[0].span, "_");
|
||||||
|
|||||||
@@ -165,4 +165,16 @@ fn refutable() {
|
|||||||
for &(1, 2, 3) in b {}
|
for &(1, 2, 3) in b {}
|
||||||
for &Option::None in b.next() {}
|
for &Option::None in b.next() {}
|
||||||
// */
|
// */
|
||||||
|
|
||||||
|
let mut y = a.iter();
|
||||||
|
loop { // x is reused, so don't lint here
|
||||||
|
while let Some(v) = y.next() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut y = a.iter();
|
||||||
|
for _ in 0..2 {
|
||||||
|
while let Some(v) = y.next() {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user