1 use super::*;
2 
opt_generic_arg_list(p: &mut Parser, colon_colon_required: bool)3 pub(super) fn opt_generic_arg_list(p: &mut Parser, colon_colon_required: bool) {
4     let m;
5     if p.at(T![::]) && p.nth(2) == T![<] {
6         m = p.start();
7         p.bump(T![::]);
8         p.bump(T![<]);
9     } else if !colon_colon_required && p.at(T![<]) && p.nth(1) != T![=] {
10         m = p.start();
11         p.bump(T![<]);
12     } else {
13         return;
14     }
15 
16     while !p.at(EOF) && !p.at(T![>]) {
17         generic_arg(p);
18         if !p.at(T![>]) && !p.expect(T![,]) {
19             break;
20         }
21     }
22     p.expect(T![>]);
23     m.complete(p, GENERIC_ARG_LIST);
24 }
25 
26 // test generic_arg
27 // type T = S<i32>;
generic_arg(p: &mut Parser)28 fn generic_arg(p: &mut Parser) {
29     match p.current() {
30         LIFETIME_IDENT => lifetime_arg(p),
31         T!['{'] | T![true] | T![false] | T![-] => const_arg(p),
32         k if k.is_literal() => const_arg(p),
33         // test associated_type_bounds
34         // fn print_all<T: Iterator<Item, Item::Item, Item::<true>, Item: Display, Item<'a> = Item>>(printables: T) {}
35 
36         // test macro_inside_generic_arg
37         // type A = Foo<syn::Token![_]>;
38         IDENT if [T![<], T![=], T![:]].contains(&p.nth(1)) && !p.nth_at(1, T![::]) => {
39             let m = p.start();
40             name_ref(p);
41             opt_generic_arg_list(p, false);
42             match p.current() {
43                 // test assoc_type_eq
44                 // type T = StreamingIterator<Item<'a> = &'a T>;
45                 T![=] => {
46                     p.bump_any();
47                     types::type_(p);
48                     m.complete(p, ASSOC_TYPE_ARG);
49                 }
50                 // test assoc_type_bound
51                 // type T = StreamingIterator<Item<'a>: Clone>;
52                 T![:] if !p.at(T![::]) => {
53                     generic_params::bounds(p);
54                     m.complete(p, ASSOC_TYPE_ARG);
55                 }
56                 _ => {
57                     let m = m.complete(p, PATH_SEGMENT).precede(p).complete(p, PATH);
58                     let m = paths::type_path_for_qualifier(p, m);
59                     m.precede(p).complete(p, PATH_TYPE).precede(p).complete(p, TYPE_ARG);
60                 }
61             }
62         }
63         _ => type_arg(p),
64     }
65 }
66 
67 // test lifetime_arg
68 // type T = S<'static>;
lifetime_arg(p: &mut Parser)69 fn lifetime_arg(p: &mut Parser) {
70     let m = p.start();
71     lifetime(p);
72     m.complete(p, LIFETIME_ARG);
73 }
74 
75 // test const_arg
76 // type T = S<92>;
const_arg(p: &mut Parser)77 pub(super) fn const_arg(p: &mut Parser) {
78     let m = p.start();
79     match p.current() {
80         // test const_arg_block
81         // type T = S<{90 + 2}>;
82         T!['{'] => {
83             expressions::block_expr(p);
84             m.complete(p, CONST_ARG);
85         }
86         // test const_arg_literal
87         // type T = S<"hello", 0xdeadbeef>;
88         k if k.is_literal() => {
89             expressions::literal(p);
90             m.complete(p, CONST_ARG);
91         }
92         // test const_arg_bool_literal
93         // type T = S<true>;
94         T![true] | T![false] => {
95             expressions::literal(p);
96             m.complete(p, CONST_ARG);
97         }
98         // test const_arg_negative_number
99         // type T = S<-92>;
100         T![-] => {
101             let lm = p.start();
102             p.bump(T![-]);
103             expressions::literal(p);
104             lm.complete(p, PREFIX_EXPR);
105             m.complete(p, CONST_ARG);
106         }
107         // test const_arg_path
108         // struct S<const N: u32 = u32::MAX>;
109         _ => {
110             let lm = p.start();
111             paths::use_path(p);
112             lm.complete(p, PATH_EXPR);
113             m.complete(p, CONST_ARG);
114         }
115     }
116 }
117 
type_arg(p: &mut Parser)118 fn type_arg(p: &mut Parser) {
119     let m = p.start();
120     types::type_(p);
121     m.complete(p, TYPE_ARG);
122 }
123