]> git.lizzy.rs Git - rust.git/blob - src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
Auto merge of #87150 - rusticstuff:simplify_wrapping_neg, r=m-ou-se
[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(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 `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 `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 `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 `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 `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 `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
219     }>::O = 5 {}
220
221     while let A::<{
222         true && let 1 = 1 //~ ERROR `let` expressions are not supported here
223     }>::O = 5 {}
224
225     if A::<{
226         true && let 1 = 1 //~ ERROR `let` expressions are not supported here
227     }>::O == 5 {}
228
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.
234
235     if A::<
236         true && let 1 = 1
237         //~^ ERROR `let` expressions are not supported here
238         //~| ERROR  expressions must be enclosed in braces
239     >::O == 5 {}
240 }