]> git.lizzy.rs Git - rust.git/blob - tests/ui/for_loop.rs
clean tests/ui/for_loop.rs
[rust.git] / tests / ui / for_loop.rs
1 #![feature(plugin, step_by, 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 #[deny(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 #[deny(needless_range_loop, explicit_iter_loop, explicit_into_iter_loop, iter_next_loop, reverse_range_loop, explicit_counter_loop, for_kv_map)]
76 #[deny(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     for i in (10..8).step_by(-1) {
193         println!("{}", i);
194     }
195
196     let x = 42;
197     for i in x..10 { // no error, not constant-foldable
198         println!("{}", i);
199     }
200
201     // See #601
202     for i in 0..10 { // no error, id_col does not exist outside the loop
203         let mut id_col = vec![0f64; 10];
204         id_col[i] = 1f64;
205     }
206
207     for _v in vec.iter() { }
208
209     for _v in vec.iter_mut() { }
210
211     let out_vec = vec![1,2,3];
212     for _v in out_vec.into_iter() { }
213
214     let array = [1, 2, 3];
215     for _v in array.into_iter() {}
216
217     for _v in &vec { } // these are fine
218     for _v in &mut vec { } // these are fine
219
220     for _v in [1, 2, 3].iter() { }
221
222     for _v in (&mut [1, 2, 3]).iter() { } // no error
223
224     for _v in [0; 32].iter() {}
225
226     for _v in [0; 33].iter() {} // no error
227
228     let ll: LinkedList<()> = LinkedList::new();
229     for _v in ll.iter() { }
230
231     let vd: VecDeque<()> = VecDeque::new();
232     for _v in vd.iter() { }
233
234     let bh: BinaryHeap<()> = BinaryHeap::new();
235     for _v in bh.iter() { }
236
237     let hm: HashMap<(), ()> = HashMap::new();
238     for _v in hm.iter() { }
239
240     let bt: BTreeMap<(), ()> = BTreeMap::new();
241     for _v in bt.iter() { }
242
243     let hs: HashSet<()> = HashSet::new();
244     for _v in hs.iter() { }
245
246     let bs: BTreeSet<()> = BTreeSet::new();
247     for _v in bs.iter() { }
248
249     for _v in vec.iter().next() { }
250
251     let u = Unrelated(vec![]);
252     for _v in u.next() { } // no error
253     for _v in u.iter() { } // no error
254
255     let mut out = vec![];
256     vec.iter().map(|x| out.push(x)).collect::<Vec<_>>();
257     let _y = vec.iter().map(|x| out.push(x)).collect::<Vec<_>>(); // this is fine
258
259     // Loop with explicit counter variable
260     let mut _index = 0;
261     for _v in &vec { _index += 1 }
262
263     let mut _index = 1;
264     _index = 0;
265     for _v in &vec { _index += 1 }
266
267     // Potential false positives
268     let mut _index = 0;
269     _index = 1;
270     for _v in &vec { _index += 1 }
271
272     let mut _index = 0;
273     _index += 1;
274     for _v in &vec { _index += 1 }
275
276     let mut _index = 0;
277     if true { _index = 1 }
278     for _v in &vec { _index += 1 }
279
280     let mut _index = 0;
281     let mut _index = 1;
282     for _v in &vec { _index += 1 }
283
284     let mut _index = 0;
285     for _v in &vec { _index += 1; _index += 1 }
286
287     let mut _index = 0;
288     for _v in &vec { _index *= 2; _index += 1 }
289
290     let mut _index = 0;
291     for _v in &vec { _index = 1; _index += 1 }
292
293     let mut _index = 0;
294
295     for _v in &vec { let mut _index = 0; _index += 1 }
296
297     let mut _index = 0;
298     for _v in &vec { _index += 1; _index = 0; }
299
300     let mut _index = 0;
301     for _v in &vec { for _x in 0..1 { _index += 1; }; _index += 1 }
302
303     let mut _index = 0;
304     for x in &vec { if *x == 1 { _index += 1 } }
305
306     let mut _index = 0;
307     if true { _index = 1 };
308     for _v in &vec { _index += 1 }
309
310     let mut _index = 1;
311     if false { _index = 0 };
312     for _v in &vec { _index += 1 }
313
314     let mut index = 0;
315     { let mut _x = &mut index; }
316     for _v in &vec { _index += 1 }
317
318     let mut index = 0;
319     for _v in &vec { index += 1 }
320     println!("index: {}", index);
321
322     for_loop_over_option_and_result();
323
324     let m : HashMap<u64, u64> = HashMap::new();
325     for (_, v) in &m {
326         let _v = v;
327     }
328
329     let m : Rc<HashMap<u64, u64>> = Rc::new(HashMap::new());
330     for (_, v) in &*m {
331         let _v = v;
332         // Here the `*` is not actually necesarry, but the test tests that we don't suggest
333         // `in *m.values()` as we used to
334     }
335
336     let mut m : HashMap<u64, u64> = HashMap::new();
337     for (_, v) in &mut m {
338         let _v = v;
339     }
340
341     let m: &mut HashMap<u64, u64> = &mut HashMap::new();
342     for (_, v) in &mut *m {
343         let _v = v;
344     }
345
346     let m : HashMap<u64, u64> = HashMap::new();
347     let rm = &m;
348     for (k, _value) in rm {
349         let _k = k;
350     }
351
352     test_for_kv_map();
353 }
354
355 #[allow(used_underscore_binding)]
356 fn test_for_kv_map() {
357     let m : HashMap<u64, u64> = HashMap::new();
358
359     // No error, _value is actually used
360     for (k, _value) in &m {
361         let _ = _value;
362         let _k = k;
363     }
364 }