2 #![feature(custom_inner_attributes)]
3 #![warn(clippy::manual_retain)]
5 use std::collections::BTreeMap;
6 use std::collections::BTreeSet;
7 use std::collections::BinaryHeap;
8 use std::collections::HashMap;
9 use std::collections::HashSet;
10 use std::collections::VecDeque;
26 fn binary_heap_retain() {
27 // NOTE: Do not lint now, because binary_heap_retain is nighyly API.
28 // And we need to add a test case for msrv if we update this implmention.
29 // https://github.com/rust-lang/rust/issues/71503
30 let mut heap = BinaryHeap::from([1, 2, 3]);
31 heap = heap.into_iter().filter(|x| x % 2 == 0).collect();
32 heap = heap.iter().filter(|&x| x % 2 == 0).copied().collect();
33 heap = heap.iter().filter(|&x| x % 2 == 0).cloned().collect();
35 // Do not lint, because type conversion is performed
36 heap = heap.into_iter().filter(|x| x % 2 == 0).collect::<BinaryHeap<i8>>();
37 heap = heap.iter().filter(|&x| x % 2 == 0).copied().collect::<BinaryHeap<i8>>();
38 heap = heap.iter().filter(|&x| x % 2 == 0).cloned().collect::<BinaryHeap<i8>>();
40 // Do not lint, because this expression is not assign.
41 let mut bar: BinaryHeap<i8> = heap.iter().filter(|&x| x % 2 == 0).copied().collect();
42 let mut foobar: BinaryHeap<i8> = heap.into_iter().filter(|x| x % 2 == 0).collect();
44 // Do not lint, because it is an assignment to a different variable.
45 bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();
46 bar = foobar.into_iter().filter(|x| x % 2 == 0).collect();
49 fn btree_map_retain() {
50 let mut btree_map: BTreeMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();
52 btree_map.retain(|k, _| k % 2 == 0);
53 btree_map.retain(|_, &mut v| v % 2 == 0);
54 btree_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0));
59 .filter(|(x, _)| x % 2 == 0)
60 .collect::<BTreeMap<i8, i8>>();
62 // Do not lint, because this expression is not assign.
63 let mut foobar: BTreeMap<i8, i8> = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
65 // Do not lint, because it is an assignment to a different variable.
66 btree_map = foobar.into_iter().filter(|(k, _)| k % 2 == 0).collect();
69 fn btree_set_retain() {
70 let mut btree_set = BTreeSet::from([1, 2, 3, 4, 5, 6]);
73 btree_set.retain(|x| x % 2 == 0);
74 btree_set.retain(|x| x % 2 == 0);
75 btree_set.retain(|x| x % 2 == 0);
77 // Do not lint, because type conversion is performed
80 .filter(|&x| x % 2 == 0)
82 .collect::<BTreeSet<i8>>();
86 .filter(|&x| x % 2 == 0)
88 .collect::<BTreeSet<i8>>();
90 btree_set = btree_set.into_iter().filter(|x| x % 2 == 0).collect::<BTreeSet<i8>>();
92 // Do not lint, because this expression is not assign.
93 let mut foobar: BTreeSet<i8> = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect();
94 let mut bar: BTreeSet<i8> = btree_set.into_iter().filter(|x| x % 2 == 0).collect();
96 // Do not lint, because it is an assignment to a different variable.
97 bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();
98 bar = foobar.iter().filter(|&x| x % 2 == 0).cloned().collect();
99 bar = foobar.into_iter().filter(|x| x % 2 == 0).collect();
102 fn hash_map_retain() {
103 let mut hash_map: HashMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();
105 hash_map.retain(|k, _| k % 2 == 0);
106 hash_map.retain(|_, &mut v| v % 2 == 0);
107 hash_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0));
112 .filter(|(x, _)| x % 2 == 0)
113 .collect::<HashMap<i8, i8>>();
115 // Do not lint, because this expression is not assign.
116 let mut foobar: HashMap<i8, i8> = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
118 // Do not lint, because it is an assignment to a different variable.
119 hash_map = foobar.into_iter().filter(|(k, _)| k % 2 == 0).collect();
122 fn hash_set_retain() {
123 let mut hash_set = HashSet::from([1, 2, 3, 4, 5, 6]);
125 hash_set.retain(|x| x % 2 == 0);
126 hash_set.retain(|x| x % 2 == 0);
127 hash_set.retain(|x| x % 2 == 0);
129 // Do not lint, because type conversion is performed
130 hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect::<HashSet<i8>>();
133 .filter(|&x| x % 2 == 0)
135 .collect::<HashSet<i8>>();
139 .filter(|&x| x % 2 == 0)
141 .collect::<HashSet<i8>>();
143 // Do not lint, because this expression is not assign.
144 let mut bar: HashSet<i8> = hash_set.iter().filter(|&x| x % 2 == 0).copied().collect();
145 let mut foobar: HashSet<i8> = hash_set.into_iter().filter(|x| x % 2 == 0).collect();
147 // Do not lint, because it is an assignment to a different variable.
148 bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();
149 bar = foobar.iter().filter(|&x| x % 2 == 0).cloned().collect();
150 bar = foobar.into_iter().filter(|&x| x % 2 == 0).collect();
154 let mut s = String::from("foobar");
156 s.retain(|c| c != 'o');
158 // Do not lint, because this expression is not assign.
159 let mut bar: String = s.chars().filter(|&c| c != 'o').to_owned().collect();
161 // Do not lint, because it is an assignment to a different variable.
162 s = bar.chars().filter(|&c| c != 'o').to_owned().collect();
166 let mut vec = vec![0, 1, 2];
168 vec.retain(|x| x % 2 == 0);
169 vec.retain(|x| x % 2 == 0);
170 vec.retain(|x| x % 2 == 0);
172 // Do not lint, because type conversion is performed
173 vec = vec.into_iter().filter(|x| x % 2 == 0).collect::<Vec<i8>>();
174 vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect::<Vec<i8>>();
175 vec = vec.iter().filter(|&x| x % 2 == 0).cloned().collect::<Vec<i8>>();
177 // Do not lint, because this expression is not assign.
178 let mut bar: Vec<i8> = vec.iter().filter(|&x| x % 2 == 0).copied().collect();
179 let mut foobar: Vec<i8> = vec.into_iter().filter(|x| x % 2 == 0).collect();
181 // Do not lint, because it is an assignment to a different variable.
182 bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();
183 bar = foobar.iter().filter(|&x| x % 2 == 0).cloned().collect();
184 bar = foobar.into_iter().filter(|x| x % 2 == 0).collect();
187 fn vec_deque_retain() {
188 let mut vec_deque = VecDeque::new();
189 vec_deque.extend(1..5);
192 vec_deque.retain(|x| x % 2 == 0);
193 vec_deque.retain(|x| x % 2 == 0);
194 vec_deque.retain(|x| x % 2 == 0);
196 // Do not lint, because type conversion is performed
197 vec_deque = vec_deque
199 .filter(|&x| x % 2 == 0)
201 .collect::<VecDeque<i8>>();
202 vec_deque = vec_deque
204 .filter(|&x| x % 2 == 0)
206 .collect::<VecDeque<i8>>();
207 vec_deque = vec_deque.into_iter().filter(|x| x % 2 == 0).collect::<VecDeque<i8>>();
209 // Do not lint, because this expression is not assign.
210 let mut bar: VecDeque<i8> = vec_deque.iter().filter(|&x| x % 2 == 0).copied().collect();
211 let mut foobar: VecDeque<i8> = vec_deque.into_iter().filter(|x| x % 2 == 0).collect();
213 // Do not lint, because it is an assignment to a different variable.
214 bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();
215 bar = foobar.iter().filter(|&x| x % 2 == 0).cloned().collect();
216 bar = foobar.into_iter().filter(|x| x % 2 == 0).collect();
220 #![clippy::msrv = "1.52"]
221 let mut btree_map: BTreeMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();
222 btree_map = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
224 let mut btree_set = BTreeSet::from([1, 2, 3, 4, 5, 6]);
225 btree_set = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect();
229 #![clippy::msrv = "1.25"]
230 let mut s = String::from("foobar");
231 s = s.chars().filter(|&c| c != 'o').to_owned().collect();
235 #![clippy::msrv = "1.17"]
236 let mut hash_set = HashSet::from([1, 2, 3, 4, 5, 6]);
237 hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect();
238 let mut hash_map: HashMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();
239 hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();