Unnamed repository; edit this file 'description' to name the repository.
Make `global_asm!()` work
Because apparently, we were not accepting inline asm in item position, completely breaking it.
Chayim Refael Friedman 10 months ago
parent bd8087e · commit 95c04c4
-rw-r--r--crates/hir-def/src/item_tree/lower.rs2
-rw-r--r--crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs12
-rw-r--r--crates/hir-def/src/resolver.rs11
-rw-r--r--crates/hir/src/source_analyzer.rs8
-rw-r--r--crates/parser/src/grammar/expressions.rs2
-rw-r--r--crates/parser/src/grammar/expressions/atom.rs2
-rw-r--r--crates/parser/src/grammar/items.rs13
-rw-r--r--crates/parser/test_data/generated/runner.rs2
-rw-r--r--crates/parser/test_data/parser/inline/ok/asm_kinds.rast19
-rw-r--r--crates/parser/test_data/parser/inline/ok/global_asm.rast10
-rw-r--r--crates/parser/test_data/parser/inline/ok/global_asm.rs1
-rw-r--r--crates/syntax/rust.ungram1
-rw-r--r--crates/syntax/src/ast/generated/nodes.rs11
13 files changed, 58 insertions, 36 deletions
diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs
index f327366715..5ab61c8939 100644
--- a/crates/hir-def/src/item_tree/lower.rs
+++ b/crates/hir-def/src/item_tree/lower.rs
@@ -143,6 +143,8 @@ impl<'a> Ctx<'a> {
ast::Item::MacroRules(ast) => self.lower_macro_rules(ast)?.into(),
ast::Item::MacroDef(ast) => self.lower_macro_def(ast)?.into(),
ast::Item::ExternBlock(ast) => self.lower_extern_block(ast).into(),
+ // FIXME: Handle `global_asm!()`.
+ ast::Item::AsmExpr(_) => return None,
};
let attrs = RawAttrs::new(self.db, item, self.span_map());
self.add_attrs(mod_item.ast_id(), attrs);
diff --git a/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs b/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
index a48a6be4d8..1c3af47d52 100644
--- a/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
+++ b/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
@@ -33,10 +33,9 @@ macro_rules! global_asm {() => {}}
#[rustc_builtin_macro]
macro_rules! naked_asm {() => {}}
-// FIXME: This creates an error
-// global_asm! {
-// ""
-// }
+global_asm! {
+ ""
+}
#[unsafe(naked)]
extern "C" fn foo() {
@@ -64,10 +63,7 @@ macro_rules! global_asm {() => {}}
#[rustc_builtin_macro]
macro_rules! naked_asm {() => {}}
-// FIXME: This creates an error
-// global_asm! {
-// ""
-// }
+builtin #global_asm ("")
#[unsafe(naked)]
extern "C" fn foo() {
diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs
index 6f321980af..316ad5dae6 100644
--- a/crates/hir-def/src/resolver.rs
+++ b/crates/hir-def/src/resolver.rs
@@ -1052,17 +1052,6 @@ impl<'db> Scope<'db> {
}
}
-pub fn resolver_for_expr(
- db: &dyn DefDatabase,
- owner: DefWithBodyId,
- expr_id: ExprId,
-) -> Resolver<'_> {
- let r = owner.resolver(db);
- let scopes = db.expr_scopes(owner);
- let scope_id = scopes.scope_for(expr_id);
- resolver_for_scope_(db, scopes, scope_id, r, owner)
-}
-
pub fn resolver_for_scope(
db: &dyn DefDatabase,
owner: DefWithBodyId,
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index cbd472f87a..536d3851e4 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -1441,9 +1441,11 @@ fn scope_for(
) -> Option<ScopeId> {
node.ancestors_with_macros(db)
.take_while(|it| {
- !ast::Item::can_cast(it.kind())
- || ast::MacroCall::can_cast(it.kind())
- || ast::Use::can_cast(it.kind())
+ let kind = it.kind();
+ !ast::Item::can_cast(kind)
+ || ast::MacroCall::can_cast(kind)
+ || ast::Use::can_cast(kind)
+ || ast::AsmExpr::can_cast(kind)
})
.filter_map(|it| it.map(ast::Expr::cast).transpose())
.filter_map(|it| source_map.node_expr(it.as_ref())?.as_expr())
diff --git a/crates/parser/src/grammar/expressions.rs b/crates/parser/src/grammar/expressions.rs
index 0ac25da329..2b4151e3b7 100644
--- a/crates/parser/src/grammar/expressions.rs
+++ b/crates/parser/src/grammar/expressions.rs
@@ -4,7 +4,7 @@ use crate::grammar::attributes::ATTRIBUTE_FIRST;
use super::*;
-pub(super) use atom::{EXPR_RECOVERY_SET, LITERAL_FIRST, literal};
+pub(super) use atom::{EXPR_RECOVERY_SET, LITERAL_FIRST, literal, parse_asm_expr};
pub(crate) use atom::{block_expr, match_arm_list};
#[derive(PartialEq, Eq)]
diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs
index b81a026173..a01021a9f7 100644
--- a/crates/parser/src/grammar/expressions/atom.rs
+++ b/crates/parser/src/grammar/expressions/atom.rs
@@ -328,7 +328,7 @@ fn builtin_expr(p: &mut Parser<'_>) -> Option<CompletedMarker> {
// tmp = out(reg) _,
// );
// }
-fn parse_asm_expr(p: &mut Parser<'_>, m: Marker) -> Option<CompletedMarker> {
+pub(crate) fn parse_asm_expr(p: &mut Parser<'_>, m: Marker) -> Option<CompletedMarker> {
p.expect(T!['(']);
if expr(p).is_none() {
p.err_and_bump("expected asm template");
diff --git a/crates/parser/src/grammar/items.rs b/crates/parser/src/grammar/items.rs
index b9f4866574..8e551b0b96 100644
--- a/crates/parser/src/grammar/items.rs
+++ b/crates/parser/src/grammar/items.rs
@@ -261,6 +261,19 @@ fn opt_item_without_modifiers(p: &mut Parser<'_>, m: Marker) -> Result<(), Marke
T![const] if (la == IDENT || la == T![_] || la == T![mut]) => consts::konst(p, m),
T![static] if (la == IDENT || la == T![_] || la == T![mut]) => consts::static_(p, m),
+ IDENT
+ if p.at_contextual_kw(T![builtin])
+ && p.nth_at(1, T![#])
+ && p.nth_at_contextual_kw(2, T![global_asm]) =>
+ {
+ p.bump_remap(T![builtin]);
+ p.bump(T![#]);
+ p.bump_remap(T![global_asm]);
+ // test global_asm
+ // builtin#global_asm("")
+ expressions::parse_asm_expr(p, m);
+ }
+
_ => return Err(m),
};
Ok(())
diff --git a/crates/parser/test_data/generated/runner.rs b/crates/parser/test_data/generated/runner.rs
index 8053d0b22d..cef7b0ee23 100644
--- a/crates/parser/test_data/generated/runner.rs
+++ b/crates/parser/test_data/generated/runner.rs
@@ -300,6 +300,8 @@ mod ok {
run_and_expect_no_errors("test_data/parser/inline/ok/generic_param_list.rs");
}
#[test]
+ fn global_asm() { run_and_expect_no_errors("test_data/parser/inline/ok/global_asm.rs"); }
+ #[test]
fn half_open_range_pat() {
run_and_expect_no_errors("test_data/parser/inline/ok/half_open_range_pat.rs");
}
diff --git a/crates/parser/test_data/parser/inline/ok/asm_kinds.rast b/crates/parser/test_data/parser/inline/ok/asm_kinds.rast
index fbf95d15f2..c337d89aa5 100644
--- a/crates/parser/test_data/parser/inline/ok/asm_kinds.rast
+++ b/crates/parser/test_data/parser/inline/ok/asm_kinds.rast
@@ -23,16 +23,15 @@ SOURCE_FILE
R_PAREN ")"
SEMICOLON ";"
WHITESPACE "\n "
- EXPR_STMT
- ASM_EXPR
- BUILTIN_KW "builtin"
- POUND "#"
- GLOBAL_ASM_KW "global_asm"
- L_PAREN "("
- LITERAL
- STRING "\"\""
- R_PAREN ")"
- SEMICOLON ";"
+ ASM_EXPR
+ BUILTIN_KW "builtin"
+ POUND "#"
+ GLOBAL_ASM_KW "global_asm"
+ L_PAREN "("
+ LITERAL
+ STRING "\"\""
+ R_PAREN ")"
+ SEMICOLON ";"
WHITESPACE "\n "
EXPR_STMT
ASM_EXPR
diff --git a/crates/parser/test_data/parser/inline/ok/global_asm.rast b/crates/parser/test_data/parser/inline/ok/global_asm.rast
new file mode 100644
index 0000000000..5337c56be1
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/ok/global_asm.rast
@@ -0,0 +1,10 @@
+SOURCE_FILE
+ ASM_EXPR
+ BUILTIN_KW "builtin"
+ POUND "#"
+ GLOBAL_ASM_KW "global_asm"
+ L_PAREN "("
+ LITERAL
+ STRING "\"\""
+ R_PAREN ")"
+ WHITESPACE "\n"
diff --git a/crates/parser/test_data/parser/inline/ok/global_asm.rs b/crates/parser/test_data/parser/inline/ok/global_asm.rs
new file mode 100644
index 0000000000..967ce1f5fd
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/ok/global_asm.rs
@@ -0,0 +1 @@
+builtin#global_asm("")
diff --git a/crates/syntax/rust.ungram b/crates/syntax/rust.ungram
index 88ecbb0ef0..4cbc88cfb5 100644
--- a/crates/syntax/rust.ungram
+++ b/crates/syntax/rust.ungram
@@ -158,6 +158,7 @@ Item =
| TypeAlias
| Union
| Use
+| AsmExpr
MacroRules =
Attr* Visibility?
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs
index e1e331d653..2b86246542 100644
--- a/crates/syntax/src/ast/generated/nodes.rs
+++ b/crates/syntax/src/ast/generated/nodes.rs
@@ -2095,6 +2095,7 @@ impl ast::HasAttrs for GenericParam {}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Item {
+ AsmExpr(AsmExpr),
Const(Const),
Enum(Enum),
ExternBlock(ExternBlock),
@@ -2114,7 +2115,6 @@ pub enum Item {
Use(Use),
}
impl ast::HasAttrs for Item {}
-impl ast::HasDocComments for Item {}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Pat {
@@ -8417,6 +8417,10 @@ impl AstNode for GenericParam {
}
}
}
+impl From<AsmExpr> for Item {
+ #[inline]
+ fn from(node: AsmExpr) -> Item { Item::AsmExpr(node) }
+}
impl From<Const> for Item {
#[inline]
fn from(node: Const) -> Item { Item::Const(node) }
@@ -8490,7 +8494,8 @@ impl AstNode for Item {
fn can_cast(kind: SyntaxKind) -> bool {
matches!(
kind,
- CONST
+ ASM_EXPR
+ | CONST
| ENUM
| EXTERN_BLOCK
| EXTERN_CRATE
@@ -8512,6 +8517,7 @@ impl AstNode for Item {
#[inline]
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
+ ASM_EXPR => Item::AsmExpr(AsmExpr { syntax }),
CONST => Item::Const(Const { syntax }),
ENUM => Item::Enum(Enum { syntax }),
EXTERN_BLOCK => Item::ExternBlock(ExternBlock { syntax }),
@@ -8536,6 +8542,7 @@ impl AstNode for Item {
#[inline]
fn syntax(&self) -> &SyntaxNode {
match self {
+ Item::AsmExpr(it) => &it.syntax,
Item::Const(it) => &it.syntax,
Item::Enum(it) => &it.syntax,
Item::ExternBlock(it) => &it.syntax,