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