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