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.rs | 112 |
1 files changed, 48 insertions, 64 deletions
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index 045a869540..a77fd54c91 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -13,6 +13,7 @@ use hir_expand::{ MacroFileIdExt, attrs::{Attr, AttrId}, builtin::{find_builtin_attr, find_builtin_derive, find_builtin_macro}, + mod_path::{ModPath, PathKind}, name::{AsName, Name}, proc_macro::CustomProcMacroExpander, }; @@ -25,18 +26,18 @@ use syntax::ast; use triomphe::Arc; use crate::{ - AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantLoc, - ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern, - ItemContainerId, LocalModuleId, Lookup, Macro2Id, Macro2Loc, MacroExpander, MacroId, - MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ModuleDefId, ModuleId, ProcMacroId, - ProcMacroLoc, StaticLoc, StructLoc, TraitAliasLoc, TraitLoc, TypeAliasLoc, UnionLoc, - UnresolvedMacro, UseId, UseLoc, + AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, ExternBlockLoc, + ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern, ItemContainerId, + LocalModuleId, Lookup, Macro2Id, Macro2Loc, MacroExpander, MacroId, MacroRulesId, + MacroRulesLoc, MacroRulesLocFlags, ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc, + StructLoc, TraitAliasLoc, TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro, UseId, UseLoc, attr::Attrs, db::DefDatabase, item_scope::{GlobId, ImportId, ImportOrExternCrate, PerNsGlobImports}, item_tree::{ - self, AttrOwner, FieldsShape, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, - ItemTreeNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId, UseTreeKind, + self, AttrOwner, FieldsShape, FileItemTreeId, ImportAlias, ImportKind, ItemTree, + ItemTreeId, ItemTreeNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId, + UseTreeKind, }, macro_call_as_call_id, macro_call_as_call_id_with_eager, nameres::{ @@ -48,7 +49,6 @@ use crate::{ proc_macro::{ProcMacroDef, ProcMacroKind, parse_macro_name_and_helper_attrs}, sub_namespace_match, }, - path::{ImportAlias, ModPath, PathKind}, per_ns::{Item, PerNs}, tt, visibility::{RawVisibility, Visibility}, @@ -580,6 +580,7 @@ impl DefCollector<'_> { &mut self, def: ProcMacroDef, id: ItemTreeId<item_tree::Function>, + ast_id: AstId<ast::Fn>, fn_id: FunctionId, ) { let kind = def.kind.to_basedb_kind(); @@ -603,6 +604,8 @@ impl DefCollector<'_> { edition: self.def_map.data.edition, } .intern(self.db); + + self.def_map.macro_def_to_macro_id.insert(ast_id.erase(), proc_macro_id.into()); self.define_proc_macro(def.name.clone(), proc_macro_id); let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap(); if let ProcMacroKind::Derive { helpers } = def.kind { @@ -967,27 +970,16 @@ impl DefCollector<'_> { Some(ModuleDefId::AdtId(AdtId::EnumId(e))) => { cov_mark::hit!(glob_enum); // glob import from enum => just import all the variants - - // We need to check if the def map the enum is from is us, if it is we can't - // call the def-map query since we are currently constructing it! - let loc = e.lookup(self.db); - let tree = loc.id.item_tree(self.db); - let current_def_map = self.def_map.krate == loc.container.krate - && self.def_map.block_id() == loc.container.block; - let def_map; - let resolutions = if current_def_map { - &self.def_map.enum_definitions[&e] - } else { - def_map = loc.container.def_map(self.db); - &def_map.enum_definitions[&e] - } - .iter() - .map(|&variant| { - let name = tree[variant.lookup(self.db).id.value].name.clone(); - let res = PerNs::both(variant.into(), variant.into(), vis, None); - (Some(name), res) - }) - .collect::<Vec<_>>(); + let resolutions = self + .db + .enum_variants(e) + .variants + .iter() + .map(|&(variant, ref name)| { + let res = PerNs::both(variant.into(), variant.into(), vis, None); + (Some(name.clone()), res) + }) + .collect::<Vec<_>>(); self.update( module_id, &resolutions, @@ -1237,6 +1229,7 @@ impl DefCollector<'_> { No, } + let mut eager_callback_buffer = vec![]; let mut res = ReachedFixedPoint::Yes; // Retain unresolved macros after this round of resolution. let mut retain = |directive: &MacroDirective| { @@ -1269,6 +1262,9 @@ impl DefCollector<'_> { *expand_to, self.def_map.krate, resolver_def_id, + &mut |ptr, call_id| { + eager_callback_buffer.push((directive.module_id, ptr, call_id)); + }, ); if let Ok(Some(call_id)) = call_id { self.def_map.modules[directive.module_id] @@ -1494,6 +1490,10 @@ impl DefCollector<'_> { macros.extend(mem::take(&mut self.unresolved_macros)); self.unresolved_macros = macros; + for (module_id, ptr, call_id) in eager_callback_buffer { + self.def_map.modules[module_id].scope.add_macro_invoc(ptr.map(|(_, it)| it), call_id); + } + for (module_id, depth, container, macro_call_id) in resolved { self.collect_macro_expansion(module_id, macro_call_id, depth, container); } @@ -1560,6 +1560,7 @@ impl DefCollector<'_> { ); resolved_res.resolved_def.take_macros().map(|it| self.db.macro_def(it)) }, + &mut |_, _| (), ); if let Err(UnresolvedMacro { path }) = macro_call_as_call_id { self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call( @@ -1839,6 +1840,7 @@ impl ModCollector<'_, '_> { self.def_collector.export_proc_macro( proc_macro, ItemTreeId::new(self.tree_id, id), + InFile::new(self.file_id(), self.item_tree[id].ast_id()), fn_id, ); } @@ -1882,39 +1884,6 @@ impl ModCollector<'_, '_> { let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); update_def(self.def_collector, enum_.into(), &it.name, vis, false); - - let mut index = 0; - let variants = FileItemTreeId::range_iter(it.variants.clone()) - .filter_map(|variant| { - let is_enabled = self - .item_tree - .attrs(db, krate, variant.into()) - .cfg() - .and_then(|cfg| self.is_cfg_enabled(&cfg).not().then_some(cfg)) - .map_or(Ok(()), Err); - match is_enabled { - Err(cfg) => { - self.emit_unconfigured_diagnostic( - self.tree_id, - variant.into(), - &cfg, - ); - None - } - Ok(()) => Some({ - let loc = EnumVariantLoc { - id: ItemTreeId::new(self.tree_id, variant), - parent: enum_, - index, - } - .intern(db); - index += 1; - loc - }), - } - }) - .collect(); - self.def_collector.def_map.enum_definitions.insert(enum_, variants); } ModItem::Const(id) => { let it = &self.item_tree[id]; @@ -2352,6 +2321,10 @@ impl ModCollector<'_, '_> { edition: self.def_collector.def_map.data.edition, } .intern(self.def_collector.db); + self.def_collector.def_map.macro_def_to_macro_id.insert( + InFile::new(self.file_id(), self.item_tree[id].ast_id()).erase(), + macro_id.into(), + ); self.def_collector.define_macro_rules( self.module_id, mac.name.clone(), @@ -2416,6 +2389,10 @@ impl ModCollector<'_, '_> { edition: self.def_collector.def_map.data.edition, } .intern(self.def_collector.db); + self.def_collector.def_map.macro_def_to_macro_id.insert( + InFile::new(self.file_id(), self.item_tree[id].ast_id()).erase(), + macro_id.into(), + ); self.def_collector.define_macro_def( self.module_id, mac.name.clone(), @@ -2444,6 +2421,7 @@ impl ModCollector<'_, '_> { // new legacy macros that create textual scopes. We need a way to resolve names in textual // scopes without eager expansion. + let mut eager_callback_buffer = vec![]; // Case 1: try to resolve macro calls with single-segment name and expand macro_rules if let Ok(res) = macro_call_as_call_id_with_eager( db.upcast(), @@ -2485,7 +2463,13 @@ impl ModCollector<'_, '_> { ); resolved_res.resolved_def.take_macros().map(|it| db.macro_def(it)) }, + &mut |ptr, call_id| eager_callback_buffer.push((ptr, call_id)), ) { + for (ptr, call_id) in eager_callback_buffer { + self.def_collector.def_map.modules[self.module_id] + .scope + .add_macro_invoc(ptr.map(|(_, it)| it), call_id); + } // FIXME: if there were errors, this might've been in the eager expansion from an // unresolved macro, so we need to push this into late macro resolution. see fixme above if res.err.is_none() { @@ -2648,7 +2632,7 @@ foo!(KABOOM); // the release mode. That's why the argument is not an ra_fixture -- // otherwise injection highlighting gets stuck. // - // We need to find a way to fail this faster. + // We need to find a way to fail this faster! do_resolve( r#" macro_rules! foo { |