@@ -13,7 +13,7 @@ pub(super) fn opt_generic_param_list(p: &mut Parser<'_>) {
13
13
14
14
// test_err generic_param_list_recover
15
15
// fn f<T: Clone,, U:, V>() {}
16
- fn generic_param_list ( p : & mut Parser < ' _ > ) {
16
+ pub ( super ) fn generic_param_list ( p : & mut Parser < ' _ > ) {
17
17
assert ! ( p. at( T ![ <] ) ) ;
18
18
let m = p. start ( ) ;
19
19
delimited (
@@ -147,7 +147,15 @@ fn type_bound(p: &mut Parser<'_>) -> bool {
147
147
let has_paren = p. eat ( T ! [ '(' ] ) ;
148
148
match p. current ( ) {
149
149
LIFETIME_IDENT => lifetime ( p) ,
150
- T ! [ for ] => types:: for_type ( p, false ) ,
150
+ // test for_binder_bound
151
+ // fn foo<T: for<'a> [const] async Trait>() {}
152
+ T ! [ for ] => {
153
+ types:: for_binder ( p) ;
154
+ if path_type_bound ( p) . is_err ( ) {
155
+ m. abandon ( p) ;
156
+ return false ;
157
+ }
158
+ }
151
159
// test precise_capturing
152
160
// fn captures<'a: 'a, 'b: 'b, T>() -> impl Sized + use<'b, T, Self> {}
153
161
@@ -180,44 +188,8 @@ fn type_bound(p: &mut Parser<'_>) -> bool {
180
188
p. bump_any ( ) ;
181
189
types:: for_type ( p, false )
182
190
}
183
- current => {
184
- match current {
185
- T ! [ ?] => p. bump_any ( ) ,
186
- T ! [ ~] => {
187
- p. bump_any ( ) ;
188
- p. expect ( T ! [ const ] ) ;
189
- }
190
- T ! [ '[' ] => {
191
- p. bump_any ( ) ;
192
- p. expect ( T ! [ const ] ) ;
193
- p. expect ( T ! [ ']' ] ) ;
194
- }
195
- // test const_trait_bound
196
- // const fn foo(_: impl const Trait) {}
197
- T ! [ const ] => {
198
- p. bump_any ( ) ;
199
- }
200
- // test async_trait_bound
201
- // fn async_foo(_: impl async Fn(&i32)) {}
202
- T ! [ async ] => {
203
- p. bump_any ( ) ;
204
- }
205
- _ => ( ) ,
206
- }
207
- if paths:: is_use_path_start ( p) {
208
- types:: path_type_bounds ( p, false ) ;
209
- // test_err type_bounds_macro_call_recovery
210
- // fn foo<T: T![], T: T!, T: T!{}>() -> Box<T! + T!{}> {}
211
- if p. at ( T ! [ !] ) {
212
- let m = p. start ( ) ;
213
- p. bump ( T ! [ !] ) ;
214
- p. error ( "unexpected `!` in type path, macro calls are not allowed here" ) ;
215
- if p. at_ts ( TokenSet :: new ( & [ T ! [ '{' ] , T ! [ '[' ] , T ! [ '(' ] ] ) ) {
216
- items:: token_tree ( p) ;
217
- }
218
- m. complete ( p, ERROR ) ;
219
- }
220
- } else {
191
+ _ => {
192
+ if path_type_bound ( p) . is_err ( ) {
221
193
m. abandon ( p) ;
222
194
return false ;
223
195
}
@@ -231,6 +203,43 @@ fn type_bound(p: &mut Parser<'_>) -> bool {
231
203
true
232
204
}
233
205
206
+ fn path_type_bound ( p : & mut Parser < ' _ > ) -> Result < ( ) , ( ) > {
207
+ if p. eat ( T ! [ ~] ) {
208
+ p. expect ( T ! [ const ] ) ;
209
+ } else if p. eat ( T ! [ '[' ] ) {
210
+ // test maybe_const_trait_bound
211
+ // const fn foo(_: impl [const] Trait) {}
212
+ p. expect ( T ! [ const ] ) ;
213
+ p. expect ( T ! [ ']' ] ) ;
214
+ } else {
215
+ // test const_trait_bound
216
+ // const fn foo(_: impl const Trait) {}
217
+ p. eat ( T ! [ const ] ) ;
218
+ }
219
+ // test async_trait_bound
220
+ // fn async_foo(_: impl async Fn(&i32)) {}
221
+ p. eat ( T ! [ async ] ) ;
222
+ p. eat ( T ! [ ?] ) ;
223
+
224
+ if paths:: is_use_path_start ( p) {
225
+ types:: path_type_bounds ( p, false ) ;
226
+ // test_err type_bounds_macro_call_recovery
227
+ // fn foo<T: T![], T: T!, T: T!{}>() -> Box<T! + T!{}> {}
228
+ if p. at ( T ! [ !] ) {
229
+ let m = p. start ( ) ;
230
+ p. bump ( T ! [ !] ) ;
231
+ p. error ( "unexpected `!` in type path, macro calls are not allowed here" ) ;
232
+ if p. at_ts ( TokenSet :: new ( & [ T ! [ '{' ] , T ! [ '[' ] , T ! [ '(' ] ] ) ) {
233
+ items:: token_tree ( p) ;
234
+ }
235
+ m. complete ( p, ERROR ) ;
236
+ }
237
+ Ok ( ( ) )
238
+ } else {
239
+ Err ( ( ) )
240
+ }
241
+ }
242
+
234
243
// test where_clause
235
244
// fn foo()
236
245
// where
0 commit comments