| #![warn(clippy::manual_pop_if)] |
| #![allow(clippy::collapsible_if, clippy::redundant_closure)] |
| #![feature(binary_heap_pop_if)] |
| |
| use std::collections::{BinaryHeap, VecDeque}; |
| use std::marker::PhantomData; |
| |
| fn main() {} |
| |
| // FakeVec has the same methods as Vec but isn't actually a Vec |
| struct FakeVec<T>(PhantomData<T>); |
| |
| impl<T> FakeVec<T> { |
| fn last(&self) -> Option<&T> { |
| None |
| } |
| |
| fn pop(&mut self) -> Option<T> { |
| None |
| } |
| } |
| |
| fn is_some_and_pattern_positive(mut vec: Vec<i32>, mut deque: VecDeque<i32>, mut heap: BinaryHeap<i32>) { |
| //~v manual_pop_if |
| vec.pop_if(|x| *x > 2); |
| |
| //~v manual_pop_if |
| vec.pop_if(|x| *x > 2); |
| |
| //~v manual_pop_if |
| vec.pop_if(|x| *x > 2); |
| |
| //~v manual_pop_if |
| deque.pop_back_if(|x| *x > 2); |
| |
| //~v manual_pop_if |
| deque.pop_front_if(|x| *x > 2); |
| |
| //~v manual_pop_if |
| heap.pop_if(|x| *x > 2); |
| } |
| |
| fn is_some_and_pattern_negative(mut vec: Vec<i32>, mut deque: VecDeque<i32>) { |
| // Do not lint, different vectors |
| let mut vec2 = vec![0]; |
| if vec.last().is_some_and(|x| *x > 2) { |
| vec2.pop().unwrap(); |
| } |
| |
| // Do not lint, non-Vec type |
| let mut fake_vec: FakeVec<i32> = FakeVec(PhantomData); |
| if fake_vec.last().is_some_and(|x| *x > 2) { |
| fake_vec.pop().unwrap(); |
| } |
| |
| // Do not lint, else block |
| let _result = if vec.last().is_some_and(|x| *x > 2) { |
| vec.pop().unwrap() |
| } else { |
| 0 |
| }; |
| } |
| |
| fn if_let_pattern_positive(mut vec: Vec<i32>, mut deque: VecDeque<i32>, mut heap: BinaryHeap<i32>) { |
| //~v manual_pop_if |
| vec.pop_if(|x| *x > 2); |
| |
| //~v manual_pop_if |
| vec.pop_if(|x| *x > 2); |
| |
| //~v manual_pop_if |
| vec.pop_if(|x| *x > 2); |
| |
| //~v manual_pop_if |
| deque.pop_back_if(|x| *x > 2); |
| |
| //~v manual_pop_if |
| deque.pop_front_if(|x| *x > 2); |
| |
| //~v manual_pop_if |
| heap.pop_if(|x| *x > 2); |
| } |
| |
| fn if_let_pattern_negative(mut vec: Vec<i32>) { |
| // Do not lint, different vectors |
| let mut vec2 = vec![0]; |
| if let Some(x) = vec.last() { |
| if *x > 2 { |
| vec2.pop().unwrap(); |
| } |
| } |
| |
| // Do not lint, intervening statements |
| if let Some(x) = vec.last() { |
| println!("Checking {}", x); |
| if *x > 2 { |
| vec.pop().unwrap(); |
| } |
| } |
| |
| // Do not lint, bound variable not used in condition |
| if let Some(_x) = vec.last() { |
| if vec.len() > 2 { |
| vec.pop().unwrap(); |
| } |
| } |
| |
| // Do not lint, else block |
| let _result = if let Some(x) = vec.last() { |
| if *x > 2 { vec.pop().unwrap() } else { 0 } |
| } else { |
| 0 |
| }; |
| } |
| |
| fn let_chain_pattern_positive(mut vec: Vec<i32>, mut deque: VecDeque<i32>, mut heap: BinaryHeap<i32>) { |
| vec.pop_if(|x| *x > 2); |
| |
| vec.pop_if(|x| *x > 2); |
| |
| vec.pop_if(|x| *x > 2); |
| |
| deque.pop_back_if(|x| *x > 2); |
| |
| deque.pop_front_if(|x| *x > 2); |
| |
| heap.pop_if(|x| *x > 2); |
| } |
| |
| fn let_chain_pattern_negative(mut vec: Vec<i32>) { |
| // Do not lint, different vectors |
| let mut vec2 = vec![0]; |
| if let Some(x) = vec.last() |
| && *x > 2 |
| { |
| vec2.pop().unwrap(); |
| } |
| |
| // Do not lint, bound variable not used in condition |
| if let Some(_x) = vec.last() |
| && vec.len() > 2 |
| { |
| vec.pop().unwrap(); |
| } |
| |
| // Do not lint, else block |
| let _result = if let Some(x) = vec.last() |
| && *x > 2 |
| { |
| vec.pop().unwrap() |
| } else { |
| 0 |
| }; |
| } |
| |
| fn map_unwrap_or_pattern_positive(mut vec: Vec<i32>, mut deque: VecDeque<i32>, mut heap: BinaryHeap<i32>) { |
| //~v manual_pop_if |
| vec.pop_if(|x| *x > 2); |
| |
| //~v manual_pop_if |
| vec.pop_if(|x| *x > 2); |
| |
| //~v manual_pop_if |
| vec.pop_if(|x| *x > 2); |
| |
| //~v manual_pop_if |
| deque.pop_back_if(|x| *x > 2); |
| |
| //~v manual_pop_if |
| deque.pop_front_if(|x| *x > 2); |
| |
| //~v manual_pop_if |
| heap.pop_if(|x| *x > 2); |
| } |
| |
| fn map_unwrap_or_pattern_negative(mut vec: Vec<i32>) { |
| // Do not lint, unwrap_or(true) instead of false |
| if vec.last().map(|x| *x > 2).unwrap_or(true) { |
| vec.pop().unwrap(); |
| } |
| |
| // Do not lint, different vectors |
| let mut vec2 = vec![0]; |
| if vec.last().map(|x| *x > 2).unwrap_or(false) { |
| vec2.pop().unwrap(); |
| } |
| |
| // Do not lint, non-Vec type |
| let mut fake_vec: FakeVec<i32> = FakeVec(PhantomData); |
| if fake_vec.last().map(|x| *x > 2).unwrap_or(false) { |
| fake_vec.pop().unwrap(); |
| } |
| |
| // Do not lint, map returns non-boolean |
| if vec.last().map(|x| x + 1).unwrap_or(0) > 2 { |
| vec.pop().unwrap(); |
| } |
| |
| // Do not lint, else block |
| let _result = if vec.last().map(|x| *x > 2).unwrap_or(false) { |
| vec.pop().unwrap() |
| } else { |
| 0 |
| }; |
| } |
| |
| // this makes sure we do not expand vec![] in the suggestion |
| fn handle_macro_in_closure(mut vec: Vec<Vec<i32>>) { |
| //~v manual_pop_if |
| vec.pop_if(|e| *e == vec![1]); |
| } |
| |
| #[clippy::msrv = "1.85.0"] |
| fn msrv_too_low_vec(mut vec: Vec<i32>) { |
| if vec.last().is_some_and(|x| *x > 2) { |
| vec.pop().unwrap(); |
| } |
| } |
| |
| #[clippy::msrv = "1.92.0"] |
| fn msrv_too_low_vecdeque(mut deque: VecDeque<i32>) { |
| if deque.back().is_some_and(|x| *x > 2) { |
| deque.pop_back().unwrap(); |
| } |
| |
| if deque.front().is_some_and(|x| *x > 2) { |
| deque.pop_front().unwrap(); |
| } |
| } |
| |
| #[clippy::msrv = "1.86.0"] |
| fn msrv_high_enough_vec(mut vec: Vec<i32>) { |
| //~v manual_pop_if |
| vec.pop_if(|x| *x > 2); |
| } |
| |
| #[clippy::msrv = "1.93.0"] |
| fn msrv_high_enough_vecdeque(mut deque: VecDeque<i32>) { |
| //~v manual_pop_if |
| deque.pop_back_if(|x| *x > 2); |
| |
| //~v manual_pop_if |
| deque.pop_front_if(|x| *x > 2); |
| } |