diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-08-09 10:21:50 +0100 |
---|---|---|
committer | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-08-09 10:21:50 +0100 |
commit | 5f82012779c374d9f6b518634aefb14ce28e17e6 (patch) | |
tree | 40db0d5e514bf1d260aa21a3a305b37986136481 | |
parent | 2fbec23d9990147e09a3b819c37dc1467a5e95d4 (diff) | |
parent | fa24e20867893178ed7265ecadb2bcb09cf76dac (diff) |
Merge #1669
1669: Parse tuple struct field initialization r=matklad a=eupn
Closes #1218.
This PR modifies the parser to accept the following code:
```rust
fn main() {
struct TupleStruct(usize);
let s = TupleStruct {
0: 1usize,
};
dbg!(s.0);
}
```
<details><summary>with following AST:</summary>
```
SOURCE_FILE@[0; 118)
FN_DEF@[0; 116)
FN_KW@[0; 2) "fn"
WHITESPACE@[2; 3) " "
NAME@[3; 7)
IDENT@[3; 7) "main"
PARAM_LIST@[7; 9)
L_PAREN@[7; 8) "("
R_PAREN@[8; 9) ")"
WHITESPACE@[9; 10) " "
BLOCK@[10; 116)
L_CURLY@[10; 11) "{"
WHITESPACE@[11; 16) "\n "
STRUCT_DEF@[16; 42)
STRUCT_KW@[16; 22) "struct"
WHITESPACE@[22; 23) " "
NAME@[23; 34)
IDENT@[23; 34) "TupleStruct"
POS_FIELD_DEF_LIST@[34; 41)
L_PAREN@[34; 35) "("
POS_FIELD_DEF@[35; 40)
PATH_TYPE@[35; 40)
PATH@[35; 40)
PATH_SEGMENT@[35; 40)
NAME_REF@[35; 40)
IDENT@[35; 40) "usize"
R_PAREN@[40; 41) ")"
SEMI@[41; 42) ";"
WHITESPACE@[42; 47) "\n "
LET_STMT@[47; 94)
LET_KW@[47; 50) "let"
WHITESPACE@[50; 51) " "
BIND_PAT@[51; 52)
NAME@[51; 52)
IDENT@[51; 52) "s"
WHITESPACE@[52; 53) " "
EQ@[53; 54) "="
WHITESPACE@[54; 55) " "
STRUCT_LIT@[55; 93)
PATH@[55; 66)
PATH_SEGMENT@[55; 66)
NAME_REF@[55; 66)
IDENT@[55; 66) "TupleStruct"
WHITESPACE@[66; 67) " "
NAMED_FIELD_LIST@[67; 93)
L_CURLY@[67; 68) "{"
WHITESPACE@[68; 77) "\n "
NAMED_FIELD@[77; 86)
NAME_REF@[77; 78)
INT_NUMBER@[77; 78) "0"
COLON@[78; 79) ":"
WHITESPACE@[79; 80) " "
LITERAL@[80; 86)
INT_NUMBER@[80; 86) "1usize"
COMMA@[86; 87) ","
WHITESPACE@[87; 92) "\n "
R_CURLY@[92; 93) "}"
SEMI@[93; 94) ";"
WHITESPACE@[94; 104) "\n \n "
EXPR_STMT@[104; 114)
MACRO_CALL@[104; 113)
PATH@[104; 107)
PATH_SEGMENT@[104; 107)
NAME_REF@[104; 107)
IDENT@[104; 107) "dbg"
EXCL@[107; 108) "!"
TOKEN_TREE@[108; 113)
L_PAREN@[108; 109) "("
IDENT@[109; 110) "s"
DOT@[110; 111) "."
INT_NUMBER@[111; 112) "0"
R_PAREN@[112; 113) ")"
SEMI@[113; 114) ";"
WHITESPACE@[114; 115) "\n"
R_CURLY@[115; 116) "}"
WHITESPACE@[116; 118) "\n\n"
```
</summary>
Co-authored-by: Evgenii P <[email protected]>
-rw-r--r-- | crates/ra_parser/src/grammar.rs | 4 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/expressions.rs | 9 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/items.rs | 2 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/paths.rs | 2 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/type_args.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/inline/ok/0061_struct_lit.rs | 1 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/inline/ok/0061_struct_lit.txt | 33 |
7 files changed, 39 insertions, 16 deletions
diff --git a/crates/ra_parser/src/grammar.rs b/crates/ra_parser/src/grammar.rs index 658034097..2ee121ccd 100644 --- a/crates/ra_parser/src/grammar.rs +++ b/crates/ra_parser/src/grammar.rs | |||
@@ -273,8 +273,8 @@ fn name(p: &mut Parser) { | |||
273 | name_r(p, TokenSet::empty()) | 273 | name_r(p, TokenSet::empty()) |
274 | } | 274 | } |
275 | 275 | ||
276 | fn name_ref(p: &mut Parser) { | 276 | fn name_ref(p: &mut Parser, allow_numeric_names: bool) { |
277 | if p.at(IDENT) { | 277 | if p.at(IDENT) || (allow_numeric_names && p.at(INT_NUMBER)) { |
278 | let m = p.start(); | 278 | let m = p.start(); |
279 | p.bump(); | 279 | p.bump(); |
280 | m.complete(p, NAME_REF); | 280 | m.complete(p, NAME_REF); |
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index 3e49e70c7..9f9e9cb0e 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs | |||
@@ -458,7 +458,7 @@ fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | |||
458 | assert!(p.at(T![.]) && p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth(2) == T![::])); | 458 | assert!(p.at(T![.]) && p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth(2) == T![::])); |
459 | let m = lhs.precede(p); | 459 | let m = lhs.precede(p); |
460 | p.bump(); | 460 | p.bump(); |
461 | name_ref(p); | 461 | name_ref(p, false); |
462 | type_args::opt_type_arg_list(p, true); | 462 | type_args::opt_type_arg_list(p, true); |
463 | if p.at(T!['(']) { | 463 | if p.at(T!['(']) { |
464 | arg_list(p); | 464 | arg_list(p); |
@@ -485,7 +485,7 @@ fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | |||
485 | let m = lhs.precede(p); | 485 | let m = lhs.precede(p); |
486 | p.bump(); | 486 | p.bump(); |
487 | if p.at(IDENT) { | 487 | if p.at(IDENT) { |
488 | name_ref(p) | 488 | name_ref(p, false) |
489 | } else if p.at(INT_NUMBER) { | 489 | } else if p.at(INT_NUMBER) { |
490 | p.bump(); | 490 | p.bump(); |
491 | } else if p.at(FLOAT_NUMBER) { | 491 | } else if p.at(FLOAT_NUMBER) { |
@@ -572,6 +572,7 @@ fn path_expr(p: &mut Parser, r: Restrictions) -> (CompletedMarker, BlockLike) { | |||
572 | // S {}; | 572 | // S {}; |
573 | // S { x, y: 32, }; | 573 | // S { x, y: 32, }; |
574 | // S { x, y: 32, ..Default::default() }; | 574 | // S { x, y: 32, ..Default::default() }; |
575 | // TupleStruct { 0: 1 }; | ||
575 | // } | 576 | // } |
576 | pub(crate) fn named_field_list(p: &mut Parser) { | 577 | pub(crate) fn named_field_list(p: &mut Parser) { |
577 | assert!(p.at(T!['{'])); | 578 | assert!(p.at(T!['{'])); |
@@ -583,10 +584,10 @@ pub(crate) fn named_field_list(p: &mut Parser) { | |||
583 | // fn main() { | 584 | // fn main() { |
584 | // S { #[cfg(test)] field: 1 } | 585 | // S { #[cfg(test)] field: 1 } |
585 | // } | 586 | // } |
586 | IDENT | T![#] => { | 587 | IDENT | INT_NUMBER | T![#] => { |
587 | let m = p.start(); | 588 | let m = p.start(); |
588 | attributes::outer_attributes(p); | 589 | attributes::outer_attributes(p); |
589 | name_ref(p); | 590 | name_ref(p, true); |
590 | if p.eat(T![:]) { | 591 | if p.eat(T![:]) { |
591 | expr(p); | 592 | expr(p); |
592 | } | 593 | } |
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs index 543af7c4b..b0081f396 100644 --- a/crates/ra_parser/src/grammar/items.rs +++ b/crates/ra_parser/src/grammar/items.rs | |||
@@ -279,7 +279,7 @@ fn extern_crate_item(p: &mut Parser, m: Marker) { | |||
279 | p.bump(); | 279 | p.bump(); |
280 | assert!(p.at(T![crate])); | 280 | assert!(p.at(T![crate])); |
281 | p.bump(); | 281 | p.bump(); |
282 | name_ref(p); | 282 | name_ref(p, false); |
283 | opt_alias(p); | 283 | opt_alias(p); |
284 | p.expect(T![;]); | 284 | p.expect(T![;]); |
285 | m.complete(p, EXTERN_CRATE_ITEM); | 285 | m.complete(p, EXTERN_CRATE_ITEM); |
diff --git a/crates/ra_parser/src/grammar/paths.rs b/crates/ra_parser/src/grammar/paths.rs index 3537b0da1..2c8f0f7e8 100644 --- a/crates/ra_parser/src/grammar/paths.rs +++ b/crates/ra_parser/src/grammar/paths.rs | |||
@@ -71,7 +71,7 @@ fn path_segment(p: &mut Parser, mode: Mode, first: bool) { | |||
71 | } | 71 | } |
72 | match p.current() { | 72 | match p.current() { |
73 | IDENT => { | 73 | IDENT => { |
74 | name_ref(p); | 74 | name_ref(p, false); |
75 | opt_path_type_args(p, mode); | 75 | opt_path_type_args(p, mode); |
76 | } | 76 | } |
77 | // test crate_path | 77 | // test crate_path |
diff --git a/crates/ra_parser/src/grammar/type_args.rs b/crates/ra_parser/src/grammar/type_args.rs index 3db08b280..f1d999dea 100644 --- a/crates/ra_parser/src/grammar/type_args.rs +++ b/crates/ra_parser/src/grammar/type_args.rs | |||
@@ -38,12 +38,12 @@ fn type_arg(p: &mut Parser) { | |||
38 | // test associated_type_bounds | 38 | // test associated_type_bounds |
39 | // fn print_all<T: Iterator<Item: Display>>(printables: T) {} | 39 | // fn print_all<T: Iterator<Item: Display>>(printables: T) {} |
40 | IDENT if p.nth(1) == T![:] => { | 40 | IDENT if p.nth(1) == T![:] => { |
41 | name_ref(p); | 41 | name_ref(p, false); |
42 | type_params::bounds(p); | 42 | type_params::bounds(p); |
43 | m.complete(p, ASSOC_TYPE_ARG); | 43 | m.complete(p, ASSOC_TYPE_ARG); |
44 | } | 44 | } |
45 | IDENT if p.nth(1) == T![=] => { | 45 | IDENT if p.nth(1) == T![=] => { |
46 | name_ref(p); | 46 | name_ref(p, false); |
47 | p.bump(); | 47 | p.bump(); |
48 | types::type_(p); | 48 | types::type_(p); |
49 | m.complete(p, ASSOC_TYPE_ARG); | 49 | m.complete(p, ASSOC_TYPE_ARG); |
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0061_struct_lit.rs b/crates/ra_syntax/test_data/parser/inline/ok/0061_struct_lit.rs index eb711f68a..6285e5549 100644 --- a/crates/ra_syntax/test_data/parser/inline/ok/0061_struct_lit.rs +++ b/crates/ra_syntax/test_data/parser/inline/ok/0061_struct_lit.rs | |||
@@ -2,4 +2,5 @@ fn foo() { | |||
2 | S {}; | 2 | S {}; |
3 | S { x, y: 32, }; | 3 | S { x, y: 32, }; |
4 | S { x, y: 32, ..Default::default() }; | 4 | S { x, y: 32, ..Default::default() }; |
5 | TupleStruct { 0: 1 }; | ||
5 | } | 6 | } |
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0061_struct_lit.txt b/crates/ra_syntax/test_data/parser/inline/ok/0061_struct_lit.txt index 94d1bfe2e..d06594cae 100644 --- a/crates/ra_syntax/test_data/parser/inline/ok/0061_struct_lit.txt +++ b/crates/ra_syntax/test_data/parser/inline/ok/0061_struct_lit.txt | |||
@@ -1,5 +1,5 @@ | |||
1 | SOURCE_FILE@[0; 86) | 1 | SOURCE_FILE@[0; 112) |
2 | FN_DEF@[0; 85) | 2 | FN_DEF@[0; 111) |
3 | FN_KW@[0; 2) "fn" | 3 | FN_KW@[0; 2) "fn" |
4 | WHITESPACE@[2; 3) " " | 4 | WHITESPACE@[2; 3) " " |
5 | NAME@[3; 6) | 5 | NAME@[3; 6) |
@@ -8,7 +8,7 @@ SOURCE_FILE@[0; 86) | |||
8 | L_PAREN@[6; 7) "(" | 8 | L_PAREN@[6; 7) "(" |
9 | R_PAREN@[7; 8) ")" | 9 | R_PAREN@[7; 8) ")" |
10 | WHITESPACE@[8; 9) " " | 10 | WHITESPACE@[8; 9) " " |
11 | BLOCK@[9; 85) | 11 | BLOCK@[9; 111) |
12 | L_CURLY@[9; 10) "{" | 12 | L_CURLY@[9; 10) "{" |
13 | WHITESPACE@[10; 15) "\n " | 13 | WHITESPACE@[10; 15) "\n " |
14 | EXPR_STMT@[15; 20) | 14 | EXPR_STMT@[15; 20) |
@@ -92,6 +92,27 @@ SOURCE_FILE@[0; 86) | |||
92 | WHITESPACE@[80; 81) " " | 92 | WHITESPACE@[80; 81) " " |
93 | R_CURLY@[81; 82) "}" | 93 | R_CURLY@[81; 82) "}" |
94 | SEMI@[82; 83) ";" | 94 | SEMI@[82; 83) ";" |
95 | WHITESPACE@[83; 84) "\n" | 95 | WHITESPACE@[83; 88) "\n " |
96 | R_CURLY@[84; 85) "}" | 96 | EXPR_STMT@[88; 109) |
97 | WHITESPACE@[85; 86) "\n" | 97 | STRUCT_LIT@[88; 108) |
98 | PATH@[88; 99) | ||
99 | PATH_SEGMENT@[88; 99) | ||
100 | NAME_REF@[88; 99) | ||
101 | IDENT@[88; 99) "TupleStruct" | ||
102 | WHITESPACE@[99; 100) " " | ||
103 | NAMED_FIELD_LIST@[100; 108) | ||
104 | L_CURLY@[100; 101) "{" | ||
105 | WHITESPACE@[101; 102) " " | ||
106 | NAMED_FIELD@[102; 106) | ||
107 | NAME_REF@[102; 103) | ||
108 | INT_NUMBER@[102; 103) "0" | ||
109 | COLON@[103; 104) ":" | ||
110 | WHITESPACE@[104; 105) " " | ||
111 | LITERAL@[105; 106) | ||
112 | INT_NUMBER@[105; 106) "1" | ||
113 | WHITESPACE@[106; 107) " " | ||
114 | R_CURLY@[107; 108) "}" | ||
115 | SEMI@[108; 109) ";" | ||
116 | WHITESPACE@[109; 110) "\n" | ||
117 | R_CURLY@[110; 111) "}" | ||
118 | WHITESPACE@[111; 112) "\n" | ||