Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21588 from railgun-0402/fix/21582-asm-sym-accept-expr
Fix asm sym operand parsing for parenthesized expr fragments
5 files changed, 91 insertions, 1 deletions
diff --git a/crates/ide-diagnostics/src/handlers/typed_hole.rs b/crates/ide-diagnostics/src/handlers/typed_hole.rs index 577c582a20..fd1674e2a4 100644 --- a/crates/ide-diagnostics/src/handlers/typed_hole.rs +++ b/crates/ide-diagnostics/src/handlers/typed_hole.rs @@ -442,4 +442,30 @@ fn rdtscp() -> u64 { }"#, ); } + + #[test] + fn asm_sym_with_macro_expr_fragment() { + // Regression test for issue #21582 + // When `$e:expr` captures a path and is used in `sym $e`, the path gets + // wrapped in parentheses during macro expansion due to invisible delimiters. + // This should not cause false positive typed-hole errors. + check_diagnostics( + r#" +//- minicore: asm +macro_rules! m { + ($e:expr) => { + core::arch::asm!("/*{f}*/", f = sym $e, out("ax") _) + }; +} + +fn generic<T>() {} + +fn main() { + unsafe { + m!(generic::<i32>); + } +} +"#, + ); + } } diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs index b75474ee2b..3214fd90f2 100644 --- a/crates/parser/src/grammar/expressions/atom.rs +++ b/crates/parser/src/grammar/expressions/atom.rs @@ -407,8 +407,18 @@ pub(crate) fn parse_asm_expr(p: &mut Parser<'_>, m: Marker) -> Option<CompletedM op.complete(p, ASM_CONST); op_n.complete(p, ASM_OPERAND_NAMED); } else if p.eat_contextual_kw(T![sym]) { + // test asm_sym_paren + // fn foo() { + // builtin#asm("", f = sym (foo::bar)); + // } dir_spec.abandon(p); - paths::type_path(p); + if p.at(T!['(']) { + p.bump(T!['(']); + paths::type_path(p); + p.expect(T![')']); + } else { + paths::type_path(p); + } op.complete(p, ASM_SYM); op_n.complete(p, ASM_OPERAND_NAMED); } else if allow_templates { diff --git a/crates/parser/test_data/generated/runner.rs b/crates/parser/test_data/generated/runner.rs index 9f919f6cea..4c001104fe 100644 --- a/crates/parser/test_data/generated/runner.rs +++ b/crates/parser/test_data/generated/runner.rs @@ -25,6 +25,8 @@ mod ok { #[test] fn asm_label() { run_and_expect_no_errors("test_data/parser/inline/ok/asm_label.rs"); } #[test] + fn asm_sym_paren() { run_and_expect_no_errors("test_data/parser/inline/ok/asm_sym_paren.rs"); } + #[test] fn assoc_const_eq() { run_and_expect_no_errors("test_data/parser/inline/ok/assoc_const_eq.rs"); } diff --git a/crates/parser/test_data/parser/inline/ok/asm_sym_paren.rast b/crates/parser/test_data/parser/inline/ok/asm_sym_paren.rast new file mode 100644 index 0000000000..d189f63f2a --- /dev/null +++ b/crates/parser/test_data/parser/inline/ok/asm_sym_paren.rast @@ -0,0 +1,49 @@ +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 "(" + LITERAL + STRING "\"\"" + COMMA "," + WHITESPACE " " + ASM_OPERAND_NAMED + NAME + IDENT "f" + WHITESPACE " " + EQ "=" + WHITESPACE " " + ASM_SYM + SYM_KW "sym" + WHITESPACE " " + L_PAREN "(" + PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + COLON2 "::" + PATH_SEGMENT + NAME_REF + IDENT "bar" + R_PAREN ")" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + R_CURLY "}" + WHITESPACE "\n" diff --git a/crates/parser/test_data/parser/inline/ok/asm_sym_paren.rs b/crates/parser/test_data/parser/inline/ok/asm_sym_paren.rs new file mode 100644 index 0000000000..7b2f80704c --- /dev/null +++ b/crates/parser/test_data/parser/inline/ok/asm_sym_paren.rs @@ -0,0 +1,3 @@ +fn foo() { + builtin#asm("", f = sym (foo::bar)); +} |