Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #18625 from Veykril/push-npnxwpxuzlqz
fix: Fix parser getting stuck for bad asm expressions
Lukas Wirth 2024-12-06
parent 150b0e7 · parent 4a24e72 · commit cddaf74
-rw-r--r--crates/parser/src/grammar/expressions/atom.rs18
-rw-r--r--crates/parser/test_data/generated/runner.rs2
-rw-r--r--crates/parser/test_data/parser/inline/err/bad_asm_expr.rast50
-rw-r--r--crates/parser/test_data/parser/inline/err/bad_asm_expr.rs5
4 files changed, 71 insertions, 4 deletions
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<CompletedMarker> {
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<CompletedMarker> {
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 0beaf1ae3a..003b7fda94 100644
--- a/crates/parser/test_data/generated/runner.rs
+++ b/crates/parser/test_data/generated/runner.rs
@@ -711,6 +711,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; }
+ );
+}