From 4a24e729b07bb4547b28e2eb8dc79e7a805687c6 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 6 Dec 2024 05:53:44 +0100 Subject: [PATCH] fix: Fix parser getting stuck for bad asm expressions --- crates/parser/src/grammar/expressions/atom.rs | 18 +++++-- crates/parser/test_data/generated/runner.rs | 2 + .../parser/inline/err/bad_asm_expr.rast | 50 +++++++++++++++++++ .../parser/inline/err/bad_asm_expr.rs | 5 ++ 4 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 crates/parser/test_data/parser/inline/err/bad_asm_expr.rast create mode 100644 crates/parser/test_data/parser/inline/err/bad_asm_expr.rs diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs index cd2ce59f62..407320e1d0 100644 --- a/crates/parser/src/grammar/expressions/atom.rs +++ b/crates/parser/src/grammar/expressions/atom.rs @@ -345,10 +345,7 @@ fn parse_asm_expr(p: &mut Parser<'_>, m: Marker) -> Option { name(p); p.bump(T![=]); allow_templates = false; - true - } else { - false - }; + } let op = p.start(); let dir_spec = p.start(); @@ -399,6 +396,19 @@ fn parse_asm_expr(p: &mut Parser<'_>, m: Marker) -> Option { op.abandon(p); op_n.abandon(p); p.err_and_bump("expected asm operand"); + + // improves error recovery and handles err_and_bump recovering from `{` which gets + // the parser stuck here + if p.at(T!['{']) { + // test_err bad_asm_expr + // fn foo() { + // builtin#asm( + // label crashy = { return; } + // ); + // } + expr(p); + } + if p.at(T!['}']) { break; } diff --git a/crates/parser/test_data/generated/runner.rs b/crates/parser/test_data/generated/runner.rs index f9486f53c2..c4ffc6cadc 100644 --- a/crates/parser/test_data/generated/runner.rs +++ b/crates/parser/test_data/generated/runner.rs @@ -704,6 +704,8 @@ mod err { run_and_expect_errors("test_data/parser/inline/err/async_without_semicolon.rs"); } #[test] + fn bad_asm_expr() { run_and_expect_errors("test_data/parser/inline/err/bad_asm_expr.rs"); } + #[test] fn comma_after_functional_update_syntax() { run_and_expect_errors( "test_data/parser/inline/err/comma_after_functional_update_syntax.rs", diff --git a/crates/parser/test_data/parser/inline/err/bad_asm_expr.rast b/crates/parser/test_data/parser/inline/err/bad_asm_expr.rast new file mode 100644 index 0000000000..306446e64d --- /dev/null +++ b/crates/parser/test_data/parser/inline/err/bad_asm_expr.rast @@ -0,0 +1,50 @@ +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 + ASM_EXPR + BUILTIN_KW "builtin" + POUND "#" + ASM_KW "asm" + L_PAREN "(" + WHITESPACE "\n " + PATH_EXPR + PATH + PATH_SEGMENT + NAME_REF + IDENT "label" + WHITESPACE " " + NAME + IDENT "crashy" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BLOCK_EXPR + STMT_LIST + L_CURLY "{" + WHITESPACE " " + EXPR_STMT + RETURN_EXPR + RETURN_KW "return" + SEMICOLON ";" + WHITESPACE " " + R_CURLY "}" + WHITESPACE "\n " + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + R_CURLY "}" + WHITESPACE "\n" +error 41: expected COMMA +error 50: expected asm operand diff --git a/crates/parser/test_data/parser/inline/err/bad_asm_expr.rs b/crates/parser/test_data/parser/inline/err/bad_asm_expr.rs new file mode 100644 index 0000000000..6056f925e3 --- /dev/null +++ b/crates/parser/test_data/parser/inline/err/bad_asm_expr.rs @@ -0,0 +1,5 @@ +fn foo() { + builtin#asm( + label crashy = { return; } + ); +}