diff options
Diffstat (limited to 'src/parser/grammar/types.rs')
-rw-r--r-- | src/parser/grammar/types.rs | 131 |
1 files changed, 127 insertions, 4 deletions
diff --git a/src/parser/grammar/types.rs b/src/parser/grammar/types.rs index 71801d8ef..a4967a00a 100644 --- a/src/parser/grammar/types.rs +++ b/src/parser/grammar/types.rs | |||
@@ -1,8 +1,14 @@ | |||
1 | use super::*; | 1 | use super::*; |
2 | 2 | ||
3 | pub(super) fn ty(p: &mut Parser) { | 3 | pub(super) fn type_(p: &mut Parser) { |
4 | match p.current() { | 4 | match p.current() { |
5 | L_PAREN => paren_or_tuple_ty(p), | 5 | L_PAREN => paren_or_tuple_type(p), |
6 | EXCL => never_type(p), | ||
7 | STAR => pointer_type(p), | ||
8 | L_BRACK => array_or_slice_type(p), | ||
9 | AMPERSAND => reference_type(p), | ||
10 | UNDERSCORE => placeholder_type(p), | ||
11 | FN_KW | UNSAFE_KW | EXTERN_KW => fn_pointer_type(p), | ||
6 | IDENT => path_type(p), | 12 | IDENT => path_type(p), |
7 | _ => { | 13 | _ => { |
8 | p.error("expected type"); | 14 | p.error("expected type"); |
@@ -10,7 +16,11 @@ pub(super) fn ty(p: &mut Parser) { | |||
10 | } | 16 | } |
11 | } | 17 | } |
12 | 18 | ||
13 | fn paren_or_tuple_ty(p: &mut Parser) { | 19 | fn type_no_plus(p: &mut Parser) { |
20 | type_(p); | ||
21 | } | ||
22 | |||
23 | fn paren_or_tuple_type(p: &mut Parser) { | ||
14 | assert!(p.at(L_PAREN)); | 24 | assert!(p.at(L_PAREN)); |
15 | let m = p.start(); | 25 | let m = p.start(); |
16 | p.bump(); | 26 | p.bump(); |
@@ -18,7 +28,7 @@ fn paren_or_tuple_ty(p: &mut Parser) { | |||
18 | let mut trailing_comma: bool = false; | 28 | let mut trailing_comma: bool = false; |
19 | while !p.at(EOF) && !p.at(R_PAREN) { | 29 | while !p.at(EOF) && !p.at(R_PAREN) { |
20 | n_types += 1; | 30 | n_types += 1; |
21 | ty(p); | 31 | type_(p); |
22 | if p.eat(COMMA) { | 32 | if p.eat(COMMA) { |
23 | trailing_comma = true; | 33 | trailing_comma = true; |
24 | } else { | 34 | } else { |
@@ -43,6 +53,119 @@ fn paren_or_tuple_ty(p: &mut Parser) { | |||
43 | m.complete(p, kind); | 53 | m.complete(p, kind); |
44 | } | 54 | } |
45 | 55 | ||
56 | // test never_type | ||
57 | // type Never = !; | ||
58 | fn never_type(p: &mut Parser) { | ||
59 | assert!(p.at(EXCL)); | ||
60 | let m = p.start(); | ||
61 | p.bump(); | ||
62 | m.complete(p, NEVER_TYPE); | ||
63 | } | ||
64 | |||
65 | fn pointer_type(p: &mut Parser) { | ||
66 | assert!(p.at(STAR)); | ||
67 | let m = p.start(); | ||
68 | p.bump(); | ||
69 | |||
70 | match p.current() { | ||
71 | // test pointer_type_mut | ||
72 | // type M = *mut (); | ||
73 | // type C = *mut (); | ||
74 | MUT_KW | CONST_KW => p.bump(), | ||
75 | _ => { | ||
76 | // test pointer_type_no_mutability | ||
77 | // type T = *(); | ||
78 | p.error( | ||
79 | "expected mut or const in raw pointer type \ | ||
80 | (use `*mut T` or `*const T` as appropriate)", | ||
81 | ); | ||
82 | } | ||
83 | }; | ||
84 | |||
85 | type_no_plus(p); | ||
86 | m.complete(p, POINTER_TYPE); | ||
87 | } | ||
88 | |||
89 | fn array_or_slice_type(p: &mut Parser) { | ||
90 | assert!(p.at(L_BRACK)); | ||
91 | let m = p.start(); | ||
92 | p.bump(); | ||
93 | |||
94 | type_(p); | ||
95 | let kind = match p.current() { | ||
96 | // test slice_type | ||
97 | // type T = [()]; | ||
98 | R_BRACK => { | ||
99 | p.bump(); | ||
100 | SLICE_TYPE | ||
101 | } | ||
102 | |||
103 | // test array_type | ||
104 | // type T = [(); 92]; | ||
105 | SEMI => { | ||
106 | p.bump(); | ||
107 | expressions::expr(p); | ||
108 | p.expect(R_BRACK); | ||
109 | ARRAY_TYPE | ||
110 | } | ||
111 | // test array_type_missing_semi | ||
112 | // type T = [() 92]; | ||
113 | _ => { | ||
114 | p.error("expected `;` or `]`"); | ||
115 | SLICE_TYPE | ||
116 | } | ||
117 | }; | ||
118 | m.complete(p, kind); | ||
119 | } | ||
120 | |||
121 | // test reference_type; | ||
122 | // type A = &(); | ||
123 | // type B = &'static (); | ||
124 | // type C = &mut (); | ||
125 | fn reference_type(p: &mut Parser) { | ||
126 | assert!(p.at(AMPERSAND)); | ||
127 | let m = p.start(); | ||
128 | p.bump(); | ||
129 | p.eat(LIFETIME); | ||
130 | p.eat(MUT_KW); | ||
131 | type_no_plus(p); | ||
132 | m.complete(p, REFERENCE_TYPE); | ||
133 | } | ||
134 | |||
135 | // test placeholder_type | ||
136 | // type Placeholder = _; | ||
137 | fn placeholder_type(p: &mut Parser) { | ||
138 | assert!(p.at(UNDERSCORE)); | ||
139 | let m = p.start(); | ||
140 | p.bump(); | ||
141 | m.complete(p, PLACEHOLDER_TYPE); | ||
142 | } | ||
143 | |||
144 | // test fn_pointer_type | ||
145 | // type A = fn(); | ||
146 | // type B = unsafe fn(); | ||
147 | // type C = unsafe extern "C" fn(); | ||
148 | fn fn_pointer_type(p: &mut Parser) { | ||
149 | let m = p.start(); | ||
150 | p.eat(UNSAFE_KW); | ||
151 | if p.at(EXTERN_KW) { | ||
152 | abi(p); | ||
153 | } | ||
154 | // test fn_pointer_type_missing_fn | ||
155 | // type F = unsafe (); | ||
156 | if !p.eat(FN_KW) { | ||
157 | m.abandon(p); | ||
158 | p.error("expected `fn`"); | ||
159 | return; | ||
160 | } | ||
161 | |||
162 | fn_value_parameters(p); | ||
163 | // test fn_pointer_type_with_ret | ||
164 | // type F = fn() -> (); | ||
165 | fn_ret_type(p); | ||
166 | m.complete(p, FN_POINTER_TYPE); | ||
167 | } | ||
168 | |||
46 | fn path_type(p: &mut Parser) { | 169 | fn path_type(p: &mut Parser) { |
47 | assert!(p.at(IDENT)); | 170 | assert!(p.at(IDENT)); |
48 | let m = p.start(); | 171 | let m = p.start(); |