mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-29 10:58:02 +00:00
Merge pull request #20210 from ChayimFriedman2/naked-asm-safe
fix: Inline asm fixes
This commit is contained in:
commit
e9968fc555
28 changed files with 303 additions and 84 deletions
|
|
@ -10,7 +10,7 @@ use tt::TextRange;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
expr_store::lower::{ExprCollector, FxIndexSet},
|
expr_store::lower::{ExprCollector, FxIndexSet},
|
||||||
hir::{AsmOperand, AsmOptions, Expr, ExprId, InlineAsm, InlineAsmRegOrRegClass},
|
hir::{AsmOperand, AsmOptions, Expr, ExprId, InlineAsm, InlineAsmKind, InlineAsmRegOrRegClass},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl ExprCollector<'_> {
|
impl ExprCollector<'_> {
|
||||||
|
|
@ -269,8 +269,17 @@ impl ExprCollector<'_> {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let kind = if asm.global_asm_token().is_some() {
|
||||||
|
InlineAsmKind::GlobalAsm
|
||||||
|
} else if asm.naked_asm_token().is_some() {
|
||||||
|
InlineAsmKind::NakedAsm
|
||||||
|
} else {
|
||||||
|
InlineAsmKind::Asm
|
||||||
|
};
|
||||||
|
|
||||||
let idx = self.alloc_expr(
|
let idx = self.alloc_expr(
|
||||||
Expr::InlineAsm(InlineAsm { operands: operands.into_boxed_slice(), options }),
|
Expr::InlineAsm(InlineAsm { operands: operands.into_boxed_slice(), options, kind }),
|
||||||
syntax_ptr,
|
syntax_ptr,
|
||||||
);
|
);
|
||||||
self.source_map
|
self.source_map
|
||||||
|
|
|
||||||
|
|
@ -332,6 +332,17 @@ pub struct OffsetOf {
|
||||||
pub struct InlineAsm {
|
pub struct InlineAsm {
|
||||||
pub operands: Box<[(Option<Name>, AsmOperand)]>,
|
pub operands: Box<[(Option<Name>, AsmOperand)]>,
|
||||||
pub options: AsmOptions,
|
pub options: AsmOptions,
|
||||||
|
pub kind: InlineAsmKind,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub enum InlineAsmKind {
|
||||||
|
/// `asm!()`.
|
||||||
|
Asm,
|
||||||
|
/// `global_asm!()`.
|
||||||
|
GlobalAsm,
|
||||||
|
/// `naked_asm!()`.
|
||||||
|
NakedAsm,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -35,10 +35,10 @@ use a::{c, d::{e}};
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![doc = " another file comment"]
|
#![doc = " another file comment"]
|
||||||
|
|
||||||
// AstId: ExternCrate[5A82, 0]
|
// AstId: ExternCrate[070B, 0]
|
||||||
pub(self) extern crate self as renamed;
|
pub(self) extern crate self as renamed;
|
||||||
|
|
||||||
// AstId: ExternCrate[7E1C, 0]
|
// AstId: ExternCrate[1EA5, 0]
|
||||||
pub(in super) extern crate bli;
|
pub(in super) extern crate bli;
|
||||||
|
|
||||||
// AstId: Use[0000, 0]
|
// AstId: Use[0000, 0]
|
||||||
|
|
@ -78,15 +78,15 @@ extern "C" {
|
||||||
// AstId: ExternBlock[0000, 0]
|
// AstId: ExternBlock[0000, 0]
|
||||||
extern {
|
extern {
|
||||||
#[on_extern_type]
|
#[on_extern_type]
|
||||||
// AstId: TypeAlias[9FDF, 0]
|
// AstId: TypeAlias[A09C, 0]
|
||||||
pub(self) type ExType;
|
pub(self) type ExType;
|
||||||
|
|
||||||
#[on_extern_static]
|
#[on_extern_static]
|
||||||
// AstId: Static[43C1, 0]
|
// AstId: Static[D85E, 0]
|
||||||
pub(self) static EX_STATIC = _;
|
pub(self) static EX_STATIC = _;
|
||||||
|
|
||||||
#[on_extern_fn]
|
#[on_extern_fn]
|
||||||
// AstId: Fn[452D, 0]
|
// AstId: Fn[B240, 0]
|
||||||
pub(self) fn ex_fn;
|
pub(self) fn ex_fn;
|
||||||
}
|
}
|
||||||
"#]],
|
"#]],
|
||||||
|
|
@ -124,20 +124,20 @@ enum E {
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
// AstId: Struct[DFF3, 0]
|
// AstId: Struct[ED35, 0]
|
||||||
pub(self) struct Unit;
|
pub(self) struct Unit;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
// AstId: Struct[C7A1, 0]
|
// AstId: Struct[A47C, 0]
|
||||||
pub(self) struct Struct { ... }
|
pub(self) struct Struct { ... }
|
||||||
|
|
||||||
// AstId: Struct[DAC2, 0]
|
// AstId: Struct[C8C9, 0]
|
||||||
pub(self) struct Tuple(...);
|
pub(self) struct Tuple(...);
|
||||||
|
|
||||||
// AstId: Union[2DBB, 0]
|
// AstId: Union[2797, 0]
|
||||||
pub(self) union Ize { ... }
|
pub(self) union Ize { ... }
|
||||||
|
|
||||||
// AstId: Enum[7FF8, 0]
|
// AstId: Enum[7D23, 0]
|
||||||
pub(self) enum E { ... }
|
pub(self) enum E { ... }
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
|
|
@ -162,18 +162,18 @@ trait Tr: SuperTrait + 'lifetime {
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
// AstId: Static[B393, 0]
|
// AstId: Static[F7C1, 0]
|
||||||
pub static ST = _;
|
pub static ST = _;
|
||||||
|
|
||||||
// AstId: Const[B309, 0]
|
// AstId: Const[84BB, 0]
|
||||||
pub(self) const _ = _;
|
pub(self) const _ = _;
|
||||||
|
|
||||||
#[attr]
|
#[attr]
|
||||||
#[inner_attr_in_fn]
|
#[inner_attr_in_fn]
|
||||||
// AstId: Fn[75E3, 0]
|
// AstId: Fn[BE8F, 0]
|
||||||
pub(self) fn f;
|
pub(self) fn f;
|
||||||
|
|
||||||
// AstId: Trait[2998, 0]
|
// AstId: Trait[9320, 0]
|
||||||
pub(self) trait Tr { ... }
|
pub(self) trait Tr { ... }
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
|
|
@ -197,16 +197,16 @@ mod outline;
|
||||||
expect![[r##"
|
expect![[r##"
|
||||||
#[doc = " outer"]
|
#[doc = " outer"]
|
||||||
#[doc = " inner"]
|
#[doc = " inner"]
|
||||||
// AstId: Module[CF93, 0]
|
// AstId: Module[03AE, 0]
|
||||||
pub(self) mod inline {
|
pub(self) mod inline {
|
||||||
// AstId: Use[0000, 0]
|
// AstId: Use[0000, 0]
|
||||||
pub(self) use super::*;
|
pub(self) use super::*;
|
||||||
|
|
||||||
// AstId: Fn[1B26, 0]
|
// AstId: Fn[2A78, 0]
|
||||||
pub(self) fn fn_in_module;
|
pub(self) fn fn_in_module;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AstId: Module[8994, 0]
|
// AstId: Module[C08B, 0]
|
||||||
pub(self) mod outline;
|
pub(self) mod outline;
|
||||||
"##]],
|
"##]],
|
||||||
);
|
);
|
||||||
|
|
@ -225,13 +225,13 @@ pub macro m2() {}
|
||||||
m!();
|
m!();
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
// AstId: MacroRules[88CE, 0]
|
// AstId: MacroRules[7E68, 0]
|
||||||
macro_rules! m { ... }
|
macro_rules! m { ... }
|
||||||
|
|
||||||
// AstId: MacroDef[DC34, 0]
|
// AstId: MacroDef[1C1E, 0]
|
||||||
pub macro m2 { ... }
|
pub macro m2 { ... }
|
||||||
|
|
||||||
// AstId: MacroCall[612F, 0], SyntaxContextId: ROOT2024, ExpandTo: Items
|
// AstId: MacroCall[7E68, 0], SyntaxContextId: ROOT2024, ExpandTo: Items
|
||||||
m!(...);
|
m!(...);
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
|
|
@ -244,7 +244,7 @@ fn pub_self() {
|
||||||
pub(self) struct S;
|
pub(self) struct S;
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
// AstId: Struct[42E2, 0]
|
// AstId: Struct[5024, 0]
|
||||||
pub(self) struct S;
|
pub(self) struct S;
|
||||||
"#]],
|
"#]],
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,19 @@ fn test_asm_expand() {
|
||||||
r#"
|
r#"
|
||||||
#[rustc_builtin_macro]
|
#[rustc_builtin_macro]
|
||||||
macro_rules! asm {() => {}}
|
macro_rules! asm {() => {}}
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
macro_rules! global_asm {() => {}}
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
macro_rules! naked_asm {() => {}}
|
||||||
|
|
||||||
|
global_asm! {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unsafe(naked)]
|
||||||
|
extern "C" fn foo() {
|
||||||
|
naked_asm!("");
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let i: u64 = 3;
|
let i: u64 = 3;
|
||||||
|
|
@ -45,6 +58,17 @@ fn main() {
|
||||||
expect![[r##"
|
expect![[r##"
|
||||||
#[rustc_builtin_macro]
|
#[rustc_builtin_macro]
|
||||||
macro_rules! asm {() => {}}
|
macro_rules! asm {() => {}}
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
macro_rules! global_asm {() => {}}
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
macro_rules! naked_asm {() => {}}
|
||||||
|
|
||||||
|
builtin #global_asm ("")
|
||||||
|
|
||||||
|
#[unsafe(naked)]
|
||||||
|
extern "C" fn foo() {
|
||||||
|
builtin #naked_asm ("");
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let i: u64 = 3;
|
let i: u64 = 3;
|
||||||
|
|
|
||||||
|
|
@ -35,9 +35,9 @@ macro_rules! f {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
struct#0:MacroRules[8C8E, 0]@58..64#14336# MyTraitMap2#0:MacroCall[D499, 0]@31..42#ROOT2024# {#0:MacroRules[8C8E, 0]@72..73#14336#
|
struct#0:MacroRules[BE8F, 0]@58..64#14336# MyTraitMap2#0:MacroCall[BE8F, 0]@31..42#ROOT2024# {#0:MacroRules[BE8F, 0]@72..73#14336#
|
||||||
map#0:MacroRules[8C8E, 0]@86..89#14336#:#0:MacroRules[8C8E, 0]@89..90#14336# #0:MacroRules[8C8E, 0]@89..90#14336#::#0:MacroRules[8C8E, 0]@91..93#14336#std#0:MacroRules[8C8E, 0]@93..96#14336#::#0:MacroRules[8C8E, 0]@96..98#14336#collections#0:MacroRules[8C8E, 0]@98..109#14336#::#0:MacroRules[8C8E, 0]@109..111#14336#HashSet#0:MacroRules[8C8E, 0]@111..118#14336#<#0:MacroRules[8C8E, 0]@118..119#14336#(#0:MacroRules[8C8E, 0]@119..120#14336#)#0:MacroRules[8C8E, 0]@120..121#14336#>#0:MacroRules[8C8E, 0]@121..122#14336#,#0:MacroRules[8C8E, 0]@122..123#14336#
|
map#0:MacroRules[BE8F, 0]@86..89#14336#:#0:MacroRules[BE8F, 0]@89..90#14336# #0:MacroRules[BE8F, 0]@89..90#14336#::#0:MacroRules[BE8F, 0]@91..93#14336#std#0:MacroRules[BE8F, 0]@93..96#14336#::#0:MacroRules[BE8F, 0]@96..98#14336#collections#0:MacroRules[BE8F, 0]@98..109#14336#::#0:MacroRules[BE8F, 0]@109..111#14336#HashSet#0:MacroRules[BE8F, 0]@111..118#14336#<#0:MacroRules[BE8F, 0]@118..119#14336#(#0:MacroRules[BE8F, 0]@119..120#14336#)#0:MacroRules[BE8F, 0]@120..121#14336#>#0:MacroRules[BE8F, 0]@121..122#14336#,#0:MacroRules[BE8F, 0]@122..123#14336#
|
||||||
}#0:MacroRules[8C8E, 0]@132..133#14336#
|
}#0:MacroRules[BE8F, 0]@132..133#14336#
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -75,12 +75,12 @@ macro_rules! f {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn#0:MacroCall[D499, 0]@30..32#ROOT2024# main#0:MacroCall[D499, 0]@33..37#ROOT2024#(#0:MacroCall[D499, 0]@37..38#ROOT2024#)#0:MacroCall[D499, 0]@38..39#ROOT2024# {#0:MacroCall[D499, 0]@40..41#ROOT2024#
|
fn#0:MacroCall[BE8F, 0]@30..32#ROOT2024# main#0:MacroCall[BE8F, 0]@33..37#ROOT2024#(#0:MacroCall[BE8F, 0]@37..38#ROOT2024#)#0:MacroCall[BE8F, 0]@38..39#ROOT2024# {#0:MacroCall[BE8F, 0]@40..41#ROOT2024#
|
||||||
1#0:MacroCall[D499, 0]@50..51#ROOT2024#;#0:MacroCall[D499, 0]@51..52#ROOT2024#
|
1#0:MacroCall[BE8F, 0]@50..51#ROOT2024#;#0:MacroCall[BE8F, 0]@51..52#ROOT2024#
|
||||||
1.0#0:MacroCall[D499, 0]@61..64#ROOT2024#;#0:MacroCall[D499, 0]@64..65#ROOT2024#
|
1.0#0:MacroCall[BE8F, 0]@61..64#ROOT2024#;#0:MacroCall[BE8F, 0]@64..65#ROOT2024#
|
||||||
(#0:MacroCall[D499, 0]@74..75#ROOT2024#(#0:MacroCall[D499, 0]@75..76#ROOT2024#1#0:MacroCall[D499, 0]@76..77#ROOT2024#,#0:MacroCall[D499, 0]@77..78#ROOT2024# )#0:MacroCall[D499, 0]@78..79#ROOT2024#,#0:MacroCall[D499, 0]@79..80#ROOT2024# )#0:MacroCall[D499, 0]@80..81#ROOT2024#.#0:MacroCall[D499, 0]@81..82#ROOT2024#0#0:MacroCall[D499, 0]@82..85#ROOT2024#.#0:MacroCall[D499, 0]@82..85#ROOT2024#0#0:MacroCall[D499, 0]@82..85#ROOT2024#;#0:MacroCall[D499, 0]@85..86#ROOT2024#
|
(#0:MacroCall[BE8F, 0]@74..75#ROOT2024#(#0:MacroCall[BE8F, 0]@75..76#ROOT2024#1#0:MacroCall[BE8F, 0]@76..77#ROOT2024#,#0:MacroCall[BE8F, 0]@77..78#ROOT2024# )#0:MacroCall[BE8F, 0]@78..79#ROOT2024#,#0:MacroCall[BE8F, 0]@79..80#ROOT2024# )#0:MacroCall[BE8F, 0]@80..81#ROOT2024#.#0:MacroCall[BE8F, 0]@81..82#ROOT2024#0#0:MacroCall[BE8F, 0]@82..85#ROOT2024#.#0:MacroCall[BE8F, 0]@82..85#ROOT2024#0#0:MacroCall[BE8F, 0]@82..85#ROOT2024#;#0:MacroCall[BE8F, 0]@85..86#ROOT2024#
|
||||||
let#0:MacroCall[D499, 0]@95..98#ROOT2024# x#0:MacroCall[D499, 0]@99..100#ROOT2024# =#0:MacroCall[D499, 0]@101..102#ROOT2024# 1#0:MacroCall[D499, 0]@103..104#ROOT2024#;#0:MacroCall[D499, 0]@104..105#ROOT2024#
|
let#0:MacroCall[BE8F, 0]@95..98#ROOT2024# x#0:MacroCall[BE8F, 0]@99..100#ROOT2024# =#0:MacroCall[BE8F, 0]@101..102#ROOT2024# 1#0:MacroCall[BE8F, 0]@103..104#ROOT2024#;#0:MacroCall[BE8F, 0]@104..105#ROOT2024#
|
||||||
}#0:MacroCall[D499, 0]@110..111#ROOT2024#
|
}#0:MacroCall[BE8F, 0]@110..111#ROOT2024#
|
||||||
|
|
||||||
|
|
||||||
"#]],
|
"#]],
|
||||||
|
|
@ -171,7 +171,7 @@ fn main(foo: ()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main(foo: ()) {
|
fn main(foo: ()) {
|
||||||
/* error: unresolved macro unresolved */"helloworld!"#0:Fn[B9C7, 0]@236..321#ROOT2024#;
|
/* error: unresolved macro unresolved */"helloworld!"#0:Fn[15AE, 0]@236..321#ROOT2024#;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -197,7 +197,7 @@ macro_rules! mk_struct {
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod foo;
|
mod foo;
|
||||||
|
|
||||||
struct#1:MacroRules[E572, 0]@59..65#14336# Foo#0:MacroCall[BDD3, 0]@32..35#ROOT2024#(#1:MacroRules[E572, 0]@70..71#14336#u32#0:MacroCall[BDD3, 0]@41..44#ROOT2024#)#1:MacroRules[E572, 0]@74..75#14336#;#1:MacroRules[E572, 0]@75..76#14336#
|
struct#1:MacroRules[DB0C, 0]@59..65#14336# Foo#0:MacroCall[DB0C, 0]@32..35#ROOT2024#(#1:MacroRules[DB0C, 0]@70..71#14336#u32#0:MacroCall[DB0C, 0]@41..44#ROOT2024#)#1:MacroRules[DB0C, 0]@74..75#14336#;#1:MacroRules[DB0C, 0]@75..76#14336#
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -181,9 +181,9 @@ fn foo(&self) {
|
||||||
self.0. 1;
|
self.0. 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn#0:Fn[4D85, 0]@45..47#ROOT2024# foo#0:Fn[4D85, 0]@48..51#ROOT2024#(#0:Fn[4D85, 0]@51..52#ROOT2024#�:Fn[4D85, 0]@52..53#ROOT2024#self#0:Fn[4D85, 0]@53..57#ROOT2024# )#0:Fn[4D85, 0]@57..58#ROOT2024# {#0:Fn[4D85, 0]@59..60#ROOT2024#
|
fn#0:Fn[8A31, 0]@45..47#ROOT2024# foo#0:Fn[8A31, 0]@48..51#ROOT2024#(#0:Fn[8A31, 0]@51..52#ROOT2024#�:Fn[8A31, 0]@52..53#ROOT2024#self#0:Fn[8A31, 0]@53..57#ROOT2024# )#0:Fn[8A31, 0]@57..58#ROOT2024# {#0:Fn[8A31, 0]@59..60#ROOT2024#
|
||||||
self#0:Fn[4D85, 0]@65..69#ROOT2024# .#0:Fn[4D85, 0]@69..70#ROOT2024#0#0:Fn[4D85, 0]@70..71#ROOT2024#.#0:Fn[4D85, 0]@71..72#ROOT2024#1#0:Fn[4D85, 0]@73..74#ROOT2024#;#0:Fn[4D85, 0]@74..75#ROOT2024#
|
self#0:Fn[8A31, 0]@65..69#ROOT2024# .#0:Fn[8A31, 0]@69..70#ROOT2024#0#0:Fn[8A31, 0]@70..71#ROOT2024#.#0:Fn[8A31, 0]@71..72#ROOT2024#1#0:Fn[8A31, 0]@73..74#ROOT2024#;#0:Fn[8A31, 0]@74..75#ROOT2024#
|
||||||
}#0:Fn[4D85, 0]@76..77#ROOT2024#"#]],
|
}#0:Fn[8A31, 0]@76..77#ROOT2024#"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -125,8 +125,8 @@ register_builtin! {
|
||||||
(assert, Assert) => assert_expand,
|
(assert, Assert) => assert_expand,
|
||||||
(stringify, Stringify) => stringify_expand,
|
(stringify, Stringify) => stringify_expand,
|
||||||
(asm, Asm) => asm_expand,
|
(asm, Asm) => asm_expand,
|
||||||
(global_asm, GlobalAsm) => asm_expand,
|
(global_asm, GlobalAsm) => global_asm_expand,
|
||||||
(naked_asm, NakedAsm) => asm_expand,
|
(naked_asm, NakedAsm) => naked_asm_expand,
|
||||||
(cfg, Cfg) => cfg_expand,
|
(cfg, Cfg) => cfg_expand,
|
||||||
(core_panic, CorePanic) => panic_expand,
|
(core_panic, CorePanic) => panic_expand,
|
||||||
(std_panic, StdPanic) => panic_expand,
|
(std_panic, StdPanic) => panic_expand,
|
||||||
|
|
@ -325,6 +325,36 @@ fn asm_expand(
|
||||||
ExpandResult::ok(expanded)
|
ExpandResult::ok(expanded)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn global_asm_expand(
|
||||||
|
_db: &dyn ExpandDatabase,
|
||||||
|
_id: MacroCallId,
|
||||||
|
tt: &tt::TopSubtree,
|
||||||
|
span: Span,
|
||||||
|
) -> ExpandResult<tt::TopSubtree> {
|
||||||
|
let mut tt = tt.clone();
|
||||||
|
tt.top_subtree_delimiter_mut().kind = tt::DelimiterKind::Parenthesis;
|
||||||
|
let pound = mk_pound(span);
|
||||||
|
let expanded = quote! {span =>
|
||||||
|
builtin #pound global_asm #tt
|
||||||
|
};
|
||||||
|
ExpandResult::ok(expanded)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn naked_asm_expand(
|
||||||
|
_db: &dyn ExpandDatabase,
|
||||||
|
_id: MacroCallId,
|
||||||
|
tt: &tt::TopSubtree,
|
||||||
|
span: Span,
|
||||||
|
) -> ExpandResult<tt::TopSubtree> {
|
||||||
|
let mut tt = tt.clone();
|
||||||
|
tt.top_subtree_delimiter_mut().kind = tt::DelimiterKind::Parenthesis;
|
||||||
|
let pound = mk_pound(span);
|
||||||
|
let expanded = quote! {span =>
|
||||||
|
builtin #pound naked_asm #tt
|
||||||
|
};
|
||||||
|
ExpandResult::ok(expanded)
|
||||||
|
}
|
||||||
|
|
||||||
fn cfg_expand(
|
fn cfg_expand(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
id: MacroCallId,
|
id: MacroCallId,
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use either::Either;
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
AdtId, DefWithBodyId, FieldId, FunctionId, VariantId,
|
AdtId, DefWithBodyId, FieldId, FunctionId, VariantId,
|
||||||
expr_store::{Body, path::Path},
|
expr_store::{Body, path::Path},
|
||||||
hir::{AsmOperand, Expr, ExprId, ExprOrPatId, Pat, PatId, Statement, UnaryOp},
|
hir::{AsmOperand, Expr, ExprId, ExprOrPatId, InlineAsmKind, Pat, PatId, Statement, UnaryOp},
|
||||||
resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs},
|
resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs},
|
||||||
signatures::StaticFlags,
|
signatures::StaticFlags,
|
||||||
type_ref::Rawness,
|
type_ref::Rawness,
|
||||||
|
|
@ -315,7 +315,12 @@ impl<'db> UnsafeVisitor<'db> {
|
||||||
self.inside_assignment = old_inside_assignment;
|
self.inside_assignment = old_inside_assignment;
|
||||||
}
|
}
|
||||||
Expr::InlineAsm(asm) => {
|
Expr::InlineAsm(asm) => {
|
||||||
|
if asm.kind == InlineAsmKind::Asm {
|
||||||
|
// `naked_asm!()` requires `unsafe` on the attribute (`#[unsafe(naked)]`),
|
||||||
|
// and `global_asm!()` doesn't require it at all.
|
||||||
self.on_unsafe_op(current.into(), UnsafetyReason::InlineAsm);
|
self.on_unsafe_op(current.into(), UnsafetyReason::InlineAsm);
|
||||||
|
}
|
||||||
|
|
||||||
asm.operands.iter().for_each(|(_, op)| match op {
|
asm.operands.iter().for_each(|(_, op)| match op {
|
||||||
AsmOperand::In { expr, .. }
|
AsmOperand::In { expr, .. }
|
||||||
| AsmOperand::Out { expr: Some(expr), .. }
|
| AsmOperand::Out { expr: Some(expr), .. }
|
||||||
|
|
|
||||||
|
|
@ -3222,7 +3222,8 @@ impl Macro {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_asm_or_global_asm(&self, db: &dyn HirDatabase) -> bool {
|
/// Is this `asm!()`, or a variant of it (e.g. `global_asm!()`)?
|
||||||
|
pub fn is_asm_like(&self, db: &dyn HirDatabase) -> bool {
|
||||||
match self.id {
|
match self.id {
|
||||||
MacroId::Macro2Id(it) => {
|
MacroId::Macro2Id(it) => {
|
||||||
matches!(it.lookup(db).expander, MacroExpander::BuiltIn(m) if m.is_asm())
|
matches!(it.lookup(db).expander, MacroExpander::BuiltIn(m) if m.is_asm())
|
||||||
|
|
|
||||||
|
|
@ -1776,7 +1776,7 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
|
|
||||||
pub fn is_unsafe_macro_call(&self, macro_call: &ast::MacroCall) -> bool {
|
pub fn is_unsafe_macro_call(&self, macro_call: &ast::MacroCall) -> bool {
|
||||||
let Some(mac) = self.resolve_macro_call(macro_call) else { return false };
|
let Some(mac) = self.resolve_macro_call(macro_call) else { return false };
|
||||||
if mac.is_asm_or_global_asm(self.db) {
|
if mac.is_asm_like(self.db) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1439,9 +1439,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())
|
||||||
|
|
|
||||||
|
|
@ -979,6 +979,21 @@ fn test() {
|
||||||
let foo = 10;
|
let foo = 10;
|
||||||
let bar = true;
|
let bar = true;
|
||||||
let _x = format_args!("{} {0} {} {last}", foo, bar, last = "!");
|
let _x = format_args!("{} {0} {} {last}", foo, bar, last = "!");
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn naked_asm_is_safe() {
|
||||||
|
check_diagnostics(
|
||||||
|
r#"
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
macro_rules! naked_asm { () => {} }
|
||||||
|
|
||||||
|
#[unsafe(naked)]
|
||||||
|
extern "C" fn naked() {
|
||||||
|
naked_asm!("");
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -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)]
|
||||||
|
|
|
||||||
|
|
@ -253,8 +253,7 @@ fn builtin_expr(p: &mut Parser<'_>) -> Option<CompletedMarker> {
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
p.bump_remap(T![builtin]);
|
p.bump_remap(T![builtin]);
|
||||||
p.bump(T![#]);
|
p.bump(T![#]);
|
||||||
if p.at_contextual_kw(T![offset_of]) {
|
if p.eat_contextual_kw(T![offset_of]) {
|
||||||
p.bump_remap(T![offset_of]);
|
|
||||||
p.expect(T!['(']);
|
p.expect(T!['(']);
|
||||||
type_(p);
|
type_(p);
|
||||||
p.expect(T![,]);
|
p.expect(T![,]);
|
||||||
|
|
@ -278,8 +277,7 @@ fn builtin_expr(p: &mut Parser<'_>) -> Option<CompletedMarker> {
|
||||||
p.expect(T![')']);
|
p.expect(T![')']);
|
||||||
}
|
}
|
||||||
Some(m.complete(p, OFFSET_OF_EXPR))
|
Some(m.complete(p, OFFSET_OF_EXPR))
|
||||||
} else if p.at_contextual_kw(T![format_args]) {
|
} else if p.eat_contextual_kw(T![format_args]) {
|
||||||
p.bump_remap(T![format_args]);
|
|
||||||
p.expect(T!['(']);
|
p.expect(T!['(']);
|
||||||
expr(p);
|
expr(p);
|
||||||
if p.eat(T![,]) {
|
if p.eat(T![,]) {
|
||||||
|
|
@ -302,7 +300,16 @@ fn builtin_expr(p: &mut Parser<'_>) -> Option<CompletedMarker> {
|
||||||
}
|
}
|
||||||
p.expect(T![')']);
|
p.expect(T![')']);
|
||||||
Some(m.complete(p, FORMAT_ARGS_EXPR))
|
Some(m.complete(p, FORMAT_ARGS_EXPR))
|
||||||
} else if p.at_contextual_kw(T![asm]) {
|
} else if p.eat_contextual_kw(T![asm])
|
||||||
|
|| p.eat_contextual_kw(T![global_asm])
|
||||||
|
|| p.eat_contextual_kw(T![naked_asm])
|
||||||
|
{
|
||||||
|
// test asm_kinds
|
||||||
|
// fn foo() {
|
||||||
|
// builtin#asm("");
|
||||||
|
// builtin#global_asm("");
|
||||||
|
// builtin#naked_asm("");
|
||||||
|
// }
|
||||||
parse_asm_expr(p, m)
|
parse_asm_expr(p, m)
|
||||||
} else {
|
} else {
|
||||||
m.abandon(p);
|
m.abandon(p);
|
||||||
|
|
@ -321,8 +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.bump_remap(T![asm]);
|
|
||||||
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(())
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -21,6 +21,8 @@ mod ok {
|
||||||
#[test]
|
#[test]
|
||||||
fn asm_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/asm_expr.rs"); }
|
fn asm_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/asm_expr.rs"); }
|
||||||
#[test]
|
#[test]
|
||||||
|
fn asm_kinds() { run_and_expect_no_errors("test_data/parser/inline/ok/asm_kinds.rs"); }
|
||||||
|
#[test]
|
||||||
fn asm_label() { run_and_expect_no_errors("test_data/parser/inline/ok/asm_label.rs"); }
|
fn asm_label() { run_and_expect_no_errors("test_data/parser/inline/ok/asm_label.rs"); }
|
||||||
#[test]
|
#[test]
|
||||||
fn assoc_const_eq() {
|
fn assoc_const_eq() {
|
||||||
|
|
@ -298,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");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
48
crates/parser/test_data/parser/inline/ok/asm_kinds.rast
Normal file
48
crates/parser/test_data/parser/inline/ok/asm_kinds.rast
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
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 "\"\""
|
||||||
|
R_PAREN ")"
|
||||||
|
SEMICOLON ";"
|
||||||
|
WHITESPACE "\n "
|
||||||
|
ASM_EXPR
|
||||||
|
BUILTIN_KW "builtin"
|
||||||
|
POUND "#"
|
||||||
|
GLOBAL_ASM_KW "global_asm"
|
||||||
|
L_PAREN "("
|
||||||
|
LITERAL
|
||||||
|
STRING "\"\""
|
||||||
|
R_PAREN ")"
|
||||||
|
SEMICOLON ";"
|
||||||
|
WHITESPACE "\n "
|
||||||
|
EXPR_STMT
|
||||||
|
ASM_EXPR
|
||||||
|
BUILTIN_KW "builtin"
|
||||||
|
POUND "#"
|
||||||
|
NAKED_ASM_KW "naked_asm"
|
||||||
|
L_PAREN "("
|
||||||
|
LITERAL
|
||||||
|
STRING "\"\""
|
||||||
|
R_PAREN ")"
|
||||||
|
SEMICOLON ";"
|
||||||
|
WHITESPACE "\n"
|
||||||
|
R_CURLY "}"
|
||||||
|
WHITESPACE "\n"
|
||||||
5
crates/parser/test_data/parser/inline/ok/asm_kinds.rs
Normal file
5
crates/parser/test_data/parser/inline/ok/asm_kinds.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
fn foo() {
|
||||||
|
builtin#asm("");
|
||||||
|
builtin#global_asm("");
|
||||||
|
builtin#naked_asm("");
|
||||||
|
}
|
||||||
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("")
|
||||||
|
|
@ -880,7 +880,8 @@ fn main() {{}}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn diagnostics_dont_block_typing() {
|
fn diagnostics_dont_block_typing() {
|
||||||
if skip_slow_tests() {
|
if skip_slow_tests() || std::env::var("CI").is_ok() {
|
||||||
|
// FIXME: This test is failing too frequently (therefore we disable it on CI).
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,7 @@ impl fmt::Debug for ErasedFileAstId {
|
||||||
Use,
|
Use,
|
||||||
Impl,
|
Impl,
|
||||||
BlockExpr,
|
BlockExpr,
|
||||||
|
AsmExpr,
|
||||||
Fixup,
|
Fixup,
|
||||||
);
|
);
|
||||||
if f.alternate() {
|
if f.alternate() {
|
||||||
|
|
@ -144,6 +145,10 @@ enum ErasedFileAstIdKind {
|
||||||
Impl,
|
Impl,
|
||||||
/// Associated with [`BlockExprFileAstId`].
|
/// Associated with [`BlockExprFileAstId`].
|
||||||
BlockExpr,
|
BlockExpr,
|
||||||
|
// `global_asm!()` is an item, so we need to give it an `AstId`. So we give to all inline asm
|
||||||
|
// because incrementality is not a problem, they will always be the only item in the macro file,
|
||||||
|
// and memory usage also not because they're rare.
|
||||||
|
AsmExpr,
|
||||||
/// Keep this last.
|
/// Keep this last.
|
||||||
Root,
|
Root,
|
||||||
}
|
}
|
||||||
|
|
@ -204,14 +209,17 @@ impl ErasedFileAstId {
|
||||||
.or_else(|| extern_block_ast_id(node, index_map))
|
.or_else(|| extern_block_ast_id(node, index_map))
|
||||||
.or_else(|| use_ast_id(node, index_map))
|
.or_else(|| use_ast_id(node, index_map))
|
||||||
.or_else(|| impl_ast_id(node, index_map))
|
.or_else(|| impl_ast_id(node, index_map))
|
||||||
|
.or_else(|| asm_expr_ast_id(node, index_map))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn should_alloc(node: &SyntaxNode) -> bool {
|
fn should_alloc(node: &SyntaxNode) -> bool {
|
||||||
should_alloc_has_name(node)
|
let kind = node.kind();
|
||||||
|| should_alloc_assoc_item(node)
|
should_alloc_has_name(kind)
|
||||||
|| ast::ExternBlock::can_cast(node.kind())
|
|| should_alloc_assoc_item(kind)
|
||||||
|| ast::Use::can_cast(node.kind())
|
|| ast::ExternBlock::can_cast(kind)
|
||||||
|| ast::Impl::can_cast(node.kind())
|
|| ast::Use::can_cast(kind)
|
||||||
|
|| ast::Impl::can_cast(kind)
|
||||||
|
|| ast::AsmExpr::can_cast(kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
@ -278,7 +286,6 @@ impl<N> FileAstId<N> {
|
||||||
|
|
||||||
#[derive(Hash)]
|
#[derive(Hash)]
|
||||||
struct ErasedHasNameFileAstId<'a> {
|
struct ErasedHasNameFileAstId<'a> {
|
||||||
kind: SyntaxKind,
|
|
||||||
name: &'a str,
|
name: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -332,6 +339,19 @@ fn use_ast_id(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AstIdNode for ast::AsmExpr {}
|
||||||
|
|
||||||
|
fn asm_expr_ast_id(
|
||||||
|
node: &SyntaxNode,
|
||||||
|
index_map: &mut ErasedAstIdNextIndexMap,
|
||||||
|
) -> Option<ErasedFileAstId> {
|
||||||
|
if ast::AsmExpr::can_cast(node.kind()) {
|
||||||
|
Some(index_map.new_id(ErasedFileAstIdKind::AsmExpr, ()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl AstIdNode for ast::Impl {}
|
impl AstIdNode for ast::Impl {}
|
||||||
|
|
||||||
fn impl_ast_id(
|
fn impl_ast_id(
|
||||||
|
|
@ -433,7 +453,6 @@ macro_rules! register_has_name_ast_id {
|
||||||
)+
|
)+
|
||||||
|
|
||||||
fn has_name_ast_id(node: &SyntaxNode, index_map: &mut ErasedAstIdNextIndexMap) -> Option<ErasedFileAstId> {
|
fn has_name_ast_id(node: &SyntaxNode, index_map: &mut ErasedAstIdNextIndexMap) -> Option<ErasedFileAstId> {
|
||||||
let kind = node.kind();
|
|
||||||
match_ast! {
|
match_ast! {
|
||||||
match node {
|
match node {
|
||||||
$(
|
$(
|
||||||
|
|
@ -441,7 +460,6 @@ macro_rules! register_has_name_ast_id {
|
||||||
let name = node.$name_method();
|
let name = node.$name_method();
|
||||||
let name = name.as_ref().map_or("", |it| it.text_non_mutable());
|
let name = name.as_ref().map_or("", |it| it.text_non_mutable());
|
||||||
let result = ErasedHasNameFileAstId {
|
let result = ErasedHasNameFileAstId {
|
||||||
kind,
|
|
||||||
name,
|
name,
|
||||||
};
|
};
|
||||||
Some(index_map.new_id(ErasedFileAstIdKind::$ident, result))
|
Some(index_map.new_id(ErasedFileAstIdKind::$ident, result))
|
||||||
|
|
@ -452,8 +470,7 @@ macro_rules! register_has_name_ast_id {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn should_alloc_has_name(node: &SyntaxNode) -> bool {
|
fn should_alloc_has_name(kind: SyntaxKind) -> bool {
|
||||||
let kind = node.kind();
|
|
||||||
false $( || ast::$ident::can_cast(kind) )*
|
false $( || ast::$ident::can_cast(kind) )*
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -483,7 +500,6 @@ macro_rules! register_assoc_item_ast_id {
|
||||||
index_map: &mut ErasedAstIdNextIndexMap,
|
index_map: &mut ErasedAstIdNextIndexMap,
|
||||||
parent: Option<&ErasedFileAstId>,
|
parent: Option<&ErasedFileAstId>,
|
||||||
) -> Option<ErasedFileAstId> {
|
) -> Option<ErasedFileAstId> {
|
||||||
let kind = node.kind();
|
|
||||||
match_ast! {
|
match_ast! {
|
||||||
match node {
|
match node {
|
||||||
$(
|
$(
|
||||||
|
|
@ -491,7 +507,6 @@ macro_rules! register_assoc_item_ast_id {
|
||||||
let name = $name_callback(node);
|
let name = $name_callback(node);
|
||||||
let name = name.as_ref().map_or("", |it| it.text_non_mutable());
|
let name = name.as_ref().map_or("", |it| it.text_non_mutable());
|
||||||
let properties = ErasedHasNameFileAstId {
|
let properties = ErasedHasNameFileAstId {
|
||||||
kind,
|
|
||||||
name,
|
name,
|
||||||
};
|
};
|
||||||
let result = ErasedAssocItemFileAstId {
|
let result = ErasedAssocItemFileAstId {
|
||||||
|
|
@ -506,8 +521,7 @@ macro_rules! register_assoc_item_ast_id {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn should_alloc_assoc_item(node: &SyntaxNode) -> bool {
|
fn should_alloc_assoc_item(kind: SyntaxKind) -> bool {
|
||||||
let kind = node.kind();
|
|
||||||
false $( || ast::$ident::can_cast(kind) )*
|
false $( || ast::$ident::can_cast(kind) )*
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,7 @@ Item =
|
||||||
| TypeAlias
|
| TypeAlias
|
||||||
| Union
|
| Union
|
||||||
| Use
|
| Use
|
||||||
|
| AsmExpr
|
||||||
|
|
||||||
MacroRules =
|
MacroRules =
|
||||||
Attr* Visibility?
|
Attr* Visibility?
|
||||||
|
|
@ -409,7 +410,8 @@ OffsetOfExpr =
|
||||||
// global_asm := "global_asm!(" format_string *("," format_string) *("," operand) [","] ")"
|
// global_asm := "global_asm!(" format_string *("," format_string) *("," operand) [","] ")"
|
||||||
// format_string := STRING_LITERAL / RAW_STRING_LITERAL
|
// format_string := STRING_LITERAL / RAW_STRING_LITERAL
|
||||||
AsmExpr =
|
AsmExpr =
|
||||||
Attr* 'builtin' '#' 'asm' '(' template:(Expr (',' Expr)*) (AsmPiece (',' AsmPiece)*)? ','? ')'
|
Attr* 'builtin' '#' ( 'asm' | 'global_asm' | 'naked_asm' )
|
||||||
|
'(' template:(Expr (',' Expr)*) (AsmPiece (',' AsmPiece)*)? ','? ')'
|
||||||
|
|
||||||
// operand_expr := expr / "_" / expr "=>" expr / expr "=>" "_"
|
// operand_expr := expr / "_" / expr "=>" expr / expr "=>" "_"
|
||||||
AsmOperandExpr = in_expr:Expr ('=>' out_expr:Expr)?
|
AsmOperandExpr = in_expr:Expr ('=>' out_expr:Expr)?
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,14 @@ impl AsmExpr {
|
||||||
pub fn asm_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![asm]) }
|
pub fn asm_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![asm]) }
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn builtin_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![builtin]) }
|
pub fn builtin_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![builtin]) }
|
||||||
|
#[inline]
|
||||||
|
pub fn global_asm_token(&self) -> Option<SyntaxToken> {
|
||||||
|
support::token(&self.syntax, T![global_asm])
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn naked_asm_token(&self) -> Option<SyntaxToken> {
|
||||||
|
support::token(&self.syntax, T![naked_asm])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub struct AsmLabel {
|
pub struct AsmLabel {
|
||||||
pub(crate) syntax: SyntaxNode,
|
pub(crate) syntax: SyntaxNode,
|
||||||
|
|
@ -2087,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),
|
||||||
|
|
@ -2106,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 {
|
||||||
|
|
@ -8409,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) }
|
||||||
|
|
@ -8482,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
|
||||||
|
|
@ -8504,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 }),
|
||||||
|
|
@ -8528,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,
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,8 @@ const CONTEXTUAL_KEYWORDS: &[&str] =
|
||||||
// keywords we use for special macro expansions
|
// keywords we use for special macro expansions
|
||||||
const CONTEXTUAL_BUILTIN_KEYWORDS: &[&str] = &[
|
const CONTEXTUAL_BUILTIN_KEYWORDS: &[&str] = &[
|
||||||
"asm",
|
"asm",
|
||||||
|
"naked_asm",
|
||||||
|
"global_asm",
|
||||||
"att_syntax",
|
"att_syntax",
|
||||||
"builtin",
|
"builtin",
|
||||||
"clobber_abi",
|
"clobber_abi",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue