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