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(let_chains)] // Avoid inflating `.stderr` with overzealous gates in this test.
21 //~^ WARN the feature `let_chains` is incomplete
23 #![allow(irrefutable_let_patterns)]
29 fn nested_within_if_expr() {
30 if &let 0 = 0 {} //~ ERROR `let` expressions are not supported here
31 //~^ ERROR mismatched types
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`
39 fn _check_try_binds_tighter() -> Result<(), ()> {
41 //~^ ERROR the `?` operator can only be applied to values that implement `Try`
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`
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
54 if x = let 0 = 0 {} //~ ERROR `let` expressions are not supported here
55 //~^ ERROR mismatched types
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
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
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
82 // Binds as `(let Range { start: true, end } = t)..(&&false)`.
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
90 if let true = let true = true {} //~ ERROR `let` expressions are not supported here
93 fn nested_within_while_expr() {
94 while &let 0 = 0 {} //~ ERROR `let` expressions are not supported here
95 //~^ ERROR mismatched types
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`
103 fn _check_try_binds_tighter() -> Result<(), ()> {
105 //~^ ERROR the `?` operator can only be applied to values that implement `Try`
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`
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
118 while x = let 0 = 0 {} //~ ERROR `let` expressions are not supported here
119 //~^ ERROR mismatched types
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
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
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
146 // Binds as `(let Range { start: true, end } = t)..(&&false)`.
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
154 while let true = let true = true {} //~ ERROR `let` expressions are not supported here
157 fn not_error_because_clarified_intent() {
158 if let Range { start: _, end: _ } = (true..true || false) { }
160 if let Range { start: _, end: _ } = (true..true && false) { }
162 while let Range { start: _, end: _ } = (true..true || false) { }
164 while let Range { start: _, end: _ } = (true..true && false) { }
167 fn outside_if_and_while_expr() {
168 &let 0 = 0; //~ ERROR `let` expressions are not supported here
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`
176 fn _check_try_binds_tighter() -> Result<(), ()> {
178 //~^ ERROR the `?` operator can only be applied to values that implement `Try`
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`
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
190 x = let 0 = 0; //~ ERROR `let` expressions are not supported here
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
196 (let Range { start: _, end: _ } = true..true || false);
197 //~^ ERROR `let` expressions are not supported here
198 //~| ERROR mismatched types
200 (let true = let true = true);
201 //~^ ERROR `let` expressions are not supported here
203 // Check function tail position.
205 //~^ ERROR `let` expressions are not supported here
206 //~| ERROR mismatched types
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; }
215 true && let 1 = 1 //~ ERROR `let` expressions are not supported here
219 true && let 1 = 1 //~ ERROR `let` expressions are not supported here
223 true && let 1 = 1 //~ ERROR `let` expressions are not supported here
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.
234 //~^ ERROR `let` expressions are not supported here
235 //~| ERROR expressions must be enclosed in braces