2 #![warn(clippy::manual_retain)]
3 #![allow(unused, clippy::redundant_clone)]
4 use std::collections::BTreeMap;
5 use std::collections::BTreeSet;
6 use std::collections::BinaryHeap;
7 use std::collections::HashMap;
8 use std::collections::HashSet;
9 use std::collections::VecDeque;
25 fn binary_heap_retain() {
26 // NOTE: Do not lint now, because binary_heap_retain is nighyly API.
27 // And we need to add a test case for msrv if we update this implmention.
28 // https://github.com/rust-lang/rust/issues/71503
29 let mut heap = BinaryHeap::from([1, 2, 3]);
30 heap = heap.into_iter().filter(|x| x % 2 == 0).collect();
31 heap = heap.iter().filter(|&x| x % 2 == 0).copied().collect();
32 heap = heap.iter().filter(|&x| x % 2 == 0).cloned().collect();
34 // Do not lint, because type conversion is performed
35 heap = heap.into_iter().filter(|x| x % 2 == 0).collect::<BinaryHeap<i8>>();
36 heap = heap.iter().filter(|&x| x % 2 == 0).copied().collect::<BinaryHeap<i8>>();
37 heap = heap.iter().filter(|&x| x % 2 == 0).cloned().collect::<BinaryHeap<i8>>();
39 // Do not lint, because this expression is not assign.
40 let mut bar: BinaryHeap<i8> = heap.iter().filter(|&x| x % 2 == 0).copied().collect();
41 let mut foobar: BinaryHeap<i8> = heap.into_iter().filter(|x| x % 2 == 0).collect();
43 // Do not lint, because it is an assignment to a different variable.
44 bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();
45 bar = foobar.into_iter().filter(|x| x % 2 == 0).collect();
48 fn btree_map_retain() {
49 let mut btree_map: BTreeMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();
51 btree_map.retain(|k, _| k % 2 == 0);
52 btree_map.retain(|_, &mut v| v % 2 == 0);
53 btree_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0));
58 .filter(|(x, _)| x % 2 == 0)
59 .collect::<BTreeMap<i8, i8>>();
61 // Do not lint, because this expression is not assign.
62 let mut foobar: BTreeMap<i8, i8> = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
64 // Do not lint, because it is an assignment to a different variable.
65 btree_map = foobar.into_iter().filter(|(k, _)| k % 2 == 0).collect();
68 fn btree_set_retain() {
69 let mut btree_set = BTreeSet::from([1, 2, 3, 4, 5, 6]);
72 btree_set.retain(|x| x % 2 == 0);
73 btree_set.retain(|x| x % 2 == 0);
74 btree_set.retain(|x| x % 2 == 0);
76 // Do not lint, because type conversion is performed
79 .filter(|&x| x % 2 == 0)
81 .collect::<BTreeSet<i8>>();
85 .filter(|&x| x % 2 == 0)
87 .collect::<BTreeSet<i8>>();
89 btree_set = btree_set.into_iter().filter(|x| x % 2 == 0).collect::<BTreeSet<i8>>();
91 // Do not lint, because this expression is not assign.
92 let mut foobar: BTreeSet<i8> = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect();
93 let mut bar: BTreeSet<i8> = btree_set.into_iter().filter(|x| x % 2 == 0).collect();
95 // Do not lint, because it is an assignment to a different variable.
96 bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();
97 bar = foobar.iter().filter(|&x| x % 2 == 0).cloned().collect();
98 bar = foobar.into_iter().filter(|x| x % 2 == 0).collect();
101 fn hash_map_retain() {
102 let mut hash_map: HashMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();
104 hash_map.retain(|k, _| k % 2 == 0);
105 hash_map.retain(|_, &mut v| v % 2 == 0);
106 hash_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0));
111 .filter(|(x, _)| x % 2 == 0)
112 .collect::<HashMap<i8, i8>>();
114 // Do not lint, because this expression is not assign.
115 let mut foobar: HashMap<i8, i8> = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
117 // Do not lint, because it is an assignment to a different variable.
118 hash_map = foobar.into_iter().filter(|(k, _)| k % 2 == 0).collect();
121 fn hash_set_retain() {
122 let mut hash_set = HashSet::from([1, 2, 3, 4, 5, 6]);
124 hash_set.retain(|x| x % 2 == 0);
125 hash_set.retain(|x| x % 2 == 0);
126 hash_set.retain(|x| x % 2 == 0);
128 // Do not lint, because type conversion is performed
129 hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect::<HashSet<i8>>();
132 .filter(|&x| x % 2 == 0)
134 .collect::<HashSet<i8>>();
138 .filter(|&x| x % 2 == 0)
140 .collect::<HashSet<i8>>();
142 // Do not lint, because this expression is not assign.
143 let mut bar: HashSet<i8> = hash_set.iter().filter(|&x| x % 2 == 0).copied().collect();
144 let mut foobar: HashSet<i8> = hash_set.into_iter().filter(|x| x % 2 == 0).collect();
146 // Do not lint, because it is an assignment to a different variable.
147 bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();
148 bar = foobar.iter().filter(|&x| x % 2 == 0).cloned().collect();
149 bar = foobar.into_iter().filter(|&x| x % 2 == 0).collect();
153 let mut s = String::from("foobar");
155 s.retain(|c| c != 'o');
157 // Do not lint, because this expression is not assign.
158 let mut bar: String = s.chars().filter(|&c| c != 'o').to_owned().collect();
160 // Do not lint, because it is an assignment to a different variable.
161 s = bar.chars().filter(|&c| c != 'o').to_owned().collect();
165 let mut vec = vec![0, 1, 2];
167 vec.retain(|x| x % 2 == 0);
168 vec.retain(|x| x % 2 == 0);
169 vec.retain(|x| x % 2 == 0);
171 // Do not lint, because type conversion is performed
172 vec = vec.into_iter().filter(|x| x % 2 == 0).collect::<Vec<i8>>();
173 vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect::<Vec<i8>>();
174 vec = vec.iter().filter(|&x| x % 2 == 0).cloned().collect::<Vec<i8>>();
176 // Do not lint, because this expression is not assign.
177 let mut bar: Vec<i8> = vec.iter().filter(|&x| x % 2 == 0).copied().collect();
178 let mut foobar: Vec<i8> = vec.into_iter().filter(|x| x % 2 == 0).collect();
180 // Do not lint, because it is an assignment to a different variable.
181 bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();
182 bar = foobar.iter().filter(|&x| x % 2 == 0).cloned().collect();
183 bar = foobar.into_iter().filter(|x| x % 2 == 0).collect();
186 fn vec_deque_retain() {
187 let mut vec_deque = VecDeque::new();
188 vec_deque.extend(1..5);
191 vec_deque.retain(|x| x % 2 == 0);
192 vec_deque.retain(|x| x % 2 == 0);
193 vec_deque.retain(|x| x % 2 == 0);
195 // Do not lint, because type conversion is performed
196 vec_deque = vec_deque
198 .filter(|&x| x % 2 == 0)
200 .collect::<VecDeque<i8>>();
201 vec_deque = vec_deque
203 .filter(|&x| x % 2 == 0)
205 .collect::<VecDeque<i8>>();
206 vec_deque = vec_deque.into_iter().filter(|x| x % 2 == 0).collect::<VecDeque<i8>>();
208 // Do not lint, because this expression is not assign.
209 let mut bar: VecDeque<i8> = vec_deque.iter().filter(|&x| x % 2 == 0).copied().collect();
210 let mut foobar: VecDeque<i8> = vec_deque.into_iter().filter(|x| x % 2 == 0).collect();
212 // Do not lint, because it is an assignment to a different variable.
213 bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();
214 bar = foobar.iter().filter(|&x| x % 2 == 0).cloned().collect();
215 bar = foobar.into_iter().filter(|x| x % 2 == 0).collect();
218 #[clippy::msrv = "1.52"]
220 let mut btree_map: BTreeMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();
221 btree_map = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
223 let mut btree_set = BTreeSet::from([1, 2, 3, 4, 5, 6]);
224 btree_set = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect();
227 #[clippy::msrv = "1.25"]
229 let mut s = String::from("foobar");
230 s = s.chars().filter(|&c| c != 'o').to_owned().collect();
233 #[clippy::msrv = "1.17"]
235 let mut hash_set = HashSet::from([1, 2, 3, 4, 5, 6]);
236 hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect();
237 let mut hash_map: HashMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();
238 hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();