Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #16553 - Veykril:field-lit-recovery, r=Veykril
fix: Imrpove recover on `=` for record field initializer and pattern
bors 2024-02-14
parent fc1ee61 · parent bf115a6 · commit 2c05da1
-rw-r--r--crates/parser/src/grammar/expressions.rs29
-rw-r--r--crates/parser/src/grammar/patterns.rs9
-rw-r--r--crates/parser/test_data/parser/inline/err/0014_record_literal_before_ellipsis_recovery.rast36
-rw-r--r--crates/parser/test_data/parser/inline/err/0032_record_literal_field_eq_recovery.rast41
-rw-r--r--crates/parser/test_data/parser/inline/err/0032_record_literal_field_eq_recovery.rs3
-rw-r--r--crates/parser/test_data/parser/inline/err/0033_record_pat_field_eq_recovery.rast43
-rw-r--r--crates/parser/test_data/parser/inline/err/0033_record_pat_field_eq_recovery.rs3
7 files changed, 137 insertions, 27 deletions
diff --git a/crates/parser/src/grammar/expressions.rs b/crates/parser/src/grammar/expressions.rs
index f40c515fa0..6b660180f8 100644
--- a/crates/parser/src/grammar/expressions.rs
+++ b/crates/parser/src/grammar/expressions.rs
@@ -678,27 +678,38 @@ pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) {
attributes::outer_attrs(p);
match p.current() {
- IDENT | INT_NUMBER => {
+ IDENT | INT_NUMBER if p.nth_at(1, T![::]) => {
// test_err record_literal_missing_ellipsis_recovery
// fn main() {
// S { S::default() }
// }
- if p.nth_at(1, T![::]) {
- m.abandon(p);
- p.expect(T![..]);
- expr(p);
- } else {
+ m.abandon(p);
+ p.expect(T![..]);
+ expr(p);
+ }
+ IDENT | INT_NUMBER => {
+ if p.nth_at(1, T![..]) {
// test_err record_literal_before_ellipsis_recovery
// fn main() {
// S { field ..S::default() }
// }
- if p.nth_at(1, T![:]) || p.nth_at(1, T![..]) {
+ name_ref_or_index(p);
+ p.error("expected `:`");
+ } else {
+ // test_err record_literal_field_eq_recovery
+ // fn main() {
+ // S { field = foo }
+ // }
+ if p.nth_at(1, T![:]) {
+ name_ref_or_index(p);
+ p.bump(T![:]);
+ } else if p.nth_at(1, T![=]) {
name_ref_or_index(p);
- p.expect(T![:]);
+ p.err_and_bump("expected `:`");
}
expr(p);
- m.complete(p, RECORD_EXPR_FIELD);
}
+ m.complete(p, RECORD_EXPR_FIELD);
}
T![.] if p.at(T![..]) => {
m.abandon(p);
diff --git a/crates/parser/src/grammar/patterns.rs b/crates/parser/src/grammar/patterns.rs
index 39ded41bb2..5036742337 100644
--- a/crates/parser/src/grammar/patterns.rs
+++ b/crates/parser/src/grammar/patterns.rs
@@ -323,6 +323,15 @@ fn record_pat_field(p: &mut Parser<'_>) {
p.bump(T![:]);
pattern(p);
}
+ // test_err record_pat_field_eq_recovery
+ // fn main() {
+ // let S { field = foo };
+ // }
+ IDENT | INT_NUMBER if p.nth(1) == T![=] => {
+ name_ref_or_index(p);
+ p.err_and_bump("expected `:`");
+ pattern(p);
+ }
T![box] => {
// FIXME: not all box patterns should be allowed
box_pat(p);
diff --git a/crates/parser/test_data/parser/inline/err/0014_record_literal_before_ellipsis_recovery.rast b/crates/parser/test_data/parser/inline/err/0014_record_literal_before_ellipsis_recovery.rast
index f511960040..741b7845e7 100644
--- a/crates/parser/test_data/parser/inline/err/0014_record_literal_before_ellipsis_recovery.rast
+++ b/crates/parser/test_data/parser/inline/err/0014_record_literal_before_ellipsis_recovery.rast
@@ -24,26 +24,26 @@ SOURCE_FILE
RECORD_EXPR_FIELD
NAME_REF
IDENT "field"
- WHITESPACE " "
- RANGE_EXPR
- DOT2 ".."
- CALL_EXPR
- PATH_EXPR
- PATH
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "S"
- COLON2 "::"
- PATH_SEGMENT
- NAME_REF
- IDENT "default"
- ARG_LIST
- L_PAREN "("
- R_PAREN ")"
+ WHITESPACE " "
+ DOT2 ".."
+ CALL_EXPR
+ PATH_EXPR
+ PATH
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "S"
+ COLON2 "::"
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "default"
+ ARG_LIST
+ L_PAREN "("
+ R_PAREN ")"
WHITESPACE " "
R_CURLY "}"
WHITESPACE "\n"
R_CURLY "}"
WHITESPACE "\n"
-error 25: expected COLON
+error 25: expected `:`
+error 25: expected COMMA
diff --git a/crates/parser/test_data/parser/inline/err/0032_record_literal_field_eq_recovery.rast b/crates/parser/test_data/parser/inline/err/0032_record_literal_field_eq_recovery.rast
new file mode 100644
index 0000000000..ad4deeb0b6
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/err/0032_record_literal_field_eq_recovery.rast
@@ -0,0 +1,41 @@
+SOURCE_FILE
+ FN
+ FN_KW "fn"
+ WHITESPACE " "
+ NAME
+ IDENT "main"
+ PARAM_LIST
+ L_PAREN "("
+ R_PAREN ")"
+ WHITESPACE " "
+ BLOCK_EXPR
+ STMT_LIST
+ L_CURLY "{"
+ WHITESPACE "\n "
+ RECORD_EXPR
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "S"
+ WHITESPACE " "
+ RECORD_EXPR_FIELD_LIST
+ L_CURLY "{"
+ WHITESPACE " "
+ RECORD_EXPR_FIELD
+ NAME_REF
+ IDENT "field"
+ WHITESPACE " "
+ ERROR
+ EQ "="
+ WHITESPACE " "
+ PATH_EXPR
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "foo"
+ WHITESPACE " "
+ R_CURLY "}"
+ WHITESPACE "\n"
+ R_CURLY "}"
+ WHITESPACE "\n"
+error 26: expected `:`
diff --git a/crates/parser/test_data/parser/inline/err/0032_record_literal_field_eq_recovery.rs b/crates/parser/test_data/parser/inline/err/0032_record_literal_field_eq_recovery.rs
new file mode 100644
index 0000000000..1eb1aa9b92
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/err/0032_record_literal_field_eq_recovery.rs
@@ -0,0 +1,3 @@
+fn main() {
+ S { field = foo }
+}
diff --git a/crates/parser/test_data/parser/inline/err/0033_record_pat_field_eq_recovery.rast b/crates/parser/test_data/parser/inline/err/0033_record_pat_field_eq_recovery.rast
new file mode 100644
index 0000000000..6940a84b68
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/err/0033_record_pat_field_eq_recovery.rast
@@ -0,0 +1,43 @@
+SOURCE_FILE
+ FN
+ FN_KW "fn"
+ WHITESPACE " "
+ NAME
+ IDENT "main"
+ PARAM_LIST
+ L_PAREN "("
+ R_PAREN ")"
+ WHITESPACE " "
+ BLOCK_EXPR
+ STMT_LIST
+ L_CURLY "{"
+ WHITESPACE "\n "
+ LET_STMT
+ LET_KW "let"
+ WHITESPACE " "
+ RECORD_PAT
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "S"
+ WHITESPACE " "
+ RECORD_PAT_FIELD_LIST
+ L_CURLY "{"
+ WHITESPACE " "
+ RECORD_PAT_FIELD
+ NAME_REF
+ IDENT "field"
+ WHITESPACE " "
+ ERROR
+ EQ "="
+ WHITESPACE " "
+ IDENT_PAT
+ NAME
+ IDENT "foo"
+ WHITESPACE " "
+ R_CURLY "}"
+ SEMICOLON ";"
+ WHITESPACE "\n"
+ R_CURLY "}"
+ WHITESPACE "\n"
+error 30: expected `:`
diff --git a/crates/parser/test_data/parser/inline/err/0033_record_pat_field_eq_recovery.rs b/crates/parser/test_data/parser/inline/err/0033_record_pat_field_eq_recovery.rs
new file mode 100644
index 0000000000..c4949d6e12
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/err/0033_record_pat_field_eq_recovery.rs
@@ -0,0 +1,3 @@
+fn main() {
+ let S { field = foo };
+}