aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/libsyntax2/src/grammar/items/mod.rs6
-rw-r--r--crates/libsyntax2/src/grammar/items/structs.rs4
-rw-r--r--crates/libsyntax2/src/grammar/items/traits.rs2
-rw-r--r--crates/libsyntax2/src/grammar/mod.rs8
-rw-r--r--crates/libsyntax2/src/parser_api.rs6
-rw-r--r--crates/libsyntax2/tests/data/parser/err/0020_fn_recover.rs3
-rw-r--r--crates/libsyntax2/tests/data/parser/err/0020_fn_recover.txt20
7 files changed, 40 insertions, 9 deletions
diff --git a/crates/libsyntax2/src/grammar/items/mod.rs b/crates/libsyntax2/src/grammar/items/mod.rs
index 7c6f7b63e..e672aa419 100644
--- a/crates/libsyntax2/src/grammar/items/mod.rs
+++ b/crates/libsyntax2/src/grammar/items/mod.rs
@@ -24,6 +24,10 @@ pub(super) enum ItemFlavor {
24 Mod, Trait 24 Mod, Trait
25} 25}
26 26
27const ITEM_RECOVERY_SET: TokenSet =
28 token_set![FN_KW, STRUCT_KW, ENUM_KW, IMPL_KW, TRAIT_KW, CONST_KW, STATIC_KW, LET_KW,
29 MOD_KW, PUB_KW, CRATE_KW];
30
27pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemFlavor) { 31pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemFlavor) {
28 let m = p.start(); 32 let m = p.start();
29 match maybe_item(p, flavor) { 33 match maybe_item(p, flavor) {
@@ -231,7 +235,7 @@ fn fn_def(p: &mut Parser, flavor: ItemFlavor) {
231 assert!(p.at(FN_KW)); 235 assert!(p.at(FN_KW));
232 p.bump(); 236 p.bump();
233 237
234 name(p); 238 name_r(p, ITEM_RECOVERY_SET);
235 // test function_type_params 239 // test function_type_params
236 // fn foo<T: Clone + Copy>(){} 240 // fn foo<T: Clone + Copy>(){}
237 type_params::opt_type_param_list(p); 241 type_params::opt_type_param_list(p);
diff --git a/crates/libsyntax2/src/grammar/items/structs.rs b/crates/libsyntax2/src/grammar/items/structs.rs
index 180205393..f1e78865c 100644
--- a/crates/libsyntax2/src/grammar/items/structs.rs
+++ b/crates/libsyntax2/src/grammar/items/structs.rs
@@ -4,7 +4,7 @@ pub(super) fn struct_def(p: &mut Parser) {
4 assert!(p.at(STRUCT_KW)); 4 assert!(p.at(STRUCT_KW));
5 p.bump(); 5 p.bump();
6 6
7 name(p); 7 name_r(p, ITEM_RECOVERY_SET);
8 type_params::opt_type_param_list(p); 8 type_params::opt_type_param_list(p);
9 match p.current() { 9 match p.current() {
10 WHERE_KW => { 10 WHERE_KW => {
@@ -41,7 +41,7 @@ pub(super) fn struct_def(p: &mut Parser) {
41pub(super) fn enum_def(p: &mut Parser) { 41pub(super) fn enum_def(p: &mut Parser) {
42 assert!(p.at(ENUM_KW)); 42 assert!(p.at(ENUM_KW));
43 p.bump(); 43 p.bump();
44 name(p); 44 name_r(p, ITEM_RECOVERY_SET);
45 type_params::opt_type_param_list(p); 45 type_params::opt_type_param_list(p);
46 type_params::opt_where_clause(p); 46 type_params::opt_where_clause(p);
47 if p.at(L_CURLY) { 47 if p.at(L_CURLY) {
diff --git a/crates/libsyntax2/src/grammar/items/traits.rs b/crates/libsyntax2/src/grammar/items/traits.rs
index 01b79e3c9..9d21d4d36 100644
--- a/crates/libsyntax2/src/grammar/items/traits.rs
+++ b/crates/libsyntax2/src/grammar/items/traits.rs
@@ -5,7 +5,7 @@ use super::*;
5pub(super) fn trait_def(p: &mut Parser) { 5pub(super) fn trait_def(p: &mut Parser) {
6 assert!(p.at(TRAIT_KW)); 6 assert!(p.at(TRAIT_KW));
7 p.bump(); 7 p.bump();
8 name(p); 8 name_r(p, ITEM_RECOVERY_SET);
9 type_params::opt_type_param_list(p); 9 type_params::opt_type_param_list(p);
10 if p.at(COLON) { 10 if p.at(COLON) {
11 type_params::bounds(p); 11 type_params::bounds(p);
diff --git a/crates/libsyntax2/src/grammar/mod.rs b/crates/libsyntax2/src/grammar/mod.rs
index 1acecac41..339664af3 100644
--- a/crates/libsyntax2/src/grammar/mod.rs
+++ b/crates/libsyntax2/src/grammar/mod.rs
@@ -129,16 +129,20 @@ fn opt_fn_ret_type(p: &mut Parser) -> bool {
129 } 129 }
130} 130}
131 131
132fn name(p: &mut Parser) { 132fn name_r(p: &mut Parser, recovery: TokenSet) {
133 if p.at(IDENT) { 133 if p.at(IDENT) {
134 let m = p.start(); 134 let m = p.start();
135 p.bump(); 135 p.bump();
136 m.complete(p, NAME); 136 m.complete(p, NAME);
137 } else { 137 } else {
138 p.err_and_bump("expected a name"); 138 p.err_recover("expected a name", recovery);
139 } 139 }
140} 140}
141 141
142fn name(p: &mut Parser) {
143 name_r(p, TokenSet::EMPTY)
144}
145
142fn name_ref(p: &mut Parser) { 146fn name_ref(p: &mut Parser) {
143 if p.at(IDENT) { 147 if p.at(IDENT) {
144 let m = p.start(); 148 let m = p.start();
diff --git a/crates/libsyntax2/src/parser_api.rs b/crates/libsyntax2/src/parser_api.rs
index 70af474ae..9bc58e7f7 100644
--- a/crates/libsyntax2/src/parser_api.rs
+++ b/crates/libsyntax2/src/parser_api.rs
@@ -12,7 +12,7 @@ fn mask(kind: SyntaxKind) -> u128 {
12} 12}
13 13
14impl TokenSet { 14impl TokenSet {
15 const EMPTY: TokenSet = TokenSet(0); 15 pub const EMPTY: TokenSet = TokenSet(0);
16 16
17 pub fn contains(&self, kind: SyntaxKind) -> bool { 17 pub fn contains(&self, kind: SyntaxKind) -> bool {
18 self.0 & mask(kind) != 0 18 self.0 & mask(kind) != 0
@@ -145,10 +145,10 @@ impl<'t> Parser<'t> {
145 } 145 }
146 146
147 /// Create an error node and consume the next token. 147 /// Create an error node and consume the next token.
148 pub(crate) fn err_recover(&mut self, message: &str, recovery_set: TokenSet) { 148 pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) {
149 if self.at(SyntaxKind::L_CURLY) 149 if self.at(SyntaxKind::L_CURLY)
150 || self.at(SyntaxKind::R_CURLY) 150 || self.at(SyntaxKind::R_CURLY)
151 || recovery_set.contains(self.current()) { 151 || recovery.contains(self.current()) {
152 self.error(message); 152 self.error(message);
153 } else { 153 } else {
154 let m = self.start(); 154 let m = self.start();
diff --git a/crates/libsyntax2/tests/data/parser/err/0020_fn_recover.rs b/crates/libsyntax2/tests/data/parser/err/0020_fn_recover.rs
new file mode 100644
index 000000000..3393b668b
--- /dev/null
+++ b/crates/libsyntax2/tests/data/parser/err/0020_fn_recover.rs
@@ -0,0 +1,3 @@
1fn
2
3fn foo() {}
diff --git a/crates/libsyntax2/tests/data/parser/err/0020_fn_recover.txt b/crates/libsyntax2/tests/data/parser/err/0020_fn_recover.txt
new file mode 100644
index 000000000..b5218b0fa
--- /dev/null
+++ b/crates/libsyntax2/tests/data/parser/err/0020_fn_recover.txt
@@ -0,0 +1,20 @@
1ROOT@[0; 16)
2 FN_DEF@[0; 2)
3 FN_KW@[0; 2)
4 err: `expected a name`
5 err: `expected function arguments`
6 err: `expected a block`
7 WHITESPACE@[2; 4)
8 FN_DEF@[4; 15)
9 FN_KW@[4; 6)
10 WHITESPACE@[6; 7)
11 NAME@[7; 10)
12 IDENT@[7; 10) "foo"
13 PARAM_LIST@[10; 12)
14 L_PAREN@[10; 11)
15 R_PAREN@[11; 12)
16 WHITESPACE@[12; 13)
17 BLOCK@[13; 15)
18 L_CURLY@[13; 14)
19 R_CURLY@[14; 15)
20 WHITESPACE@[15; 16)