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
main()26 fn main() {}
27
_if()28 fn _if() {
29 if (let 0 = 1) {}
30 //~^ ERROR `let` expressions are not supported here
31 //~| ERROR expected expression, found `let` statement
32
33 if (((let 0 = 1))) {}
34 //~^ ERROR `let` expressions are not supported here
35 //~| ERROR expected expression, found `let` statement
36
37 if (let 0 = 1) && true {}
38 //~^ ERROR `let` expressions are not supported here
39 //~| ERROR expected expression, found `let` statement
40
41 if true && (let 0 = 1) {}
42 //~^ ERROR `let` expressions are not supported here
43 //~| ERROR expected expression, found `let` statement
44
45 if (let 0 = 1) && (let 0 = 1) {}
46 //~^ ERROR `let` expressions are not supported here
47 //~| ERROR `let` expressions are not supported here
48 //~| ERROR expected expression, found `let` statement
49 //~| ERROR expected expression, found `let` statement
50
51 if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
52 //~^ ERROR `let` expressions are not supported here
53 //~| ERROR `let` expressions are not supported here
54 //~| ERROR `let` expressions are not supported here
55 //~| ERROR expected expression, found `let` statement
56 //~| ERROR expected expression, found `let` statement
57 //~| ERROR expected expression, found `let` statement
58 }
59
_while()60 fn _while() {
61 while (let 0 = 1) {}
62 //~^ ERROR `let` expressions are not supported here
63 //~| ERROR expected expression, found `let` statement
64
65 while (((let 0 = 1))) {}
66 //~^ ERROR `let` expressions are not supported here
67 //~| ERROR expected expression, found `let` statement
68
69 while (let 0 = 1) && true {}
70 //~^ ERROR `let` expressions are not supported here
71 //~| ERROR expected expression, found `let` statement
72
73 while true && (let 0 = 1) {}
74 //~^ ERROR `let` expressions are not supported here
75 //~| ERROR expected expression, found `let` statement
76
77 while (let 0 = 1) && (let 0 = 1) {}
78 //~^ ERROR `let` expressions are not supported here
79 //~| ERROR `let` expressions are not supported here
80 //~| ERROR expected expression, found `let` statement
81 //~| ERROR expected expression, found `let` statement
82
83 while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
84 //~^ ERROR `let` expressions are not supported here
85 //~| ERROR `let` expressions are not supported here
86 //~| ERROR `let` expressions are not supported here
87 //~| ERROR expected expression, found `let` statement
88 //~| ERROR expected expression, found `let` statement
89 //~| ERROR expected expression, found `let` statement
90 }
91
_macros()92 fn _macros() {
93 macro_rules! use_expr {
94 ($e:expr) => {
95 if $e {}
96 while $e {}
97 }
98 }
99 use_expr!((let 0 = 1 && 0 == 0));
100 //~^ ERROR `let` expressions are not supported here
101 //~| ERROR `let` expressions are not supported here
102 //~| ERROR expected expression, found `let` statement
103 use_expr!((let 0 = 1));
104 //~^ ERROR `let` expressions are not supported here
105 //~| ERROR `let` expressions are not supported here
106 //~| ERROR expected expression, found `let` statement
107 }
108
nested_within_if_expr()109 fn nested_within_if_expr() {
110 if &let 0 = 0 {}
111 //~^ ERROR `let` expressions are not supported here
112 //~| ERROR mismatched types
113 //~| ERROR expected expression, found `let` statement
114
115 if !let 0 = 0 {}
116 //~^ ERROR `let` expressions are not supported here
117 //~| ERROR expected expression, found `let` statement
118 if *let 0 = 0 {}
119 //~^ ERROR `let` expressions are not supported here
120 //~| ERROR type `bool` cannot be dereferenced
121 //~| ERROR expected expression, found `let` statement
122 if -let 0 = 0 {}
123 //~^ ERROR `let` expressions are not supported here
124 //~| ERROR cannot apply unary operator `-` to type `bool`
125 //~| ERROR expected expression, found `let` statement
126
127 fn _check_try_binds_tighter() -> Result<(), ()> {
128 if let 0 = 0? {}
129 //~^ ERROR the `?` operator can only be applied to values that implement `Try`
130 Ok(())
131 }
132 if (let 0 = 0)? {}
133 //~^ ERROR `let` expressions are not supported here
134 //~| ERROR the `?` operator can only be applied to values that implement `Try`
135 //~| ERROR the `?` operator can only be used in a function that returns `Result`
136 //~| ERROR expected expression, found `let` statement
137
138 if true || let 0 = 0 {}
139 //~^ ERROR `let` expressions are not supported here
140 //~| ERROR expected expression, found `let` statement
141 if (true || let 0 = 0) {}
142 //~^ ERROR `let` expressions are not supported here
143 //~| ERROR expected expression, found `let` statement
144 if true && (true || let 0 = 0) {}
145 //~^ ERROR `let` expressions are not supported here
146 //~| ERROR expected expression, found `let` statement
147 if true || (true && let 0 = 0) {}
148 //~^ ERROR `let` expressions are not supported here
149 //~| ERROR expected expression, found `let` statement
150
151 let mut x = true;
152 if x = let 0 = 0 {}
153 //~^ ERROR `let` expressions are not supported here
154 //~| ERROR mismatched types
155 //~| ERROR expected expression, found `let` statement
156
157 if true..(let 0 = 0) {}
158 //~^ ERROR `let` expressions are not supported here
159 //~| ERROR mismatched types
160 //~| ERROR expected expression, found `let` statement
161 if ..(let 0 = 0) {}
162 //~^ ERROR `let` expressions are not supported here
163 //~| ERROR mismatched types
164 //~| ERROR expected expression, found `let` statement
165 if (let 0 = 0).. {}
166 //~^ ERROR `let` expressions are not supported here
167 //~| ERROR mismatched types
168 //~| ERROR expected expression, found `let` statement
169
170 // Binds as `(let ... = true)..true &&/|| false`.
171 if let Range { start: _, end: _ } = true..true && false {}
172 //~^ ERROR `let` expressions are not supported here
173 //~| ERROR mismatched types
174 //~| ERROR mismatched types
175 if let Range { start: _, end: _ } = true..true || false {}
176 //~^ ERROR `let` expressions are not supported here
177 //~| ERROR mismatched types
178 //~| ERROR mismatched types
179
180 // Binds as `(let Range { start: F, end } = F)..(|| true)`.
181 const F: fn() -> bool = || true;
182 if let Range { start: F, end } = F..|| true {}
183 //~^ ERROR `let` expressions are not supported here
184 //~| ERROR mismatched types
185 //~| ERROR mismatched types
186 //~| ERROR mismatched types
187
188 // Binds as `(let Range { start: true, end } = t)..(&&false)`.
189 let t = &&true;
190 if let Range { start: true, end } = t..&&false {}
191 //~^ ERROR `let` expressions are not supported here
192 //~| ERROR mismatched types
193 //~| ERROR mismatched types
194 //~| ERROR mismatched types
195
196 if let true = let true = true {}
197 //~^ ERROR `let` expressions are not supported here
198 //~| ERROR expected expression, found `let` statement
199 }
200
nested_within_while_expr()201 fn nested_within_while_expr() {
202 while &let 0 = 0 {}
203 //~^ ERROR `let` expressions are not supported here
204 //~| ERROR mismatched types
205 //~| ERROR expected expression, found `let` statement
206
207 while !let 0 = 0 {}
208 //~^ ERROR `let` expressions are not supported here
209 //~| ERROR expected expression, found `let` statement
210 while *let 0 = 0 {}
211 //~^ ERROR `let` expressions are not supported here
212 //~| ERROR type `bool` cannot be dereferenced
213 //~| ERROR expected expression, found `let` statement
214 while -let 0 = 0 {}
215 //~^ ERROR `let` expressions are not supported here
216 //~| ERROR cannot apply unary operator `-` to type `bool`
217 //~| ERROR expected expression, found `let` statement
218
219 fn _check_try_binds_tighter() -> Result<(), ()> {
220 while let 0 = 0? {}
221 //~^ ERROR the `?` operator can only be applied to values that implement `Try`
222 Ok(())
223 }
224 while (let 0 = 0)? {}
225 //~^ ERROR `let` expressions are not supported here
226 //~| ERROR the `?` operator can only be applied to values that implement `Try`
227 //~| ERROR the `?` operator can only be used in a function that returns `Result`
228 //~| ERROR expected expression, found `let` statement
229
230 while true || let 0 = 0 {}
231 //~^ ERROR `let` expressions are not supported here
232 //~| ERROR expected expression, found `let` statement
233 while (true || let 0 = 0) {}
234 //~^ ERROR `let` expressions are not supported here
235 //~| ERROR expected expression, found `let` statement
236 while true && (true || let 0 = 0) {}
237 //~^ ERROR `let` expressions are not supported here
238 //~| ERROR expected expression, found `let` statement
239 while true || (true && let 0 = 0) {}
240 //~^ ERROR `let` expressions are not supported here
241 //~| ERROR expected expression, found `let` statement
242
243 let mut x = true;
244 while x = let 0 = 0 {}
245 //~^ ERROR `let` expressions are not supported here
246 //~| ERROR mismatched types
247 //~| ERROR expected expression, found `let` statement
248
249 while true..(let 0 = 0) {}
250 //~^ ERROR `let` expressions are not supported here
251 //~| ERROR mismatched types
252 //~| ERROR expected expression, found `let` statement
253 while ..(let 0 = 0) {}
254 //~^ ERROR `let` expressions are not supported here
255 //~| ERROR mismatched types
256 //~| ERROR expected expression, found `let` statement
257 while (let 0 = 0).. {}
258 //~^ ERROR `let` expressions are not supported here
259 //~| ERROR mismatched types
260 //~| ERROR expected expression, found `let` statement
261
262 // Binds as `(let ... = true)..true &&/|| false`.
263 while let Range { start: _, end: _ } = true..true && false {}
264 //~^ ERROR `let` expressions are not supported here
265 //~| ERROR mismatched types
266 //~| ERROR mismatched types
267 while let Range { start: _, end: _ } = true..true || false {}
268 //~^ ERROR `let` expressions are not supported here
269 //~| ERROR mismatched types
270 //~| ERROR mismatched types
271
272 // Binds as `(let Range { start: F, end } = F)..(|| true)`.
273 const F: fn() -> bool = || true;
274 while let Range { start: F, end } = F..|| true {}
275 //~^ ERROR `let` expressions are not supported here
276 //~| ERROR mismatched types
277 //~| ERROR mismatched types
278 //~| ERROR mismatched types
279
280 // Binds as `(let Range { start: true, end } = t)..(&&false)`.
281 let t = &&true;
282 while let Range { start: true, end } = t..&&false {}
283 //~^ ERROR `let` expressions are not supported here
284 //~| ERROR mismatched types
285 //~| ERROR mismatched types
286 //~| ERROR mismatched types
287
288 while let true = let true = true {}
289 //~^ ERROR `let` expressions are not supported here
290 //~| ERROR expected expression, found `let` statement
291 }
292
not_error_because_clarified_intent()293 fn not_error_because_clarified_intent() {
294 if let Range { start: _, end: _ } = (true..true || false) { }
295
296 if let Range { start: _, end: _ } = (true..true && false) { }
297
298 while let Range { start: _, end: _ } = (true..true || false) { }
299
300 while let Range { start: _, end: _ } = (true..true && false) { }
301 }
302
outside_if_and_while_expr()303 fn outside_if_and_while_expr() {
304 &let 0 = 0;
305 //~^ ERROR `let` expressions are not supported here
306 //~| ERROR expected expression, found `let` statement
307
308 !let 0 = 0;
309 //~^ ERROR `let` expressions are not supported here
310 //~| ERROR expected expression, found `let` statement
311 *let 0 = 0;
312 //~^ ERROR `let` expressions are not supported here
313 //~| ERROR type `bool` cannot be dereferenced
314 //~| ERROR expected expression, found `let` statement
315 -let 0 = 0;
316 //~^ ERROR `let` expressions are not supported here
317 //~| ERROR cannot apply unary operator `-` to type `bool`
318 //~| ERROR expected expression, found `let` statement
319
320 fn _check_try_binds_tighter() -> Result<(), ()> {
321 let 0 = 0?;
322 //~^ ERROR the `?` operator can only be applied to values that implement `Try`
323 Ok(())
324 }
325 (let 0 = 0)?;
326 //~^ ERROR `let` expressions are not supported here
327 //~| ERROR the `?` operator can only be used in a function that returns `Result`
328 //~| ERROR the `?` operator can only be applied to values that implement `Try`
329 //~| ERROR expected expression, found `let` statement
330
331 true || let 0 = 0;
332 //~^ ERROR `let` expressions are not supported here
333 //~| ERROR expected expression, found `let` statement
334 (true || let 0 = 0);
335 //~^ ERROR `let` expressions are not supported here
336 //~| ERROR expected expression, found `let` statement
337 true && (true || let 0 = 0);
338 //~^ ERROR `let` expressions are not supported here
339 //~| ERROR expected expression, found `let` statement
340
341 let mut x = true;
342 x = let 0 = 0;
343 //~^ ERROR `let` expressions are not supported here
344 //~| ERROR expected expression, found `let` statement
345
346 true..(let 0 = 0);
347 //~^ ERROR `let` expressions are not supported here
348 //~| ERROR expected expression, found `let` statement
349 ..(let 0 = 0);
350 //~^ ERROR `let` expressions are not supported here
351 //~| ERROR expected expression, found `let` statement
352 (let 0 = 0)..;
353 //~^ ERROR `let` expressions are not supported here
354 //~| ERROR expected expression, found `let` statement
355
356 (let Range { start: _, end: _ } = true..true || false);
357 //~^ ERROR `let` expressions are not supported here
358 //~| ERROR mismatched types
359 //~| ERROR expected expression, found `let` statement
360
361 (let true = let true = true);
362 //~^ ERROR `let` expressions are not supported here
363 //~| ERROR expected expression, found `let` statement
364 //~| ERROR expected expression, found `let` statement
365
366 {
367 #[cfg(FALSE)]
368 let x = true && let y = 1;
369 //~^ ERROR expected expression, found `let` statement
370 }
371
372 #[cfg(FALSE)]
373 {
374 [1, 2, 3][let _ = ()]
375 //~^ ERROR expected expression, found `let` statement
376 }
377
378 // Check function tail position.
379 &let 0 = 0
380 //~^ ERROR `let` expressions are not supported here
381 //~| ERROR mismatched types
382 //~| ERROR expected expression, found `let` statement
383 }
384
385 // Let's make sure that `let` inside const generic arguments are considered.
inside_const_generic_arguments()386 fn inside_const_generic_arguments() {
387 struct A<const B: bool>;
388 impl<const B: bool> A<{B}> { const O: u32 = 5; }
389
390 if let A::<{
391 true && let 1 = 1
392 //~^ ERROR `let` expressions are not supported here
393 //~| ERROR expected expression, found `let` statement
394 }>::O = 5 {}
395
396 while let A::<{
397 true && let 1 = 1
398 //~^ ERROR `let` expressions are not supported here
399 //~| ERROR expected expression, found `let` statement
400 }>::O = 5 {}
401
402 if A::<{
403 true && let 1 = 1
404 //~^ ERROR `let` expressions are not supported here
405 //~| ERROR expected expression, found `let` statement
406 }>::O == 5 {}
407
408 // In the cases above we have `ExprKind::Block` to help us out.
409 // Below however, we would not have a block and so an implementation might go
410 // from visiting expressions to types without banning `let` expressions down the tree.
411 // This tests ensures that we are not caught by surprise should the parser
412 // admit non-IDENT expressions in const generic arguments.
413
414 if A::<
415 true && let 1 = 1
416 //~^ ERROR `let` expressions are not supported here
417 //~| ERROR expressions must be enclosed in braces
418 //~| ERROR expected expression, found `let` statement
419 >::O == 5 {}
420 }
421
with_parenthesis()422 fn with_parenthesis() {
423 let opt = Some(Some(1i32));
424
425 if (let Some(a) = opt && true) {
426 //~^ ERROR `let` expressions are not supported here
427 //~| ERROR expected expression, found `let` statement
428 }
429
430 if (let Some(a) = opt) && true {
431 //~^ ERROR `let` expressions are not supported here
432 //~| ERROR expected expression, found `let` statement
433 }
434 if (let Some(a) = opt) && (let Some(b) = a) {
435 //~^ ERROR `let` expressions are not supported here
436 //~| ERROR `let` expressions are not supported here
437 //~| ERROR expected expression, found `let` statement
438 //~| ERROR expected expression, found `let` statement
439 }
440 if let Some(a) = opt && (true && true) {
441 }
442
443 if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
444 //~^ ERROR `let` expressions are not supported here
445 //~| ERROR `let` expressions are not supported here
446 //~| ERROR expected expression, found `let` statement
447 //~| ERROR expected expression, found `let` statement
448 }
449 if (let Some(a) = opt && (let Some(b) = a)) && true {
450 //~^ ERROR `let` expressions are not supported here
451 //~| ERROR `let` expressions are not supported here
452 //~| ERROR expected expression, found `let` statement
453 //~| ERROR expected expression, found `let` statement
454 }
455 if (let Some(a) = opt && (true)) && true {
456 //~^ ERROR `let` expressions are not supported here
457 //~| ERROR expected expression, found `let` statement
458 }
459
460 if (true && (true)) && let Some(a) = opt {
461 }
462 if (true) && let Some(a) = opt {
463 }
464 if true && let Some(a) = opt {
465 }
466
467 let fun = || true;
468 if let true = (true && fun()) && (true) {
469 }
470
471 #[cfg(FALSE)]
472 let x = (true && let y = 1);
473 //~^ ERROR expected expression, found `let` statement
474
475 #[cfg(FALSE)]
476 {
477 ([1, 2, 3][let _ = ()])
478 //~^ ERROR expected expression, found `let` statement
479 }
480 }
481