]> git.lizzy.rs Git - rust.git/blob - src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
Rollup merge of #89468 - FabianWolff:issue-89358, r=jackh726
[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 //~^ WARN the feature `let_chains` is incomplete
22
23 #![allow(irrefutable_let_patterns)]
24
25 use std::ops::Range;
26
27 fn main() {}
28
29 fn nested_within_if_expr() {
30     if &let 0 = 0 {} //~ ERROR `let` expressions are not supported here
31     //~^ ERROR mismatched types
32
33     if !let 0 = 0 {} //~ ERROR `let` expressions are not supported here
34     if *let 0 = 0 {} //~ ERROR `let` expressions are not supported here
35     //~^ ERROR type `bool` cannot be dereferenced
36     if -let 0 = 0 {} //~ ERROR `let` expressions are not supported here
37     //~^ ERROR cannot apply unary operator `-` to type `bool`
38
39     fn _check_try_binds_tighter() -> Result<(), ()> {
40         if let 0 = 0? {}
41         //~^ ERROR the `?` operator can only be applied to values that implement `Try`
42         Ok(())
43     }
44     if (let 0 = 0)? {} //~ ERROR `let` expressions are not supported here
45     //~^ ERROR the `?` operator can only be applied to values that implement `Try`
46     //~| ERROR the `?` operator can only be used in a function that returns `Result`
47
48     if true || let 0 = 0 {} //~ ERROR `let` expressions are not supported here
49     if (true || let 0 = 0) {} //~ ERROR `let` expressions are not supported here
50     if true && (true || let 0 = 0) {} //~ ERROR `let` expressions are not supported here
51     if true || (true && let 0 = 0) {} //~ ERROR `let` expressions are not supported here
52
53     let mut x = true;
54     if x = let 0 = 0 {} //~ ERROR `let` expressions are not supported here
55     //~^ ERROR mismatched types
56
57     if true..(let 0 = 0) {} //~ ERROR `let` expressions are not supported here
58     //~^ ERROR mismatched types
59     if ..(let 0 = 0) {} //~ ERROR `let` expressions are not supported here
60     //~^ ERROR mismatched types
61     if (let 0 = 0).. {} //~ ERROR `let` expressions are not supported here
62     //~^ ERROR mismatched types
63
64     // Binds as `(let ... = true)..true &&/|| false`.
65     if let Range { start: _, end: _ } = true..true && false {}
66     //~^ ERROR `let` expressions are not supported here
67     //~| ERROR mismatched types
68     //~| ERROR mismatched types
69     if let Range { start: _, end: _ } = true..true || false {}
70     //~^ ERROR `let` expressions are not supported here
71     //~| ERROR mismatched types
72     //~| ERROR mismatched types
73
74     // Binds as `(let Range { start: F, end } = F)..(|| true)`.
75     const F: fn() -> bool = || true;
76     if let Range { start: F, end } = F..|| true {}
77     //~^ ERROR `let` expressions are not supported here
78     //~| ERROR mismatched types
79     //~| ERROR mismatched types
80     //~| ERROR mismatched types
81
82     // Binds as `(let Range { start: true, end } = t)..(&&false)`.
83     let t = &&true;
84     if let Range { start: true, end } = t..&&false {}
85     //~^ ERROR `let` expressions are not supported here
86     //~| ERROR mismatched types
87     //~| ERROR mismatched types
88     //~| ERROR mismatched types
89
90     if let true = let true = true {} //~ ERROR `let` expressions are not supported here
91 }
92
93 fn nested_within_while_expr() {
94     while &let 0 = 0 {} //~ ERROR `let` expressions are not supported here
95     //~^ ERROR mismatched types
96
97     while !let 0 = 0 {} //~ ERROR `let` expressions are not supported here
98     while *let 0 = 0 {} //~ ERROR `let` expressions are not supported here
99     //~^ ERROR type `bool` cannot be dereferenced
100     while -let 0 = 0 {} //~ ERROR `let` expressions are not supported here
101     //~^ ERROR cannot apply unary operator `-` to type `bool`
102
103     fn _check_try_binds_tighter() -> Result<(), ()> {
104         while let 0 = 0? {}
105         //~^ ERROR the `?` operator can only be applied to values that implement `Try`
106         Ok(())
107     }
108     while (let 0 = 0)? {} //~ ERROR `let` expressions are not supported here
109     //~^ ERROR the `?` operator can only be applied to values that implement `Try`
110     //~| ERROR the `?` operator can only be used in a function that returns `Result`
111
112     while true || let 0 = 0 {} //~ ERROR `let` expressions are not supported here
113     while (true || let 0 = 0) {} //~ ERROR `let` expressions are not supported here
114     while true && (true || let 0 = 0) {} //~ ERROR `let` expressions are not supported here
115     while true || (true && let 0 = 0) {} //~ ERROR `let` expressions are not supported here
116
117     let mut x = true;
118     while x = let 0 = 0 {} //~ ERROR `let` expressions are not supported here
119     //~^ ERROR mismatched types
120
121     while true..(let 0 = 0) {} //~ ERROR `let` expressions are not supported here
122     //~^ ERROR mismatched types
123     while ..(let 0 = 0) {} //~ ERROR `let` expressions are not supported here
124     //~^ ERROR mismatched types
125     while (let 0 = 0).. {} //~ ERROR `let` expressions are not supported here
126     //~^ ERROR mismatched types
127
128     // Binds as `(let ... = true)..true &&/|| false`.
129     while let Range { start: _, end: _ } = true..true && false {}
130     //~^ ERROR `let` expressions are not supported here
131     //~| ERROR mismatched types
132     //~| ERROR mismatched types
133     while let Range { start: _, end: _ } = true..true || false {}
134     //~^ ERROR `let` expressions are not supported here
135     //~| ERROR mismatched types
136     //~| ERROR mismatched types
137
138     // Binds as `(let Range { start: F, end } = F)..(|| true)`.
139     const F: fn() -> bool = || true;
140     while let Range { start: F, end } = F..|| true {}
141     //~^ ERROR `let` expressions are not supported here
142     //~| ERROR mismatched types
143     //~| ERROR mismatched types
144     //~| ERROR mismatched types
145
146     // Binds as `(let Range { start: true, end } = t)..(&&false)`.
147     let t = &&true;
148     while let Range { start: true, end } = t..&&false {}
149     //~^ ERROR `let` expressions are not supported here
150     //~| ERROR mismatched types
151     //~| ERROR mismatched types
152     //~| ERROR mismatched types
153
154     while let true = let true = true {} //~ ERROR `let` expressions are not supported here
155 }
156
157 fn not_error_because_clarified_intent() {
158     if let Range { start: _, end: _ } = (true..true || false) { }
159
160     if let Range { start: _, end: _ } = (true..true && false) { }
161
162     while let Range { start: _, end: _ } = (true..true || false) { }
163
164     while let Range { start: _, end: _ } = (true..true && false) { }
165 }
166
167 fn outside_if_and_while_expr() {
168     &let 0 = 0; //~ ERROR `let` expressions are not supported here
169
170     !let 0 = 0; //~ ERROR `let` expressions are not supported here
171     *let 0 = 0; //~ ERROR `let` expressions are not supported here
172     //~^ ERROR type `bool` cannot be dereferenced
173     -let 0 = 0; //~ ERROR `let` expressions are not supported here
174     //~^ ERROR cannot apply unary operator `-` to type `bool`
175
176     fn _check_try_binds_tighter() -> Result<(), ()> {
177         let 0 = 0?;
178         //~^ ERROR the `?` operator can only be applied to values that implement `Try`
179         Ok(())
180     }
181     (let 0 = 0)?; //~ ERROR `let` expressions are not supported here
182     //~^ ERROR the `?` operator can only be used in a function that returns `Result`
183     //~| ERROR the `?` operator can only be applied to values that implement `Try`
184
185     true || let 0 = 0; //~ ERROR `let` expressions are not supported here
186     (true || let 0 = 0); //~ ERROR `let` expressions are not supported here
187     true && (true || let 0 = 0); //~ ERROR `let` expressions are not supported here
188
189     let mut x = true;
190     x = let 0 = 0; //~ ERROR `let` expressions are not supported here
191
192     true..(let 0 = 0); //~ ERROR `let` expressions are not supported here
193     ..(let 0 = 0); //~ ERROR `let` expressions are not supported here
194     (let 0 = 0)..; //~ ERROR `let` expressions are not supported here
195
196     (let Range { start: _, end: _ } = true..true || false);
197     //~^ ERROR `let` expressions are not supported here
198     //~| ERROR mismatched types
199
200     (let true = let true = true);
201     //~^ ERROR `let` expressions are not supported here
202
203     // Check function tail position.
204     &let 0 = 0
205     //~^ ERROR `let` expressions are not supported here
206     //~| ERROR mismatched types
207 }
208
209 // Let's make sure that `let` inside const generic arguments are considered.
210 fn inside_const_generic_arguments() {
211     struct A<const B: bool>;
212     impl<const B: bool> A<{B}> { const O: u32 = 5; }
213
214     if let A::<{
215         true && let 1 = 1 //~ ERROR `let` expressions are not supported here
216     }>::O = 5 {}
217
218     while let A::<{
219         true && let 1 = 1 //~ ERROR `let` expressions are not supported here
220     }>::O = 5 {}
221
222     if A::<{
223         true && let 1 = 1 //~ ERROR `let` expressions are not supported here
224     }>::O == 5 {}
225
226     // In the cases above we have `ExprKind::Block` to help us out.
227     // Below however, we would not have a block and so an implementation might go
228     // from visiting expressions to types without banning `let` expressions down the tree.
229     // This tests ensures that we are not caught by surprise should the parser
230     // admit non-IDENT expressions in const generic arguments.
231
232     if A::<
233         true && let 1 = 1
234         //~^ ERROR `let` expressions are not supported here
235         //~| ERROR  expressions must be enclosed in braces
236     >::O == 5 {}
237 }