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