Recover from missing ellipsis in record literals for path expressions

This commit is contained in:
Lukas Wirth 2022-08-09 18:23:25 +02:00
parent b3ac58dfb8
commit 49d24f639f
5 changed files with 116 additions and 7 deletions

View file

@ -564,8 +564,10 @@ fn path_expr(p: &mut Parser<'_>, r: Restrictions) -> (CompletedMarker, BlockLike
// test record_lit // test record_lit
// fn foo() { // fn foo() {
// S {}; // S {};
// S { x };
// S { x, y: 32, }; // S { x, y: 32, };
// S { x, y: 32, ..Default::default() }; // S { x, y: 32, ..Default::default() };
// S { x: ::default() };
// TupleStruct { 0: 1 }; // TupleStruct { 0: 1 };
// } // }
pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) { pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) {
@ -582,16 +584,26 @@ pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) {
match p.current() { match p.current() {
IDENT | INT_NUMBER => { IDENT | INT_NUMBER => {
// test_err record_literal_before_ellipsis_recovery // test_err record_literal_missing_ellipsis_recovery
// fn main() { // fn main() {
// S { field ..S::default() } // S { S::default() }
// } // }
if p.nth_at(1, T![:]) || p.nth_at(1, T![..]) { if p.nth_at(1, T![::]) {
name_ref_or_index(p); m.abandon(p);
p.expect(T![:]); p.expect(T![..]);
expr(p);
} else {
// 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.expect(T![:]);
}
expr(p);
m.complete(p, RECORD_EXPR_FIELD);
} }
expr(p);
m.complete(p, RECORD_EXPR_FIELD);
} }
T![.] if p.at(T![..]) => { T![.] if p.at(T![..]) => {
m.abandon(p); m.abandon(p);

View file

@ -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 "
RECORD_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "S"
WHITESPACE " "
RECORD_EXPR_FIELD_LIST
L_CURLY "{"
WHITESPACE " "
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 19: expected DOT2

View file

@ -0,0 +1,3 @@
fn main() {
S { S::default() }
}

View file

@ -24,6 +24,26 @@ SOURCE_FILE
R_CURLY "}" R_CURLY "}"
SEMICOLON ";" SEMICOLON ";"
WHITESPACE "\n " WHITESPACE "\n "
EXPR_STMT
RECORD_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "S"
WHITESPACE " "
RECORD_EXPR_FIELD_LIST
L_CURLY "{"
WHITESPACE " "
RECORD_EXPR_FIELD
PATH_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "x"
WHITESPACE " "
R_CURLY "}"
SEMICOLON ";"
WHITESPACE "\n "
EXPR_STMT EXPR_STMT
RECORD_EXPR RECORD_EXPR
PATH PATH
@ -100,6 +120,35 @@ SOURCE_FILE
R_CURLY "}" R_CURLY "}"
SEMICOLON ";" SEMICOLON ";"
WHITESPACE "\n " WHITESPACE "\n "
EXPR_STMT
RECORD_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "S"
WHITESPACE " "
RECORD_EXPR_FIELD_LIST
L_CURLY "{"
WHITESPACE " "
RECORD_EXPR_FIELD
NAME_REF
IDENT "x"
COLON ":"
WHITESPACE " "
CALL_EXPR
PATH_EXPR
PATH
PATH_SEGMENT
COLON2 "::"
NAME_REF
IDENT "default"
ARG_LIST
L_PAREN "("
R_PAREN ")"
WHITESPACE " "
R_CURLY "}"
SEMICOLON ";"
WHITESPACE "\n "
EXPR_STMT EXPR_STMT
RECORD_EXPR RECORD_EXPR
PATH PATH

View file

@ -1,6 +1,8 @@
fn foo() { fn foo() {
S {}; S {};
S { x };
S { x, y: 32, }; S { x, y: 32, };
S { x, y: 32, ..Default::default() }; S { x, y: 32, ..Default::default() };
S { x: ::default() };
TupleStruct { 0: 1 }; TupleStruct { 0: 1 };
} }