diff options
| author | Lukas Wirth <lukastw97@gmail.com> | 2024-12-06 05:53:44 +0100 |
|---|---|---|
| committer | Lukas Wirth <lukastw97@gmail.com> | 2024-12-06 05:57:00 +0100 |
| commit | 3db9b1d943f7a665ea98a6dab40ece33375f4f99 (patch) | |
| tree | 3aebd3d945bb072318234a181c1c94780e37fb83 | |
| parent | 6ef7f8e01409884d160769d6a62ba3d82dfb0207 (diff) | |
| download | rust-3db9b1d943f7a665ea98a6dab40ece33375f4f99.tar.gz rust-3db9b1d943f7a665ea98a6dab40ece33375f4f99.zip | |
fix: Fix parser getting stuck for bad asm expressions
4 files changed, 71 insertions, 4 deletions
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs index cd2ce59f627..407320e1d08 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs index f9486f53c25..c4ffc6cadc8 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/bad_asm_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/bad_asm_expr.rast new file mode 100644 index 00000000000..306446e64dd --- /dev/null +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/bad_asm_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/bad_asm_expr.rs new file mode 100644 index 00000000000..6056f925e33 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/bad_asm_expr.rs @@ -0,0 +1,5 @@ +fn foo() { + builtin#asm( + label crashy = { return; } + ); +} |
