1 // Here we test that `lowering` behaves correctly wrt. `let $pats = $expr` expressions.
3 // We want to make sure that `let` is banned in situations other than:
7 // | "if" expr_with_let block {"else" block}?
8 // | {label ":"}? while" expr_with_let block
12 // | "let" top_pats "=" expr
13 // | expr_with_let "&&" expr_with_let
14 // | "(" expr_with_let ")"
18 // To that end, we check some positions which is not part of the language above.
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
25 #![allow(irrefutable_let_patterns)]
31 fn nested_within_if_expr() {
32 if &let 0 = 0 {} //~ ERROR `let` expressions are not supported here
33 //~^ ERROR mismatched types
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`
41 fn _check_try_binds_tighter() -> Result<(), ()> {
43 //~^ ERROR the `?` operator can only be applied to values that implement `Try`
46 if (let 0 = 0)? {} //~ ERROR `let` expressions are not supported here
47 //~^ ERROR the `?` operator can only be applied to values that implement `Try`
48 //~| ERROR the `?` operator can only be used in a function that returns `Result`
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
56 if x = let 0 = 0 {} //~ ERROR `let` expressions are not supported here
57 //~^ ERROR mismatched types
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
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
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
84 // Binds as `(let Range { start: true, end } = t)..(&&false)`.
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
92 if let true = let true = true {} //~ ERROR `let` expressions are not supported here
95 fn nested_within_while_expr() {
96 while &let 0 = 0 {} //~ ERROR `let` expressions are not supported here
97 //~^ ERROR mismatched types
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`
105 fn _check_try_binds_tighter() -> Result<(), ()> {
107 //~^ ERROR the `?` operator can only be applied to values that implement `Try`
110 while (let 0 = 0)? {} //~ ERROR `let` expressions are not supported here
111 //~^ ERROR the `?` operator can only be applied to values that implement `Try`
112 //~| ERROR the `?` operator can only be used in a function that returns `Result`
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
120 while x = let 0 = 0 {} //~ ERROR `let` expressions are not supported here
121 //~^ ERROR mismatched types
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
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
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
148 // Binds as `(let Range { start: true, end } = t)..(&&false)`.
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
156 while let true = let true = true {} //~ ERROR `let` expressions are not supported here
159 fn not_error_because_clarified_intent() {
160 if let Range { start: _, end: _ } = (true..true || false) { }
162 if let Range { start: _, end: _ } = (true..true && false) { }
164 while let Range { start: _, end: _ } = (true..true || false) { }
166 while let Range { start: _, end: _ } = (true..true && false) { }
169 fn outside_if_and_while_expr() {
170 &let 0 = 0; //~ ERROR `let` expressions are not supported here
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`
178 fn _check_try_binds_tighter() -> Result<(), ()> {
180 //~^ ERROR the `?` operator can only be applied to values that implement `Try`
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 `Try`
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
192 x = let 0 = 0; //~ ERROR `let` expressions are not supported here
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
198 (let Range { start: _, end: _ } = true..true || false);
199 //~^ ERROR `let` expressions are not supported here
200 //~| ERROR mismatched types
202 (let true = let true = true);
203 //~^ ERROR `let` expressions are not supported here
204 //~| ERROR `let` expressions are not supported here
206 // Check function tail position.
208 //~^ ERROR `let` expressions are not supported here
209 //~| ERROR mismatched types
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; }
218 true && let 1 = 1 //~ ERROR `let` expressions are not supported here
222 true && let 1 = 1 //~ ERROR `let` expressions are not supported here
226 true && let 1 = 1 //~ ERROR `let` expressions are not supported here
229 // In the cases above we have `ExprKind::Block` to help us out.
230 // Below however, we would not have a block and so an implementation might go
231 // from visiting expressions to types without banning `let` expressions down the tree.
232 // This tests ensures that we are not caught by surprise should the parser
233 // admit non-IDENT expressions in const generic arguments.
237 //~^ ERROR `let` expressions are not supported here
238 //~| ERROR expressions must be enclosed in braces