blob: 670406071a51a147da5c206bb043d4f6eb3163db (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
use super::*;
pub(super) fn struct_item(p: &mut Parser) {
assert!(p.at(STRUCT_KW));
p.bump();
if !p.expect(IDENT) {
return;
}
type_param_list(p);
match p.current() {
WHERE_KW => {
where_clause(p);
match p.current() {
SEMI => {
p.bump();
return;
}
L_CURLY => named_fields(p),
_ => {
//TODO: special case `(` error message
p.error().message("expected `;` or `{`").emit();
return;
}
}
}
SEMI => {
p.bump();
return;
}
L_CURLY => named_fields(p),
L_PAREN => {
pos_fields(p);
p.expect(SEMI);
}
_ => {
p.error().message("expected `;`, `{`, or `(`").emit();
return;
}
}
}
pub(super) fn enum_item(p: &mut Parser) {
assert!(p.at(ENUM_KW));
p.bump();
p.expect(IDENT);
type_param_list(p);
where_clause(p);
if p.expect(L_CURLY) {
while !p.at(EOF) && !p.at(R_CURLY) {
let var = p.start();
attributes::outer_attributes(p);
if p.at(IDENT) {
p.bump();
match p.current() {
L_CURLY => named_fields(p),
L_PAREN => pos_fields(p),
EQ => {
p.bump();
expressions::expr(p);
}
_ => ()
}
var.complete(p, ENUM_VARIANT);
} else {
var.abandon(p);
p.err_and_bump("expected enum variant");
}
if !p.at(R_CURLY) {
p.expect(COMMA);
}
}
p.expect(R_CURLY);
}
}
fn named_fields(p: &mut Parser) {
assert!(p.at(L_CURLY));
p.bump();
while !p.at(R_CURLY) && !p.at(EOF) {
named_field(p);
if !p.at(R_CURLY) {
p.expect(COMMA);
}
}
p.expect(R_CURLY);
fn named_field(p: &mut Parser) {
let field = p.start();
visibility(p);
if p.expect(IDENT) {
p.expect(COLON);
types::type_ref(p);
field.complete(p, NAMED_FIELD);
} else {
field.abandon(p);
p.err_and_bump("expected field declaration");
}
}
}
fn pos_fields(p: &mut Parser) {
if !p.expect(L_PAREN) {
return;
}
while !p.at(R_PAREN) && !p.at(EOF) {
let pos_field = p.start();
visibility(p);
types::type_ref(p);
pos_field.complete(p, POS_FIELD);
if !p.at(R_PAREN) {
p.expect(COMMA);
}
}
p.expect(R_PAREN);
}
|