1
1
use super :: * ;
2
2
3
- // test_err generic_arg_list_recover
4
- // type T = T<0, ,T>;
5
- pub ( super ) fn opt_generic_arg_list ( p : & mut Parser < ' _ > , colon_colon_required : bool ) {
3
+ // test_err generic_arg_list_recover_expr
4
+ // const _: () = T::<0, ,T>;
5
+ // const _: () = T::<0, ,T>();
6
+ pub ( super ) fn opt_generic_arg_list_expr ( p : & mut Parser < ' _ > ) {
6
7
let m;
7
8
if p. at ( T ! [ :: ] ) && p. nth ( 2 ) == T ! [ <] {
8
9
m = p. start ( ) ;
9
10
p. bump ( T ! [ :: ] ) ;
10
- } else if !colon_colon_required && p. at ( T ! [ <] ) && p. nth ( 1 ) != T ! [ =] {
11
- m = p. start ( ) ;
12
11
} else {
13
12
return ;
14
13
}
@@ -25,7 +24,7 @@ pub(super) fn opt_generic_arg_list(p: &mut Parser<'_>, colon_colon_required: boo
25
24
m. complete ( p, GENERIC_ARG_LIST ) ;
26
25
}
27
26
28
- const GENERIC_ARG_FIRST : TokenSet = TokenSet :: new ( & [
27
+ pub ( crate ) const GENERIC_ARG_FIRST : TokenSet = TokenSet :: new ( & [
29
28
LIFETIME_IDENT ,
30
29
IDENT ,
31
30
T ! [ '{' ] ,
@@ -47,20 +46,23 @@ const GENERIC_ARG_RECOVERY_SET: TokenSet = TokenSet::new(&[T![>], T![,]]);
47
46
48
47
// test generic_arg
49
48
// type T = S<i32>;
50
- fn generic_arg ( p : & mut Parser < ' _ > ) -> bool {
49
+ pub ( crate ) fn generic_arg ( p : & mut Parser < ' _ > ) -> bool {
51
50
match p. current ( ) {
52
51
LIFETIME_IDENT if !p. nth_at ( 1 , T ! [ +] ) => lifetime_arg ( p) ,
53
52
T ! [ '{' ] | T ! [ true ] | T ! [ false ] | T ! [ -] => const_arg ( p) ,
54
53
k if k. is_literal ( ) => const_arg ( p) ,
55
- // test associated_type_bounds
56
- // fn print_all<T: Iterator<Item, Item::Item, Item::<true>, Item: Display, Item<'a> = Item>>(printables: T) {}
54
+ // test generic_arg_bounds
55
+ // type Plain = Foo<Item, Item::Item, Item: Bound, Item = Item>;
56
+ // type GenericArgs = Foo<Item<T>, Item::<T>, Item<T>: Bound, Item::<T>: Bound, Item<T> = Item, Item::<T> = Item>;
57
+ // type ParenthesizedArgs = Foo<Item(T), Item::(T), Item(T): Bound, Item::(T): Bound, Item(T) = Item, Item::(T) = Item>;
58
+ // type RTN = Foo<Item(..), Item(..), Item(..): Bound, Item(..): Bound, Item(..) = Item, Item(..) = Item>;
57
59
58
60
// test macro_inside_generic_arg
59
61
// type A = Foo<syn::Token![_]>;
60
- IDENT if [ T ! [ < ] , T ! [ = ] , T ! [ : ] ] . contains ( & p . nth ( 1 ) ) && !p . nth_at ( 1 , T ! [ :: ] ) => {
62
+ IDENT => {
61
63
let m = p. start ( ) ;
62
64
name_ref ( p) ;
63
- opt_generic_arg_list ( p , false ) ;
65
+ paths :: opt_path_type_args ( p ) ;
64
66
match p. current ( ) {
65
67
T ! [ =] => {
66
68
p. bump_any ( ) ;
@@ -88,45 +90,26 @@ fn generic_arg(p: &mut Parser<'_>) -> bool {
88
90
}
89
91
// test assoc_type_bound
90
92
// type T = StreamingIterator<Item<'a>: Clone>;
93
+ // type T = StreamingIterator<Item(T): Clone>;
91
94
T ! [ : ] if !p. at ( T ! [ :: ] ) => {
92
95
generic_params:: bounds ( p) ;
93
96
m. complete ( p, ASSOC_TYPE_ARG ) ;
94
97
}
98
+ // Turned out to be just a normal path type (mirror `path_or_macro_type`)
95
99
_ => {
96
100
let m = m. complete ( p, PATH_SEGMENT ) . precede ( p) . complete ( p, PATH ) ;
97
101
let m = paths:: type_path_for_qualifier ( p, m) ;
98
- m. precede ( p) . complete ( p, PATH_TYPE ) . precede ( p) . complete ( p, TYPE_ARG ) ;
102
+ let m = if p. at ( T ! [ !] ) && !p. at ( T ! [ !=] ) {
103
+ let m = m. precede ( p) ;
104
+ items:: macro_call_after_excl ( p) ;
105
+ m. complete ( p, MACRO_CALL ) . precede ( p) . complete ( p, MACRO_TYPE )
106
+ } else {
107
+ m. precede ( p) . complete ( p, PATH_TYPE )
108
+ } ;
109
+ types:: opt_type_bounds_as_dyn_trait_type ( p, m) . precede ( p) . complete ( p, TYPE_ARG ) ;
99
110
}
100
111
}
101
112
}
102
- IDENT if p. nth_at ( 1 , T ! [ '(' ] ) => {
103
- let m = p. start ( ) ;
104
- name_ref ( p) ;
105
- if p. nth_at ( 1 , T ! [ ..] ) {
106
- let rtn = p. start ( ) ;
107
- p. bump ( T ! [ '(' ] ) ;
108
- p. bump ( T ! [ ..] ) ;
109
- p. expect ( T ! [ ')' ] ) ;
110
- rtn. complete ( p, RETURN_TYPE_SYNTAX ) ;
111
- // test return_type_syntax_assoc_type_bound
112
- // fn foo<T: Trait<method(..): Send>>() {}
113
- generic_params:: bounds ( p) ;
114
- m. complete ( p, ASSOC_TYPE_ARG ) ;
115
- } else {
116
- params:: param_list_fn_trait ( p) ;
117
- // test bare_dyn_types_with_paren_as_generic_args
118
- // type A = S<Fn(i32)>;
119
- // type A = S<Fn(i32) + Send>;
120
- // type B = S<Fn(i32) -> i32>;
121
- // type C = S<Fn(i32) -> i32 + Send>;
122
- opt_ret_type ( p) ;
123
- let m = m. complete ( p, PATH_SEGMENT ) . precede ( p) . complete ( p, PATH ) ;
124
- let m = paths:: type_path_for_qualifier ( p, m) ;
125
- let m = m. precede ( p) . complete ( p, PATH_TYPE ) ;
126
- let m = types:: opt_type_bounds_as_dyn_trait_type ( p, m) ;
127
- m. precede ( p) . complete ( p, TYPE_ARG ) ;
128
- }
129
- }
130
113
_ if p. at_ts ( types:: TYPE_FIRST ) => type_arg ( p) ,
131
114
_ => return false ,
132
115
}
@@ -190,7 +173,7 @@ pub(super) fn const_arg(p: &mut Parser<'_>) {
190
173
m. complete ( p, CONST_ARG ) ;
191
174
}
192
175
193
- fn type_arg ( p : & mut Parser < ' _ > ) {
176
+ pub ( crate ) fn type_arg ( p : & mut Parser < ' _ > ) {
194
177
let m = p. start ( ) ;
195
178
types:: type_ ( p) ;
196
179
m. complete ( p, TYPE_ARG ) ;
0 commit comments