]> git.proxmox.com Git - rustc.git/blob - src/tools/clippy/tests/ui/while_let_on_iterator.rs
New upstream version 1.57.0+dfsg1
[rustc.git] / src / tools / clippy / tests / ui / while_let_on_iterator.rs
1 // run-rustfix
2
3 #![warn(clippy::while_let_on_iterator)]
4 #![allow(
5 clippy::never_loop,
6 unreachable_code,
7 unused_mut,
8 dead_code,
9 clippy::equatable_if_let
10 )]
11
12 fn base() {
13 let mut iter = 1..20;
14 while let Option::Some(x) = iter.next() {
15 println!("{}", x);
16 }
17
18 let mut iter = 1..20;
19 while let Some(x) = iter.next() {
20 println!("{}", x);
21 }
22
23 let mut iter = 1..20;
24 while let Some(_) = iter.next() {}
25
26 let mut iter = 1..20;
27 while let None = iter.next() {} // this is fine (if nonsensical)
28
29 let mut iter = 1..20;
30 if let Some(x) = iter.next() {
31 // also fine
32 println!("{}", x)
33 }
34
35 // the following shouldn't warn because it can't be written with a for loop
36 let mut iter = 1u32..20;
37 while let Some(_) = iter.next() {
38 println!("next: {:?}", iter.next())
39 }
40
41 // neither can this
42 let mut iter = 1u32..20;
43 while let Some(_) = iter.next() {
44 println!("next: {:?}", iter.next());
45 }
46
47 // or this
48 let mut iter = 1u32..20;
49 while let Some(_) = iter.next() {
50 iter = 1..20;
51 }
52 }
53
54 // Issue #1188
55 fn refutable() {
56 let a = [42, 1337];
57 let mut b = a.iter();
58
59 // consume all the 42s
60 while let Some(&42) = b.next() {}
61
62 let a = [(1, 2, 3)];
63 let mut b = a.iter();
64
65 while let Some(&(1, 2, 3)) = b.next() {}
66
67 let a = [Some(42)];
68 let mut b = a.iter();
69
70 while let Some(&None) = b.next() {}
71
72 /* This gives “refutable pattern in `for` loop binding: `&_` not covered”
73 for &42 in b {}
74 for &(1, 2, 3) in b {}
75 for &Option::None in b.next() {}
76 // */
77 }
78
79 fn refutable2() {
80 // Issue 3780
81 {
82 let v = vec![1, 2, 3];
83 let mut it = v.windows(2);
84 while let Some([x, y]) = it.next() {
85 println!("x: {}", x);
86 println!("y: {}", y);
87 }
88
89 let mut it = v.windows(2);
90 while let Some([x, ..]) = it.next() {
91 println!("x: {}", x);
92 }
93
94 let mut it = v.windows(2);
95 while let Some([.., y]) = it.next() {
96 println!("y: {}", y);
97 }
98
99 let mut it = v.windows(2);
100 while let Some([..]) = it.next() {}
101
102 let v = vec![[1], [2], [3]];
103 let mut it = v.iter();
104 while let Some([1]) = it.next() {}
105
106 let mut it = v.iter();
107 while let Some([_x]) = it.next() {}
108 }
109
110 // binding
111 {
112 let v = vec![1, 2, 3];
113 let mut it = v.iter();
114 while let Some(x @ 1) = it.next() {
115 println!("{}", x);
116 }
117
118 let v = vec![[1], [2], [3]];
119 let mut it = v.iter();
120 while let Some(x @ [_]) = it.next() {
121 println!("{:?}", x);
122 }
123 }
124
125 // false negative
126 {
127 let v = vec![1, 2, 3];
128 let mut it = v.iter().map(Some);
129 while let Some(Some(_) | None) = it.next() {
130 println!("1");
131 }
132 }
133 }
134
135 fn nested_loops() {
136 let a = [42, 1337];
137
138 loop {
139 let mut y = a.iter();
140 while let Some(_) = y.next() {
141 // use a for loop here
142 }
143 }
144 }
145
146 fn issue1121() {
147 use std::collections::HashSet;
148 let mut values = HashSet::new();
149 values.insert(1);
150
151 while let Some(&value) = values.iter().next() {
152 values.remove(&value);
153 }
154 }
155
156 fn issue2965() {
157 // This should not cause an ICE
158
159 use std::collections::HashSet;
160 let mut values = HashSet::new();
161 values.insert(1);
162
163 while let Some(..) = values.iter().next() {}
164 }
165
166 fn issue3670() {
167 let array = [Some(0), None, Some(1)];
168 let mut iter = array.iter();
169
170 while let Some(elem) = iter.next() {
171 let _ = elem.or_else(|| *iter.next()?);
172 }
173 }
174
175 fn issue1654() {
176 // should not lint if the iterator is generated on every iteration
177 use std::collections::HashSet;
178 let mut values = HashSet::new();
179 values.insert(1);
180
181 while let Some(..) = values.iter().next() {
182 values.remove(&1);
183 }
184
185 while let Some(..) = values.iter().map(|x| x + 1).next() {}
186
187 let chars = "Hello, World!".char_indices();
188 while let Some((i, ch)) = chars.clone().next() {
189 println!("{}: {}", i, ch);
190 }
191 }
192
193 fn issue6491() {
194 // Used in outer loop, needs &mut
195 let mut it = 1..40;
196 while let Some(n) = it.next() {
197 while let Some(m) = it.next() {
198 if m % 10 == 0 {
199 break;
200 }
201 println!("doing something with m: {}", m);
202 }
203 println!("n still is {}", n);
204 }
205
206 // This is fine, inner loop uses a new iterator.
207 let mut it = 1..40;
208 while let Some(n) = it.next() {
209 let mut it = 1..40;
210 while let Some(m) = it.next() {
211 if m % 10 == 0 {
212 break;
213 }
214 println!("doing something with m: {}", m);
215 }
216
217 // Weird binding shouldn't change anything.
218 let (mut it, _) = (1..40, 0);
219 while let Some(m) = it.next() {
220 if m % 10 == 0 {
221 break;
222 }
223 println!("doing something with m: {}", m);
224 }
225
226 // Used after the loop, needs &mut.
227 let mut it = 1..40;
228 while let Some(m) = it.next() {
229 if m % 10 == 0 {
230 break;
231 }
232 println!("doing something with m: {}", m);
233 }
234 println!("next item {}", it.next().unwrap());
235
236 println!("n still is {}", n);
237 }
238 }
239
240 fn issue6231() {
241 // Closure in the outer loop, needs &mut
242 let mut it = 1..40;
243 let mut opt = Some(0);
244 while let Some(n) = opt.take().or_else(|| it.next()) {
245 while let Some(m) = it.next() {
246 if n % 10 == 0 {
247 break;
248 }
249 println!("doing something with m: {}", m);
250 }
251 println!("n still is {}", n);
252 }
253 }
254
255 fn issue1924() {
256 struct S<T>(T);
257 impl<T: Iterator<Item = u32>> S<T> {
258 fn f(&mut self) -> Option<u32> {
259 // Used as a field.
260 while let Some(i) = self.0.next() {
261 if i < 3 || i > 7 {
262 return Some(i);
263 }
264 }
265 None
266 }
267
268 fn f2(&mut self) -> Option<u32> {
269 // Don't lint, self borrowed inside the loop
270 while let Some(i) = self.0.next() {
271 if i == 1 {
272 return self.f();
273 }
274 }
275 None
276 }
277 }
278 impl<T: Iterator<Item = u32>> S<(S<T>, Option<u32>)> {
279 fn f3(&mut self) -> Option<u32> {
280 // Don't lint, self borrowed inside the loop
281 while let Some(i) = self.0.0.0.next() {
282 if i == 1 {
283 return self.0.0.f();
284 }
285 }
286 while let Some(i) = self.0.0.0.next() {
287 if i == 1 {
288 return self.f3();
289 }
290 }
291 // This one is fine, a different field is borrowed
292 while let Some(i) = self.0.0.0.next() {
293 if i == 1 {
294 return self.0.1.take();
295 } else {
296 self.0.1 = Some(i);
297 }
298 }
299 None
300 }
301 }
302
303 struct S2<T>(T, u32);
304 impl<T: Iterator<Item = u32>> Iterator for S2<T> {
305 type Item = u32;
306 fn next(&mut self) -> Option<u32> {
307 self.0.next()
308 }
309 }
310
311 // Don't lint, field of the iterator is accessed in the loop
312 let mut it = S2(1..40, 0);
313 while let Some(n) = it.next() {
314 if n == it.1 {
315 break;
316 }
317 }
318
319 // Needs &mut, field of the iterator is accessed after the loop
320 let mut it = S2(1..40, 0);
321 while let Some(n) = it.next() {
322 if n == 0 {
323 break;
324 }
325 }
326 println!("iterator field {}", it.1);
327 }
328
329 fn issue7249() {
330 let mut it = 0..10;
331 let mut x = || {
332 // Needs &mut, the closure can be called multiple times
333 while let Some(x) = it.next() {
334 if x % 2 == 0 {
335 break;
336 }
337 }
338 };
339 x();
340 x();
341 }
342
343 fn issue7510() {
344 let mut it = 0..10;
345 let it = &mut it;
346 // Needs to reborrow `it` as the binding isn't mutable
347 while let Some(x) = it.next() {
348 if x % 2 == 0 {
349 break;
350 }
351 }
352 println!("{}", it.next().unwrap());
353
354 struct S<T>(T);
355 let mut it = 0..10;
356 let it = S(&mut it);
357 // Needs to reborrow `it.0` as the binding isn't mutable
358 while let Some(x) = it.0.next() {
359 if x % 2 == 0 {
360 break;
361 }
362 }
363 println!("{}", it.0.next().unwrap());
364 }
365
366 fn exact_match_with_single_field() {
367 struct S<T>(T);
368 let mut s = S(0..10);
369 // Don't lint. `s.0` is used inside the loop.
370 while let Some(_) = s.0.next() {
371 let _ = &mut s.0;
372 }
373 }
374
375 fn main() {
376 let mut it = 0..20;
377 while let Some(..) = it.next() {
378 println!("test");
379 }
380 }