aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/libsyntax2/src/grammar/expressions/atom.rs2
-rw-r--r--crates/libsyntax2/src/grammar/expressions/mod.rs2
-rw-r--r--crates/libsyntax2/src/grammar/items/mod.rs4
-rw-r--r--crates/libsyntax2/src/grammar/params.rs11
-rw-r--r--crates/libsyntax2/src/grammar/paths.rs3
-rw-r--r--crates/libsyntax2/src/grammar/patterns.rs7
-rw-r--r--crates/libsyntax2/src/grammar/types.rs8
-rw-r--r--crates/libsyntax2/src/lib.rs11
-rw-r--r--crates/libsyntax2/tests/data/parser/err/0015_curly_in_params.rs2
-rw-r--r--crates/libsyntax2/tests/data/parser/err/0015_curly_in_params.txt24
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// }
16const LITERAL_FIRST: TokenSet = 16pub(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 @@
1mod atom; 1mod atom;
2 2
3use super::*; 3use super::*;
4pub(super) use self::atom::literal; 4pub(super) use self::atom::{literal, LITERAL_FIRST};
5 5
6const EXPR_FIRST: TokenSet = LHS_FIRST; 6const 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
65const VALUE_PARAMETER_FIRST: TokenSet =
66 token_set_union![
67 patterns::PATTERN_FIRST,
68 types::TYPE_FIRST,
69 ];
70
60fn value_parameter(p: &mut Parser, flavor: Flavor) { 71fn 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 @@
1use super::*; 1use super::*;
2 2
3pub(super) const PATH_FIRST: TokenSet =
4 token_set![IDENT, SELF_KW, SUPER_KW, COLONCOLON, L_ANGLE];
5
3pub(super) fn is_path_start(p: &Parser) -> bool { 6pub(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 @@
1use super::*; 1use super::*;
2 2
3pub(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
3pub(super) fn pattern(p: &mut Parser) { 10pub(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 @@
1use super::*; 1use super::*;
2 2
3pub(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
3pub(super) fn type_(p: &mut Parser) { 11pub(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))]
62fn validate_block_structure(_: SyntaxNodeRef) {}
63
64#[cfg(debug_assertions)]
61fn validate_block_structure(root: SyntaxNodeRef) { 65fn 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 @@
1fn 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 @@
1FILE@[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)