]>
Commit | Line | Data |
---|---|---|
f20569fa XL |
1 | // run-rustfix |
2 | ||
3 | #![warn(clippy::while_let_on_iterator)] | |
17df50a5 | 4 | #![allow(clippy::never_loop, unreachable_code, unused_mut, dead_code)] |
f20569fa XL |
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 | ||
f20569fa XL |
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]; | |
f20569fa XL |
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() { | |
17df50a5 XL |
151 | // This should not cause an ICE |
152 | ||
f20569fa XL |
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 | ||
17df50a5 XL |
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 | ||
136023e0 XL |
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 | ||
f20569fa | 337 | fn main() { |
17df50a5 XL |
338 | let mut it = 0..20; |
339 | for _ in it { | |
340 | println!("test"); | |
341 | } | |
f20569fa | 342 | } |