]> git.lizzy.rs Git - rust.git/blob - tests/ui/while_loop.rs
Merge branch 'master' into add-lints-aseert-checks
[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::cyclomatic_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 okay 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     let mut y = a.iter();
174     loop {
175         // x is reused, so don't lint here
176         while let Some(v) = y.next() {}
177     }
178
179     let mut y = a.iter();
180     for _ in 0..2 {
181         while let Some(v) = y.next() {
182             // y is reused, don't lint
183         }
184     }
185
186     loop {
187         let mut y = a.iter();
188         while let Some(v) = y.next() {
189             // use a for loop here
190         }
191     }
192
193     // should not trigger clippy::while_let_loop lint because break passes an expression
194     let a = Some(10);
195     let b = loop {
196         if let Some(c) = a {
197             break Some(c);
198         } else {
199             break None;
200         }
201     };
202
203     use std::collections::HashSet;
204     let mut values = HashSet::new();
205     values.insert(1);
206
207     while let Some(&value) = values.iter().next() {
208         values.remove(&value);
209     }
210
211     // This should not cause an ICE and suggest:
212     //
213     // for _ in values.iter() {}
214     //
215     // See #2965
216     while let Some(..) = values.iter().next() {
217         values.remove(&1);
218     }
219
220     // Issue 3670
221     {
222         let array = [Some(0), None, Some(1)];
223         let mut iter = array.iter();
224
225         while let Some(elem) = iter.next() {
226             let _ = elem.or_else(|| *iter.next()?);
227         }
228     }
229 }