]> git.lizzy.rs Git - rust.git/blob - src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
Rollup merge of #105758 - Nilstrieb:typeck-results-mod, r=compiler-errors
[rust.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     //~| 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
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
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
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
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
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
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.
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
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 }