1+ use crate :: grammar:: attributes:: ATTRIBUTE_FIRST ;
2+
13use super :: * ;
24
35pub ( super ) fn opt_generic_param_list ( p : & mut Parser < ' _ > ) {
@@ -11,32 +13,31 @@ pub(super) fn opt_generic_param_list(p: &mut Parser<'_>) {
1113fn generic_param_list ( p : & mut Parser < ' _ > ) {
1214 assert ! ( p. at( T ![ <] ) ) ;
1315 let m = p. start ( ) ;
14- p. bump ( T ! [ <] ) ;
16+ delimited ( p, T ! [ <] , T ! [ >] , T ! [ , ] , GENERIC_PARAM_FIRST . union ( ATTRIBUTE_FIRST ) , |p| {
17+ // test generic_param_attribute
18+ // fn foo<#[lt_attr] 'a, #[t_attr] T>() {}
19+ let m = p. start ( ) ;
20+ attributes:: outer_attrs ( p) ;
21+ generic_param ( p, m)
22+ } ) ;
1523
16- while !p. at ( EOF ) && !p. at ( T ! [ >] ) {
17- generic_param ( p) ;
18- if !p. at ( T ! [ >] ) && !p. expect ( T ! [ , ] ) {
19- break ;
20- }
21- }
22- p. expect ( T ! [ >] ) ;
2324 m. complete ( p, GENERIC_PARAM_LIST ) ;
2425}
2526
26- fn generic_param ( p : & mut Parser < ' _ > ) {
27- let m = p. start ( ) ;
28- // test generic_param_attribute
29- // fn foo<#[lt_attr] 'a, #[t_attr] T>() {}
30- attributes:: outer_attrs ( p) ;
27+ const GENERIC_PARAM_FIRST : TokenSet = TokenSet :: new ( & [ IDENT , LIFETIME_IDENT , T ! [ const ] ] ) ;
28+
29+ fn generic_param ( p : & mut Parser < ' _ > , m : Marker ) -> bool {
3130 match p. current ( ) {
3231 LIFETIME_IDENT => lifetime_param ( p, m) ,
3332 IDENT => type_param ( p, m) ,
3433 T ! [ const ] => const_param ( p, m) ,
3534 _ => {
3635 m. abandon ( p) ;
37- p. err_and_bump ( "expected type parameter" ) ;
36+ p. err_and_bump ( "expected generic parameter" ) ;
37+ return false ;
3838 }
3939 }
40+ true
4041}
4142
4243// test lifetime_param
0 commit comments