aboutsummaryrefslogtreecommitdiff
path: root/src/parser/grammar/types.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser/grammar/types.rs')
-rw-r--r--src/parser/grammar/types.rs131
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 @@
1use super::*; 1use super::*;
2 2
3pub(super) fn ty(p: &mut Parser) { 3pub(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
13fn paren_or_tuple_ty(p: &mut Parser) { 19fn type_no_plus(p: &mut Parser) {
20 type_(p);
21}
22
23fn 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 = !;
58fn 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
65fn 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
89fn 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 ();
125fn 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 = _;
137fn 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();
148fn 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
46fn path_type(p: &mut Parser) { 169fn 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();