aboutsummaryrefslogtreecommitdiff
path: root/crates/parser/src/grammar/type_args.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/parser/src/grammar/type_args.rs')
-rw-r--r--crates/parser/src/grammar/type_args.rs63
1 files changed, 63 insertions, 0 deletions
diff --git a/crates/parser/src/grammar/type_args.rs b/crates/parser/src/grammar/type_args.rs
new file mode 100644
index 000000000..aef7cd6fb
--- /dev/null
+++ b/crates/parser/src/grammar/type_args.rs
@@ -0,0 +1,63 @@
1//! FIXME: write short doc here
2
3use super::*;
4
5pub(super) fn opt_type_arg_list(p: &mut Parser, colon_colon_required: bool) {
6 let m;
7 if p.at(T![::]) && p.nth(2) == T![<] {
8 m = p.start();
9 p.bump(T![::]);
10 p.bump(T![<]);
11 } else if !colon_colon_required && p.at(T![<]) && p.nth(1) != T![=] {
12 m = p.start();
13 p.bump(T![<]);
14 } else {
15 return;
16 }
17
18 while !p.at(EOF) && !p.at(T![>]) {
19 type_arg(p);
20 if !p.at(T![>]) && !p.expect(T![,]) {
21 break;
22 }
23 }
24 p.expect(T![>]);
25 m.complete(p, GENERIC_ARG_LIST);
26}
27
28// test type_arg
29// type A = B<'static, i32, 1, { 2 }, Item=u64>;
30fn type_arg(p: &mut Parser) {
31 let m = p.start();
32 match p.current() {
33 LIFETIME => {
34 p.bump(LIFETIME);
35 m.complete(p, LIFETIME_ARG);
36 }
37 // test associated_type_bounds
38 // fn print_all<T: Iterator<Item: Display>>(printables: T) {}
39 IDENT if p.nth(1) == T![:] && p.nth(2) != T![:] => {
40 name_ref(p);
41 type_params::bounds(p);
42 m.complete(p, ASSOC_TYPE_ARG);
43 }
44 IDENT if p.nth(1) == T![=] => {
45 name_ref(p);
46 p.bump_any();
47 types::type_(p);
48 m.complete(p, ASSOC_TYPE_ARG);
49 }
50 T!['{'] => {
51 expressions::block_expr(p);
52 m.complete(p, CONST_ARG);
53 }
54 k if k.is_literal() => {
55 expressions::literal(p);
56 m.complete(p, CONST_ARG);
57 }
58 _ => {
59 types::type_(p);
60 m.complete(p, TYPE_ARG);
61 }
62 }
63}