]> git.lizzy.rs Git - rust.git/blob - tests/ui/while_loop.rs
Auto merge of #3603 - xfix:random-state-lint, r=phansch
[rust.git] / tests / ui / while_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 #![warn(clippy::while_let_loop, clippy::empty_loop, clippy::while_let_on_iterator)]
11 #![allow(dead_code, clippy::never_loop, unused, clippy::cyclomatic_complexity)]
12
13 fn main() {
14     let y = Some(true);
15     loop {
16         if let Some(_x) = y {
17             let _v = 1;
18         } else {
19             break;
20         }
21     }
22     loop {
23         // no error, break is not in else clause
24         if let Some(_x) = y {
25             let _v = 1;
26         }
27         break;
28     }
29     loop {
30         match y {
31             Some(_x) => true,
32             None => break,
33         };
34     }
35     loop {
36         let x = match y {
37             Some(x) => x,
38             None => break,
39         };
40         let _x = x;
41         let _str = "foo";
42     }
43     loop {
44         let x = match y {
45             Some(x) => x,
46             None => break,
47         };
48         {
49             let _a = "bar";
50         };
51         {
52             let _b = "foobar";
53         }
54     }
55     loop {
56         // no error, else branch does something other than break
57         match y {
58             Some(_x) => true,
59             _ => {
60                 let _z = 1;
61                 break;
62             },
63         };
64     }
65     while let Some(x) = y {
66         // no error, obviously
67         println!("{}", x);
68     }
69
70     // #675, this used to have a wrong suggestion
71     loop {
72         let (e, l) = match "".split_whitespace().next() {
73             Some(word) => (word.is_empty(), word.len()),
74             None => break,
75         };
76
77         let _ = (e, l);
78     }
79
80     let mut iter = 1..20;
81     while let Option::Some(x) = iter.next() {
82         println!("{}", x);
83     }
84
85     let mut iter = 1..20;
86     while let Some(x) = iter.next() {
87         println!("{}", x);
88     }
89
90     let mut iter = 1..20;
91     while let Some(_) = iter.next() {}
92
93     let mut iter = 1..20;
94     while let None = iter.next() {} // this is fine (if nonsensical)
95
96     let mut iter = 1..20;
97     if let Some(x) = iter.next() {
98         // also fine
99         println!("{}", x)
100     }
101
102     // the following shouldn't warn because it can't be written with a for loop
103     let mut iter = 1u32..20;
104     while let Some(x) = iter.next() {
105         println!("next: {:?}", iter.next())
106     }
107
108     // neither can this
109     let mut iter = 1u32..20;
110     while let Some(x) = iter.next() {
111         println!("next: {:?}", iter.next());
112     }
113
114     // or this
115     let mut iter = 1u32..20;
116     while let Some(x) = iter.next() {
117         break;
118     }
119     println!("Remaining iter {:?}", iter);
120
121     // or this
122     let mut iter = 1u32..20;
123     while let Some(x) = iter.next() {
124         iter = 1..20;
125     }
126 }
127
128 // regression test (#360)
129 // this should not panic
130 // it's okay if further iterations of the lint
131 // cause this function to trigger it
132 fn no_panic<T>(slice: &[T]) {
133     let mut iter = slice.iter();
134     loop {
135         let _ = match iter.next() {
136             Some(ele) => ele,
137             None => break,
138         };
139         loop {}
140     }
141 }
142
143 fn issue1017() {
144     let r: Result<u32, u32> = Ok(42);
145     let mut len = 1337;
146
147     loop {
148         match r {
149             Err(_) => len = 0,
150             Ok(length) => {
151                 len = length;
152                 break;
153             },
154         }
155     }
156 }
157
158 // Issue #1188
159 fn refutable() {
160     let a = [42, 1337];
161     let mut b = a.iter();
162
163     // consume all the 42s
164     while let Some(&42) = b.next() {}
165
166     let a = [(1, 2, 3)];
167     let mut b = a.iter();
168
169     while let Some(&(1, 2, 3)) = b.next() {}
170
171     let a = [Some(42)];
172     let mut b = a.iter();
173
174     while let Some(&None) = b.next() {}
175
176     /* This gives “refutable pattern in `for` loop binding: `&_` not covered”
177     for &42 in b {}
178     for &(1, 2, 3) in b {}
179     for &Option::None in b.next() {}
180     // */
181
182     let mut y = a.iter();
183     loop {
184         // x is reused, so don't lint here
185         while let Some(v) = y.next() {}
186     }
187
188     let mut y = a.iter();
189     for _ in 0..2 {
190         while let Some(v) = y.next() {
191             // y is reused, don't lint
192         }
193     }
194
195     loop {
196         let mut y = a.iter();
197         while let Some(v) = y.next() {
198             // use a for loop here
199         }
200     }
201
202     // should not trigger clippy::while_let_loop lint because break passes an expression
203     let a = Some(10);
204     let b = loop {
205         if let Some(c) = a {
206             break Some(c);
207         } else {
208             break None;
209         }
210     };
211
212     use std::collections::HashSet;
213     let mut values = HashSet::new();
214     values.insert(1);
215
216     while let Some(&value) = values.iter().next() {
217         values.remove(&value);
218     }
219
220     // This should not cause an ICE and suggest:
221     //
222     // for _ in values.iter() {}
223     //
224     // See #2965
225     while let Some(..) = values.iter().next() {
226         values.remove(&1);
227     }
228 }