Unnamed repository; edit this file 'description' to name the repository.
feat: Resolve builtin-attr and tools in ide layer
Lukas Wirth 2021-12-03
parent 4691a06 · commit e58af21
-rw-r--r--crates/hir/src/lib.rs20
-rw-r--r--crates/hir/src/semantics.rs26
-rw-r--r--crates/hir/src/source_analyzer.rs66
-rw-r--r--crates/hir_def/src/builtin_attr.rs104
-rw-r--r--crates/hir_def/src/nameres/collector.rs8
-rw-r--r--crates/ide/src/doc_links.rs12
-rw-r--r--crates/ide/src/hover/render.rs2
-rw-r--r--crates/ide/src/hover/tests.rs1
-rw-r--r--crates/ide/src/navigation_target.rs2
-rw-r--r--crates/ide/src/static_index.rs1
-rw-r--r--crates/ide/src/syntax_highlighting/highlight.rs2
-rw-r--r--crates/ide/src/syntax_highlighting/inject.rs2
-rw-r--r--crates/ide_db/src/defs.rs50
-rw-r--r--crates/ide_db/src/path_transform.rs4
-rw-r--r--crates/ide_db/src/rename.rs6
15 files changed, 208 insertions, 98 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index e0dc921c9f..c0c2cc7818 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -2024,6 +2024,26 @@ impl Local {
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+pub struct BuiltinAttr(usize);
+
+impl BuiltinAttr {
+ pub(crate) fn by_name(name: &str) -> Option<Self> {
+ // TODO: def maps registered attrs?
+ hir_def::builtin_attr::find_builtin_attr_idx(name).map(Self)
+ }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+pub struct Tool(usize);
+
+impl Tool {
+ pub(crate) fn by_name(name: &str) -> Option<Self> {
+ // TODO: def maps registered tools
+ hir_def::builtin_attr::TOOL_MODULES.iter().position(|&tool| tool == name).map(Self)
+ }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Label {
pub(crate) parent: DefWithBodyId,
pub(crate) label_id: LabelId,
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 27ba42ce1a..c48bd1b053 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -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, Tool, 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),
+ Tool(Tool),
}
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::Tool(_)
+ | 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| {
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 23fcd02b57..8f6c3d995f 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -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, Tool, Trait, Type, TypeAlias, TypeParam,
+ Variant,
};
use base_db::CrateId;
@@ -246,18 +247,6 @@ 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,
@@ -318,29 +307,60 @@ 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
+ // 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(outer_path) = parent().and_then(ast::Path::cast) {
- if let Some(qualifier) = outer_path.qualifier() {
- if path == &qualifier {
+ if let Some(use_tree) = parent().and_then(ast::UseTree::cast) {
+ if let Some(qualifier) = use_tree.path() {
+ if path == &qualifier && use_tree.coloncolon_token().is_some() {
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
+
+ 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(use_tree) = parent().and_then(ast::UseTree::cast) {
- if let Some(qualifier) = use_tree.path() {
- if path == &qualifier && use_tree.coloncolon_token().is_some() {
+ 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 Some(builtin) = BuiltinAttr::by_name(&name_ref.text()) {
+ Some(PathResolution::BuiltinAttr(builtin))
+ } else if let Some(tool) = Tool::by_name(&name_ref.text()) {
+ Some(PathResolution::Tool(tool))
+ } else {
+ None
+ }
+ }),
+ };
}
- if parent().map_or(false, |it| ast::Visibility::can_cast(it.kind())) {
+ 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,
+ None if is_path_of_attr => path
+ .first_segment()
+ .and_then(|seg| seg.name_ref())
+ .and_then(|name_ref| Tool::by_name(&name_ref.text()))
+ .map(PathResolution::Tool),
+ None => None,
}
}
diff --git a/crates/hir_def/src/builtin_attr.rs b/crates/hir_def/src/builtin_attr.rs
index 6cd185ceeb..cd3a8a8605 100644
--- a/crates/hir_def/src/builtin_attr.rs
+++ b/crates/hir_def/src/builtin_attr.rs
@@ -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:
@@ -259,10 +328,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 \
which contains compiler-rt intrinsics and will never be stable",
@@ -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),
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index d7a35caf29..ad4a4aa752 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -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;
}
}
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs
index d5dca95fba..edcea7aace 100644
--- a/crates/ide/src/doc_links.rs
+++ b/crates/ide/src/doc_links.rs
@@ -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::Tool(_)
+ | 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::Tool(_) => return None,
};
Some((def, res, None))
diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs
index dd4a961d31..e72ed8c2b2 100644
--- a/crates/ide/src/hover/render.rs
+++ b/crates/ide/src/hover/render.rs
@@ -369,6 +369,8 @@ pub(super) fn definition(
}
Definition::GenericParam(it) => label_and_docs(db, it),
Definition::Label(it) => return Some(Markup::fenced_block(&it.name(db))),
+ Definition::BuiltinAttr(_) => return None, // FIXME
+ Definition::Tool(_) => return None, // FIXME
};
markup(docs.filter(|_| config.documentation.is_some()).map(Into::into), label, mod_path)
diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs
index 5718b9097c..4187e9ca36 100644
--- a/crates/ide/src/hover/tests.rs
+++ b/crates/ide/src/hover/tests.rs
@@ -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
diff --git a/crates/ide/src/navigation_target.rs b/crates/ide/src/navigation_target.rs
index 7deb6cae38..aa865ddc21 100644
--- a/crates/ide/src/navigation_target.rs
+++ b/crates/ide/src/navigation_target.rs
@@ -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::Tool(_) => None,
+ Definition::BuiltinAttr(_) => None,
}
}
}
diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs
index cf98bc32fa..77d202cc39 100644
--- a/crates/ide/src/static_index.rs
+++ b/crates/ide/src/static_index.rs
@@ -299,6 +299,7 @@ pub func() {
r#"
//- minicore:derive
#[rustc_builtin_macro]
+//^^^^^^^^^^^^^^^^^^^
pub macro Copy {}
//^^^^
#[derive(Copy)]
diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs
index b8177b4ab6..52e729ee68 100644
--- a/crates/ide/src/syntax_highlighting/highlight.rs
+++ b/crates/ide/src/syntax_highlighting/highlight.rs
@@ -542,6 +542,8 @@ fn highlight_def(
h
}
Definition::Label(_) => Highlight::new(HlTag::Symbol(SymbolKind::Label)),
+ Definition::BuiltinAttr(_) => Highlight::new(HlTag::Symbol(SymbolKind::Label)), // FIXME
+ Definition::Tool(_) => Highlight::new(HlTag::Symbol(SymbolKind::Label)), // FIXME
};
let famous_defs = FamousDefs(sema, krate);
diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs
index 686fd5baa7..d4dba50834 100644
--- a/crates/ide/src/syntax_highlighting/inject.rs
+++ b/crates/ide/src/syntax_highlighting/inject.rs
@@ -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::Label, // FIXME
+ Definition::Tool(_) => SymbolKind::Label, // FIXME
};
HlTag::Symbol(symbol)
}
diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs
index 1d7f4392dd..26cdaa1ac1 100644
--- a/crates/ide_db/src/defs.rs
+++ b/crates/ide_db/src/defs.rs
@@ -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, Tool, 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),
+ Tool(Tool),
}
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::Tool(_) => {
+ 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::Tool(_)
+ | 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::Tool(_) => 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::Tool(tool) => Definition::Tool(tool),
}
}
}
diff --git a/crates/ide_db/src/path_transform.rs b/crates/ide_db/src/path_transform.rs
index b8b1307a3c..a4db8b3848 100644
--- a/crates/ide_db/src/path_transform.rs
+++ b/crates/ide_db/src/path_transform.rs
@@ -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::Tool(_) => (),
}
Some(())
}
diff --git a/crates/ide_db/src/rename.rs b/crates/ide_db/src/rename.rs
index 678153c6e1..35bd4d02a6 100644
--- a/crates/ide_db/src/rename.rs
+++ b/crates/ide_db/src/rename.rs
@@ -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::Tool(_) => return None,
};
return res;