mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 14:51:48 +00:00
feat: Resolve builtin-attr and tools in ide layer
This commit is contained in:
parent
4691a0647b
commit
e58af219a4
15 changed files with 209 additions and 99 deletions
|
@ -2,35 +2,98 @@
|
|||
//!
|
||||
//! The actual definitions were copied from rustc's `compiler/rustc_feature/src/builtin_attrs.rs`.
|
||||
//!
|
||||
//! It was last synchronized with upstream commit 835150e70288535bc57bb624792229b9dc94991d.
|
||||
//! It was last synchronized with upstream commit ae90dcf0207c57c3034f00b07048d63f8b2363c8.
|
||||
//!
|
||||
//! The macros were adjusted to only expand to the attribute name, since that is all we need to do
|
||||
//! name resolution, and `BUILTIN_ATTRIBUTES` is almost entirely unchanged from the original, to
|
||||
//! ease updating.
|
||||
|
||||
use once_cell::sync::OnceCell;
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
/// Ignored attribute namespaces used by tools.
|
||||
pub const TOOL_MODULES: &[&str] = &["rustfmt", "clippy"];
|
||||
|
||||
type BuiltinAttribute = &'static str;
|
||||
pub struct BuiltinAttribute {
|
||||
pub name: &'static str,
|
||||
pub template: AttributeTemplate,
|
||||
}
|
||||
|
||||
/// A template that the attribute input must match.
|
||||
/// Only top-level shape (`#[attr]` vs `#[attr(...)]` vs `#[attr = ...]`) is considered now.
|
||||
pub struct AttributeTemplate {
|
||||
pub word: bool,
|
||||
pub list: Option<&'static str>,
|
||||
pub name_value_str: Option<&'static str>,
|
||||
}
|
||||
|
||||
static BUILTIN_LOOKUP_TABLE: OnceCell<FxHashMap<&'static str, usize>> = OnceCell::new();
|
||||
|
||||
pub fn find_builtin_attr_idx(name: &str) -> Option<usize> {
|
||||
BUILTIN_LOOKUP_TABLE
|
||||
.get_or_init(|| {
|
||||
INERT_ATTRIBUTES.iter().map(|attr| attr.name).enumerate().map(|(a, b)| (b, a)).collect()
|
||||
})
|
||||
.get(name)
|
||||
.copied()
|
||||
}
|
||||
|
||||
// impl AttributeTemplate {
|
||||
// const DEFAULT: AttributeTemplate =
|
||||
// AttributeTemplate { word: false, list: None, name_value_str: None };
|
||||
// }
|
||||
|
||||
/// A convenience macro for constructing attribute templates.
|
||||
/// E.g., `template!(Word, List: "description")` means that the attribute
|
||||
/// supports forms `#[attr]` and `#[attr(description)]`.
|
||||
macro_rules! template {
|
||||
(Word) => { template!(@ true, None, None) };
|
||||
(List: $descr: expr) => { template!(@ false, Some($descr), None) };
|
||||
(NameValueStr: $descr: expr) => { template!(@ false, None, Some($descr)) };
|
||||
(Word, List: $descr: expr) => { template!(@ true, Some($descr), None) };
|
||||
(Word, NameValueStr: $descr: expr) => { template!(@ true, None, Some($descr)) };
|
||||
(List: $descr1: expr, NameValueStr: $descr2: expr) => {
|
||||
template!(@ false, Some($descr1), Some($descr2))
|
||||
};
|
||||
(Word, List: $descr1: expr, NameValueStr: $descr2: expr) => {
|
||||
template!(@ true, Some($descr1), Some($descr2))
|
||||
};
|
||||
(@ $word: expr, $list: expr, $name_value_str: expr) => { AttributeTemplate {
|
||||
word: $word, list: $list, name_value_str: $name_value_str
|
||||
} };
|
||||
}
|
||||
|
||||
macro_rules! ungated {
|
||||
($attr:ident, $typ:expr, $tpl:expr $(,)?) => {
|
||||
stringify!($attr)
|
||||
BuiltinAttribute { name: stringify!($attr), template: $tpl }
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! gated {
|
||||
($attr:ident $($rest:tt)*) => {
|
||||
stringify!($attr)
|
||||
($attr:ident, $typ:expr, $tpl:expr, $gate:ident, $msg:expr $(,)?) => {
|
||||
BuiltinAttribute { name: stringify!($attr), template: $tpl }
|
||||
};
|
||||
($attr:ident, $typ:expr, $tpl:expr, $msg:expr $(,)?) => {
|
||||
BuiltinAttribute { name: stringify!($attr), template: $tpl }
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! rustc_attr {
|
||||
(TEST, $attr:ident $($rest:tt)*) => {
|
||||
stringify!($attr)
|
||||
(TEST, $attr:ident, $typ:expr, $tpl:expr $(,)?) => {
|
||||
rustc_attr!(
|
||||
$attr,
|
||||
$typ,
|
||||
$tpl,
|
||||
concat!(
|
||||
"the `#[",
|
||||
stringify!($attr),
|
||||
"]` attribute is just used for rustc unit tests \
|
||||
and will never be stable",
|
||||
),
|
||||
)
|
||||
};
|
||||
($attr:ident $($rest:tt)*) => {
|
||||
stringify!($attr)
|
||||
($attr:ident, $typ:expr, $tpl:expr, $msg:expr $(,)?) => {
|
||||
BuiltinAttribute { name: stringify!($attr), template: $tpl }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -158,8 +221,8 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
|
||||
// Plugins:
|
||||
// XXX Modified for use in rust-analyzer
|
||||
gated!(plugin_registrar),
|
||||
gated!(plugin),
|
||||
gated!(plugin_registrar, Normal, template!(Word), experimental!()),
|
||||
gated!(plugin, CrateLevel, template!(Word), experimental!()),
|
||||
|
||||
// Testing:
|
||||
gated!(allow_fail, Normal, template!(Word), experimental!(allow_fail)),
|
||||
|
@ -195,6 +258,12 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
),
|
||||
|
||||
gated!(cmse_nonsecure_entry, AssumedUsed, template!(Word), experimental!(cmse_nonsecure_entry)),
|
||||
// RFC 2632
|
||||
gated!(
|
||||
default_method_body_is_const, AssumedUsed, template!(Word), const_trait_impl,
|
||||
"`default_method_body_is_const` is a temporary placeholder for declaring default bodies \
|
||||
as `const`, which may be removed or renamed in the future."
|
||||
),
|
||||
|
||||
// ==========================================================================
|
||||
// Internal attributes: Stability, deprecation, and unsafe:
|
||||
|
@ -258,10 +327,6 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
),
|
||||
gated!(panic_runtime, AssumedUsed, template!(Word), experimental!(panic_runtime)),
|
||||
gated!(needs_panic_runtime, AssumedUsed, template!(Word), experimental!(needs_panic_runtime)),
|
||||
gated!(
|
||||
unwind, AssumedUsed, template!(List: "allowed|aborts"), unwind_attributes,
|
||||
experimental!(unwind),
|
||||
),
|
||||
gated!(
|
||||
compiler_builtins, AssumedUsed, template!(Word),
|
||||
"the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate \
|
||||
|
@ -287,7 +352,11 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
// Internal attributes, Macro related:
|
||||
// ==========================================================================
|
||||
|
||||
rustc_attr!(rustc_builtin_macro, AssumedUsed, template!(Word, NameValueStr: "name"), IMPL_DETAIL),
|
||||
rustc_attr!(
|
||||
rustc_builtin_macro, AssumedUsed,
|
||||
template!(Word, List: "name, /*opt*/ attributes(name1, name2, ...)"),
|
||||
IMPL_DETAIL,
|
||||
),
|
||||
rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), INTERNAL_UNSTABLE),
|
||||
rustc_attr!(
|
||||
rustc_macro_transparency, AssumedUsed,
|
||||
|
@ -344,7 +413,7 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
lang, Normal, template!(NameValueStr: "name"), lang_items,
|
||||
"language items are subject to change",
|
||||
),
|
||||
gated!(rustc_diagnostic_item), // XXX modified in rust-analyzer
|
||||
gated!(rustc_diagnostic_item, Normal, template!(NameValueStr: "name"), experimental!()), // XXX Modified for use in rust-analyzer
|
||||
gated!(
|
||||
// Used in resolve:
|
||||
prelude_import, AssumedUsed, template!(Word),
|
||||
|
@ -428,6 +497,7 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
rustc_attr!(TEST, rustc_dump_program_clauses, AssumedUsed, template!(Word)),
|
||||
rustc_attr!(TEST, rustc_dump_env_program_clauses, AssumedUsed, template!(Word)),
|
||||
rustc_attr!(TEST, rustc_object_lifetime_default, AssumedUsed, template!(Word)),
|
||||
rustc_attr!(TEST, rustc_dump_vtable, AssumedUsed, template!(Word)),
|
||||
rustc_attr!(TEST, rustc_dummy, Normal, template!(Word /* doesn't matter*/)),
|
||||
gated!(
|
||||
omit_gdb_pretty_printer_section, AssumedUsed, template!(Word),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue