| #![feature(try_blocks)] | |
| #![expect(clippy::eq_op, clippy::single_match, clippy::while_immutable_condition)] | |
| //@no-rustfix | |
| use std::arch::asm; | |
| fn test1() { | |
| let mut x = 0; | |
| loop { | |
| //~^ never_loop | |
| // clippy::never_loop | |
| x += 1; | |
| if x == 1 { | |
| return; | |
| } | |
| break; | |
| } | |
| } | |
| fn test2() { | |
| let mut x = 0; | |
| loop { | |
| x += 1; | |
| if x == 1 { | |
| break; | |
| } | |
| } | |
| } | |
| fn test3() { | |
| let mut x = 0; | |
| loop { | |
| //~^ never_loop | |
| // never loops | |
| x += 1; | |
| break; | |
| } | |
| } | |
| fn test4() { | |
| let mut x = 1; | |
| loop { | |
| x += 1; | |
| match x { | |
| 5 => return, | |
| _ => (), | |
| } | |
| } | |
| } | |
| fn test5() { | |
| let i = 0; | |
| loop { | |
| //~^ never_loop | |
| // never loops | |
| while i == 0 { | |
| //~^ never_loop | |
| // never loops | |
| break; | |
| } | |
| return; | |
| } | |
| } | |
| fn test6() { | |
| let mut x = 0; | |
| 'outer: loop { | |
| x += 1; | |
| loop { | |
| //~^ never_loop | |
| // never loops | |
| if x == 5 { | |
| break; | |
| } | |
| continue 'outer; | |
| } | |
| return; | |
| } | |
| } | |
| fn test7() { | |
| let mut x = 0; | |
| loop { | |
| x += 1; | |
| match x { | |
| 1 => continue, | |
| _ => (), | |
| } | |
| return; | |
| } | |
| } | |
| fn test8() { | |
| let mut x = 0; | |
| loop { | |
| x += 1; | |
| match x { | |
| 5 => return, | |
| _ => continue, | |
| } | |
| } | |
| } | |
| fn test9() { | |
| let x = Some(1); | |
| while let Some(y) = x { | |
| //~^ never_loop | |
| // never loops | |
| return; | |
| } | |
| } | |
| fn test10() { | |
| for x in 0..10 { | |
| //~^ never_loop | |
| // never loops | |
| match x { | |
| 1 => break, | |
| _ => return, | |
| } | |
| } | |
| } | |
| fn test11<F: FnMut() -> i32>(mut f: F) { | |
| loop { | |
| return match f() { | |
| 1 => continue, | |
| _ => (), | |
| }; | |
| } | |
| } | |
| pub fn test12(a: bool, b: bool) { | |
| 'label: loop { | |
| loop { | |
| if a { | |
| continue 'label; | |
| } | |
| if b { | |
| break; | |
| } | |
| } | |
| break; | |
| } | |
| } | |
| pub fn test13() { | |
| let mut a = true; | |
| loop { | |
| // infinite loop | |
| while a { | |
| if true { | |
| a = false; | |
| continue; | |
| } | |
| return; | |
| } | |
| } | |
| } | |
| pub fn test14() { | |
| let mut a = true; | |
| 'outer: while a { | |
| //~^ never_loop | |
| // never loops | |
| while a { | |
| if a { | |
| a = false; | |
| continue; | |
| } | |
| } | |
| break 'outer; | |
| } | |
| } | |
| // Issue #1991: the outer loop should not warn. | |
| pub fn test15() { | |
| 'label: loop { | |
| while false { | |
| //~^ never_loop | |
| break 'label; | |
| } | |
| } | |
| } | |
| // Issue #4058: `continue` in `break` expression | |
| pub fn test16() { | |
| let mut n = 1; | |
| loop { | |
| break if n != 5 { | |
| n += 1; | |
| continue; | |
| }; | |
| } | |
| } | |
| // Issue #9001: `continue` in struct expression fields | |
| pub fn test17() { | |
| struct Foo { | |
| f: (), | |
| } | |
| let mut n = 0; | |
| let _ = loop { | |
| break Foo { | |
| f: if n < 5 { | |
| n += 1; | |
| continue; | |
| }, | |
| }; | |
| }; | |
| } | |
| // Issue #9356: `continue` in else branch of let..else | |
| pub fn test18() { | |
| let x = Some(0); | |
| let y = 0; | |
| // might loop | |
| let _ = loop { | |
| let Some(x) = x else { | |
| if y > 0 { | |
| continue; | |
| } else { | |
| return; | |
| } | |
| }; | |
| break x; | |
| }; | |
| // never loops | |
| let _ = loop { | |
| //~^ never_loop | |
| let Some(x) = x else { | |
| return; | |
| }; | |
| break x; | |
| }; | |
| } | |
| // Issue #9831: unconditional break to internal labeled block | |
| pub fn test19() { | |
| fn thing(iter: impl Iterator) { | |
| for _ in iter { | |
| 'b: { | |
| break 'b; | |
| } | |
| } | |
| } | |
| } | |
| pub fn test20() { | |
| 'a: loop { | |
| //~^ never_loop | |
| 'b: { | |
| break 'b 'c: { | |
| break 'a; | |
| //~^ diverging_sub_expression | |
| }; | |
| } | |
| } | |
| } | |
| pub fn test21() { | |
| loop { | |
| 'a: { | |
| {} | |
| break 'a; | |
| } | |
| } | |
| } | |
| // Issue 10304: code after break from block was not considered | |
| // unreachable code and was considered for further analysis of | |
| // whether the loop would ever be executed or not. | |
| pub fn test22() { | |
| for _ in 0..10 { | |
| 'block: { | |
| break 'block; | |
| return; | |
| } | |
| println!("looped"); | |
| } | |
| } | |
| pub fn test23() { | |
| for _ in 0..10 { | |
| 'block: { | |
| for _ in 0..20 { | |
| //~^ never_loop | |
| break 'block; | |
| } | |
| } | |
| println!("looped"); | |
| } | |
| } | |
| pub fn test24() { | |
| 'a: for _ in 0..10 { | |
| 'b: { | |
| let x = Some(1); | |
| match x { | |
| None => break 'a, | |
| Some(_) => break 'b, | |
| } | |
| } | |
| } | |
| } | |
| // Do not lint, we can evaluate `true` to always succeed thus can short-circuit before the `return` | |
| pub fn test25() { | |
| loop { | |
| 'label: { | |
| if const { true } { | |
| break 'label; | |
| } | |
| return; | |
| } | |
| } | |
| } | |
| pub fn test26() { | |
| loop { | |
| 'label: { | |
| if 1 == 1 { | |
| break 'label; | |
| } | |
| return; | |
| } | |
| } | |
| } | |
| pub fn test27() { | |
| loop { | |
| 'label: { | |
| let x = true; | |
| if x { | |
| break 'label; | |
| } | |
| return; | |
| } | |
| } | |
| } | |
| // issue 11004 | |
| pub fn test29() { | |
| loop { | |
| 'label: { | |
| if true { | |
| break 'label; | |
| } | |
| return; | |
| } | |
| } | |
| } | |
| pub fn test30() { | |
| 'a: loop { | |
| 'b: { | |
| for j in 0..2 { | |
| if j == 1 { | |
| break 'b; | |
| } | |
| } | |
| break 'a; | |
| } | |
| } | |
| } | |
| pub fn test31(b: bool) { | |
| 'a: loop { | |
| 'b: { | |
| 'c: loop { | |
| //~^ never_loop | |
| if b { break 'c } else { break 'b } | |
| } | |
| continue 'a; | |
| } | |
| break 'a; | |
| } | |
| } | |
| pub fn test32() { | |
| loop { | |
| //~^ never_loop | |
| panic!("oh no"); | |
| } | |
| loop { | |
| //~^ never_loop | |
| unimplemented!("not yet"); | |
| } | |
| loop { | |
| // no error | |
| todo!("maybe later"); | |
| } | |
| } | |
| pub fn issue12205() -> Option<()> { | |
| loop { | |
| let _: Option<_> = try { | |
| None?; | |
| return Some(()); | |
| }; | |
| } | |
| } | |
| fn stmt_after_return() { | |
| for v in 0..10 { | |
| //~^ never_loop | |
| break; | |
| println!("{v}"); | |
| } | |
| } | |
| fn loop_label() { | |
| 'outer: for v in 0..10 { | |
| //~^ never_loop | |
| loop { | |
| //~^ never_loop | |
| break 'outer; | |
| } | |
| return; | |
| } | |
| for v in 0..10 { | |
| //~^ never_loop | |
| 'inner: loop { | |
| //~^ never_loop | |
| break 'inner; | |
| } | |
| return; | |
| } | |
| } | |
| fn main() {} | |
| fn issue15059() { | |
| 'a: for _ in 0..1 { | |
| //~^ never_loop | |
| break 'a; | |
| } | |
| let mut b = 1; | |
| 'a: for i in 0..1 { | |
| //~^ never_loop | |
| match i { | |
| 0 => { | |
| b *= 2; | |
| break 'a; | |
| }, | |
| x => { | |
| b += x; | |
| break 'a; | |
| }, | |
| } | |
| } | |
| #[allow(clippy::unused_unit)] | |
| for v in 0..10 { | |
| //~^ never_loop | |
| break; | |
| println!("{v}"); | |
| // This is comment and should be kept | |
| println!("This is a comment"); | |
| () | |
| } | |
| } | |
| fn issue15350() { | |
| 'bar: for _ in 0..100 { | |
| //~^ never_loop | |
| loop { | |
| //~^ never_loop | |
| println!("This will still run"); | |
| break 'bar; | |
| } | |
| } | |
| 'foo: for _ in 0..100 { | |
| //~^ never_loop | |
| loop { | |
| //~^ never_loop | |
| println!("This will still run"); | |
| loop { | |
| //~^ never_loop | |
| println!("This will still run"); | |
| break 'foo; | |
| } | |
| } | |
| } | |
| } | |
| fn issue15673() { | |
| loop { | |
| unsafe { | |
| // No lint since we don't analyze the inside of the asm | |
| asm! { | |
| "/* {} */", | |
| label { | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| //~v never_loop | |
| loop { | |
| unsafe { | |
| asm! { | |
| "/* {} */", | |
| label { | |
| break; | |
| } | |
| } | |
| } | |
| return; | |
| } | |
| } | |
| #[expect(clippy::diverging_sub_expression, clippy::short_circuit_statement)] | |
| fn issue16462() { | |
| let mut n = 10; | |
| loop { | |
| println!("{n}"); | |
| n -= 1; | |
| n >= 0 || break; | |
| } | |
| } |