aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--grammar.ron5
-rw-r--r--src/parser/event_parser/grammar/items/mod.rs (renamed from src/parser/event_parser/grammar/items.rs)108
-rw-r--r--src/parser/event_parser/grammar/items/structs.rs83
-rw-r--r--src/syntax_kinds.rs6
-rw-r--r--tests/data/parser/err/0009_broken_struct_type_parameter.rs5
-rw-r--r--tests/data/parser/err/0009_broken_struct_type_parameter.txt42
-rw-r--r--tests/data/parser/ok/0018_struct_type_params.rs17
-rw-r--r--tests/data/parser/ok/0018_struct_type_params.txt223
8 files changed, 415 insertions, 74 deletions
diff --git a/grammar.ron b/grammar.ron
index 70e269e20..7c76d595d 100644
--- a/grammar.ron
+++ b/grammar.ron
@@ -88,5 +88,8 @@ Grammar(
88 "LITERAL", 88 "LITERAL",
89 "ALIAS", 89 "ALIAS",
90 "VISIBILITY", 90 "VISIBILITY",
91 "TYPE_PARAM_LIST",
92 "LIFETIME_PARAM",
93 "TYPE_PARAM",
91 ] 94 ]
92) \ No newline at end of file 95)
diff --git a/src/parser/event_parser/grammar/items.rs b/src/parser/event_parser/grammar/items/mod.rs
index 56e3208ac..f10fb230b 100644
--- a/src/parser/event_parser/grammar/items.rs
+++ b/src/parser/event_parser/grammar/items/mod.rs
@@ -1,5 +1,7 @@
1use super::*; 1use super::*;
2 2
3mod structs;
4
3pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) { 5pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) {
4 attributes::inner_attributes(p); 6 attributes::inner_attributes(p);
5 while !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) { 7 while !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) {
@@ -29,7 +31,7 @@ fn item(p: &mut Parser) {
29 USE_ITEM 31 USE_ITEM
30 } 32 }
31 STRUCT_KW => { 33 STRUCT_KW => {
32 struct_item(p); 34 structs::struct_item(p);
33 STRUCT_ITEM 35 STRUCT_ITEM
34 } 36 }
35 FN_KW => { 37 FN_KW => {
@@ -57,90 +59,50 @@ fn item(p: &mut Parser) {
57 item.complete(p, item_kind); 59 item.complete(p, item_kind);
58} 60}
59 61
60fn struct_item(p: &mut Parser) { 62fn type_param_list(p: &mut Parser) {
61 assert!(p.at(STRUCT_KW)); 63 if !p.at(L_ANGLE) {
62 p.bump();
63
64 if !p.expect(IDENT) {
65 return; 64 return;
66 } 65 }
67 generic_parameters(p); 66 let m = p.start();
68 match p.current() {
69 WHERE_KW => {
70 where_clause(p);
71 match p.current() {
72 SEMI => {
73 p.bump();
74 return;
75 }
76 L_CURLY => named_fields(p),
77 _ => {
78 //TODO: special case `(` error message
79 p.error().message("expected `;` or `{`").emit();
80 return;
81 }
82 }
83 }
84 SEMI => {
85 p.bump();
86 return;
87 }
88 L_CURLY => named_fields(p),
89 L_PAREN => {
90 pos_fields(p);
91 p.expect(SEMI);
92 }
93 _ => {
94 p.error().message("expected `;`, `{`, or `(`").emit();
95 return;
96 }
97 }
98}
99
100fn named_fields(p: &mut Parser) {
101 assert!(p.at(L_CURLY));
102 p.bump(); 67 p.bump();
103 while !p.at(R_CURLY) && !p.at(EOF) {
104 named_field(p);
105 if !p.at(R_CURLY) {
106 p.expect(COMMA);
107 }
108 }
109 p.expect(R_CURLY);
110 68
111 fn named_field(p: &mut Parser) { 69 while !p.at(EOF) && !p.at(R_ANGLE) {
112 let field = p.start(); 70 match p.current() {
113 visibility(p); 71 LIFETIME => lifetime_param(p),
114 if p.expect(IDENT) { 72 IDENT => type_param(p),
115 p.expect(COLON); 73 _ => p.err_and_bump("expected type parameter"),
116 types::type_ref(p); 74 }
117 field.complete(p, NAMED_FIELD); 75 if !p.at(R_ANGLE) && !p.expect(COMMA) {
118 } else { 76 break;
119 field.abandon(p);
120 p.err_and_bump("expected field declaration");
121 } 77 }
122 } 78 }
123} 79 p.expect(R_ANGLE);
80 m.complete(p, TYPE_PARAM_LIST);
124 81
125fn pos_fields(p: &mut Parser) { 82 fn lifetime_param(p: &mut Parser) {
126 if !p.expect(L_PAREN) { 83 assert!(p.at(LIFETIME));
127 return; 84 let m = p.start();
85 p.bump();
86 if p.eat(COLON) {
87 while p.at(LIFETIME) {
88 p.bump();
89 if !p.eat(PLUS) {
90 break;
91 }
92 }
93 }
94 m.complete(p, LIFETIME_PARAM);
128 } 95 }
129 while !p.at(R_PAREN) && !p.at(EOF) {
130 let pos_field = p.start();
131 visibility(p);
132 types::type_ref(p);
133 pos_field.complete(p, POS_FIELD);
134 96
135 if !p.at(R_PAREN) { 97 fn type_param(p: &mut Parser) {
136 p.expect(COMMA); 98 assert!(p.at(IDENT));
137 } 99 let m = p.start();
100 p.bump();
101 m.complete(p, TYPE_PARAM);
102 //TODO: bounds
138 } 103 }
139 p.expect(R_PAREN);
140} 104}
141 105
142fn generic_parameters(_: &mut Parser) {}
143
144fn where_clause(_: &mut Parser) {} 106fn where_clause(_: &mut Parser) {}
145 107
146fn extern_crate_item(p: &mut Parser) { 108fn extern_crate_item(p: &mut Parser) {
diff --git a/src/parser/event_parser/grammar/items/structs.rs b/src/parser/event_parser/grammar/items/structs.rs
new file mode 100644
index 000000000..0934f3d28
--- /dev/null
+++ b/src/parser/event_parser/grammar/items/structs.rs
@@ -0,0 +1,83 @@
1use super::*;
2
3pub(super) fn struct_item(p: &mut Parser) {
4 assert!(p.at(STRUCT_KW));
5 p.bump();
6
7 if !p.expect(IDENT) {
8 return;
9 }
10 type_param_list(p);
11 match p.current() {
12 WHERE_KW => {
13 where_clause(p);
14 match p.current() {
15 SEMI => {
16 p.bump();
17 return;
18 }
19 L_CURLY => named_fields(p),
20 _ => {
21 //TODO: special case `(` error message
22 p.error().message("expected `;` or `{`").emit();
23 return;
24 }
25 }
26 }
27 SEMI => {
28 p.bump();
29 return;
30 }
31 L_CURLY => named_fields(p),
32 L_PAREN => {
33 pos_fields(p);
34 p.expect(SEMI);
35 }
36 _ => {
37 p.error().message("expected `;`, `{`, or `(`").emit();
38 return;
39 }
40 }
41}
42
43fn named_fields(p: &mut Parser) {
44 assert!(p.at(L_CURLY));
45 p.bump();
46 while !p.at(R_CURLY) && !p.at(EOF) {
47 named_field(p);
48 if !p.at(R_CURLY) {
49 p.expect(COMMA);
50 }
51 }
52 p.expect(R_CURLY);
53
54 fn named_field(p: &mut Parser) {
55 let field = p.start();
56 visibility(p);
57 if p.expect(IDENT) {
58 p.expect(COLON);
59 types::type_ref(p);
60 field.complete(p, NAMED_FIELD);
61 } else {
62 field.abandon(p);
63 p.err_and_bump("expected field declaration");
64 }
65 }
66}
67
68fn pos_fields(p: &mut Parser) {
69 if !p.expect(L_PAREN) {
70 return;
71 }
72 while !p.at(R_PAREN) && !p.at(EOF) {
73 let pos_field = p.start();
74 visibility(p);
75 types::type_ref(p);
76 pos_field.complete(p, POS_FIELD);
77
78 if !p.at(R_PAREN) {
79 p.expect(COMMA);
80 }
81 }
82 p.expect(R_PAREN);
83}
diff --git a/src/syntax_kinds.rs b/src/syntax_kinds.rs
index 23a0881b7..b6c281cd5 100644
--- a/src/syntax_kinds.rs
+++ b/src/syntax_kinds.rs
@@ -90,6 +90,9 @@ pub enum SyntaxKind {
90 LITERAL, 90 LITERAL,
91 ALIAS, 91 ALIAS,
92 VISIBILITY, 92 VISIBILITY,
93 TYPE_PARAM_LIST,
94 LIFETIME_PARAM,
95 TYPE_PARAM,
93 96
94 // Technical SyntaxKinds: they appear temporally during parsing, 97 // Technical SyntaxKinds: they appear temporally during parsing,
95 // but never end up in the final tree 98 // but never end up in the final tree
@@ -187,6 +190,9 @@ impl SyntaxKind {
187 LITERAL => &SyntaxInfo { name: "LITERAL" }, 190 LITERAL => &SyntaxInfo { name: "LITERAL" },
188 ALIAS => &SyntaxInfo { name: "ALIAS" }, 191 ALIAS => &SyntaxInfo { name: "ALIAS" },
189 VISIBILITY => &SyntaxInfo { name: "VISIBILITY" }, 192 VISIBILITY => &SyntaxInfo { name: "VISIBILITY" },
193 TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" },
194 LIFETIME_PARAM => &SyntaxInfo { name: "LIFETIME_PARAM" },
195 TYPE_PARAM => &SyntaxInfo { name: "TYPE_PARAM" },
190 196
191 TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" }, 197 TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" },
192 EOF => &SyntaxInfo { name: "EOF" }, 198 EOF => &SyntaxInfo { name: "EOF" },
diff --git a/tests/data/parser/err/0009_broken_struct_type_parameter.rs b/tests/data/parser/err/0009_broken_struct_type_parameter.rs
new file mode 100644
index 000000000..0dd30d0bd
--- /dev/null
+++ b/tests/data/parser/err/0009_broken_struct_type_parameter.rs
@@ -0,0 +1,5 @@
1struct S<90 + 2> {
2 f: u32
3}
4
5struct T;
diff --git a/tests/data/parser/err/0009_broken_struct_type_parameter.txt b/tests/data/parser/err/0009_broken_struct_type_parameter.txt
new file mode 100644
index 000000000..c6b1adb0c
--- /dev/null
+++ b/tests/data/parser/err/0009_broken_struct_type_parameter.txt
@@ -0,0 +1,42 @@
1FILE@[0; 43)
2 STRUCT_ITEM@[0; 12)
3 STRUCT_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 IDENT@[7; 8)
6 TYPE_PARAM_LIST@[8; 12)
7 L_ANGLE@[8; 9)
8 ERROR@[9; 12)
9 err: `expected type parameter`
10 INT_NUMBER@[9; 11)
11 WHITESPACE@[11; 12)
12 err: `expected COMMA`
13 err: `expected R_ANGLE`
14 err: `expected `;`, `{`, or `(``
15 ERROR@[12; 14)
16 err: `expected item`
17 PLUS@[12; 13)
18 WHITESPACE@[13; 14)
19 ERROR@[14; 15)
20 err: `expected item`
21 INT_NUMBER@[14; 15)
22 ERROR@[15; 17)
23 err: `expected item`
24 R_ANGLE@[15; 16)
25 WHITESPACE@[16; 17)
26 ERROR@[17; 33)
27 err: `expected item`
28 L_CURLY@[17; 18)
29 WHITESPACE@[18; 23)
30 IDENT@[23; 24)
31 COLON@[24; 25)
32 WHITESPACE@[25; 26)
33 IDENT@[26; 29)
34 WHITESPACE@[29; 30)
35 R_CURLY@[30; 31)
36 WHITESPACE@[31; 33)
37 STRUCT_ITEM@[33; 43)
38 STRUCT_KW@[33; 39)
39 WHITESPACE@[39; 40)
40 IDENT@[40; 41)
41 SEMI@[41; 42)
42 WHITESPACE@[42; 43)
diff --git a/tests/data/parser/ok/0018_struct_type_params.rs b/tests/data/parser/ok/0018_struct_type_params.rs
new file mode 100644
index 000000000..88c544923
--- /dev/null
+++ b/tests/data/parser/ok/0018_struct_type_params.rs
@@ -0,0 +1,17 @@
1struct S1<T>;
2struct S2<T>(u32);
3struct S3<T> { u: u32 }
4
5struct S4<>;
6struct S5<'a>;
7struct S6<'a:>;
8struct S7<'a: 'b>;
9struct S8<'a: 'b + >;
10struct S9<'a: 'b + 'c>;
11struct S10<'a,>;
12struct S11<'a, 'b>;
13struct S12<'a: 'b+, 'b: 'c,>;
14
15struct S13<T>;
16struct S14<T, U>;
17struct S15<'a, T, U>;
diff --git a/tests/data/parser/ok/0018_struct_type_params.txt b/tests/data/parser/ok/0018_struct_type_params.txt
new file mode 100644
index 000000000..b2e7ef9d7
--- /dev/null
+++ b/tests/data/parser/ok/0018_struct_type_params.txt
@@ -0,0 +1,223 @@
1FILE@[0; 290)
2 STRUCT_ITEM@[0; 14)
3 STRUCT_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 IDENT@[7; 9)
6 TYPE_PARAM_LIST@[9; 12)
7 L_ANGLE@[9; 10)
8 TYPE_PARAM@[10; 11)
9 IDENT@[10; 11)
10 R_ANGLE@[11; 12)
11 SEMI@[12; 13)
12 WHITESPACE@[13; 14)
13 STRUCT_ITEM@[14; 33)
14 STRUCT_KW@[14; 20)
15 WHITESPACE@[20; 21)
16 IDENT@[21; 23)
17 TYPE_PARAM_LIST@[23; 26)
18 L_ANGLE@[23; 24)
19 TYPE_PARAM@[24; 25)
20 IDENT@[24; 25)
21 R_ANGLE@[25; 26)
22 L_PAREN@[26; 27)
23 POS_FIELD@[27; 30)
24 IDENT@[27; 30)
25 R_PAREN@[30; 31)
26 SEMI@[31; 32)
27 WHITESPACE@[32; 33)
28 STRUCT_ITEM@[33; 58)
29 STRUCT_KW@[33; 39)
30 WHITESPACE@[39; 40)
31 IDENT@[40; 42)
32 TYPE_PARAM_LIST@[42; 46)
33 L_ANGLE@[42; 43)
34 TYPE_PARAM@[43; 44)
35 IDENT@[43; 44)
36 R_ANGLE@[44; 45)
37 WHITESPACE@[45; 46)
38 L_CURLY@[46; 47)
39 NAMED_FIELD@[47; 55)
40 WHITESPACE@[47; 48)
41 IDENT@[48; 49)
42 COLON@[49; 50)
43 WHITESPACE@[50; 51)
44 IDENT@[51; 54)
45 WHITESPACE@[54; 55)
46 R_CURLY@[55; 56)
47 WHITESPACE@[56; 58)
48 STRUCT_ITEM@[58; 71)
49 STRUCT_KW@[58; 64)
50 WHITESPACE@[64; 65)
51 IDENT@[65; 67)
52 TYPE_PARAM_LIST@[67; 69)
53 L_ANGLE@[67; 68)
54 R_ANGLE@[68; 69)
55 SEMI@[69; 70)
56 WHITESPACE@[70; 71)
57 STRUCT_ITEM@[71; 86)
58 STRUCT_KW@[71; 77)
59 WHITESPACE@[77; 78)
60 IDENT@[78; 80)
61 TYPE_PARAM_LIST@[80; 84)
62 L_ANGLE@[80; 81)
63 LIFETIME_PARAM@[81; 83)
64 LIFETIME@[81; 83)
65 R_ANGLE@[83; 84)
66 SEMI@[84; 85)
67 WHITESPACE@[85; 86)
68 STRUCT_ITEM@[86; 102)
69 STRUCT_KW@[86; 92)
70 WHITESPACE@[92; 93)
71 IDENT@[93; 95)
72 TYPE_PARAM_LIST@[95; 100)
73 L_ANGLE@[95; 96)
74 LIFETIME_PARAM@[96; 99)
75 LIFETIME@[96; 98)
76 COLON@[98; 99)
77 R_ANGLE@[99; 100)
78 SEMI@[100; 101)
79 WHITESPACE@[101; 102)
80 STRUCT_ITEM@[102; 121)
81 STRUCT_KW@[102; 108)
82 WHITESPACE@[108; 109)
83 IDENT@[109; 111)
84 TYPE_PARAM_LIST@[111; 119)
85 L_ANGLE@[111; 112)
86 LIFETIME_PARAM@[112; 118)
87 LIFETIME@[112; 114)
88 COLON@[114; 115)
89 WHITESPACE@[115; 116)
90 LIFETIME@[116; 118)
91 R_ANGLE@[118; 119)
92 SEMI@[119; 120)
93 WHITESPACE@[120; 121)
94 STRUCT_ITEM@[121; 143)
95 STRUCT_KW@[121; 127)
96 WHITESPACE@[127; 128)
97 IDENT@[128; 130)
98 TYPE_PARAM_LIST@[130; 141)
99 L_ANGLE@[130; 131)
100 LIFETIME_PARAM@[131; 140)
101 LIFETIME@[131; 133)
102 COLON@[133; 134)
103 WHITESPACE@[134; 135)
104 LIFETIME@[135; 137)
105 WHITESPACE@[137; 138)
106 PLUS@[138; 139)
107 WHITESPACE@[139; 140)
108 R_ANGLE@[140; 141)
109 SEMI@[141; 142)
110 WHITESPACE@[142; 143)
111 STRUCT_ITEM@[143; 167)
112 STRUCT_KW@[143; 149)
113 WHITESPACE@[149; 150)
114 IDENT@[150; 152)
115 TYPE_PARAM_LIST@[152; 165)
116 L_ANGLE@[152; 153)
117 LIFETIME_PARAM@[153; 164)
118 LIFETIME@[153; 155)
119 COLON@[155; 156)
120 WHITESPACE@[156; 157)
121 LIFETIME@[157; 159)
122 WHITESPACE@[159; 160)
123 PLUS@[160; 161)
124 WHITESPACE@[161; 162)
125 LIFETIME@[162; 164)
126 R_ANGLE@[164; 165)
127 SEMI@[165; 166)
128 WHITESPACE@[166; 167)
129 STRUCT_ITEM@[167; 184)
130 STRUCT_KW@[167; 173)
131 WHITESPACE@[173; 174)
132 IDENT@[174; 177)
133 TYPE_PARAM_LIST@[177; 182)
134 L_ANGLE@[177; 178)
135 LIFETIME_PARAM@[178; 180)
136 LIFETIME@[178; 180)
137 COMMA@[180; 181)
138 R_ANGLE@[181; 182)
139 SEMI@[182; 183)
140 WHITESPACE@[183; 184)
141 STRUCT_ITEM@[184; 204)
142 STRUCT_KW@[184; 190)
143 WHITESPACE@[190; 191)
144 IDENT@[191; 194)
145 TYPE_PARAM_LIST@[194; 202)
146 L_ANGLE@[194; 195)
147 LIFETIME_PARAM@[195; 197)
148 LIFETIME@[195; 197)
149 COMMA@[197; 198)
150 LIFETIME_PARAM@[198; 201)
151 WHITESPACE@[198; 199)
152 LIFETIME@[199; 201)
153 R_ANGLE@[201; 202)
154 SEMI@[202; 203)
155 WHITESPACE@[203; 204)
156 STRUCT_ITEM@[204; 235)
157 STRUCT_KW@[204; 210)
158 WHITESPACE@[210; 211)
159 IDENT@[211; 214)
160 TYPE_PARAM_LIST@[214; 232)
161 L_ANGLE@[214; 215)
162 LIFETIME_PARAM@[215; 222)
163 LIFETIME@[215; 217)
164 COLON@[217; 218)
165 WHITESPACE@[218; 219)
166 LIFETIME@[219; 221)
167 PLUS@[221; 222)
168 COMMA@[222; 223)
169 LIFETIME_PARAM@[223; 230)
170 WHITESPACE@[223; 224)
171 LIFETIME@[224; 226)
172 COLON@[226; 227)
173 WHITESPACE@[227; 228)
174 LIFETIME@[228; 230)
175 COMMA@[230; 231)
176 R_ANGLE@[231; 232)
177 SEMI@[232; 233)
178 WHITESPACE@[233; 235)
179 STRUCT_ITEM@[235; 250)
180 STRUCT_KW@[235; 241)
181 WHITESPACE@[241; 242)
182 IDENT@[242; 245)
183 TYPE_PARAM_LIST@[245; 248)
184 L_ANGLE@[245; 246)
185 TYPE_PARAM@[246; 247)
186 IDENT@[246; 247)
187 R_ANGLE@[247; 248)
188 SEMI@[248; 249)
189 WHITESPACE@[249; 250)
190 STRUCT_ITEM@[250; 268)
191 STRUCT_KW@[250; 256)
192 WHITESPACE@[256; 257)
193 IDENT@[257; 260)
194 TYPE_PARAM_LIST@[260; 266)
195 L_ANGLE@[260; 261)
196 TYPE_PARAM@[261; 262)
197 IDENT@[261; 262)
198 COMMA@[262; 263)
199 TYPE_PARAM@[263; 265)
200 WHITESPACE@[263; 264)
201 IDENT@[264; 265)
202 R_ANGLE@[265; 266)
203 SEMI@[266; 267)
204 WHITESPACE@[267; 268)
205 STRUCT_ITEM@[268; 290)
206 STRUCT_KW@[268; 274)
207 WHITESPACE@[274; 275)
208 IDENT@[275; 278)
209 TYPE_PARAM_LIST@[278; 288)
210 L_ANGLE@[278; 279)
211 LIFETIME_PARAM@[279; 281)
212 LIFETIME@[279; 281)
213 COMMA@[281; 282)
214 TYPE_PARAM@[282; 284)
215 WHITESPACE@[282; 283)
216 IDENT@[283; 284)
217 COMMA@[284; 285)
218 TYPE_PARAM@[285; 287)
219 WHITESPACE@[285; 286)
220 IDENT@[286; 287)
221 R_ANGLE@[287; 288)
222 SEMI@[288; 289)
223 WHITESPACE@[289; 290)