diff options
-rw-r--r-- | crates/libsyntax2/src/grammar/expressions/atom.rs | 2 | ||||
-rw-r--r-- | crates/libsyntax2/src/grammar/expressions/mod.rs | 2 | ||||
-rw-r--r-- | crates/libsyntax2/src/grammar/items/mod.rs | 4 | ||||
-rw-r--r-- | crates/libsyntax2/src/grammar/params.rs | 11 | ||||
-rw-r--r-- | crates/libsyntax2/src/grammar/paths.rs | 3 | ||||
-rw-r--r-- | crates/libsyntax2/src/grammar/patterns.rs | 7 | ||||
-rw-r--r-- | crates/libsyntax2/src/grammar/types.rs | 8 | ||||
-rw-r--r-- | crates/libsyntax2/src/lib.rs | 11 | ||||
-rw-r--r-- | crates/libsyntax2/tests/data/parser/err/0015_curly_in_params.rs | 2 | ||||
-rw-r--r-- | crates/libsyntax2/tests/data/parser/err/0015_curly_in_params.txt | 24 |
10 files changed, 70 insertions, 4 deletions
diff --git a/crates/libsyntax2/src/grammar/expressions/atom.rs b/crates/libsyntax2/src/grammar/expressions/atom.rs index 417366026..b0e270426 100644 --- a/crates/libsyntax2/src/grammar/expressions/atom.rs +++ b/crates/libsyntax2/src/grammar/expressions/atom.rs | |||
@@ -13,7 +13,7 @@ use super::*; | |||
13 | // let _ = b"e"; | 13 | // let _ = b"e"; |
14 | // let _ = br"f"; | 14 | // let _ = br"f"; |
15 | // } | 15 | // } |
16 | const LITERAL_FIRST: TokenSet = | 16 | pub(crate) const LITERAL_FIRST: TokenSet = |
17 | token_set![TRUE_KW, FALSE_KW, INT_NUMBER, FLOAT_NUMBER, BYTE, CHAR, | 17 | token_set![TRUE_KW, FALSE_KW, INT_NUMBER, FLOAT_NUMBER, BYTE, CHAR, |
18 | STRING, RAW_STRING, BYTE_STRING, RAW_BYTE_STRING]; | 18 | STRING, RAW_STRING, BYTE_STRING, RAW_BYTE_STRING]; |
19 | 19 | ||
diff --git a/crates/libsyntax2/src/grammar/expressions/mod.rs b/crates/libsyntax2/src/grammar/expressions/mod.rs index e133c1d9b..59a0564d9 100644 --- a/crates/libsyntax2/src/grammar/expressions/mod.rs +++ b/crates/libsyntax2/src/grammar/expressions/mod.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | mod atom; | 1 | mod atom; |
2 | 2 | ||
3 | use super::*; | 3 | use super::*; |
4 | pub(super) use self::atom::literal; | 4 | pub(super) use self::atom::{literal, LITERAL_FIRST}; |
5 | 5 | ||
6 | const EXPR_FIRST: TokenSet = LHS_FIRST; | 6 | const EXPR_FIRST: TokenSet = LHS_FIRST; |
7 | 7 | ||
diff --git a/crates/libsyntax2/src/grammar/items/mod.rs b/crates/libsyntax2/src/grammar/items/mod.rs index d236fb506..206c85280 100644 --- a/crates/libsyntax2/src/grammar/items/mod.rs +++ b/crates/libsyntax2/src/grammar/items/mod.rs | |||
@@ -250,8 +250,10 @@ fn function(p: &mut Parser, flavor: ItemFlavor) { | |||
250 | 250 | ||
251 | // test fn_decl | 251 | // test fn_decl |
252 | // trait T { fn foo(); } | 252 | // trait T { fn foo(); } |
253 | if !p.eat(SEMI) { | 253 | if p.at(L_CURLY) { |
254 | expressions::block(p); | 254 | expressions::block(p); |
255 | } else { | ||
256 | p.expect(SEMI); | ||
255 | } | 257 | } |
256 | } | 258 | } |
257 | 259 | ||
diff --git a/crates/libsyntax2/src/grammar/params.rs b/crates/libsyntax2/src/grammar/params.rs index 5b1322b3a..bc0cb44ba 100644 --- a/crates/libsyntax2/src/grammar/params.rs +++ b/crates/libsyntax2/src/grammar/params.rs | |||
@@ -48,6 +48,10 @@ fn list_(p: &mut Parser, flavor: Flavor) { | |||
48 | opt_self_param(p); | 48 | opt_self_param(p); |
49 | } | 49 | } |
50 | while !p.at(EOF) && !p.at(ket) { | 50 | while !p.at(EOF) && !p.at(ket) { |
51 | if !VALUE_PARAMETER_FIRST.contains(p.current()) { | ||
52 | p.error("expected value parameter"); | ||
53 | break; | ||
54 | } | ||
51 | value_parameter(p, flavor); | 55 | value_parameter(p, flavor); |
52 | if !p.at(ket) { | 56 | if !p.at(ket) { |
53 | p.expect(COMMA); | 57 | p.expect(COMMA); |
@@ -57,6 +61,13 @@ fn list_(p: &mut Parser, flavor: Flavor) { | |||
57 | m.complete(p, PARAM_LIST); | 61 | m.complete(p, PARAM_LIST); |
58 | } | 62 | } |
59 | 63 | ||
64 | |||
65 | const VALUE_PARAMETER_FIRST: TokenSet = | ||
66 | token_set_union![ | ||
67 | patterns::PATTERN_FIRST, | ||
68 | types::TYPE_FIRST, | ||
69 | ]; | ||
70 | |||
60 | fn value_parameter(p: &mut Parser, flavor: Flavor) { | 71 | fn value_parameter(p: &mut Parser, flavor: Flavor) { |
61 | let m = p.start(); | 72 | let m = p.start(); |
62 | match flavor { | 73 | match flavor { |
diff --git a/crates/libsyntax2/src/grammar/paths.rs b/crates/libsyntax2/src/grammar/paths.rs index 8f5e82d91..7c9fb8be2 100644 --- a/crates/libsyntax2/src/grammar/paths.rs +++ b/crates/libsyntax2/src/grammar/paths.rs | |||
@@ -1,5 +1,8 @@ | |||
1 | use super::*; | 1 | use super::*; |
2 | 2 | ||
3 | pub(super) const PATH_FIRST: TokenSet = | ||
4 | token_set![IDENT, SELF_KW, SUPER_KW, COLONCOLON, L_ANGLE]; | ||
5 | |||
3 | pub(super) fn is_path_start(p: &Parser) -> bool { | 6 | pub(super) fn is_path_start(p: &Parser) -> bool { |
4 | match p.current() { | 7 | match p.current() { |
5 | IDENT | SELF_KW | SUPER_KW | COLONCOLON => true, | 8 | IDENT | SELF_KW | SUPER_KW | COLONCOLON => true, |
diff --git a/crates/libsyntax2/src/grammar/patterns.rs b/crates/libsyntax2/src/grammar/patterns.rs index 7ddbfa318..11852e0d3 100644 --- a/crates/libsyntax2/src/grammar/patterns.rs +++ b/crates/libsyntax2/src/grammar/patterns.rs | |||
@@ -1,5 +1,12 @@ | |||
1 | use super::*; | 1 | use super::*; |
2 | 2 | ||
3 | pub(super) const PATTERN_FIRST: TokenSet = | ||
4 | token_set_union![ | ||
5 | token_set![REF_KW, MUT_KW, L_PAREN, L_BRACK, AMP], | ||
6 | expressions::LITERAL_FIRST, | ||
7 | paths::PATH_FIRST, | ||
8 | ]; | ||
9 | |||
3 | pub(super) fn pattern(p: &mut Parser) { | 10 | pub(super) fn pattern(p: &mut Parser) { |
4 | if let Some(lhs) = atom_pat(p) { | 11 | if let Some(lhs) = atom_pat(p) { |
5 | // test range_pat | 12 | // test range_pat |
diff --git a/crates/libsyntax2/src/grammar/types.rs b/crates/libsyntax2/src/grammar/types.rs index 2088a38e3..89030e66c 100644 --- a/crates/libsyntax2/src/grammar/types.rs +++ b/crates/libsyntax2/src/grammar/types.rs | |||
@@ -1,5 +1,13 @@ | |||
1 | use super::*; | 1 | use super::*; |
2 | 2 | ||
3 | pub(super) const TYPE_FIRST: TokenSet = | ||
4 | token_set_union![ | ||
5 | token_set![ | ||
6 | L_PAREN, EXCL, STAR, L_BRACK, AMP, UNDERSCORE, FN_KW, UNSAFE_KW, EXTERN_KW, FOR_KW, IMPL_KW, DYN_KW, L_ANGLE, | ||
7 | ], | ||
8 | paths::PATH_FIRST, | ||
9 | ]; | ||
10 | |||
3 | pub(super) fn type_(p: &mut Parser) { | 11 | pub(super) fn type_(p: &mut Parser) { |
4 | match p.current() { | 12 | match p.current() { |
5 | L_PAREN => paren_or_tuple_type(p), | 13 | L_PAREN => paren_or_tuple_type(p), |
diff --git a/crates/libsyntax2/src/lib.rs b/crates/libsyntax2/src/lib.rs index d3ecbe470..9f9f3ab3a 100644 --- a/crates/libsyntax2/src/lib.rs +++ b/crates/libsyntax2/src/lib.rs | |||
@@ -58,6 +58,10 @@ pub fn parse(text: &str) -> SyntaxNode { | |||
58 | res | 58 | res |
59 | } | 59 | } |
60 | 60 | ||
61 | #[cfg(not(debug_assertions))] | ||
62 | fn validate_block_structure(_: SyntaxNodeRef) {} | ||
63 | |||
64 | #[cfg(debug_assertions)] | ||
61 | fn validate_block_structure(root: SyntaxNodeRef) { | 65 | fn validate_block_structure(root: SyntaxNodeRef) { |
62 | let mut stack = Vec::new(); | 66 | let mut stack = Vec::new(); |
63 | for node in algo::walk::preorder(root) { | 67 | for node in algo::walk::preorder(root) { |
@@ -67,7 +71,12 @@ fn validate_block_structure(root: SyntaxNodeRef) { | |||
67 | } | 71 | } |
68 | SyntaxKind::R_CURLY => { | 72 | SyntaxKind::R_CURLY => { |
69 | if let Some(pair) = stack.pop() { | 73 | if let Some(pair) = stack.pop() { |
70 | assert_eq!(node.parent(), pair.parent()); | 74 | assert_eq!( |
75 | node.parent(), | ||
76 | pair.parent(), | ||
77 | "unpaired curleys:\n{}", | ||
78 | utils::dump_tree(root), | ||
79 | ); | ||
71 | assert!( | 80 | assert!( |
72 | node.next_sibling().is_none() && pair.prev_sibling().is_none(), | 81 | node.next_sibling().is_none() && pair.prev_sibling().is_none(), |
73 | "floating curlys at {:?}\nfile:\n{}\nerror:\n{}\n", | 82 | "floating curlys at {:?}\nfile:\n{}\nerror:\n{}\n", |
diff --git a/crates/libsyntax2/tests/data/parser/err/0015_curly_in_params.rs b/crates/libsyntax2/tests/data/parser/err/0015_curly_in_params.rs new file mode 100644 index 000000000..156e70251 --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/err/0015_curly_in_params.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | fn foo(}) { | ||
2 | } | ||
diff --git a/crates/libsyntax2/tests/data/parser/err/0015_curly_in_params.txt b/crates/libsyntax2/tests/data/parser/err/0015_curly_in_params.txt new file mode 100644 index 000000000..841379797 --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/err/0015_curly_in_params.txt | |||
@@ -0,0 +1,24 @@ | |||
1 | FILE@[0; 14) | ||
2 | FN_DEF@[0; 7) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 7) | ||
8 | L_PAREN@[6; 7) | ||
9 | err: `expected value parameter` | ||
10 | err: `expected R_PAREN` | ||
11 | err: `expected SEMI` | ||
12 | err: `expected an item` | ||
13 | ERROR@[7; 8) | ||
14 | R_CURLY@[7; 8) | ||
15 | err: `expected an item` | ||
16 | ERROR@[8; 9) | ||
17 | R_PAREN@[8; 9) | ||
18 | WHITESPACE@[9; 10) | ||
19 | err: `expected an item` | ||
20 | ERROR@[10; 13) | ||
21 | L_CURLY@[10; 11) | ||
22 | WHITESPACE@[11; 12) | ||
23 | R_CURLY@[12; 13) | ||
24 | WHITESPACE@[13; 14) | ||