]> git.lizzy.rs Git - rust.git/blob - tests/ui/for_loop.rs
Auto merge of #3635 - matthiaskrgr:revert_random_state_3603, r=xfix
[rust.git] / tests / ui / for_loop.rs
1 // Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution.
3 //
4 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7 // option. This file may not be copied, modified, or distributed
8 // except according to those terms.
9
10 use std::collections::*;
11 use std::rc::Rc;
12
13 static STATIC: [usize; 4] = [0, 1, 8, 16];
14 const CONST: [usize; 4] = [0, 1, 8, 16];
15
16 #[warn(clippy::all)]
17 struct Unrelated(Vec<u8>);
18 impl Unrelated {
19     fn next(&self) -> std::slice::Iter<u8> {
20         self.0.iter()
21     }
22
23     fn iter(&self) -> std::slice::Iter<u8> {
24         self.0.iter()
25     }
26 }
27
28 #[warn(
29     clippy::needless_range_loop,
30     clippy::explicit_iter_loop,
31     clippy::explicit_into_iter_loop,
32     clippy::iter_next_loop,
33     clippy::reverse_range_loop,
34     clippy::for_kv_map
35 )]
36 #[warn(clippy::unused_collect)]
37 #[allow(
38     clippy::linkedlist,
39     clippy::shadow_unrelated,
40     clippy::unnecessary_mut_passed,
41     clippy::cyclomatic_complexity,
42     clippy::similar_names
43 )]
44 #[allow(clippy::many_single_char_names, unused_variables, clippy::into_iter_on_array)]
45 fn main() {
46     const MAX_LEN: usize = 42;
47
48     let mut vec = vec![1, 2, 3, 4];
49     let vec2 = vec![1, 2, 3, 4];
50     for i in 0..vec.len() {
51         println!("{}", vec[i]);
52     }
53
54     for i in 0..vec.len() {
55         let i = 42; // make a different `i`
56         println!("{}", vec[i]); // ok, not the `i` of the for-loop
57     }
58
59     for i in 0..vec.len() {
60         let _ = vec[i];
61     }
62
63     // ICE #746
64     for j in 0..4 {
65         println!("{:?}", STATIC[j]);
66     }
67
68     for j in 0..4 {
69         println!("{:?}", CONST[j]);
70     }
71
72     for i in 0..vec.len() {
73         println!("{} {}", vec[i], i);
74     }
75     for i in 0..vec.len() {
76         // not an error, indexing more than one variable
77         println!("{} {}", vec[i], vec2[i]);
78     }
79
80     for i in 0..vec.len() {
81         println!("{}", vec2[i]);
82     }
83
84     for i in 5..vec.len() {
85         println!("{}", vec[i]);
86     }
87
88     for i in 0..MAX_LEN {
89         println!("{}", vec[i]);
90     }
91
92     for i in 0..=MAX_LEN {
93         println!("{}", vec[i]);
94     }
95
96     for i in 5..10 {
97         println!("{}", vec[i]);
98     }
99
100     for i in 5..=10 {
101         println!("{}", vec[i]);
102     }
103
104     for i in 5..vec.len() {
105         println!("{} {}", vec[i], i);
106     }
107
108     for i in 5..10 {
109         println!("{} {}", vec[i], i);
110     }
111
112     for i in 10..0 {
113         println!("{}", i);
114     }
115
116     for i in 10..=0 {
117         println!("{}", i);
118     }
119
120     for i in MAX_LEN..0 {
121         println!("{}", i);
122     }
123
124     for i in 5..5 {
125         println!("{}", i);
126     }
127
128     for i in 5..=5 {
129         // not an error, this is the range with only one element “5”
130         println!("{}", i);
131     }
132
133     for i in 0..10 {
134         // not an error, the start index is less than the end index
135         println!("{}", i);
136     }
137
138     for i in -10..0 {
139         // not an error
140         println!("{}", i);
141     }
142
143     for i in (10..0).map(|x| x * 2) {
144         // not an error, it can't be known what arbitrary methods do to a range
145         println!("{}", i);
146     }
147
148     // testing that the empty range lint folds constants
149     for i in 10..5 + 4 {
150         println!("{}", i);
151     }
152
153     for i in (5 + 2)..(3 - 1) {
154         println!("{}", i);
155     }
156
157     for i in (5 + 2)..(8 - 1) {
158         println!("{}", i);
159     }
160
161     for i in (2 * 2)..(2 * 3) {
162         // no error, 4..6 is fine
163         println!("{}", i);
164     }
165
166     let x = 42;
167     for i in x..10 {
168         // no error, not constant-foldable
169         println!("{}", i);
170     }
171
172     // See #601
173     for i in 0..10 {
174         // no error, id_col does not exist outside the loop
175         let mut id_col = vec![0f64; 10];
176         id_col[i] = 1f64;
177     }
178
179     for _v in vec.iter() {}
180
181     for _v in vec.iter_mut() {}
182
183     let out_vec = vec![1, 2, 3];
184     for _v in out_vec.into_iter() {}
185
186     let array = [1, 2, 3];
187     for _v in array.into_iter() {}
188
189     for _v in &vec {} // these are fine
190     for _v in &mut vec {} // these are fine
191
192     for _v in [1, 2, 3].iter() {}
193
194     for _v in (&mut [1, 2, 3]).iter() {} // no error
195
196     for _v in [0; 32].iter() {}
197
198     for _v in [0; 33].iter() {} // no error
199
200     let ll: LinkedList<()> = LinkedList::new();
201     for _v in ll.iter() {}
202
203     let vd: VecDeque<()> = VecDeque::new();
204     for _v in vd.iter() {}
205
206     let bh: BinaryHeap<()> = BinaryHeap::new();
207     for _v in bh.iter() {}
208
209     let hm: HashMap<(), ()> = HashMap::new();
210     for _v in hm.iter() {}
211
212     let bt: BTreeMap<(), ()> = BTreeMap::new();
213     for _v in bt.iter() {}
214
215     let hs: HashSet<()> = HashSet::new();
216     for _v in hs.iter() {}
217
218     let bs: BTreeSet<()> = BTreeSet::new();
219     for _v in bs.iter() {}
220
221     for _v in vec.iter().next() {}
222
223     let u = Unrelated(vec![]);
224     for _v in u.next() {} // no error
225     for _v in u.iter() {} // no error
226
227     let mut out = vec![];
228     vec.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>();
229     let _y = vec.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>(); // this is fine
230
231     // Loop with explicit counter variable
232
233     // Potential false positives
234     let mut _index = 0;
235     _index = 1;
236     for _v in &vec {
237         _index += 1
238     }
239
240     let mut _index = 0;
241     _index += 1;
242     for _v in &vec {
243         _index += 1
244     }
245
246     let mut _index = 0;
247     if true {
248         _index = 1
249     }
250     for _v in &vec {
251         _index += 1
252     }
253
254     let mut _index = 0;
255     let mut _index = 1;
256     for _v in &vec {
257         _index += 1
258     }
259
260     let mut _index = 0;
261     for _v in &vec {
262         _index += 1;
263         _index += 1
264     }
265
266     let mut _index = 0;
267     for _v in &vec {
268         _index *= 2;
269         _index += 1
270     }
271
272     let mut _index = 0;
273     for _v in &vec {
274         _index = 1;
275         _index += 1
276     }
277
278     let mut _index = 0;
279
280     for _v in &vec {
281         let mut _index = 0;
282         _index += 1
283     }
284
285     let mut _index = 0;
286     for _v in &vec {
287         _index += 1;
288         _index = 0;
289     }
290
291     let mut _index = 0;
292     for _v in &vec {
293         for _x in 0..1 {
294             _index += 1;
295         }
296         _index += 1
297     }
298
299     let mut _index = 0;
300     for x in &vec {
301         if *x == 1 {
302             _index += 1
303         }
304     }
305
306     let mut _index = 0;
307     if true {
308         _index = 1
309     };
310     for _v in &vec {
311         _index += 1
312     }
313
314     let mut _index = 1;
315     if false {
316         _index = 0
317     };
318     for _v in &vec {
319         _index += 1
320     }
321
322     let mut index = 0;
323     {
324         let mut _x = &mut index;
325     }
326     for _v in &vec {
327         _index += 1
328     }
329
330     let mut index = 0;
331     for _v in &vec {
332         index += 1
333     }
334     println!("index: {}", index);
335
336     fn f<T>(_: &T, _: &T) -> bool {
337         unimplemented!()
338     }
339     fn g<T>(_: &mut [T], _: usize, _: usize) {
340         unimplemented!()
341     }
342     for i in 1..vec.len() {
343         if f(&vec[i - 1], &vec[i]) {
344             g(&mut vec, i - 1, i);
345         }
346     }
347
348     for mid in 1..vec.len() {
349         let (_, _) = vec.split_at(mid);
350     }
351 }
352
353 #[allow(dead_code)]
354 fn partition<T: PartialOrd + Send>(v: &mut [T]) -> usize {
355     let pivot = v.len() - 1;
356     let mut i = 0;
357     for j in 0..pivot {
358         if v[j] <= v[pivot] {
359             v.swap(i, j);
360             i += 1;
361         }
362     }
363     v.swap(i, pivot);
364     i
365 }
366
367 const LOOP_OFFSET: usize = 5000;
368
369 #[warn(clippy::needless_range_loop)]
370 pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) {
371     // plain manual memcpy
372     for i in 0..src.len() {
373         dst[i] = src[i];
374     }
375
376     // dst offset memcpy
377     for i in 0..src.len() {
378         dst[i + 10] = src[i];
379     }
380
381     // src offset memcpy
382     for i in 0..src.len() {
383         dst[i] = src[i + 10];
384     }
385
386     // src offset memcpy
387     for i in 11..src.len() {
388         dst[i] = src[i - 10];
389     }
390
391     // overwrite entire dst
392     for i in 0..dst.len() {
393         dst[i] = src[i];
394     }
395
396     // manual copy with branch - can't easily convert to memcpy!
397     for i in 0..src.len() {
398         dst[i] = src[i];
399         if dst[i] > 5 {
400             break;
401         }
402     }
403
404     // multiple copies - suggest two memcpy statements
405     for i in 10..256 {
406         dst[i] = src[i - 5];
407         dst2[i + 500] = src[i]
408     }
409
410     // this is a reversal - the copy lint shouldn't be triggered
411     for i in 10..LOOP_OFFSET {
412         dst[i + LOOP_OFFSET] = src[LOOP_OFFSET - i];
413     }
414
415     let some_var = 5;
416     // Offset in variable
417     for i in 10..LOOP_OFFSET {
418         dst[i + LOOP_OFFSET] = src[i - some_var];
419     }
420
421     // Non continuous copy - don't trigger lint
422     for i in 0..10 {
423         dst[i + i] = src[i];
424     }
425
426     let src_vec = vec![1, 2, 3, 4, 5];
427     let mut dst_vec = vec![0, 0, 0, 0, 0];
428
429     // make sure vectors are supported
430     for i in 0..src_vec.len() {
431         dst_vec[i] = src_vec[i];
432     }
433
434     // lint should not trigger when either
435     // source or destination type is not
436     // slice-like, like DummyStruct
437     struct DummyStruct(i32);
438
439     impl ::std::ops::Index<usize> for DummyStruct {
440         type Output = i32;
441
442         fn index(&self, _: usize) -> &i32 {
443             &self.0
444         }
445     }
446
447     let src = DummyStruct(5);
448     let mut dst_vec = vec![0; 10];
449
450     for i in 0..10 {
451         dst_vec[i] = src[i];
452     }
453
454     // Simplify suggestion (issue #3004)
455     let src = [0, 1, 2, 3, 4];
456     let mut dst = [0, 0, 0, 0, 0, 0];
457     let from = 1;
458
459     for i in from..from + src.len() {
460         dst[i] = src[i - from];
461     }
462
463     for i in from..from + 3 {
464         dst[i] = src[i - from];
465     }
466 }
467
468 #[warn(clippy::needless_range_loop)]
469 pub fn manual_clone(src: &[String], dst: &mut [String]) {
470     for i in 0..src.len() {
471         dst[i] = src[i].clone();
472     }
473 }
474
475 #[warn(clippy::needless_range_loop)]
476 pub fn manual_copy_same_destination(dst: &mut [i32], d: usize, s: usize) {
477     // Same source and destination - don't trigger lint
478     for i in 0..dst.len() {
479         dst[d + i] = dst[s + i];
480     }
481 }
482
483 mod issue_2496 {
484     pub trait Handle {
485         fn new_for_index(index: usize) -> Self;
486         fn index(&self) -> usize;
487     }
488
489     pub fn test<H: Handle>() -> H {
490         for x in 0..5 {
491             let next_handle = H::new_for_index(x);
492             println!("{}", next_handle.index());
493         }
494         unimplemented!()
495     }
496 }