]> git.lizzy.rs Git - rust.git/blob - tests/ui/for_loop.rs
Move all our tests back to ui tests
[rust.git] / tests / ui / for_loop.rs
1 #![feature(plugin, inclusive_range_syntax)]
2 #![plugin(clippy)]
3
4 use std::collections::*;
5 use std::rc::Rc;
6
7 static STATIC: [usize; 4] = [ 0,  1,  8, 16 ];
8 const CONST: [usize; 4] = [ 0,  1,  8, 16 ];
9
10 #[warn(clippy)]
11 fn for_loop_over_option_and_result() {
12     let option = Some(1);
13     let result = option.ok_or("x not found");
14     let v = vec![0,1,2];
15
16     // check FOR_LOOP_OVER_OPTION lint
17     for x in option {
18         println!("{}", x);
19     }
20
21     // check FOR_LOOP_OVER_RESULT lint
22     for x in result {
23         println!("{}", x);
24     }
25
26     for x in option.ok_or("x not found") {
27         println!("{}", x);
28     }
29
30     // make sure LOOP_OVER_NEXT lint takes precedence when next() is the last call in the chain
31     for x in v.iter().next() {
32         println!("{}", x);
33     }
34
35     // make sure we lint when next() is not the last call in the chain
36     for x in v.iter().next().and(Some(0)) {
37         println!("{}", x);
38     }
39
40     for x in v.iter().next().ok_or("x not found") {
41         println!("{}", x);
42     }
43
44     // check for false positives
45
46     // for loop false positive
47     for x in v {
48         println!("{}", x);
49     }
50
51     // while let false positive for Option
52     while let Some(x) = option {
53         println!("{}", x);
54         break;
55     }
56
57     // while let false positive for Result
58     while let Ok(x) = result {
59         println!("{}", x);
60         break;
61     }
62 }
63
64 struct Unrelated(Vec<u8>);
65 impl Unrelated {
66     fn next(&self) -> std::slice::Iter<u8> {
67         self.0.iter()
68     }
69
70     fn iter(&self) -> std::slice::Iter<u8> {
71         self.0.iter()
72     }
73 }
74
75 #[warn(needless_range_loop, explicit_iter_loop, explicit_into_iter_loop, iter_next_loop, reverse_range_loop, explicit_counter_loop, for_kv_map)]
76 #[warn(unused_collect)]
77 #[allow(linkedlist, shadow_unrelated, unnecessary_mut_passed, cyclomatic_complexity, similar_names)]
78 #[allow(many_single_char_names)]
79 fn main() {
80     const MAX_LEN: usize = 42;
81
82     let mut vec = vec![1, 2, 3, 4];
83     let vec2 = vec![1, 2, 3, 4];
84     for i in 0..vec.len() {
85         println!("{}", vec[i]);
86     }
87
88     for i in 0..vec.len() {
89         let i = 42; // make a different `i`
90         println!("{}", vec[i]); // ok, not the `i` of the for-loop
91     }
92
93     for i in 0..vec.len() { let _ = vec[i]; }
94
95     // ICE #746
96     for j in 0..4 {
97         println!("{:?}", STATIC[j]);
98     }
99
100     for j in 0..4 {
101         println!("{:?}", CONST[j]);
102     }
103
104     for i in 0..vec.len() {
105         println!("{} {}", vec[i], i);
106     }
107     for i in 0..vec.len() {      // not an error, indexing more than one variable
108         println!("{} {}", vec[i], vec2[i]);
109     }
110
111     for i in 0..vec.len() {
112         println!("{}", vec2[i]);
113     }
114
115     for i in 5..vec.len() {
116         println!("{}", vec[i]);
117     }
118
119     for i in 0..MAX_LEN {
120         println!("{}", vec[i]);
121     }
122
123     for i in 0...MAX_LEN {
124         println!("{}", vec[i]);
125     }
126
127     for i in 5..10 {
128         println!("{}", vec[i]);
129     }
130
131     for i in 5...10 {
132         println!("{}", vec[i]);
133     }
134
135     for i in 5..vec.len() {
136         println!("{} {}", vec[i], i);
137     }
138
139     for i in 5..10 {
140         println!("{} {}", vec[i], i);
141     }
142
143     for i in 10..0 {
144         println!("{}", i);
145     }
146
147     for i in 10...0 {
148         println!("{}", i);
149     }
150
151     for i in MAX_LEN..0 {
152         println!("{}", i);
153     }
154
155     for i in 5..5 {
156         println!("{}", i);
157     }
158
159     for i in 5...5 { // not an error, this is the range with only one element “5”
160         println!("{}", i);
161     }
162
163     for i in 0..10 { // not an error, the start index is less than the end index
164         println!("{}", i);
165     }
166
167     for i in -10..0 { // not an error
168         println!("{}", i);
169     }
170
171     for i in (10..0).map(|x| x * 2) { // not an error, it can't be known what arbitrary methods do to a range
172         println!("{}", i);
173     }
174
175     // testing that the empty range lint folds constants
176     for i in 10..5+4 {
177         println!("{}", i);
178     }
179
180     for i in (5+2)..(3-1) {
181         println!("{}", i);
182     }
183
184     for i in (5+2)..(8-1) {
185         println!("{}", i);
186     }
187
188     for i in (2*2)..(2*3) { // no error, 4..6 is fine
189         println!("{}", i);
190     }
191
192     let x = 42;
193     for i in x..10 { // no error, not constant-foldable
194         println!("{}", i);
195     }
196
197     // See #601
198     for i in 0..10 { // no error, id_col does not exist outside the loop
199         let mut id_col = vec![0f64; 10];
200         id_col[i] = 1f64;
201     }
202
203     for _v in vec.iter() { }
204
205     for _v in vec.iter_mut() { }
206
207     let out_vec = vec![1,2,3];
208     for _v in out_vec.into_iter() { }
209
210     let array = [1, 2, 3];
211     for _v in array.into_iter() {}
212
213     for _v in &vec { } // these are fine
214     for _v in &mut vec { } // these are fine
215
216     for _v in [1, 2, 3].iter() { }
217
218     for _v in (&mut [1, 2, 3]).iter() { } // no error
219
220     for _v in [0; 32].iter() {}
221
222     for _v in [0; 33].iter() {} // no error
223
224     let ll: LinkedList<()> = LinkedList::new();
225     for _v in ll.iter() { }
226
227     let vd: VecDeque<()> = VecDeque::new();
228     for _v in vd.iter() { }
229
230     let bh: BinaryHeap<()> = BinaryHeap::new();
231     for _v in bh.iter() { }
232
233     let hm: HashMap<(), ()> = HashMap::new();
234     for _v in hm.iter() { }
235
236     let bt: BTreeMap<(), ()> = BTreeMap::new();
237     for _v in bt.iter() { }
238
239     let hs: HashSet<()> = HashSet::new();
240     for _v in hs.iter() { }
241
242     let bs: BTreeSet<()> = BTreeSet::new();
243     for _v in bs.iter() { }
244
245     for _v in vec.iter().next() { }
246
247     let u = Unrelated(vec![]);
248     for _v in u.next() { } // no error
249     for _v in u.iter() { } // no error
250
251     let mut out = vec![];
252     vec.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>();
253     let _y = vec.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>(); // this is fine
254
255     // Loop with explicit counter variable
256     let mut _index = 0;
257     for _v in &vec { _index += 1 }
258
259     let mut _index = 1;
260     _index = 0;
261     for _v in &vec { _index += 1 }
262
263     // Potential false positives
264     let mut _index = 0;
265     _index = 1;
266     for _v in &vec { _index += 1 }
267
268     let mut _index = 0;
269     _index += 1;
270     for _v in &vec { _index += 1 }
271
272     let mut _index = 0;
273     if true { _index = 1 }
274     for _v in &vec { _index += 1 }
275
276     let mut _index = 0;
277     let mut _index = 1;
278     for _v in &vec { _index += 1 }
279
280     let mut _index = 0;
281     for _v in &vec { _index += 1; _index += 1 }
282
283     let mut _index = 0;
284     for _v in &vec { _index *= 2; _index += 1 }
285
286     let mut _index = 0;
287     for _v in &vec { _index = 1; _index += 1 }
288
289     let mut _index = 0;
290
291     for _v in &vec { let mut _index = 0; _index += 1 }
292
293     let mut _index = 0;
294     for _v in &vec { _index += 1; _index = 0; }
295
296     let mut _index = 0;
297     for _v in &vec { for _x in 0..1 { _index += 1; }; _index += 1 }
298
299     let mut _index = 0;
300     for x in &vec { if *x == 1 { _index += 1 } }
301
302     let mut _index = 0;
303     if true { _index = 1 };
304     for _v in &vec { _index += 1 }
305
306     let mut _index = 1;
307     if false { _index = 0 };
308     for _v in &vec { _index += 1 }
309
310     let mut index = 0;
311     { let mut _x = &mut index; }
312     for _v in &vec { _index += 1 }
313
314     let mut index = 0;
315     for _v in &vec { index += 1 }
316     println!("index: {}", index);
317
318     for_loop_over_option_and_result();
319
320     let m : HashMap<u64, u64> = HashMap::new();
321     for (_, v) in &m {
322         let _v = v;
323     }
324
325     let m : Rc<HashMap<u64, u64>> = Rc::new(HashMap::new());
326     for (_, v) in &*m {
327         let _v = v;
328         // Here the `*` is not actually necesarry, but the test tests that we don't suggest
329         // `in *m.values()` as we used to
330     }
331
332     let mut m : HashMap<u64, u64> = HashMap::new();
333     for (_, v) in &mut m {
334         let _v = v;
335     }
336
337     let m: &mut HashMap<u64, u64> = &mut HashMap::new();
338     for (_, v) in &mut *m {
339         let _v = v;
340     }
341
342     let m : HashMap<u64, u64> = HashMap::new();
343     let rm = &m;
344     for (k, _value) in rm {
345         let _k = k;
346     }
347
348     test_for_kv_map();
349
350     fn f<T>(_: &T, _: &T) -> bool { unimplemented!() }
351     fn g<T>(_: &mut [T], _: usize, _: usize) { unimplemented!() }
352     for i in 1..vec.len() {
353         if f(&vec[i - 1], &vec[i]) {
354             g(&mut vec, i - 1, i);
355         }
356     }
357
358     for mid in 1..vec.len() {
359         let (_, _) = vec.split_at(mid);
360     }
361 }
362
363 #[allow(used_underscore_binding)]
364 fn test_for_kv_map() {
365     let m : HashMap<u64, u64> = HashMap::new();
366
367     // No error, _value is actually used
368     for (k, _value) in &m {
369         let _ = _value;
370         let _k = k;
371     }
372 }
373
374 #[allow(dead_code)]
375 fn partition<T:PartialOrd+Send>(v: &mut [T]) -> usize {
376     let pivot = v.len() - 1;
377     let mut i = 0;
378     for j in 0..pivot {
379         if v[j] <= v[pivot] {
380             v.swap(i, j);
381             i += 1;
382         }
383     }
384     v.swap(i, pivot);
385     i
386 }