From 7d1bf7023d7c11c20bfc35c9b9f4bfa027858d65 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 1 Jun 2023 08:40:50 +0200 Subject: [PATCH] Recover from leading comma in tuple pat and expr --- crates/ide/src/signature_help.rs | 17 +++++++++--- crates/parser/src/grammar/expressions/atom.rs | 10 +++++++ crates/parser/src/grammar/patterns.rs | 10 +++++++ .../err/0019_tuple_expr_leading_comma.rast | 24 +++++++++++++++++ .../err/0019_tuple_expr_leading_comma.rs | 3 +++ .../err/0020_tuple_pat_leading_comma.rast | 26 +++++++++++++++++++ .../err/0020_tuple_pat_leading_comma.rs | 3 +++ 7 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 crates/parser/test_data/parser/inline/err/0019_tuple_expr_leading_comma.rast create mode 100644 crates/parser/test_data/parser/inline/err/0019_tuple_expr_leading_comma.rs create mode 100644 crates/parser/test_data/parser/inline/err/0020_tuple_pat_leading_comma.rast create mode 100644 crates/parser/test_data/parser/inline/err/0020_tuple_pat_leading_comma.rs diff --git a/crates/ide/src/signature_help.rs b/crates/ide/src/signature_help.rs index 455b519f80..9bd9a948e7 100644 --- a/crates/ide/src/signature_help.rs +++ b/crates/ide/src/signature_help.rs @@ -2003,7 +2003,10 @@ fn main() { let _: (&str, u32, u32)= ($0, 1, 3); } "#, - expect![""], + expect![[r#" + (&str, u32) + ^^^^ --- + "#]], ); check( r#" @@ -2011,7 +2014,10 @@ fn main() { let _: (&str, u32, u32, u32)= ($0, 1, 3); } "#, - expect![""], + expect![[r#" + (&str, u32) + ^^^^ --- + "#]], ); check( r#" @@ -2019,7 +2025,10 @@ fn main() { let _: (&str, u32, u32)= ($0, 1, 3, 5); } "#, - expect![""], + expect![[r#" + (&str, u32, u32) + ^^^^ --- --- + "#]], ); } @@ -2111,7 +2120,7 @@ fn main() { check( r#" fn main() { - let ($0 1, 3): (i32, i32, i32); + let ($0, 1, 3): (i32, i32, i32); } "#, // FIXME: tuple pat should be of size 3 ideally diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs index 3cf9c4dd4b..d8553d3f95 100644 --- a/crates/parser/src/grammar/expressions/atom.rs +++ b/crates/parser/src/grammar/expressions/atom.rs @@ -184,6 +184,16 @@ fn tuple_expr(p: &mut Parser<'_>) -> CompletedMarker { let mut saw_comma = false; let mut saw_expr = false; + + // test_err tuple_expr_leading_comma + // fn foo() { + // (,); + // } + if p.eat(T![,]) { + p.error("expected expression"); + saw_comma = true; + } + while !p.at(EOF) && !p.at(T![')']) { saw_expr = true; diff --git a/crates/parser/src/grammar/patterns.rs b/crates/parser/src/grammar/patterns.rs index 4801732101..39ded41bb2 100644 --- a/crates/parser/src/grammar/patterns.rs +++ b/crates/parser/src/grammar/patterns.rs @@ -413,6 +413,16 @@ fn tuple_pat(p: &mut Parser<'_>) -> CompletedMarker { let mut has_comma = false; let mut has_pat = false; let mut has_rest = false; + + // test_err tuple_pat_leading_comma + // fn foo() { + // let (,); + // } + if p.eat(T![,]) { + p.error("expected pattern"); + has_comma = true; + } + while !p.at(EOF) && !p.at(T![')']) { has_pat = true; if !p.at_ts(PAT_TOP_FIRST) { diff --git a/crates/parser/test_data/parser/inline/err/0019_tuple_expr_leading_comma.rast b/crates/parser/test_data/parser/inline/err/0019_tuple_expr_leading_comma.rast new file mode 100644 index 0000000000..3fbc0da400 --- /dev/null +++ b/crates/parser/test_data/parser/inline/err/0019_tuple_expr_leading_comma.rast @@ -0,0 +1,24 @@ +SOURCE_FILE + FN + FN_KW "fn" + WHITESPACE " " + NAME + IDENT "foo" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + BLOCK_EXPR + STMT_LIST + L_CURLY "{" + WHITESPACE "\n " + EXPR_STMT + TUPLE_EXPR + L_PAREN "(" + COMMA "," + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + R_CURLY "}" + WHITESPACE "\n" +error 17: expected expression diff --git a/crates/parser/test_data/parser/inline/err/0019_tuple_expr_leading_comma.rs b/crates/parser/test_data/parser/inline/err/0019_tuple_expr_leading_comma.rs new file mode 100644 index 0000000000..12fab59a77 --- /dev/null +++ b/crates/parser/test_data/parser/inline/err/0019_tuple_expr_leading_comma.rs @@ -0,0 +1,3 @@ +fn foo() { + (,); +} diff --git a/crates/parser/test_data/parser/inline/err/0020_tuple_pat_leading_comma.rast b/crates/parser/test_data/parser/inline/err/0020_tuple_pat_leading_comma.rast new file mode 100644 index 0000000000..9c8837292d --- /dev/null +++ b/crates/parser/test_data/parser/inline/err/0020_tuple_pat_leading_comma.rast @@ -0,0 +1,26 @@ +SOURCE_FILE + FN + FN_KW "fn" + WHITESPACE " " + NAME + IDENT "foo" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + BLOCK_EXPR + STMT_LIST + L_CURLY "{" + WHITESPACE "\n " + LET_STMT + LET_KW "let" + WHITESPACE " " + TUPLE_PAT + L_PAREN "(" + COMMA "," + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + R_CURLY "}" + WHITESPACE "\n" +error 21: expected pattern diff --git a/crates/parser/test_data/parser/inline/err/0020_tuple_pat_leading_comma.rs b/crates/parser/test_data/parser/inline/err/0020_tuple_pat_leading_comma.rs new file mode 100644 index 0000000000..de168521e1 --- /dev/null +++ b/crates/parser/test_data/parser/inline/err/0020_tuple_pat_leading_comma.rs @@ -0,0 +1,3 @@ +fn foo() { + let (,); +}