mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-29 19:17:12 +00:00
Make global_asm!() work
Because apparently, we were not accepting inline asm in item position, completely breaking it.
This commit is contained in:
parent
bd8087e86e
commit
95c04c4503
13 changed files with 58 additions and 36 deletions
|
|
@ -143,6 +143,8 @@ impl<'a> Ctx<'a> {
|
||||||
ast::Item::MacroRules(ast) => self.lower_macro_rules(ast)?.into(),
|
ast::Item::MacroRules(ast) => self.lower_macro_rules(ast)?.into(),
|
||||||
ast::Item::MacroDef(ast) => self.lower_macro_def(ast)?.into(),
|
ast::Item::MacroDef(ast) => self.lower_macro_def(ast)?.into(),
|
||||||
ast::Item::ExternBlock(ast) => self.lower_extern_block(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());
|
let attrs = RawAttrs::new(self.db, item, self.span_map());
|
||||||
self.add_attrs(mod_item.ast_id(), attrs);
|
self.add_attrs(mod_item.ast_id(), attrs);
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,9 @@ macro_rules! global_asm {() => {}}
|
||||||
#[rustc_builtin_macro]
|
#[rustc_builtin_macro]
|
||||||
macro_rules! naked_asm {() => {}}
|
macro_rules! naked_asm {() => {}}
|
||||||
|
|
||||||
// FIXME: This creates an error
|
global_asm! {
|
||||||
// global_asm! {
|
""
|
||||||
// ""
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
#[unsafe(naked)]
|
#[unsafe(naked)]
|
||||||
extern "C" fn foo() {
|
extern "C" fn foo() {
|
||||||
|
|
@ -64,10 +63,7 @@ macro_rules! global_asm {() => {}}
|
||||||
#[rustc_builtin_macro]
|
#[rustc_builtin_macro]
|
||||||
macro_rules! naked_asm {() => {}}
|
macro_rules! naked_asm {() => {}}
|
||||||
|
|
||||||
// FIXME: This creates an error
|
builtin #global_asm ("")
|
||||||
// global_asm! {
|
|
||||||
// ""
|
|
||||||
// }
|
|
||||||
|
|
||||||
#[unsafe(naked)]
|
#[unsafe(naked)]
|
||||||
extern "C" fn foo() {
|
extern "C" fn foo() {
|
||||||
|
|
|
||||||
|
|
@ -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(
|
pub fn resolver_for_scope(
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
owner: DefWithBodyId,
|
owner: DefWithBodyId,
|
||||||
|
|
|
||||||
|
|
@ -1441,9 +1441,11 @@ fn scope_for(
|
||||||
) -> Option<ScopeId> {
|
) -> Option<ScopeId> {
|
||||||
node.ancestors_with_macros(db)
|
node.ancestors_with_macros(db)
|
||||||
.take_while(|it| {
|
.take_while(|it| {
|
||||||
!ast::Item::can_cast(it.kind())
|
let kind = it.kind();
|
||||||
|| ast::MacroCall::can_cast(it.kind())
|
!ast::Item::can_cast(kind)
|
||||||
|| ast::Use::can_cast(it.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| it.map(ast::Expr::cast).transpose())
|
||||||
.filter_map(|it| source_map.node_expr(it.as_ref())?.as_expr())
|
.filter_map(|it| source_map.node_expr(it.as_ref())?.as_expr())
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use crate::grammar::attributes::ATTRIBUTE_FIRST;
|
||||||
|
|
||||||
use super::*;
|
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};
|
pub(crate) use atom::{block_expr, match_arm_list};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq)]
|
||||||
|
|
|
||||||
|
|
@ -328,7 +328,7 @@ fn builtin_expr(p: &mut Parser<'_>) -> Option<CompletedMarker> {
|
||||||
// tmp = out(reg) _,
|
// 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!['(']);
|
p.expect(T!['(']);
|
||||||
if expr(p).is_none() {
|
if expr(p).is_none() {
|
||||||
p.err_and_bump("expected asm template");
|
p.err_and_bump("expected asm template");
|
||||||
|
|
|
||||||
|
|
@ -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![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),
|
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),
|
_ => return Err(m),
|
||||||
};
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -300,6 +300,8 @@ mod ok {
|
||||||
run_and_expect_no_errors("test_data/parser/inline/ok/generic_param_list.rs");
|
run_and_expect_no_errors("test_data/parser/inline/ok/generic_param_list.rs");
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
|
fn global_asm() { run_and_expect_no_errors("test_data/parser/inline/ok/global_asm.rs"); }
|
||||||
|
#[test]
|
||||||
fn half_open_range_pat() {
|
fn half_open_range_pat() {
|
||||||
run_and_expect_no_errors("test_data/parser/inline/ok/half_open_range_pat.rs");
|
run_and_expect_no_errors("test_data/parser/inline/ok/half_open_range_pat.rs");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ SOURCE_FILE
|
||||||
R_PAREN ")"
|
R_PAREN ")"
|
||||||
SEMICOLON ";"
|
SEMICOLON ";"
|
||||||
WHITESPACE "\n "
|
WHITESPACE "\n "
|
||||||
EXPR_STMT
|
|
||||||
ASM_EXPR
|
ASM_EXPR
|
||||||
BUILTIN_KW "builtin"
|
BUILTIN_KW "builtin"
|
||||||
POUND "#"
|
POUND "#"
|
||||||
|
|
|
||||||
10
crates/parser/test_data/parser/inline/ok/global_asm.rast
Normal file
10
crates/parser/test_data/parser/inline/ok/global_asm.rast
Normal file
|
|
@ -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"
|
||||||
1
crates/parser/test_data/parser/inline/ok/global_asm.rs
Normal file
1
crates/parser/test_data/parser/inline/ok/global_asm.rs
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
builtin#global_asm("")
|
||||||
|
|
@ -158,6 +158,7 @@ Item =
|
||||||
| TypeAlias
|
| TypeAlias
|
||||||
| Union
|
| Union
|
||||||
| Use
|
| Use
|
||||||
|
| AsmExpr
|
||||||
|
|
||||||
MacroRules =
|
MacroRules =
|
||||||
Attr* Visibility?
|
Attr* Visibility?
|
||||||
|
|
|
||||||
|
|
@ -2095,6 +2095,7 @@ impl ast::HasAttrs for GenericParam {}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum Item {
|
pub enum Item {
|
||||||
|
AsmExpr(AsmExpr),
|
||||||
Const(Const),
|
Const(Const),
|
||||||
Enum(Enum),
|
Enum(Enum),
|
||||||
ExternBlock(ExternBlock),
|
ExternBlock(ExternBlock),
|
||||||
|
|
@ -2114,7 +2115,6 @@ pub enum Item {
|
||||||
Use(Use),
|
Use(Use),
|
||||||
}
|
}
|
||||||
impl ast::HasAttrs for Item {}
|
impl ast::HasAttrs for Item {}
|
||||||
impl ast::HasDocComments for Item {}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum Pat {
|
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 {
|
impl From<Const> for Item {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(node: Const) -> Item { Item::Const(node) }
|
fn from(node: Const) -> Item { Item::Const(node) }
|
||||||
|
|
@ -8490,7 +8494,8 @@ impl AstNode for Item {
|
||||||
fn can_cast(kind: SyntaxKind) -> bool {
|
fn can_cast(kind: SyntaxKind) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
kind,
|
kind,
|
||||||
CONST
|
ASM_EXPR
|
||||||
|
| CONST
|
||||||
| ENUM
|
| ENUM
|
||||||
| EXTERN_BLOCK
|
| EXTERN_BLOCK
|
||||||
| EXTERN_CRATE
|
| EXTERN_CRATE
|
||||||
|
|
@ -8512,6 +8517,7 @@ impl AstNode for Item {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||||
let res = match syntax.kind() {
|
let res = match syntax.kind() {
|
||||||
|
ASM_EXPR => Item::AsmExpr(AsmExpr { syntax }),
|
||||||
CONST => Item::Const(Const { syntax }),
|
CONST => Item::Const(Const { syntax }),
|
||||||
ENUM => Item::Enum(Enum { syntax }),
|
ENUM => Item::Enum(Enum { syntax }),
|
||||||
EXTERN_BLOCK => Item::ExternBlock(ExternBlock { syntax }),
|
EXTERN_BLOCK => Item::ExternBlock(ExternBlock { syntax }),
|
||||||
|
|
@ -8536,6 +8542,7 @@ impl AstNode for Item {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn syntax(&self) -> &SyntaxNode {
|
fn syntax(&self) -> &SyntaxNode {
|
||||||
match self {
|
match self {
|
||||||
|
Item::AsmExpr(it) => &it.syntax,
|
||||||
Item::Const(it) => &it.syntax,
|
Item::Const(it) => &it.syntax,
|
||||||
Item::Enum(it) => &it.syntax,
|
Item::Enum(it) => &it.syntax,
|
||||||
Item::ExternBlock(it) => &it.syntax,
|
Item::ExternBlock(it) => &it.syntax,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue