Skip to content

Commit 2c05da1

Browse files
committed
Auto merge of rust-lang#16553 - Veykril:field-lit-recovery, r=Veykril
fix: Imrpove recover on `=` for record field initializer and pattern
2 parents fc1ee61 + bf115a6 commit 2c05da1

7 files changed

+137
-27
lines changed

crates/parser/src/grammar/expressions.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -678,27 +678,38 @@ pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) {
678678
attributes::outer_attrs(p);
679679

680680
match p.current() {
681-
IDENT | INT_NUMBER => {
681+
IDENT | INT_NUMBER if p.nth_at(1, T![::]) => {
682682
// test_err record_literal_missing_ellipsis_recovery
683683
// fn main() {
684684
// S { S::default() }
685685
// }
686-
if p.nth_at(1, T![::]) {
687-
m.abandon(p);
688-
p.expect(T![..]);
689-
expr(p);
690-
} else {
686+
m.abandon(p);
687+
p.expect(T![..]);
688+
expr(p);
689+
}
690+
IDENT | INT_NUMBER => {
691+
if p.nth_at(1, T![..]) {
691692
// test_err record_literal_before_ellipsis_recovery
692693
// fn main() {
693694
// S { field ..S::default() }
694695
// }
695-
if p.nth_at(1, T![:]) || p.nth_at(1, T![..]) {
696+
name_ref_or_index(p);
697+
p.error("expected `:`");
698+
} else {
699+
// test_err record_literal_field_eq_recovery
700+
// fn main() {
701+
// S { field = foo }
702+
// }
703+
if p.nth_at(1, T![:]) {
704+
name_ref_or_index(p);
705+
p.bump(T![:]);
706+
} else if p.nth_at(1, T![=]) {
696707
name_ref_or_index(p);
697-
p.expect(T![:]);
708+
p.err_and_bump("expected `:`");
698709
}
699710
expr(p);
700-
m.complete(p, RECORD_EXPR_FIELD);
701711
}
712+
m.complete(p, RECORD_EXPR_FIELD);
702713
}
703714
T![.] if p.at(T![..]) => {
704715
m.abandon(p);

crates/parser/src/grammar/patterns.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,15 @@ fn record_pat_field(p: &mut Parser<'_>) {
323323
p.bump(T![:]);
324324
pattern(p);
325325
}
326+
// test_err record_pat_field_eq_recovery
327+
// fn main() {
328+
// let S { field = foo };
329+
// }
330+
IDENT | INT_NUMBER if p.nth(1) == T![=] => {
331+
name_ref_or_index(p);
332+
p.err_and_bump("expected `:`");
333+
pattern(p);
334+
}
326335
T![box] => {
327336
// FIXME: not all box patterns should be allowed
328337
box_pat(p);

crates/parser/test_data/parser/inline/err/0014_record_literal_before_ellipsis_recovery.rast

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,26 +24,26 @@ SOURCE_FILE
2424
RECORD_EXPR_FIELD
2525
NAME_REF
2626
IDENT "field"
27-
WHITESPACE " "
28-
RANGE_EXPR
29-
DOT2 ".."
30-
CALL_EXPR
31-
PATH_EXPR
32-
PATH
33-
PATH
34-
PATH_SEGMENT
35-
NAME_REF
36-
IDENT "S"
37-
COLON2 "::"
38-
PATH_SEGMENT
39-
NAME_REF
40-
IDENT "default"
41-
ARG_LIST
42-
L_PAREN "("
43-
R_PAREN ")"
27+
WHITESPACE " "
28+
DOT2 ".."
29+
CALL_EXPR
30+
PATH_EXPR
31+
PATH
32+
PATH
33+
PATH_SEGMENT
34+
NAME_REF
35+
IDENT "S"
36+
COLON2 "::"
37+
PATH_SEGMENT
38+
NAME_REF
39+
IDENT "default"
40+
ARG_LIST
41+
L_PAREN "("
42+
R_PAREN ")"
4443
WHITESPACE " "
4544
R_CURLY "}"
4645
WHITESPACE "\n"
4746
R_CURLY "}"
4847
WHITESPACE "\n"
49-
error 25: expected COLON
48+
error 25: expected `:`
49+
error 25: expected COMMA
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
SOURCE_FILE
2+
FN
3+
FN_KW "fn"
4+
WHITESPACE " "
5+
NAME
6+
IDENT "main"
7+
PARAM_LIST
8+
L_PAREN "("
9+
R_PAREN ")"
10+
WHITESPACE " "
11+
BLOCK_EXPR
12+
STMT_LIST
13+
L_CURLY "{"
14+
WHITESPACE "\n "
15+
RECORD_EXPR
16+
PATH
17+
PATH_SEGMENT
18+
NAME_REF
19+
IDENT "S"
20+
WHITESPACE " "
21+
RECORD_EXPR_FIELD_LIST
22+
L_CURLY "{"
23+
WHITESPACE " "
24+
RECORD_EXPR_FIELD
25+
NAME_REF
26+
IDENT "field"
27+
WHITESPACE " "
28+
ERROR
29+
EQ "="
30+
WHITESPACE " "
31+
PATH_EXPR
32+
PATH
33+
PATH_SEGMENT
34+
NAME_REF
35+
IDENT "foo"
36+
WHITESPACE " "
37+
R_CURLY "}"
38+
WHITESPACE "\n"
39+
R_CURLY "}"
40+
WHITESPACE "\n"
41+
error 26: expected `:`
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
S { field = foo }
3+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
SOURCE_FILE
2+
FN
3+
FN_KW "fn"
4+
WHITESPACE " "
5+
NAME
6+
IDENT "main"
7+
PARAM_LIST
8+
L_PAREN "("
9+
R_PAREN ")"
10+
WHITESPACE " "
11+
BLOCK_EXPR
12+
STMT_LIST
13+
L_CURLY "{"
14+
WHITESPACE "\n "
15+
LET_STMT
16+
LET_KW "let"
17+
WHITESPACE " "
18+
RECORD_PAT
19+
PATH
20+
PATH_SEGMENT
21+
NAME_REF
22+
IDENT "S"
23+
WHITESPACE " "
24+
RECORD_PAT_FIELD_LIST
25+
L_CURLY "{"
26+
WHITESPACE " "
27+
RECORD_PAT_FIELD
28+
NAME_REF
29+
IDENT "field"
30+
WHITESPACE " "
31+
ERROR
32+
EQ "="
33+
WHITESPACE " "
34+
IDENT_PAT
35+
NAME
36+
IDENT "foo"
37+
WHITESPACE " "
38+
R_CURLY "}"
39+
SEMICOLON ";"
40+
WHITESPACE "\n"
41+
R_CURLY "}"
42+
WHITESPACE "\n"
43+
error 30: expected `:`
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
let S { field = foo };
3+
}

0 commit comments

Comments
 (0)