]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/tests/ui/while_let_on_iterator.fixed
Auto merge of #107843 - bjorn3:sync_cg_clif-2023-02-09, r=bjorn3
[rust.git] / src / tools / clippy / tests / ui / while_let_on_iterator.fixed
1 // run-rustfix
2 #![warn(clippy::while_let_on_iterator)]
3 #![allow(dead_code, unreachable_code, unused_mut)]
4 #![allow(
5     clippy::equatable_if_let,
6     clippy::manual_find,
7     clippy::never_loop,
8     clippy::redundant_closure_call,
9     clippy::uninlined_format_args
10 )]
11
12 fn base() {
13     let mut iter = 1..20;
14     for x in iter {
15         println!("{}", x);
16     }
17
18     let mut iter = 1..20;
19     for x in iter {
20         println!("{}", x);
21     }
22
23     let mut iter = 1..20;
24     for _ in iter {}
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         for [..] in it {}
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         for [_x] in it {}
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         for x @ [_] in it {
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         for _ in y {
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         for m in it.by_ref() {
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     for n in it {
209         let mut it = 1..40;
210         for m in it {
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         for m in it {
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         for m in it.by_ref() {
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         for m in it.by_ref() {
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             for i in self.0.by_ref() {
261                 if !(3..8).contains(&i) {
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             for i in self.0.0.0.by_ref() {
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     for n in it.by_ref() {
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         for x in it.by_ref() {
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     for x in it.by_ref() {
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     for x in it.0.by_ref() {
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 custom_deref() {
376     struct S1<T> {
377         x: T,
378     }
379     struct S2<T>(S1<T>);
380     impl<T> core::ops::Deref for S2<T> {
381         type Target = S1<T>;
382         fn deref(&self) -> &Self::Target {
383             &self.0
384         }
385     }
386     impl<T> core::ops::DerefMut for S2<T> {
387         fn deref_mut(&mut self) -> &mut Self::Target {
388             &mut self.0
389         }
390     }
391
392     let mut s = S2(S1 { x: 0..10 });
393     for x in s.x.by_ref() {
394         println!("{}", x);
395     }
396 }
397
398 fn issue_8113() {
399     let mut x = [0..10];
400     for x in x[0].by_ref() {
401         println!("{}", x);
402     }
403 }
404
405 fn fn_once_closure() {
406     let mut it = 0..10;
407     (|| {
408         for x in it {
409             if x % 2 == 0 {
410                 break;
411             }
412         }
413     })();
414
415     fn f(_: impl FnOnce()) {}
416     let mut it = 0..10;
417     f(|| {
418         for x in it {
419             if x % 2 == 0 {
420                 break;
421             }
422         }
423     });
424
425     fn f2(_: impl FnMut()) {}
426     let mut it = 0..10;
427     f2(|| {
428         for x in it.by_ref() {
429             if x % 2 == 0 {
430                 break;
431             }
432         }
433     });
434
435     fn f3(_: fn()) {}
436     f3(|| {
437         let mut it = 0..10;
438         for x in it {
439             if x % 2 == 0 {
440                 break;
441             }
442         }
443     })
444 }
445
446 fn main() {
447     let mut it = 0..20;
448     for _ in it {
449         println!("test");
450     }
451 }