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