//@run-rustfix #![allow(unused)] #![warn(clippy::manual_while_let_some)] struct VecInStruct { numbers: Vec, unrelated: String, } struct Foo { a: i32, b: i32, } fn accept_i32(_: i32) {} fn accept_optional_i32(_: Option) {} fn accept_i32_tuple(_: (i32, i32)) {} fn main() { let mut numbers = vec![1, 2, 3, 4, 5]; while let Some(number) = numbers.pop() { } let mut val = VecInStruct { numbers: vec![1, 2, 3, 4, 5], unrelated: String::new(), }; while let Some(number) = val.numbers.pop() { } while let Some(element) = numbers.pop() { accept_i32(element); } while let Some(element) = numbers.pop() { accept_i32(element); } // This should not warn. It "conditionally" pops elements. while !numbers.is_empty() { if true { accept_i32(numbers.pop().unwrap()); } } // This should also not warn. It conditionally pops elements. while !numbers.is_empty() { if false { continue; } accept_i32(numbers.pop().unwrap()); } // This should not warn. It pops elements, but does not unwrap it. // Might handle the Option in some other arbitrary way. while !numbers.is_empty() { accept_optional_i32(numbers.pop()); } let unrelated_vec: Vec = Vec::new(); // This should not warn. It pops elements from a different vector. while !unrelated_vec.is_empty() { accept_i32(numbers.pop().unwrap()); } macro_rules! generate_loop { () => { while !numbers.is_empty() { accept_i32(numbers.pop().unwrap()); } }; } // Do not warn if the loop comes from a macro. generate_loop!(); // Try other kinds of patterns let mut numbers = vec![(0, 0), (1, 1), (2, 2)]; while let Some((a, b)) = numbers.pop() { } while let Some(element) = numbers.pop() { accept_i32_tuple(element); } let mut results = vec![Foo { a: 1, b: 2 }, Foo { a: 3, b: 4 }]; while let Some(Foo { a, b }) = results.pop() { } }