mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-11 16:15:03 +00:00
Merge #10915
10915: feat: Resolve builtin-attr and tools in ide layer r=Veykril a=Veykril Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
commit
3f3289df2a
@ -103,6 +103,7 @@ pub use {
|
||||
hir_def::{
|
||||
adt::StructKind,
|
||||
attr::{Attr, Attrs, AttrsWithOwner, Documentation},
|
||||
builtin_attr::AttributeTemplate,
|
||||
find_path::PrefixKind,
|
||||
import_map,
|
||||
item_scope::ItemScope,
|
||||
@ -2023,6 +2024,40 @@ impl Local {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct BuiltinAttr(usize);
|
||||
|
||||
impl BuiltinAttr {
|
||||
pub(crate) fn by_name(name: &str) -> Option<Self> {
|
||||
// FIXME: def maps registered attrs?
|
||||
hir_def::builtin_attr::find_builtin_attr_idx(name).map(Self)
|
||||
}
|
||||
|
||||
pub fn name(&self, _: &dyn HirDatabase) -> &str {
|
||||
// FIXME: Return a `Name` here
|
||||
hir_def::builtin_attr::INERT_ATTRIBUTES[self.0].name
|
||||
}
|
||||
|
||||
pub fn template(&self, _: &dyn HirDatabase) -> AttributeTemplate {
|
||||
hir_def::builtin_attr::INERT_ATTRIBUTES[self.0].template
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ToolModule(usize);
|
||||
|
||||
impl ToolModule {
|
||||
pub(crate) fn by_name(name: &str) -> Option<Self> {
|
||||
// FIXME: def maps registered tools
|
||||
hir_def::builtin_attr::TOOL_MODULES.iter().position(|&tool| tool == name).map(Self)
|
||||
}
|
||||
|
||||
pub fn name(&self, _: &dyn HirDatabase) -> &str {
|
||||
// FIXME: Return a `Name` here
|
||||
hir_def::builtin_attr::TOOL_MODULES[self.0]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct Label {
|
||||
pub(crate) parent: DefWithBodyId,
|
||||
|
@ -25,9 +25,9 @@ use crate::{
|
||||
db::HirDatabase,
|
||||
semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
|
||||
source_analyzer::{resolve_hir_path, resolve_hir_path_as_macro, SourceAnalyzer},
|
||||
Access, AssocItem, Callable, ConstParam, Crate, Field, Function, HasSource, HirFileId, Impl,
|
||||
InFile, Label, LifetimeParam, Local, MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait,
|
||||
Type, TypeAlias, TypeParam, VariantDef,
|
||||
Access, AssocItem, BuiltinAttr, Callable, ConstParam, Crate, Field, Function, HasSource,
|
||||
HirFileId, Impl, InFile, Label, LifetimeParam, Local, MacroDef, Module, ModuleDef, Name, Path,
|
||||
ScopeDef, ToolModule, Trait, Type, TypeAlias, TypeParam, VariantDef,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
@ -43,6 +43,8 @@ pub enum PathResolution {
|
||||
SelfType(Impl),
|
||||
Macro(MacroDef),
|
||||
AssocItem(AssocItem),
|
||||
BuiltinAttr(BuiltinAttr),
|
||||
ToolModule(ToolModule),
|
||||
}
|
||||
|
||||
impl PathResolution {
|
||||
@ -63,9 +65,11 @@ impl PathResolution {
|
||||
PathResolution::Def(ModuleDef::TypeAlias(alias)) => {
|
||||
Some(TypeNs::TypeAliasId((*alias).into()))
|
||||
}
|
||||
PathResolution::Local(_) | PathResolution::Macro(_) | PathResolution::ConstParam(_) => {
|
||||
None
|
||||
}
|
||||
PathResolution::BuiltinAttr(_)
|
||||
| PathResolution::ToolModule(_)
|
||||
| PathResolution::Local(_)
|
||||
| PathResolution::Macro(_)
|
||||
| PathResolution::ConstParam(_) => None,
|
||||
PathResolution::TypeParam(param) => Some(TypeNs::GenericParam((*param).into())),
|
||||
PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType((*impl_def).into())),
|
||||
PathResolution::AssocItem(AssocItem::Const(_) | AssocItem::Function(_)) => None,
|
||||
@ -334,10 +338,6 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
|
||||
self.imp.resolve_path(path)
|
||||
}
|
||||
|
||||
pub fn resolve_path_as_macro(&self, path: &ast::Path) -> Option<MacroDef> {
|
||||
self.imp.resolve_path_as_macro(path)
|
||||
}
|
||||
|
||||
pub fn resolve_extern_crate(&self, extern_crate: &ast::ExternCrate) -> Option<Crate> {
|
||||
self.imp.resolve_extern_crate(extern_crate)
|
||||
}
|
||||
@ -860,12 +860,6 @@ impl<'db> SemanticsImpl<'db> {
|
||||
self.analyze(path.syntax()).resolve_path(self.db, path)
|
||||
}
|
||||
|
||||
// FIXME: This shouldn't exist, but is currently required to always resolve attribute paths in
|
||||
// the IDE layer due to namespace collisions
|
||||
fn resolve_path_as_macro(&self, path: &ast::Path) -> Option<MacroDef> {
|
||||
self.analyze(path.syntax()).resolve_path_as_macro(self.db, path)
|
||||
}
|
||||
|
||||
fn resolve_extern_crate(&self, extern_crate: &ast::ExternCrate) -> Option<Crate> {
|
||||
let krate = self.scope(extern_crate.syntax()).krate()?;
|
||||
krate.dependencies(self.db).into_iter().find_map(|dep| {
|
||||
|
@ -29,8 +29,9 @@ use syntax::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
db::HirDatabase, semantics::PathResolution, Adt, BuiltinType, Const, Field, Function, Local,
|
||||
MacroDef, ModuleDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Variant,
|
||||
db::HirDatabase, semantics::PathResolution, Adt, BuiltinAttr, BuiltinType, Const, Field,
|
||||
Function, Local, MacroDef, ModuleDef, Static, Struct, ToolModule, Trait, Type, TypeAlias,
|
||||
TypeParam, Variant,
|
||||
};
|
||||
use base_db::CrateId;
|
||||
|
||||
@ -246,24 +247,14 @@ impl SourceAnalyzer {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_path_as_macro(
|
||||
&self,
|
||||
db: &dyn HirDatabase,
|
||||
path: &ast::Path,
|
||||
) -> Option<MacroDef> {
|
||||
// This must be a normal source file rather than macro file.
|
||||
let hygiene = Hygiene::new(db.upcast(), self.file_id);
|
||||
let ctx = body::LowerCtx::with_hygiene(db.upcast(), &hygiene);
|
||||
let hir_path = Path::from_src(path.clone(), &ctx)?;
|
||||
resolve_hir_path_as_macro(db, &self.resolver, &hir_path)
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_path(
|
||||
&self,
|
||||
db: &dyn HirDatabase,
|
||||
path: &ast::Path,
|
||||
) -> Option<PathResolution> {
|
||||
let parent = || path.syntax().parent();
|
||||
let parent = path.syntax().parent();
|
||||
let parent = || parent.clone();
|
||||
|
||||
let mut prefer_value_ns = false;
|
||||
if let Some(path_expr) = parent().and_then(ast::PathExpr::cast) {
|
||||
let expr_id = self.expr_id(db, &path_expr.into())?;
|
||||
@ -318,15 +309,6 @@ impl SourceAnalyzer {
|
||||
let ctx = body::LowerCtx::with_hygiene(db.upcast(), &hygiene);
|
||||
let hir_path = Path::from_src(path.clone(), &ctx)?;
|
||||
|
||||
// Case where path is a qualifier of another path, e.g. foo::bar::Baz where we are
|
||||
// trying to resolve foo::bar.
|
||||
if let Some(outer_path) = parent().and_then(ast::Path::cast) {
|
||||
if let Some(qualifier) = outer_path.qualifier() {
|
||||
if path == &qualifier {
|
||||
return resolve_hir_path_qualifier(db, &self.resolver, &hir_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Case where path is a qualifier of a use tree, e.g. foo::bar::{Baz, Qux} where we are
|
||||
// trying to resolve foo::bar.
|
||||
if let Some(use_tree) = parent().and_then(ast::UseTree::cast) {
|
||||
@ -337,10 +319,52 @@ impl SourceAnalyzer {
|
||||
}
|
||||
}
|
||||
|
||||
if parent().map_or(false, |it| ast::Visibility::can_cast(it.kind())) {
|
||||
let is_path_of_attr = path
|
||||
.top_path()
|
||||
.syntax()
|
||||
.ancestors()
|
||||
.nth(2) // Path -> Meta -> Attr
|
||||
.map_or(false, |it| ast::Attr::can_cast(it.kind()));
|
||||
|
||||
// Case where path is a qualifier of another path, e.g. foo::bar::Baz where we are
|
||||
// trying to resolve foo::bar.
|
||||
if let Some(outer_path) = path.parent_path() {
|
||||
if let Some(qualifier) = outer_path.qualifier() {
|
||||
if path == &qualifier {
|
||||
return resolve_hir_path_qualifier(db, &self.resolver, &hir_path);
|
||||
}
|
||||
}
|
||||
} else if is_path_of_attr {
|
||||
let res = resolve_hir_path_as_macro(db, &self.resolver, &hir_path);
|
||||
return match res {
|
||||
Some(_) => res.map(PathResolution::Macro),
|
||||
None => path.as_single_name_ref().and_then(|name_ref| {
|
||||
if let builtin @ Some(_) = BuiltinAttr::by_name(&name_ref.text()) {
|
||||
builtin.map(PathResolution::BuiltinAttr)
|
||||
} else if let tool @ Some(_) = ToolModule::by_name(&name_ref.text()) {
|
||||
tool.map(PathResolution::ToolModule)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
let res = if parent().map_or(false, |it| ast::Visibility::can_cast(it.kind())) {
|
||||
resolve_hir_path_qualifier(db, &self.resolver, &hir_path)
|
||||
} else {
|
||||
resolve_hir_path_(db, &self.resolver, &hir_path, prefer_value_ns)
|
||||
};
|
||||
match res {
|
||||
Some(_) => res,
|
||||
// this labels any path that starts with a tool module as the tool itself, this is technically wrong
|
||||
// but there is no benefit in differentiating these two cases for the time being
|
||||
None if is_path_of_attr => path
|
||||
.first_segment()
|
||||
.and_then(|seg| seg.name_ref())
|
||||
.and_then(|name_ref| ToolModule::by_name(&name_ref.text()))
|
||||
.map(PathResolution::ToolModule),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,35 +2,100 @@
|
||||
//!
|
||||
//! 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.
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct AttributeTemplate {
|
||||
pub word: bool,
|
||||
pub list: Option<&'static str>,
|
||||
pub name_value_str: Option<&'static str>,
|
||||
}
|
||||
|
||||
pub fn find_builtin_attr_idx(name: &str) -> Option<usize> {
|
||||
static BUILTIN_LOOKUP_TABLE: OnceCell<FxHashMap<&'static str, usize>> = OnceCell::new();
|
||||
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 +223,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 +260,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 +329,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 +354,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 +415,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 +499,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),
|
||||
|
@ -1798,14 +1798,18 @@ impl ModCollector<'_, '_> {
|
||||
|
||||
let registered = self.def_collector.registered_tools.iter().map(SmolStr::as_str);
|
||||
let is_tool = builtin_attr::TOOL_MODULES.iter().copied().chain(registered).any(pred);
|
||||
// FIXME: tool modules can be shadowed by actual modules
|
||||
if is_tool {
|
||||
return true;
|
||||
}
|
||||
|
||||
if segments.len() == 1 {
|
||||
let registered = self.def_collector.registered_attrs.iter().map(SmolStr::as_str);
|
||||
let is_inert =
|
||||
builtin_attr::INERT_ATTRIBUTES.iter().copied().chain(registered).any(pred);
|
||||
let is_inert = builtin_attr::INERT_ATTRIBUTES
|
||||
.iter()
|
||||
.map(|it| it.name)
|
||||
.chain(registered)
|
||||
.any(pred);
|
||||
return is_inert;
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +181,9 @@ pub(crate) fn resolve_doc_path_for_def(
|
||||
Definition::TypeAlias(it) => it.resolve_doc_path(db, link, ns),
|
||||
Definition::Macro(it) => it.resolve_doc_path(db, link, ns),
|
||||
Definition::Field(it) => it.resolve_doc_path(db, link, ns),
|
||||
Definition::BuiltinType(_)
|
||||
Definition::BuiltinAttr(_)
|
||||
| Definition::ToolModule(_)
|
||||
| Definition::BuiltinType(_)
|
||||
| Definition::SelfType(_)
|
||||
| Definition::Local(_)
|
||||
| Definition::GenericParam(_)
|
||||
@ -492,9 +494,11 @@ fn filename_and_frag_for_def(
|
||||
// FIXME fragment numbering
|
||||
return Some((adt, file, Some(String::from("impl"))));
|
||||
}
|
||||
Definition::Local(_) => return None,
|
||||
Definition::GenericParam(_) => return None,
|
||||
Definition::Label(_) => return None,
|
||||
Definition::Local(_)
|
||||
| Definition::GenericParam(_)
|
||||
| Definition::Label(_)
|
||||
| Definition::BuiltinAttr(_)
|
||||
| Definition::ToolModule(_) => return None,
|
||||
};
|
||||
|
||||
Some((def, res, None))
|
||||
|
@ -2,7 +2,7 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use either::Either;
|
||||
use hir::{AsAssocItem, HasAttrs, HasSource, HirDisplay, Semantics, TypeInfo};
|
||||
use hir::{AsAssocItem, AttributeTemplate, HasAttrs, HasSource, HirDisplay, Semantics, TypeInfo};
|
||||
use ide_db::{
|
||||
base_db::SourceDatabase,
|
||||
defs::Definition,
|
||||
@ -369,11 +369,32 @@ pub(super) fn definition(
|
||||
}
|
||||
Definition::GenericParam(it) => label_and_docs(db, it),
|
||||
Definition::Label(it) => return Some(Markup::fenced_block(&it.name(db))),
|
||||
// FIXME: We should be able to show more info about these
|
||||
Definition::BuiltinAttr(it) => return render_builtin_attr(db, it),
|
||||
Definition::ToolModule(it) => return Some(Markup::fenced_block(&it.name(db))),
|
||||
};
|
||||
|
||||
markup(docs.filter(|_| config.documentation.is_some()).map(Into::into), label, mod_path)
|
||||
}
|
||||
|
||||
fn render_builtin_attr(db: &RootDatabase, attr: hir::BuiltinAttr) -> Option<Markup> {
|
||||
let name = attr.name(db);
|
||||
let desc = format!("#[{}]", name);
|
||||
|
||||
let AttributeTemplate { word, list, name_value_str } = attr.template(db);
|
||||
let mut docs = "Valid forms are:".to_owned();
|
||||
if word {
|
||||
format_to!(docs, "\n - #\\[{}]", name);
|
||||
}
|
||||
if let Some(list) = list {
|
||||
format_to!(docs, "\n - #\\[{}({})]", name, list);
|
||||
}
|
||||
if let Some(name_value_str) = name_value_str {
|
||||
format_to!(docs, "\n - #\\[{} = {}]", name, name_value_str);
|
||||
}
|
||||
markup(Some(docs.replace('*', "\\*")), desc, None)
|
||||
}
|
||||
|
||||
fn label_and_docs<D>(db: &RootDatabase, def: D) -> (String, Option<hir::Documentation>)
|
||||
where
|
||||
D: HasAttrs + HirDisplay,
|
||||
|
@ -3678,7 +3678,6 @@ fn hover_clippy_lint() {
|
||||
|
||||
#[test]
|
||||
fn hover_attr_path_qualifier() {
|
||||
cov_mark::check!(name_ref_classify_attr_path_qualifier);
|
||||
check(
|
||||
r#"
|
||||
//- /foo.rs crate:foo
|
||||
@ -4278,3 +4277,46 @@ pub struct Foo;
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hover_inert_attr() {
|
||||
check(
|
||||
r#"
|
||||
#[doc$0 = ""]
|
||||
pub struct Foo;
|
||||
"#,
|
||||
expect![[r##"
|
||||
*doc*
|
||||
|
||||
```rust
|
||||
#[doc]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Valid forms are:
|
||||
|
||||
* \#\[doc(hidden|inline|...)\]
|
||||
* \#\[doc = string\]
|
||||
"##]],
|
||||
);
|
||||
check(
|
||||
r#"
|
||||
#[allow$0()]
|
||||
pub struct Foo;
|
||||
"#,
|
||||
expect![[r##"
|
||||
*allow*
|
||||
|
||||
```rust
|
||||
#[allow]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Valid forms are:
|
||||
|
||||
* \#\[allow(lint1, lint2, ..., /\*opt\*/ reason = "...")\]
|
||||
"##]],
|
||||
);
|
||||
}
|
||||
|
@ -214,6 +214,8 @@ impl TryToNav for Definition {
|
||||
Definition::Trait(it) => it.try_to_nav(db),
|
||||
Definition::TypeAlias(it) => it.try_to_nav(db),
|
||||
Definition::BuiltinType(_) => None,
|
||||
Definition::ToolModule(_) => None,
|
||||
Definition::BuiltinAttr(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -299,6 +299,7 @@ pub func() {
|
||||
r#"
|
||||
//- minicore:derive
|
||||
#[rustc_builtin_macro]
|
||||
//^^^^^^^^^^^^^^^^^^^
|
||||
pub macro Copy {}
|
||||
//^^^^
|
||||
#[derive(Copy)]
|
||||
|
@ -115,6 +115,7 @@ pub struct HlRange {
|
||||
// parameter:: Emitted for non-self function parameters.
|
||||
// property:: Emitted for struct and union fields.
|
||||
// selfKeyword:: Emitted for the self function parameter and self path-specifier.
|
||||
// toolModule:: Emitted for tool modules.
|
||||
// typeParameter:: Emitted for type parameters.
|
||||
// unresolvedReference:: Emitted for unresolved references, names that rust-analyzer can't find the definition of.
|
||||
// variable:: Emitted for locals, constants and statics.
|
||||
|
@ -208,22 +208,14 @@ fn node(
|
||||
},
|
||||
// Highlight references like the definitions they resolve to
|
||||
ast::NameRef(name_ref) => {
|
||||
if node.ancestors().any(|it| it.kind() == ATTR) {
|
||||
|
||||
// FIXME: We highlight paths in attributes slightly differently to work around this module
|
||||
// currently not knowing about tool attributes and rustc builtin attributes as
|
||||
// we do not want to resolve those to functions that may be defined in scope.
|
||||
highlight_name_ref_in_attr(sema, name_ref)
|
||||
} else {
|
||||
highlight_name_ref(
|
||||
sema,
|
||||
krate,
|
||||
bindings_shadow_count,
|
||||
&mut binding_hash,
|
||||
syntactic_name_ref_highlighting,
|
||||
name_ref,
|
||||
)
|
||||
}
|
||||
highlight_name_ref(
|
||||
sema,
|
||||
krate,
|
||||
bindings_shadow_count,
|
||||
&mut binding_hash,
|
||||
syntactic_name_ref_highlighting,
|
||||
name_ref,
|
||||
)
|
||||
},
|
||||
ast::Lifetime(lifetime) => {
|
||||
match NameClass::classify_lifetime(sema, &lifetime) {
|
||||
@ -243,28 +235,6 @@ fn node(
|
||||
Some((highlight, binding_hash))
|
||||
}
|
||||
|
||||
fn highlight_name_ref_in_attr(sema: &Semantics<RootDatabase>, name_ref: ast::NameRef) -> Highlight {
|
||||
match NameRefClass::classify(sema, &name_ref) {
|
||||
Some(name_class) => match name_class {
|
||||
NameRefClass::Definition(Definition::Module(_))
|
||||
if name_ref
|
||||
.syntax()
|
||||
.ancestors()
|
||||
.find_map(ast::Path::cast)
|
||||
.map_or(false, |it| it.parent_path().is_some()) =>
|
||||
{
|
||||
HlTag::Symbol(SymbolKind::Module)
|
||||
}
|
||||
NameRefClass::Definition(Definition::Macro(m)) if m.kind() == hir::MacroKind::Attr => {
|
||||
HlTag::Symbol(SymbolKind::Macro)
|
||||
}
|
||||
_ => HlTag::BuiltinAttr,
|
||||
},
|
||||
None => HlTag::BuiltinAttr,
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
fn highlight_name_ref(
|
||||
sema: &Semantics<RootDatabase>,
|
||||
krate: Option<hir::Crate>,
|
||||
@ -542,6 +512,8 @@ fn highlight_def(
|
||||
h
|
||||
}
|
||||
Definition::Label(_) => Highlight::new(HlTag::Symbol(SymbolKind::Label)),
|
||||
Definition::BuiltinAttr(_) => Highlight::new(HlTag::Symbol(SymbolKind::BuiltinAttr)),
|
||||
Definition::ToolModule(_) => Highlight::new(HlTag::Symbol(SymbolKind::ToolModule)),
|
||||
};
|
||||
|
||||
let famous_defs = FamousDefs(sema, krate);
|
||||
|
@ -263,6 +263,8 @@ fn module_def_to_hl_tag(def: Definition) -> HlTag {
|
||||
hir::GenericParam::ConstParam(_) => SymbolKind::ConstParam,
|
||||
},
|
||||
Definition::Label(_) => SymbolKind::Label,
|
||||
Definition::BuiltinAttr(_) => SymbolKind::BuiltinAttr,
|
||||
Definition::ToolModule(_) => SymbolKind::ToolModule,
|
||||
};
|
||||
HlTag::Symbol(symbol)
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ pub enum HlTag {
|
||||
|
||||
Attribute,
|
||||
BoolLiteral,
|
||||
BuiltinAttr,
|
||||
BuiltinType,
|
||||
ByteLiteral,
|
||||
CharLiteral,
|
||||
@ -125,30 +124,31 @@ impl HlTag {
|
||||
fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
HlTag::Symbol(symbol) => match symbol {
|
||||
SymbolKind::BuiltinAttr => "builtin_attr",
|
||||
SymbolKind::Const => "constant",
|
||||
SymbolKind::Static => "static",
|
||||
SymbolKind::ConstParam => "const_param",
|
||||
SymbolKind::Enum => "enum",
|
||||
SymbolKind::Variant => "enum_variant",
|
||||
SymbolKind::Struct => "struct",
|
||||
SymbolKind::Union => "union",
|
||||
SymbolKind::Field => "field",
|
||||
SymbolKind::Module => "module",
|
||||
SymbolKind::Trait => "trait",
|
||||
SymbolKind::Function => "function",
|
||||
SymbolKind::Impl => "self_type",
|
||||
SymbolKind::Label => "label",
|
||||
SymbolKind::LifetimeParam => "lifetime",
|
||||
SymbolKind::Local => "variable",
|
||||
SymbolKind::Macro => "macro",
|
||||
SymbolKind::Module => "module",
|
||||
SymbolKind::SelfParam => "self_keyword",
|
||||
SymbolKind::Static => "static",
|
||||
SymbolKind::Struct => "struct",
|
||||
SymbolKind::ToolModule => "tool_module",
|
||||
SymbolKind::Trait => "trait",
|
||||
SymbolKind::TypeAlias => "type_alias",
|
||||
SymbolKind::TypeParam => "type_param",
|
||||
SymbolKind::ConstParam => "const_param",
|
||||
SymbolKind::LifetimeParam => "lifetime",
|
||||
SymbolKind::Macro => "macro",
|
||||
SymbolKind::Local => "variable",
|
||||
SymbolKind::Label => "label",
|
||||
SymbolKind::Union => "union",
|
||||
SymbolKind::ValueParam => "value_param",
|
||||
SymbolKind::SelfParam => "self_keyword",
|
||||
SymbolKind::Impl => "self_type",
|
||||
SymbolKind::Variant => "enum_variant",
|
||||
},
|
||||
HlTag::Attribute => "attribute",
|
||||
HlTag::BoolLiteral => "bool_literal",
|
||||
HlTag::BuiltinAttr => "builtin_attr",
|
||||
HlTag::BuiltinType => "builtin_type",
|
||||
HlTag::ByteLiteral => "byte_literal",
|
||||
HlTag::CharLiteral => "char_literal",
|
||||
|
@ -72,7 +72,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
<span class="comment documentation">/// # Examples</span>
|
||||
<span class="comment documentation">///</span>
|
||||
<span class="comment documentation">/// ```</span>
|
||||
<span class="comment documentation">/// #</span><span class="none injected"> </span><span class="attribute attribute injected">#</span><span class="attribute attribute injected">!</span><span class="attribute attribute injected">[</span><span class="builtin_attr attribute injected">allow</span><span class="parenthesis attribute injected">(</span><span class="none attribute injected">unused_mut</span><span class="parenthesis attribute injected">)</span><span class="attribute attribute injected">]</span>
|
||||
<span class="comment documentation">/// #</span><span class="none injected"> </span><span class="attribute attribute injected">#</span><span class="attribute attribute injected">!</span><span class="attribute attribute injected">[</span><span class="builtin_attr attribute injected library">allow</span><span class="parenthesis attribute injected">(</span><span class="none attribute injected">unused_mut</span><span class="parenthesis attribute injected">)</span><span class="attribute attribute injected">]</span>
|
||||
<span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="keyword injected">mut</span><span class="none injected"> </span><span class="variable declaration injected mutable">foo</span><span class="colon injected">:</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span>
|
||||
<span class="comment documentation">/// ```</span>
|
||||
<span class="keyword">pub</span> <span class="keyword">const</span> <span class="keyword">fn</span> <span class="function associated declaration public static">new</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="struct">Foo</span> <span class="brace">{</span>
|
||||
@ -143,12 +143,12 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
<span class="comment documentation">///</span>
|
||||
<span class="comment documentation">/// ```</span>
|
||||
<span class="comment documentation">/// </span><span class="keyword control injected">loop</span><span class="none injected"> </span><span class="brace injected">{</span><span class="brace injected">}</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">cfg_attr</span><span class="parenthesis attribute">(</span><span class="none attribute">not</span><span class="parenthesis attribute">(</span><span class="none attribute">feature</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"false"</span><span class="parenthesis attribute">)</span><span class="comma attribute">,</span><span class="attribute attribute"> </span><span class="none attribute">doc</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"</span><span class="keyword control injected">loop</span><span class="none injected"> </span><span class="brace injected">{</span><span class="brace injected">}</span><span class="string_literal attribute">"</span><span class="parenthesis attribute">)</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">doc</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"</span><span class="keyword control injected">loop</span><span class="none injected"> </span><span class="brace injected">{</span><span class="brace injected">}</span><span class="string_literal attribute">"</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute library">cfg_attr</span><span class="parenthesis attribute">(</span><span class="none attribute">not</span><span class="parenthesis attribute">(</span><span class="none attribute">feature</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"false"</span><span class="parenthesis attribute">)</span><span class="comma attribute">,</span><span class="attribute attribute"> </span><span class="none attribute">doc</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"</span><span class="keyword control injected">loop</span><span class="none injected"> </span><span class="brace injected">{</span><span class="brace injected">}</span><span class="string_literal attribute">"</span><span class="parenthesis attribute">)</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute library">doc</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"</span><span class="keyword control injected">loop</span><span class="none injected"> </span><span class="brace injected">{</span><span class="brace injected">}</span><span class="string_literal attribute">"</span><span class="attribute attribute">]</span>
|
||||
<span class="comment documentation">/// ```</span>
|
||||
<span class="comment documentation">///</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">cfg_attr</span><span class="parenthesis attribute">(</span><span class="none attribute">feature</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"alloc"</span><span class="comma attribute">,</span><span class="attribute attribute"> </span><span class="none attribute">doc</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"```rust"</span><span class="parenthesis attribute">)</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">cfg_attr</span><span class="parenthesis attribute">(</span><span class="none attribute">not</span><span class="parenthesis attribute">(</span><span class="none attribute">feature</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"alloc"</span><span class="parenthesis attribute">)</span><span class="comma attribute">,</span><span class="attribute attribute"> </span><span class="none attribute">doc</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"```ignore"</span><span class="parenthesis attribute">)</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute library">cfg_attr</span><span class="parenthesis attribute">(</span><span class="none attribute">feature</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"alloc"</span><span class="comma attribute">,</span><span class="attribute attribute"> </span><span class="none attribute">doc</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"```rust"</span><span class="parenthesis attribute">)</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute library">cfg_attr</span><span class="parenthesis attribute">(</span><span class="none attribute">not</span><span class="parenthesis attribute">(</span><span class="none attribute">feature</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"alloc"</span><span class="parenthesis attribute">)</span><span class="comma attribute">,</span><span class="attribute attribute"> </span><span class="none attribute">doc</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"```ignore"</span><span class="parenthesis attribute">)</span><span class="attribute attribute">]</span>
|
||||
<span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="punctuation injected">_</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="function injected">example</span><span class="parenthesis injected">(</span><span class="operator injected">&</span><span class="none injected">alloc::</span><span class="macro injected">vec!</span><span class="bracket injected">[</span><span class="numeric_literal injected">1</span><span class="comma injected">,</span><span class="none injected"> </span><span class="numeric_literal injected">2</span><span class="comma injected">,</span><span class="none injected"> </span><span class="numeric_literal injected">3</span><span class="bracket injected">]</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span>
|
||||
<span class="comment documentation">/// ```</span>
|
||||
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration public">mix_and_match</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
|
@ -45,14 +45,14 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
<span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>io<span class="colon">:</span><span class="colon">:</span>_print<span class="parenthesis">(</span><span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>format_args_nl<span class="punctuation">!</span><span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span><span class="parenthesis">)</span><span class="semicolon">;</span>
|
||||
<span class="brace">}</span><span class="parenthesis">)</span>
|
||||
<span class="brace">}</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">rustc_builtin_macro</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">macro_export</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute library">rustc_builtin_macro</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute library">macro_export</span><span class="attribute attribute">]</span>
|
||||
<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">format_args</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">rustc_builtin_macro</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">macro_export</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute library">rustc_builtin_macro</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute library">macro_export</span><span class="attribute attribute">]</span>
|
||||
<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">const_format_args</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">rustc_builtin_macro</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">macro_export</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute library">rustc_builtin_macro</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute library">macro_export</span><span class="attribute attribute">]</span>
|
||||
<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">format_args_nl</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
|
||||
<span class="keyword">mod</span> <span class="module declaration">panic</span> <span class="brace">{</span>
|
||||
@ -77,12 +77,12 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
<span class="brace">}</span>
|
||||
<span class="brace">}</span>
|
||||
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">rustc_builtin_macro</span><span class="parenthesis attribute">(</span><span class="none attribute">std_panic</span><span class="parenthesis attribute">)</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">macro_export</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute library">rustc_builtin_macro</span><span class="parenthesis attribute">(</span><span class="none attribute">std_panic</span><span class="parenthesis attribute">)</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute library">macro_export</span><span class="attribute attribute">]</span>
|
||||
<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">panic</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">rustc_builtin_macro</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute library">rustc_builtin_macro</span><span class="attribute attribute">]</span>
|
||||
<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">assert</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">rustc_builtin_macro</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute library">rustc_builtin_macro</span><span class="attribute attribute">]</span>
|
||||
<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">asm</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
|
||||
<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">toho</span> <span class="brace">{</span>
|
||||
|
@ -54,7 +54,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
<span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function associated declaration reference unsafe">unsafe_method</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="brace">}</span>
|
||||
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">repr</span><span class="parenthesis attribute">(</span><span class="none attribute">packed</span><span class="parenthesis attribute">)</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute library">repr</span><span class="parenthesis attribute">(</span><span class="none attribute">packed</span><span class="parenthesis attribute">)</span><span class="attribute attribute">]</span>
|
||||
<span class="keyword">struct</span> <span class="struct declaration">Packed</span> <span class="brace">{</span>
|
||||
<span class="field declaration">a</span><span class="colon">:</span> <span class="builtin_type">u16</span><span class="comma">,</span>
|
||||
<span class="brace">}</span>
|
||||
|
@ -43,15 +43,16 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
<pre><code><span class="keyword">use</span> <span class="module">inner</span><span class="operator">::</span><span class="brace">{</span><span class="self_keyword">self</span> <span class="keyword">as</span> <span class="module declaration">inner_mod</span><span class="brace">}</span><span class="semicolon">;</span>
|
||||
<span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="module attribute">proc_macros</span><span class="operator attribute">::</span><span class="macro attribute">identity</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute library">allow</span><span class="parenthesis attribute">(</span><span class="parenthesis attribute">)</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="module attribute crate_root library">proc_macros</span><span class="operator attribute">::</span><span class="macro attribute library">identity</span><span class="attribute attribute">]</span>
|
||||
<span class="keyword">pub</span> <span class="keyword">mod</span> <span class="module declaration public">ops</span> <span class="brace">{</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">lang</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"fn_once"</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute library">lang</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"fn_once"</span><span class="attribute attribute">]</span>
|
||||
<span class="keyword">pub</span> <span class="keyword">trait</span> <span class="trait declaration public">FnOnce</span><span class="angle"><</span><span class="type_param declaration">Args</span><span class="angle">></span> <span class="brace">{</span><span class="brace">}</span>
|
||||
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">lang</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"fn_mut"</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute library">lang</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"fn_mut"</span><span class="attribute attribute">]</span>
|
||||
<span class="keyword">pub</span> <span class="keyword">trait</span> <span class="trait declaration public">FnMut</span><span class="angle"><</span><span class="type_param declaration">Args</span><span class="angle">></span><span class="colon">:</span> <span class="trait public">FnOnce</span><span class="angle"><</span><span class="type_param">Args</span><span class="angle">></span> <span class="brace">{</span><span class="brace">}</span>
|
||||
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">lang</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"fn"</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute library">lang</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"fn"</span><span class="attribute attribute">]</span>
|
||||
<span class="keyword">pub</span> <span class="keyword">trait</span> <span class="trait declaration public">Fn</span><span class="angle"><</span><span class="type_param declaration">Args</span><span class="angle">></span><span class="colon">:</span> <span class="trait public">FnMut</span><span class="angle"><</span><span class="type_param">Args</span><span class="angle">></span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="brace">}</span>
|
||||
|
||||
@ -86,7 +87,7 @@ proc_macros::<span class="macro">mirror!</span> <span class="brace">{</span>
|
||||
<span class="brace">}</span>
|
||||
<span class="brace">}</span>
|
||||
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="macro attribute">derive</span><span class="parenthesis attribute">(</span><span class="macro attribute default_library library">Copy</span><span class="parenthesis attribute">)</span><span class="attribute attribute">]</span>
|
||||
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="macro attribute default_library library">derive</span><span class="parenthesis attribute">(</span><span class="macro attribute default_library library">Copy</span><span class="parenthesis attribute">)</span><span class="attribute attribute">]</span>
|
||||
<span class="keyword">struct</span> <span class="struct declaration">FooCopy</span> <span class="brace">{</span>
|
||||
<span class="field declaration">x</span><span class="colon">:</span> <span class="builtin_type">u32</span><span class="comma">,</span>
|
||||
<span class="brace">}</span>
|
||||
|
@ -16,6 +16,7 @@ fn test_highlighting() {
|
||||
use inner::{self as inner_mod};
|
||||
mod inner {}
|
||||
|
||||
#[allow()]
|
||||
#[proc_macros::identity]
|
||||
pub mod ops {
|
||||
#[lang = "fn_once"]
|
||||
|
@ -232,6 +232,7 @@ impl CompletionItemKind {
|
||||
pub(crate) fn tag(&self) -> &'static str {
|
||||
match self {
|
||||
CompletionItemKind::SymbolKind(kind) => match kind {
|
||||
SymbolKind::BuiltinAttr => "ba",
|
||||
SymbolKind::Const => "ct",
|
||||
SymbolKind::ConstParam => "cp",
|
||||
SymbolKind::Enum => "en",
|
||||
@ -246,6 +247,7 @@ impl CompletionItemKind {
|
||||
SymbolKind::SelfParam => "sp",
|
||||
SymbolKind::Static => "sc",
|
||||
SymbolKind::Struct => "st",
|
||||
SymbolKind::ToolModule => "tm",
|
||||
SymbolKind::Trait => "tt",
|
||||
SymbolKind::TypeAlias => "ta",
|
||||
SymbolKind::TypeParam => "tp",
|
||||
|
@ -7,9 +7,9 @@
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
use hir::{
|
||||
Adt, AsAssocItem, AssocItem, BuiltinType, Const, Field, Function, GenericParam, HasVisibility,
|
||||
Impl, ItemInNs, Label, Local, MacroDef, Module, ModuleDef, Name, PathResolution, Semantics,
|
||||
Static, Trait, TypeAlias, Variant, Visibility,
|
||||
Adt, AsAssocItem, AssocItem, BuiltinAttr, BuiltinType, Const, Field, Function, GenericParam,
|
||||
HasVisibility, Impl, ItemInNs, Label, Local, MacroDef, Module, ModuleDef, Name, PathResolution,
|
||||
Semantics, Static, ToolModule, Trait, TypeAlias, Variant, Visibility,
|
||||
};
|
||||
use stdx::impl_from;
|
||||
use syntax::{
|
||||
@ -37,6 +37,8 @@ pub enum Definition {
|
||||
Local(Local),
|
||||
GenericParam(GenericParam),
|
||||
Label(Label),
|
||||
BuiltinAttr(BuiltinAttr),
|
||||
ToolModule(ToolModule),
|
||||
}
|
||||
|
||||
impl Definition {
|
||||
@ -48,10 +50,9 @@ impl Definition {
|
||||
Some(parent) => parent,
|
||||
None => return Default::default(),
|
||||
};
|
||||
// resolve derives if possible
|
||||
if let Some(ident) = ast::Ident::cast(token.clone()) {
|
||||
let attr = parent
|
||||
.ancestors()
|
||||
.find_map(ast::TokenTree::cast)
|
||||
let attr = ast::TokenTree::cast(parent.clone())
|
||||
.and_then(|tt| tt.parent_meta())
|
||||
.and_then(|meta| meta.parent_attr());
|
||||
if let Some(attr) = attr {
|
||||
@ -128,7 +129,9 @@ impl Definition {
|
||||
Definition::Local(it) => it.module(db),
|
||||
Definition::GenericParam(it) => it.module(db),
|
||||
Definition::Label(it) => it.module(db),
|
||||
Definition::BuiltinType(_) => return None,
|
||||
Definition::BuiltinAttr(_) | Definition::BuiltinType(_) | Definition::ToolModule(_) => {
|
||||
return None
|
||||
}
|
||||
};
|
||||
Some(module)
|
||||
}
|
||||
@ -146,7 +149,9 @@ impl Definition {
|
||||
Definition::Variant(it) => it.visibility(db),
|
||||
Definition::BuiltinType(_) => Visibility::Public,
|
||||
Definition::Macro(_) => return None,
|
||||
Definition::SelfType(_)
|
||||
Definition::BuiltinAttr(_)
|
||||
| Definition::ToolModule(_)
|
||||
| Definition::SelfType(_)
|
||||
| Definition::Local(_)
|
||||
| Definition::GenericParam(_)
|
||||
| Definition::Label(_) => return None,
|
||||
@ -171,6 +176,8 @@ impl Definition {
|
||||
Definition::Local(it) => it.name(db)?,
|
||||
Definition::GenericParam(it) => it.name(db),
|
||||
Definition::Label(it) => it.name(db),
|
||||
Definition::BuiltinAttr(_) => return None, // FIXME
|
||||
Definition::ToolModule(_) => return None, // FIXME
|
||||
};
|
||||
Some(name)
|
||||
}
|
||||
@ -450,30 +457,7 @@ impl NameRefClass {
|
||||
}
|
||||
}
|
||||
}
|
||||
let top_path = path.top_path();
|
||||
let is_attribute_path = top_path
|
||||
.syntax()
|
||||
.ancestors()
|
||||
.find_map(ast::Attr::cast)
|
||||
.map(|attr| attr.path().as_ref() == Some(&top_path));
|
||||
return match is_attribute_path {
|
||||
Some(true) if path == top_path => sema
|
||||
.resolve_path_as_macro(&path)
|
||||
.filter(|mac| mac.kind() == hir::MacroKind::Attr)
|
||||
.map(Definition::Macro)
|
||||
.map(NameRefClass::Definition),
|
||||
// in case of the path being a qualifier, don't resolve to anything but a module
|
||||
Some(true) => match sema.resolve_path(&path)? {
|
||||
PathResolution::Def(ModuleDef::Module(module)) => {
|
||||
cov_mark::hit!(name_ref_classify_attr_path_qualifier);
|
||||
Some(NameRefClass::Definition(Definition::Module(module)))
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
// inside attribute, but our path isn't part of the attribute's path(might be in its expression only)
|
||||
Some(false) => None,
|
||||
None => sema.resolve_path(&path).map(Into::into).map(NameRefClass::Definition),
|
||||
};
|
||||
return sema.resolve_path(&path).map(Into::into).map(NameRefClass::Definition);
|
||||
}
|
||||
|
||||
let extern_crate = ast::ExternCrate::cast(parent)?;
|
||||
@ -566,6 +550,8 @@ impl From<PathResolution> for Definition {
|
||||
PathResolution::Macro(def) => Definition::Macro(def),
|
||||
PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def),
|
||||
PathResolution::ConstParam(par) => Definition::GenericParam(par.into()),
|
||||
PathResolution::BuiltinAttr(attr) => Definition::BuiltinAttr(attr),
|
||||
PathResolution::ToolModule(tool) => Definition::ToolModule(tool),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -145,6 +145,7 @@ fn line_index(db: &dyn LineIndexDatabase, file_id: FileId) -> Arc<LineIndex> {
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub enum SymbolKind {
|
||||
BuiltinAttr,
|
||||
Const,
|
||||
ConstParam,
|
||||
Enum,
|
||||
@ -159,6 +160,7 @@ pub enum SymbolKind {
|
||||
SelfParam,
|
||||
Static,
|
||||
Struct,
|
||||
ToolModule,
|
||||
Trait,
|
||||
TypeAlias,
|
||||
TypeParam,
|
||||
|
@ -164,7 +164,9 @@ impl<'a> Ctx<'a> {
|
||||
| hir::PathResolution::ConstParam(_)
|
||||
| hir::PathResolution::SelfType(_)
|
||||
| hir::PathResolution::Macro(_)
|
||||
| hir::PathResolution::AssocItem(_) => (),
|
||||
| hir::PathResolution::AssocItem(_)
|
||||
| hir::PathResolution::BuiltinAttr(_)
|
||||
| hir::PathResolution::ToolModule(_) => (),
|
||||
}
|
||||
Some(())
|
||||
}
|
||||
|
@ -115,8 +115,6 @@ impl Definition {
|
||||
Definition::Static(it) => name_range(it, sema),
|
||||
Definition::Trait(it) => name_range(it, sema),
|
||||
Definition::TypeAlias(it) => name_range(it, sema),
|
||||
Definition::BuiltinType(_) => return None,
|
||||
Definition::SelfType(_) => return None,
|
||||
Definition::Local(local) => {
|
||||
let src = local.source(sema.db);
|
||||
let name = match &src.value {
|
||||
@ -146,6 +144,10 @@ impl Definition {
|
||||
let lifetime = src.value.lifetime()?;
|
||||
src.with_value(lifetime.syntax()).original_file_range_opt(sema.db)
|
||||
}
|
||||
Definition::BuiltinType(_) => return None,
|
||||
Definition::SelfType(_) => return None,
|
||||
Definition::BuiltinAttr(_) => return None,
|
||||
Definition::ToolModule(_) => return None,
|
||||
};
|
||||
return res;
|
||||
|
||||
|
@ -65,6 +65,7 @@ define_semantic_token_types![
|
||||
(SELF_KEYWORD, "selfKeyword"),
|
||||
(SEMICOLON, "semicolon"),
|
||||
(TYPE_ALIAS, "typeAlias"),
|
||||
(TOOL_MODULE, "toolModule"),
|
||||
(UNION, "union"),
|
||||
(UNRESOLVED_REFERENCE, "unresolvedReference"),
|
||||
];
|
||||
|
@ -50,8 +50,8 @@ pub(crate) fn symbol_kind(symbol_kind: SymbolKind) -> lsp_types::SymbolKind {
|
||||
SymbolKind::Enum => lsp_types::SymbolKind::ENUM,
|
||||
SymbolKind::Variant => lsp_types::SymbolKind::ENUM_MEMBER,
|
||||
SymbolKind::Trait => lsp_types::SymbolKind::INTERFACE,
|
||||
SymbolKind::Macro => lsp_types::SymbolKind::FUNCTION,
|
||||
SymbolKind::Module => lsp_types::SymbolKind::MODULE,
|
||||
SymbolKind::Macro | SymbolKind::BuiltinAttr => lsp_types::SymbolKind::FUNCTION,
|
||||
SymbolKind::Module | SymbolKind::ToolModule => lsp_types::SymbolKind::MODULE,
|
||||
SymbolKind::TypeAlias | SymbolKind::TypeParam => lsp_types::SymbolKind::TYPE_PARAMETER,
|
||||
SymbolKind::Field => lsp_types::SymbolKind::FIELD,
|
||||
SymbolKind::Static => lsp_types::SymbolKind::CONSTANT,
|
||||
@ -128,6 +128,8 @@ pub(crate) fn completion_item_kind(
|
||||
SymbolKind::Union => lsp_types::CompletionItemKind::STRUCT,
|
||||
SymbolKind::ValueParam => lsp_types::CompletionItemKind::VALUE,
|
||||
SymbolKind::Variant => lsp_types::CompletionItemKind::ENUM_MEMBER,
|
||||
SymbolKind::BuiltinAttr => lsp_types::CompletionItemKind::FUNCTION,
|
||||
SymbolKind::ToolModule => lsp_types::CompletionItemKind::MODULE,
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -499,10 +501,11 @@ fn semantic_token_type_and_modifiers(
|
||||
SymbolKind::TypeAlias => semantic_tokens::TYPE_ALIAS,
|
||||
SymbolKind::Trait => lsp_types::SemanticTokenType::INTERFACE,
|
||||
SymbolKind::Macro => lsp_types::SemanticTokenType::MACRO,
|
||||
SymbolKind::BuiltinAttr => semantic_tokens::BUILTIN_ATTRIBUTE,
|
||||
SymbolKind::ToolModule => semantic_tokens::TOOL_MODULE,
|
||||
},
|
||||
HlTag::Attribute => semantic_tokens::ATTRIBUTE,
|
||||
HlTag::BoolLiteral => semantic_tokens::BOOLEAN,
|
||||
HlTag::BuiltinAttr => semantic_tokens::BUILTIN_ATTRIBUTE,
|
||||
HlTag::BuiltinType => semantic_tokens::BUILTIN_TYPE,
|
||||
HlTag::ByteLiteral | HlTag::NumericLiteral => lsp_types::SemanticTokenType::NUMBER,
|
||||
HlTag::CharLiteral => semantic_tokens::CHAR,
|
||||
|
Loading…
Reference in New Issue
Block a user