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