]> git.proxmox.com Git - rustc.git/blame - src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
New upstream version 1.41.1+dfsg1
[rustc.git] / src / test / ui / rfc-2497-if-let-chains / disallowed-positions.rs
CommitLineData
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
27use std::ops::Range;
28
29fn main() {}
30
31fn 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
95fn 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
159fn 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
169fn 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.
213fn 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}