@@ -304,8 +304,10 @@ declare_lint! {
304
304
"any loop that will always `break` or `return`"
305
305
}
306
306
307
- #[ derive( Copy , Clone ) ]
308
- pub struct Pass ;
307
+ #[ derive( Copy , Clone , Default ) ]
308
+ pub struct Pass {
309
+ loop_count : usize ,
310
+ }
309
311
310
312
impl LintPass for Pass {
311
313
fn get_lints ( & self ) -> LintArray {
@@ -327,6 +329,13 @@ impl LintPass for Pass {
327
329
}
328
330
329
331
impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for Pass {
332
+ fn check_expr_post ( & mut self , _: & LateContext < ' a , ' tcx > , expr : & ' tcx Expr ) {
333
+ match expr. node {
334
+ ExprWhile ( ..) | ExprLoop ( ..) => { self . loop_count -= 1 ; }
335
+ _ => ( )
336
+ }
337
+ }
338
+
330
339
fn check_expr ( & mut self , cx : & LateContext < ' a , ' tcx > , expr : & ' tcx Expr ) {
331
340
if let Some ( ( pat, arg, body) ) = higher:: for_loop ( expr) {
332
341
check_for_loop ( cx, pat, arg, body, expr) ;
@@ -336,6 +345,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
336
345
match expr. node {
337
346
ExprWhile ( _, ref block, _) |
338
347
ExprLoop ( ref block, _, _) => {
348
+ self . loop_count += 1 ;
339
349
if never_loop ( block, & expr. id ) {
340
350
span_lint ( cx, NEVER_LOOP , expr. span , "this loop never actually loops" ) ;
341
351
}
@@ -398,7 +408,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
398
408
& ExprMethodCall ( method_name, _, ref method_args) ) = ( pat, & match_expr. node ) {
399
409
let iter_expr = & method_args[ 0 ] ;
400
410
let lhs_constructor = last_path_segment ( qpath) ;
401
- if method_name. node == "next" && match_trait_method ( cx, match_expr, & paths:: ITERATOR ) &&
411
+ if self . loop_count < 2 && method_name. node == "next" &&
412
+ match_trait_method ( cx, match_expr, & paths:: ITERATOR ) &&
402
413
lhs_constructor. name == "Some" && !is_refutable ( cx, & pat_args[ 0 ] ) &&
403
414
!is_iterator_used_after_while_let ( cx, iter_expr) {
404
415
let iterator = snippet ( cx, method_args[ 0 ] . span , "_" ) ;
0 commit comments