Skip to content

Commit b014965

Browse files
committed
Support attributes on array members
Array members are allow to have attributes such as `#[cfg]`. This is a bit tricky as we don't know if the first expression is an initializer or a member until we encounter a `;`. This reuses a trick from `stmt` where we remember if we saw an attribute and then raise an error if the first expression ends up being an initializer. This isn't perfect as the error isn't correctly located on the attribute or initializer; it ends up immediately after the `;`.
1 parent 27df89f commit b014965

File tree

7 files changed

+205
-0
lines changed

7 files changed

+205
-0
lines changed

crates/ra_parser/src/grammar/expressions/atom.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,28 @@ fn array_expr(p: &mut Parser) -> CompletedMarker {
170170
if p.eat(T![']']) {
171171
return m.complete(p, ARRAY_EXPR);
172172
}
173+
174+
// test first_array_member_attributes
175+
// pub const A: &[i64] = &[
176+
// #[cfg(test)]
177+
// 1,
178+
// 2,
179+
// ];
180+
let first_member_has_attrs = p.at(T![#]);
181+
attributes::outer_attributes(p);
182+
173183
expr(p);
174184
if p.eat(T![;]) {
185+
if first_member_has_attrs {
186+
// test_err array_length_attributes
187+
// pub const A: &[i64] = &[
188+
// #[cfg(test)]
189+
// 1;
190+
// 2,
191+
// ];
192+
p.error("removing an expression is not supported in this position");
193+
}
194+
175195
expr(p);
176196
p.expect(T![']']);
177197
return m.complete(p, ARRAY_EXPR);
@@ -181,6 +201,14 @@ fn array_expr(p: &mut Parser) -> CompletedMarker {
181201
if p.at(T![']']) {
182202
break;
183203
}
204+
205+
// test subsequent_array_member_attributes
206+
// pub const A: &[i64] = &[
207+
// 1,
208+
// #[cfg(test)]
209+
// 2,
210+
// ];
211+
attributes::outer_attributes(p);
184212
if !p.at_ts(EXPR_FIRST) {
185213
p.error("expected expression");
186214
break;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pub const A: &[i64] = &[
2+
#[cfg(test)]
3+
1;
4+
2,
5+
];
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
SOURCE_FILE@[0; 53)
2+
CONST_DEF@[0; 48)
3+
VISIBILITY@[0; 3)
4+
PUB_KW@[0; 3) "pub"
5+
WHITESPACE@[3; 4) " "
6+
CONST_KW@[4; 9) "const"
7+
WHITESPACE@[9; 10) " "
8+
NAME@[10; 11)
9+
IDENT@[10; 11) "A"
10+
COLON@[11; 12) ":"
11+
WHITESPACE@[12; 13) " "
12+
REFERENCE_TYPE@[13; 19)
13+
AMP@[13; 14) "&"
14+
SLICE_TYPE@[14; 19)
15+
L_BRACK@[14; 15) "["
16+
PATH_TYPE@[15; 18)
17+
PATH@[15; 18)
18+
PATH_SEGMENT@[15; 18)
19+
NAME_REF@[15; 18)
20+
IDENT@[15; 18) "i64"
21+
R_BRACK@[18; 19) "]"
22+
WHITESPACE@[19; 20) " "
23+
EQ@[20; 21) "="
24+
WHITESPACE@[21; 22) " "
25+
REF_EXPR@[22; 48)
26+
AMP@[22; 23) "&"
27+
ARRAY_EXPR@[23; 48)
28+
L_BRACK@[23; 24) "["
29+
WHITESPACE@[24; 27) "\n "
30+
ATTR@[27; 39)
31+
POUND@[27; 28) "#"
32+
TOKEN_TREE@[28; 39)
33+
L_BRACK@[28; 29) "["
34+
IDENT@[29; 32) "cfg"
35+
TOKEN_TREE@[32; 38)
36+
L_PAREN@[32; 33) "("
37+
IDENT@[33; 37) "test"
38+
R_PAREN@[37; 38) ")"
39+
R_BRACK@[38; 39) "]"
40+
WHITESPACE@[39; 42) "\n "
41+
LITERAL@[42; 43)
42+
INT_NUMBER@[42; 43) "1"
43+
SEMI@[43; 44) ";"
44+
WHITESPACE@[44; 47) "\n "
45+
LITERAL@[47; 48)
46+
INT_NUMBER@[47; 48) "2"
47+
ERROR@[48; 49)
48+
COMMA@[48; 49) ","
49+
WHITESPACE@[49; 50) "\n"
50+
ERROR@[50; 51)
51+
R_BRACK@[50; 51) "]"
52+
ERROR@[51; 52)
53+
SEMI@[51; 52) ";"
54+
WHITESPACE@[52; 53) "\n"
55+
error 44: removing an expression is not supported in this position
56+
error 48: expected R_BRACK
57+
error 48: expected SEMI
58+
error 48: expected an item
59+
error 50: expected an item
60+
error 51: expected an item
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pub const A: &[i64] = &[
2+
#[cfg(test)]
3+
1,
4+
2,
5+
];
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
SOURCE_FILE@[0; 56)
2+
CONST_DEF@[0; 55)
3+
VISIBILITY@[0; 3)
4+
PUB_KW@[0; 3) "pub"
5+
WHITESPACE@[3; 4) " "
6+
CONST_KW@[4; 9) "const"
7+
WHITESPACE@[9; 10) " "
8+
NAME@[10; 11)
9+
IDENT@[10; 11) "A"
10+
COLON@[11; 12) ":"
11+
WHITESPACE@[12; 13) " "
12+
REFERENCE_TYPE@[13; 19)
13+
AMP@[13; 14) "&"
14+
SLICE_TYPE@[14; 19)
15+
L_BRACK@[14; 15) "["
16+
PATH_TYPE@[15; 18)
17+
PATH@[15; 18)
18+
PATH_SEGMENT@[15; 18)
19+
NAME_REF@[15; 18)
20+
IDENT@[15; 18) "i64"
21+
R_BRACK@[18; 19) "]"
22+
WHITESPACE@[19; 20) " "
23+
EQ@[20; 21) "="
24+
WHITESPACE@[21; 22) " "
25+
REF_EXPR@[22; 54)
26+
AMP@[22; 23) "&"
27+
ARRAY_EXPR@[23; 54)
28+
L_BRACK@[23; 24) "["
29+
WHITESPACE@[24; 28) "\n "
30+
ATTR@[28; 40)
31+
POUND@[28; 29) "#"
32+
TOKEN_TREE@[29; 40)
33+
L_BRACK@[29; 30) "["
34+
IDENT@[30; 33) "cfg"
35+
TOKEN_TREE@[33; 39)
36+
L_PAREN@[33; 34) "("
37+
IDENT@[34; 38) "test"
38+
R_PAREN@[38; 39) ")"
39+
R_BRACK@[39; 40) "]"
40+
WHITESPACE@[40; 44) "\n "
41+
LITERAL@[44; 45)
42+
INT_NUMBER@[44; 45) "1"
43+
COMMA@[45; 46) ","
44+
WHITESPACE@[46; 50) "\n "
45+
LITERAL@[50; 51)
46+
INT_NUMBER@[50; 51) "2"
47+
COMMA@[51; 52) ","
48+
WHITESPACE@[52; 53) "\n"
49+
R_BRACK@[53; 54) "]"
50+
SEMI@[54; 55) ";"
51+
WHITESPACE@[55; 56) "\n"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pub const A: &[i64] = &[
2+
1,
3+
#[cfg(test)]
4+
2,
5+
];
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
SOURCE_FILE@[0; 56)
2+
CONST_DEF@[0; 55)
3+
VISIBILITY@[0; 3)
4+
PUB_KW@[0; 3) "pub"
5+
WHITESPACE@[3; 4) " "
6+
CONST_KW@[4; 9) "const"
7+
WHITESPACE@[9; 10) " "
8+
NAME@[10; 11)
9+
IDENT@[10; 11) "A"
10+
COLON@[11; 12) ":"
11+
WHITESPACE@[12; 13) " "
12+
REFERENCE_TYPE@[13; 19)
13+
AMP@[13; 14) "&"
14+
SLICE_TYPE@[14; 19)
15+
L_BRACK@[14; 15) "["
16+
PATH_TYPE@[15; 18)
17+
PATH@[15; 18)
18+
PATH_SEGMENT@[15; 18)
19+
NAME_REF@[15; 18)
20+
IDENT@[15; 18) "i64"
21+
R_BRACK@[18; 19) "]"
22+
WHITESPACE@[19; 20) " "
23+
EQ@[20; 21) "="
24+
WHITESPACE@[21; 22) " "
25+
REF_EXPR@[22; 54)
26+
AMP@[22; 23) "&"
27+
ARRAY_EXPR@[23; 54)
28+
L_BRACK@[23; 24) "["
29+
WHITESPACE@[24; 28) "\n "
30+
LITERAL@[28; 29)
31+
INT_NUMBER@[28; 29) "1"
32+
COMMA@[29; 30) ","
33+
WHITESPACE@[30; 34) "\n "
34+
ATTR@[34; 46)
35+
POUND@[34; 35) "#"
36+
TOKEN_TREE@[35; 46)
37+
L_BRACK@[35; 36) "["
38+
IDENT@[36; 39) "cfg"
39+
TOKEN_TREE@[39; 45)
40+
L_PAREN@[39; 40) "("
41+
IDENT@[40; 44) "test"
42+
R_PAREN@[44; 45) ")"
43+
R_BRACK@[45; 46) "]"
44+
WHITESPACE@[46; 50) "\n "
45+
LITERAL@[50; 51)
46+
INT_NUMBER@[50; 51) "2"
47+
COMMA@[51; 52) ","
48+
WHITESPACE@[52; 53) "\n"
49+
R_BRACK@[53; 54) "]"
50+
SEMI@[54; 55) ";"
51+
WHITESPACE@[55; 56) "\n"

0 commit comments

Comments
 (0)