Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir_def/src/nameres/collector.rs')
-rw-r--r--crates/hir_def/src/nameres/collector.rs71
1 files changed, 38 insertions, 33 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index e1a297a3fc..985789b70e 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -22,10 +22,10 @@ use itertools::Itertools;
use la_arena::Idx;
use limit::Limit;
use rustc_hash::{FxHashMap, FxHashSet};
-use syntax::ast;
+use syntax::{ast, SmolStr};
use crate::{
- attr::{Attr, AttrId, AttrInput, Attrs},
+ attr::{Attr, AttrId, Attrs},
attr_macro_as_call_id,
db::DefDatabase,
derive_macro_as_call_id,
@@ -61,7 +61,8 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: T
let mut deps = FxHashMap::default();
// populate external prelude and dependency list
- for dep in &crate_graph[def_map.krate].dependencies {
+ let krate = &crate_graph[def_map.krate];
+ for dep in &krate.dependencies {
tracing::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id);
let dep_def_map = db.crate_def_map(dep.crate_id);
let dep_root = dep_def_map.module_id(dep_def_map.root);
@@ -73,9 +74,9 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: T
}
}
- let cfg_options = &crate_graph[def_map.krate].cfg_options;
- let proc_macros = &crate_graph[def_map.krate].proc_macro;
- let proc_macros = proc_macros
+ let cfg_options = &krate.cfg_options;
+ let proc_macros = krate
+ .proc_macro
.iter()
.enumerate()
.map(|(idx, it)| {
@@ -87,6 +88,7 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: T
)
})
.collect();
+ let is_proc_macro = krate.is_proc_macro;
let mut collector = DefCollector {
db,
@@ -103,6 +105,7 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: T
from_glob_import: Default::default(),
skip_attrs: Default::default(),
derive_helpers_in_scope: Default::default(),
+ is_proc_macro,
};
if tree_id.is_block() {
collector.seed_with_inner(tree_id);
@@ -243,6 +246,7 @@ struct DefCollector<'a> {
/// empty when proc. macro support is disabled (in which case we still do name resolution for
/// them).
proc_macros: Vec<(Name, ProcMacroExpander)>,
+ is_proc_macro: bool,
exports_proc_macros: bool,
from_glob_import: PerNsGlobImports,
/// If we fail to resolve an attribute on a `ModItem`, we fall back to ignoring the attribute.
@@ -277,27 +281,29 @@ impl DefCollector<'_> {
};
if *attr_name == hir_expand::name![recursion_limit] {
- if let Some(input) = &attr.input {
- if let AttrInput::Literal(limit) = &**input {
- if let Ok(limit) = limit.parse() {
- self.def_map.recursion_limit = Some(limit);
- }
+ if let Some(limit) = attr.string_value() {
+ if let Ok(limit) = limit.parse() {
+ self.def_map.recursion_limit = Some(limit);
}
}
continue;
}
+ if *attr_name == hir_expand::name![crate_type] {
+ if let Some("proc-macro") = attr.string_value().map(SmolStr::as_str) {
+ self.is_proc_macro = true;
+ }
+ continue;
+ }
+
let attr_is_register_like = *attr_name == hir_expand::name![register_attr]
|| *attr_name == hir_expand::name![register_tool];
if !attr_is_register_like {
continue;
}
- let registered_name = match attr.input.as_deref() {
- Some(AttrInput::TokenTree(subtree, _)) => match &*subtree.token_trees {
- [tt::TokenTree::Leaf(tt::Leaf::Ident(name))] => name.as_name(),
- _ => continue,
- },
+ let registered_name = match attr.single_ident_value() {
+ Some(ident) => ident.as_name(),
_ => continue,
};
@@ -404,8 +410,7 @@ impl DefCollector<'_> {
}
self.unresolved_imports = unresolved_imports;
- // FIXME: This condition should instead check if this is a `proc-macro` type crate.
- if self.exports_proc_macros {
+ if self.is_proc_macro {
// A crate exporting procedural macros is not allowed to export anything else.
//
// Additionally, while the proc macro entry points must be `pub`, they are not publicly
@@ -1555,22 +1560,21 @@ impl ModCollector<'_, '_> {
let fn_id =
FunctionLoc { container, id: ItemTreeId::new(self.tree_id, id) }.intern(db);
- let is_proc_macro = attrs.parse_proc_macro_decl(&it.name);
- let vis = match is_proc_macro {
- Some(proc_macro) => {
- // FIXME: this should only be done in the root module of `proc-macro` crates, not everywhere
- let module_id = def_map.module_id(def_map.root());
-
- self.def_collector.export_proc_macro(
- proc_macro,
- ItemTreeId::new(self.tree_id, id),
- fn_id,
- module_id,
- );
- Visibility::Module(module_id)
+ let vis = resolve_vis(def_map, &self.item_tree[it.visibility]);
+ if self.def_collector.is_proc_macro {
+ if self.module_id == def_map.root {
+ if let Some(proc_macro) = attrs.parse_proc_macro_decl(&it.name) {
+ let crate_root = def_map.module_id(def_map.root);
+ self.def_collector.export_proc_macro(
+ proc_macro,
+ ItemTreeId::new(self.tree_id, id),
+ fn_id,
+ crate_root,
+ );
+ }
}
- None => resolve_vis(def_map, &self.item_tree[it.visibility]),
- };
+ }
+
update_def(self.def_collector, fn_id.into(), &it.name, vis, false);
}
ModItem::Struct(id) => {
@@ -2099,6 +2103,7 @@ mod tests {
from_glob_import: Default::default(),
skip_attrs: Default::default(),
derive_helpers_in_scope: Default::default(),
+ is_proc_macro: false,
};
collector.seed_with_top_level();
collector.collect();