]> git.proxmox.com Git - rustc.git/blob - src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
New upstream version 1.62.1+dfsg1
[rustc.git] / src / test / ui / rfc-2497-if-let-chains / disallowed-positions.rs
1 // Here we test that `lowering` behaves correctly wrt. `let $pats = $expr` expressions.
2 //
3 // We want to make sure that `let` is banned in situations other than:
4 //
5 // expr =
6 // | ...
7 // | "if" expr_with_let block {"else" block}?
8 // | {label ":"}? while" expr_with_let block
9 // ;
10 //
11 // expr_with_let =
12 // | "let" top_pats "=" expr
13 // | expr_with_let "&&" expr_with_let
14 // | "(" expr_with_let ")"
15 // | expr
16 // ;
17 //
18 // To that end, we check some positions which is not part of the language above.
19
20 #![feature(let_chains)] // Avoid inflating `.stderr` with overzealous gates in this test.
21
22 #![allow(irrefutable_let_patterns)]
23
24 use std::ops::Range;
25
26 fn main() {}
27
28 fn _if() {
29 if (let 0 = 1) {}
30 //~^ ERROR `let` expressions are not supported here
31
32 if (((let 0 = 1))) {}
33 //~^ ERROR `let` expressions are not supported here
34
35 if (let 0 = 1) && true {}
36 //~^ ERROR `let` expressions are not supported here
37
38 if true && (let 0 = 1) {}
39 //~^ ERROR `let` expressions are not supported here
40
41 if (let 0 = 1) && (let 0 = 1) {}
42 //~^ ERROR `let` expressions are not supported here
43 //~| ERROR `let` expressions are not supported here
44
45 if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
46 //~^ ERROR `let` expressions are not supported here
47 //~| ERROR `let` expressions are not supported here
48 //~| ERROR `let` expressions are not supported here
49 }
50
51 fn _while() {
52 while (let 0 = 1) {}
53 //~^ ERROR `let` expressions are not supported here
54
55 while (((let 0 = 1))) {}
56 //~^ ERROR `let` expressions are not supported here
57
58 while (let 0 = 1) && true {}
59 //~^ ERROR `let` expressions are not supported here
60
61 while true && (let 0 = 1) {}
62 //~^ ERROR `let` expressions are not supported here
63
64 while (let 0 = 1) && (let 0 = 1) {}
65 //~^ ERROR `let` expressions are not supported here
66 //~| ERROR `let` expressions are not supported here
67
68 while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
69 //~^ ERROR `let` expressions are not supported here
70 //~| ERROR `let` expressions are not supported here
71 //~| ERROR `let` expressions are not supported here
72 }
73
74 fn _macros() {
75 macro_rules! use_expr {
76 ($e:expr) => {
77 if $e {}
78 while $e {}
79 }
80 }
81 use_expr!((let 0 = 1 && 0 == 0));
82 //~^ ERROR `let` expressions are not supported here
83 //~| ERROR `let` expressions are not supported here
84 use_expr!((let 0 = 1));
85 //~^ ERROR `let` expressions are not supported here
86 //~| ERROR `let` expressions are not supported here
87 }
88
89 fn nested_within_if_expr() {
90 if &let 0 = 0 {} //~ ERROR `let` expressions are not supported here
91 //~^ ERROR mismatched types
92
93 if !let 0 = 0 {} //~ ERROR `let` expressions are not supported here
94 if *let 0 = 0 {} //~ ERROR `let` expressions are not supported here
95 //~^ ERROR type `bool` cannot be dereferenced
96 if -let 0 = 0 {} //~ ERROR `let` expressions are not supported here
97 //~^ ERROR cannot apply unary operator `-` to type `bool`
98
99 fn _check_try_binds_tighter() -> Result<(), ()> {
100 if let 0 = 0? {}
101 //~^ ERROR the `?` operator can only be applied to values that implement `Try`
102 Ok(())
103 }
104 if (let 0 = 0)? {} //~ ERROR `let` expressions are not supported here
105 //~^ ERROR the `?` operator can only be applied to values that implement `Try`
106 //~| ERROR the `?` operator can only be used in a function that returns `Result`
107
108 if true || let 0 = 0 {} //~ ERROR `let` expressions are not supported here
109 if (true || let 0 = 0) {} //~ ERROR `let` expressions are not supported here
110 if true && (true || let 0 = 0) {} //~ ERROR `let` expressions are not supported here
111 if true || (true && let 0 = 0) {} //~ ERROR `let` expressions are not supported here
112
113 let mut x = true;
114 if x = let 0 = 0 {} //~ ERROR `let` expressions are not supported here
115 //~^ ERROR mismatched types
116
117 if true..(let 0 = 0) {} //~ ERROR `let` expressions are not supported here
118 //~^ ERROR mismatched types
119 if ..(let 0 = 0) {} //~ ERROR `let` expressions are not supported here
120 //~^ ERROR mismatched types
121 if (let 0 = 0).. {} //~ ERROR `let` expressions are not supported here
122 //~^ ERROR mismatched types
123
124 // Binds as `(let ... = true)..true &&/|| false`.
125 if let Range { start: _, end: _ } = true..true && false {}
126 //~^ ERROR `let` expressions are not supported here
127 //~| ERROR mismatched types
128 //~| ERROR mismatched types
129 if let Range { start: _, end: _ } = true..true || false {}
130 //~^ ERROR `let` expressions are not supported here
131 //~| ERROR mismatched types
132 //~| ERROR mismatched types
133
134 // Binds as `(let Range { start: F, end } = F)..(|| true)`.
135 const F: fn() -> bool = || true;
136 if let Range { start: F, end } = F..|| true {}
137 //~^ ERROR `let` expressions are not supported here
138 //~| ERROR mismatched types
139 //~| ERROR mismatched types
140 //~| ERROR mismatched types
141
142 // Binds as `(let Range { start: true, end } = t)..(&&false)`.
143 let t = &&true;
144 if let Range { start: true, end } = t..&&false {}
145 //~^ ERROR `let` expressions are not supported here
146 //~| ERROR mismatched types
147 //~| ERROR mismatched types
148 //~| ERROR mismatched types
149
150 if let true = let true = true {} //~ ERROR `let` expressions are not supported here
151 }
152
153 fn nested_within_while_expr() {
154 while &let 0 = 0 {} //~ ERROR `let` expressions are not supported here
155 //~^ ERROR mismatched types
156
157 while !let 0 = 0 {} //~ ERROR `let` expressions are not supported here
158 while *let 0 = 0 {} //~ ERROR `let` expressions are not supported here
159 //~^ ERROR type `bool` cannot be dereferenced
160 while -let 0 = 0 {} //~ ERROR `let` expressions are not supported here
161 //~^ ERROR cannot apply unary operator `-` to type `bool`
162
163 fn _check_try_binds_tighter() -> Result<(), ()> {
164 while let 0 = 0? {}
165 //~^ ERROR the `?` operator can only be applied to values that implement `Try`
166 Ok(())
167 }
168 while (let 0 = 0)? {} //~ ERROR `let` expressions are not supported here
169 //~^ ERROR the `?` operator can only be applied to values that implement `Try`
170 //~| ERROR the `?` operator can only be used in a function that returns `Result`
171
172 while true || let 0 = 0 {} //~ ERROR `let` expressions are not supported here
173 while (true || let 0 = 0) {} //~ ERROR `let` expressions are not supported here
174 while true && (true || let 0 = 0) {} //~ ERROR `let` expressions are not supported here
175 while true || (true && let 0 = 0) {} //~ ERROR `let` expressions are not supported here
176
177 let mut x = true;
178 while x = let 0 = 0 {} //~ ERROR `let` expressions are not supported here
179 //~^ ERROR mismatched types
180
181 while true..(let 0 = 0) {} //~ ERROR `let` expressions are not supported here
182 //~^ ERROR mismatched types
183 while ..(let 0 = 0) {} //~ ERROR `let` expressions are not supported here
184 //~^ ERROR mismatched types
185 while (let 0 = 0).. {} //~ ERROR `let` expressions are not supported here
186 //~^ ERROR mismatched types
187
188 // Binds as `(let ... = true)..true &&/|| false`.
189 while let Range { start: _, end: _ } = true..true && false {}
190 //~^ ERROR `let` expressions are not supported here
191 //~| ERROR mismatched types
192 //~| ERROR mismatched types
193 while let Range { start: _, end: _ } = true..true || false {}
194 //~^ ERROR `let` expressions are not supported here
195 //~| ERROR mismatched types
196 //~| ERROR mismatched types
197
198 // Binds as `(let Range { start: F, end } = F)..(|| true)`.
199 const F: fn() -> bool = || true;
200 while let Range { start: F, end } = F..|| true {}
201 //~^ ERROR `let` expressions are not supported here
202 //~| ERROR mismatched types
203 //~| ERROR mismatched types
204 //~| ERROR mismatched types
205
206 // Binds as `(let Range { start: true, end } = t)..(&&false)`.
207 let t = &&true;
208 while let Range { start: true, end } = t..&&false {}
209 //~^ ERROR `let` expressions are not supported here
210 //~| ERROR mismatched types
211 //~| ERROR mismatched types
212 //~| ERROR mismatched types
213
214 while let true = let true = true {} //~ ERROR `let` expressions are not supported here
215 }
216
217 fn not_error_because_clarified_intent() {
218 if let Range { start: _, end: _ } = (true..true || false) { }
219
220 if let Range { start: _, end: _ } = (true..true && false) { }
221
222 while let Range { start: _, end: _ } = (true..true || false) { }
223
224 while let Range { start: _, end: _ } = (true..true && false) { }
225 }
226
227 fn outside_if_and_while_expr() {
228 &let 0 = 0; //~ ERROR `let` expressions are not supported here
229
230 !let 0 = 0; //~ ERROR `let` expressions are not supported here
231 *let 0 = 0; //~ ERROR `let` expressions are not supported here
232 //~^ ERROR type `bool` cannot be dereferenced
233 -let 0 = 0; //~ ERROR `let` expressions are not supported here
234 //~^ ERROR cannot apply unary operator `-` to type `bool`
235
236 fn _check_try_binds_tighter() -> Result<(), ()> {
237 let 0 = 0?;
238 //~^ ERROR the `?` operator can only be applied to values that implement `Try`
239 Ok(())
240 }
241 (let 0 = 0)?; //~ ERROR `let` expressions are not supported here
242 //~^ ERROR the `?` operator can only be used in a function that returns `Result`
243 //~| ERROR the `?` operator can only be applied to values that implement `Try`
244
245 true || let 0 = 0; //~ ERROR `let` expressions are not supported here
246 (true || let 0 = 0); //~ ERROR `let` expressions are not supported here
247 true && (true || let 0 = 0); //~ ERROR `let` expressions are not supported here
248
249 let mut x = true;
250 x = let 0 = 0; //~ ERROR `let` expressions are not supported here
251
252 true..(let 0 = 0); //~ ERROR `let` expressions are not supported here
253 ..(let 0 = 0); //~ ERROR `let` expressions are not supported here
254 (let 0 = 0)..; //~ ERROR `let` expressions are not supported here
255
256 (let Range { start: _, end: _ } = true..true || false);
257 //~^ ERROR `let` expressions are not supported here
258 //~| ERROR mismatched types
259
260 (let true = let true = true);
261 //~^ ERROR `let` expressions are not supported here
262
263 // Check function tail position.
264 &let 0 = 0
265 //~^ ERROR `let` expressions are not supported here
266 //~| ERROR mismatched types
267 }
268
269 // Let's make sure that `let` inside const generic arguments are considered.
270 fn inside_const_generic_arguments() {
271 struct A<const B: bool>;
272 impl<const B: bool> A<{B}> { const O: u32 = 5; }
273
274 if let A::<{
275 true && let 1 = 1 //~ ERROR `let` expressions are not supported here
276 }>::O = 5 {}
277
278 while let A::<{
279 true && let 1 = 1 //~ ERROR `let` expressions are not supported here
280 }>::O = 5 {}
281
282 if A::<{
283 true && let 1 = 1 //~ ERROR `let` expressions are not supported here
284 }>::O == 5 {}
285
286 // In the cases above we have `ExprKind::Block` to help us out.
287 // Below however, we would not have a block and so an implementation might go
288 // from visiting expressions to types without banning `let` expressions down the tree.
289 // This tests ensures that we are not caught by surprise should the parser
290 // admit non-IDENT expressions in const generic arguments.
291
292 if A::<
293 true && let 1 = 1
294 //~^ ERROR `let` expressions are not supported here
295 //~| ERROR expressions must be enclosed in braces
296 >::O == 5 {}
297 }
298
299 fn with_parenthesis() {
300 let opt = Some(Some(1i32));
301
302 if (let Some(a) = opt && true) {
303 //~^ ERROR `let` expressions are not supported here
304 }
305
306 if (let Some(a) = opt) && true {
307 //~^ ERROR `let` expressions are not supported here
308 }
309 if (let Some(a) = opt) && (let Some(b) = a) {
310 //~^ ERROR `let` expressions are not supported here
311 //~| ERROR `let` expressions are not supported here
312 }
313 if let Some(a) = opt && (true && true) {
314 }
315
316 if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
317 //~^ ERROR `let` expressions are not supported here
318 //~| ERROR `let` expressions are not supported here
319 }
320 if (let Some(a) = opt && (let Some(b) = a)) && true {
321 //~^ ERROR `let` expressions are not supported here
322 //~| ERROR `let` expressions are not supported here
323 }
324 if (let Some(a) = opt && (true)) && true {
325 //~^ ERROR `let` expressions are not supported here
326 }
327
328 if (true && (true)) && let Some(a) = opt {
329 }
330 if (true) && let Some(a) = opt {
331 }
332 if true && let Some(a) = opt {
333 }
334
335 let fun = || true;
336 if let true = (true && fun()) && (true) {
337 }
338 }