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 | 434 |
1 files changed, 232 insertions, 202 deletions
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index eef54fc492..e9e71a8747 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -33,7 +33,7 @@ use crate::{ attr_macro_as_call_id, db::DefDatabase, derive_macro_as_call_id, - item_scope::{ImportType, PerNsGlobImports}, + item_scope::{ImportId, ImportOrExternCrate, ImportType, PerNsGlobImports}, item_tree::{ self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, ItemTreeNode, MacroCall, MacroDef, MacroRules, Mod, ModItem, ModKind, TreeId, @@ -52,10 +52,10 @@ use crate::{ tt, visibility::{RawVisibility, Visibility}, AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantId, - ExternBlockLoc, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern, ItemContainerId, - LocalModuleId, Macro2Id, Macro2Loc, MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, - ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc, StructLoc, TraitAliasLoc, - TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro, UseLoc, + ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern, + ItemContainerId, LocalModuleId, Lookup, Macro2Id, Macro2Loc, MacroExpander, MacroId, + MacroRulesId, MacroRulesLoc, ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc, + StructLoc, TraitAliasLoc, TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro, UseId, UseLoc, }; static GLOB_RECURSION_LIMIT: Limit = Limit::new(100); @@ -146,8 +146,8 @@ impl PartialResolvedImport { #[derive(Clone, Debug, Eq, PartialEq)] enum ImportSource { - Use { id: ItemTreeId<item_tree::Use>, use_tree: Idx<ast::UseTree> }, - ExternCrate(ItemTreeId<item_tree::ExternCrate>), + Use { use_tree: Idx<ast::UseTree>, id: UseId, is_prelude: bool, kind: ImportKind }, + ExternCrate { id: ExternCrateId }, } #[derive(Debug, Eq, PartialEq)] @@ -155,54 +155,41 @@ struct Import { path: ModPath, alias: Option<ImportAlias>, visibility: RawVisibility, - kind: ImportKind, source: ImportSource, - is_prelude: bool, - is_macro_use: bool, } impl Import { fn from_use( - db: &dyn DefDatabase, - krate: CrateId, tree: &ItemTree, - id: ItemTreeId<item_tree::Use>, + item_tree_id: ItemTreeId<item_tree::Use>, + id: UseId, + is_prelude: bool, mut cb: impl FnMut(Self), ) { - let it = &tree[id.value]; - let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into()); + let it = &tree[item_tree_id.value]; let visibility = &tree[it.visibility]; - let is_prelude = attrs.by_key("prelude_import").exists(); it.use_tree.expand(|idx, path, kind, alias| { cb(Self { path, alias, visibility: visibility.clone(), - kind, - is_prelude, - is_macro_use: false, - source: ImportSource::Use { id, use_tree: idx }, + source: ImportSource::Use { use_tree: idx, id, is_prelude, kind }, }); }); } fn from_extern_crate( - db: &dyn DefDatabase, - krate: CrateId, tree: &ItemTree, - id: ItemTreeId<item_tree::ExternCrate>, + item_tree_id: ItemTreeId<item_tree::ExternCrate>, + id: ExternCrateId, ) -> Self { - let it = &tree[id.value]; - let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into()); + let it = &tree[item_tree_id.value]; let visibility = &tree[it.visibility]; Self { path: ModPath::from_segments(PathKind::Plain, iter::once(it.name.clone())), alias: it.alias.clone(), visibility: visibility.clone(), - kind: ImportKind::Plain, - is_prelude: false, - is_macro_use: attrs.by_key("macro_use").exists(), - source: ImportSource::ExternCrate(id), + source: ImportSource::ExternCrate { id }, } } } @@ -235,7 +222,7 @@ struct DefCollector<'a> { db: &'a dyn DefDatabase, def_map: DefMap, deps: FxHashMap<Name, Dependency>, - glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility)>>, + glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility, UseId)>>, unresolved_imports: Vec<ImportDirective>, indeterminate_imports: Vec<ImportDirective>, unresolved_macros: Vec<MacroDirective>, @@ -280,7 +267,7 @@ impl DefCollector<'_> { if dep.is_prelude() { crate_data .extern_prelude - .insert(name.clone(), CrateRootModuleId { krate: dep.crate_id }); + .insert(name.clone(), (CrateRootModuleId { krate: dep.crate_id }, None)); } } @@ -556,8 +543,12 @@ impl DefCollector<'_> { self.def_map.resolve_path(self.db, DefMap::ROOT, &path, BuiltinShadowMode::Other, None); match per_ns.types { - Some((ModuleDefId::ModuleId(m), _)) => { - self.def_map.prelude = Some(m); + Some((ModuleDefId::ModuleId(m), _, import)) => { + // FIXME: This should specifically look for a glob import somehow and record that here + self.def_map.prelude = Some(( + m, + import.and_then(ImportOrExternCrate::into_import).map(|it| it.import), + )); } types => { tracing::debug!( @@ -657,9 +648,9 @@ impl DefCollector<'_> { self.def_map.modules[module_id].scope.declare(macro_.into()); self.update( module_id, - &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))], + &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))], Visibility::Public, - ImportType::Named, + None, ); } } @@ -693,9 +684,9 @@ impl DefCollector<'_> { self.def_map.modules[module_id].scope.declare(macro_.into()); self.update( module_id, - &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))], + &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))], vis, - ImportType::Named, + None, ); } @@ -708,9 +699,9 @@ impl DefCollector<'_> { self.def_map.modules[module_id].scope.declare(macro_.into()); self.update( module_id, - &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))], + &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))], Visibility::Public, - ImportType::Named, + None, ); } @@ -720,21 +711,29 @@ impl DefCollector<'_> { /// Exported macros are just all macros in the root module scope. /// Note that it contains not only all `#[macro_export]` macros, but also all aliases /// created by `use` in the root module, ignoring the visibility of `use`. - fn import_macros_from_extern_crate(&mut self, krate: CrateId, names: Option<Vec<Name>>) { + fn import_macros_from_extern_crate( + &mut self, + krate: CrateId, + names: Option<Vec<Name>>, + extern_crate: Option<ExternCrateId>, + ) { let def_map = self.db.crate_def_map(krate); // `#[macro_use]` brings macros into macro_use prelude. Yes, even non-`macro_rules!` // macros. let root_scope = &def_map[DefMap::ROOT].scope; - if let Some(names) = names { - for name in names { - // FIXME: Report diagnostic on 404. - if let Some(def) = root_scope.get(&name).take_macros() { - self.def_map.macro_use_prelude.insert(name, def); + match names { + Some(names) => { + for name in names { + // FIXME: Report diagnostic on 404. + if let Some(def) = root_scope.get(&name).take_macros() { + self.def_map.macro_use_prelude.insert(name, (def, extern_crate)); + } } } - } else { - for (name, def) in root_scope.macros() { - self.def_map.macro_use_prelude.insert(name.clone(), def); + None => { + for (name, def) in root_scope.macros() { + self.def_map.macro_use_prelude.insert(name.clone(), (def, extern_crate)); + } } } } @@ -771,48 +770,53 @@ impl DefCollector<'_> { let _p = profile::span("resolve_import") .detail(|| format!("{}", import.path.display(self.db.upcast()))); tracing::debug!("resolving import: {:?} ({:?})", import, self.def_map.data.edition); - if matches!(import.source, ImportSource::ExternCrate { .. }) { - let name = import - .path - .as_ident() - .expect("extern crate should have been desugared to one-element path"); - - let res = self.resolve_extern_crate(name); - - match res { - Some(res) => { - PartialResolvedImport::Resolved(PerNs::types(res.into(), Visibility::Public)) + match import.source { + ImportSource::ExternCrate { .. } => { + let name = import + .path + .as_ident() + .expect("extern crate should have been desugared to one-element path"); + + let res = self.resolve_extern_crate(name); + + match res { + Some(res) => PartialResolvedImport::Resolved(PerNs::types( + res.into(), + Visibility::Public, + None, + )), + None => PartialResolvedImport::Unresolved, } - None => PartialResolvedImport::Unresolved, } - } else { - let res = self.def_map.resolve_path_fp_with_macro( - self.db, - ResolveMode::Import, - module_id, - &import.path, - BuiltinShadowMode::Module, - None, // An import may resolve to any kind of macro. - ); + ImportSource::Use { .. } => { + let res = self.def_map.resolve_path_fp_with_macro( + self.db, + ResolveMode::Import, + module_id, + &import.path, + BuiltinShadowMode::Module, + None, // An import may resolve to any kind of macro. + ); - let def = res.resolved_def; - if res.reached_fixedpoint == ReachedFixedPoint::No || def.is_none() { - return PartialResolvedImport::Unresolved; - } + let def = res.resolved_def; + if res.reached_fixedpoint == ReachedFixedPoint::No || def.is_none() { + return PartialResolvedImport::Unresolved; + } - if let Some(krate) = res.krate { - if krate != self.def_map.krate { - return PartialResolvedImport::Resolved( - def.filter_visibility(|v| matches!(v, Visibility::Public)), - ); + if let Some(krate) = res.krate { + if krate != self.def_map.krate { + return PartialResolvedImport::Resolved( + def.filter_visibility(|v| matches!(v, Visibility::Public)), + ); + } } - } - // Check whether all namespaces are resolved. - if def.is_full() { - PartialResolvedImport::Resolved(def) - } else { - PartialResolvedImport::Indeterminate(def) + // Check whether all namespaces are resolved. + if def.is_full() { + PartialResolvedImport::Resolved(def) + } else { + PartialResolvedImport::Indeterminate(def) + } } } } @@ -837,8 +841,9 @@ impl DefCollector<'_> { .resolve_visibility(self.db, module_id, &directive.import.visibility, false) .unwrap_or(Visibility::Public); - match import.kind { - ImportKind::Plain | ImportKind::TypeOnly => { + match import.source { + ImportSource::ExternCrate { .. } + | ImportSource::Use { kind: ImportKind::Plain | ImportKind::TypeOnly, .. } => { let name = match &import.alias { Some(ImportAlias::Alias(name)) => Some(name), Some(ImportAlias::Underscore) => None, @@ -851,40 +856,44 @@ impl DefCollector<'_> { }, }; - if import.kind == ImportKind::TypeOnly { - def.values = None; - def.macros = None; - } - - tracing::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def); - - // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658 - if matches!(import.source, ImportSource::ExternCrate { .. }) - && self.def_map.block.is_none() - && module_id == DefMap::ROOT - { - if let (Some(ModuleDefId::ModuleId(def)), Some(name)) = (def.take_types(), name) - { - if let Ok(def) = def.try_into() { - Arc::get_mut(&mut self.def_map.data) - .unwrap() - .extern_prelude - .insert(name.clone(), def); + let imp = match import.source { + // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658 + ImportSource::ExternCrate { id, .. } => { + if self.def_map.block.is_none() && module_id == DefMap::ROOT { + if let (Some(ModuleDefId::ModuleId(def)), Some(name)) = + (def.take_types(), name) + { + if let Ok(def) = def.try_into() { + Arc::get_mut(&mut self.def_map.data) + .unwrap() + .extern_prelude + .insert(name.clone(), (def, Some(id))); + } + } } + ImportType::ExternCrate(id) } - } + ImportSource::Use { kind, id, use_tree, .. } => { + if kind == ImportKind::TypeOnly { + def.values = None; + def.macros = None; + } + ImportType::Import(ImportId { import: id, idx: use_tree }) + } + }; + tracing::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def); - self.update(module_id, &[(name.cloned(), def)], vis, ImportType::Named); + self.update(module_id, &[(name.cloned(), def)], vis, Some(imp)); } - ImportKind::Glob => { + ImportSource::Use { kind: ImportKind::Glob, id, .. } => { tracing::debug!("glob import: {:?}", import); match def.take_types() { Some(ModuleDefId::ModuleId(m)) => { - if import.is_prelude { + if let ImportSource::Use { id, is_prelude: true, .. } = import.source { // Note: This dodgily overrides the injected prelude. The rustc // implementation seems to work the same though. cov_mark::hit!(std_prelude); - self.def_map.prelude = Some(m); + self.def_map.prelude = Some((m, Some(id))); } else if m.krate != self.def_map.krate { cov_mark::hit!(glob_across_crates); // glob import from other crate => we can just import everything once @@ -901,7 +910,7 @@ impl DefCollector<'_> { .filter(|(_, res)| !res.is_none()) .collect::<Vec<_>>(); - self.update(module_id, &items, vis, ImportType::Glob); + self.update(module_id, &items, vis, Some(ImportType::Glob(id))); } else { // glob import from same crate => we do an initial // import, and then need to propagate any further @@ -933,11 +942,11 @@ impl DefCollector<'_> { .filter(|(_, res)| !res.is_none()) .collect::<Vec<_>>(); - self.update(module_id, &items, vis, ImportType::Glob); + self.update(module_id, &items, vis, Some(ImportType::Glob(id))); // record the glob import in case we add further items let glob = self.glob_imports.entry(m.local_id).or_default(); - if !glob.iter().any(|(mid, _)| *mid == module_id) { - glob.push((module_id, vis)); + if !glob.iter().any(|(mid, _, _)| *mid == module_id) { + glob.push((module_id, vis, id)); } } } @@ -959,11 +968,11 @@ impl DefCollector<'_> { .map(|(local_id, variant_data)| { let name = variant_data.name.clone(); let variant = EnumVariantId { parent: e, local_id }; - let res = PerNs::both(variant.into(), variant.into(), vis); + let res = PerNs::both(variant.into(), variant.into(), vis, None); (Some(name), res) }) .collect::<Vec<_>>(); - self.update(module_id, &resolutions, vis, ImportType::Glob); + self.update(module_id, &resolutions, vis, Some(ImportType::Glob(id))); } Some(d) => { tracing::debug!("glob import {:?} from non-module/enum {:?}", import, d); @@ -983,10 +992,10 @@ impl DefCollector<'_> { resolutions: &[(Option<Name>, PerNs)], // Visibility this import will have vis: Visibility, - import_type: ImportType, + import: Option<ImportType>, ) { self.db.unwind_if_cancelled(); - self.update_recursive(module_id, resolutions, vis, import_type, 0) + self.update_recursive(module_id, resolutions, vis, import, 0) } fn update_recursive( @@ -997,7 +1006,7 @@ impl DefCollector<'_> { // All resolutions are imported with this visibility; the visibilities in // the `PerNs` values are ignored and overwritten vis: Visibility, - import_type: ImportType, + import: Option<ImportType>, depth: usize, ) { if GLOB_RECURSION_LIMIT.check(depth).is_err() { @@ -1014,7 +1023,7 @@ impl DefCollector<'_> { &mut self.from_glob_import, (module_id, name.clone()), res.with_visibility(vis), - import_type, + import, ); } None => { @@ -1059,7 +1068,7 @@ impl DefCollector<'_> { .get(&module_id) .into_iter() .flatten() - .filter(|(glob_importing_module, _)| { + .filter(|(glob_importing_module, _, _)| { // we know all resolutions have the same visibility (`vis`), so we // just need to check that once vis.is_visible_from_def_map(self.db, &self.def_map, *glob_importing_module) @@ -1067,12 +1076,12 @@ impl DefCollector<'_> { .cloned() .collect::<Vec<_>>(); - for (glob_importing_module, glob_import_vis) in glob_imports { + for (glob_importing_module, glob_import_vis, use_) in glob_imports { self.update_recursive( glob_importing_module, resolutions, glob_import_vis, - ImportType::Glob, + Some(ImportType::Glob(use_)), depth + 1, ); } @@ -1460,31 +1469,34 @@ impl DefCollector<'_> { // heuristic, but it works in practice. let mut diagnosed_extern_crates = FxHashSet::default(); for directive in &self.unresolved_imports { - if let ImportSource::ExternCrate(krate) = directive.import.source { - let item_tree = krate.item_tree(self.db); - let extern_crate = &item_tree[krate.value]; + if let ImportSource::ExternCrate { id } = directive.import.source { + let item_tree_id = id.lookup(self.db).id; + let item_tree = item_tree_id.item_tree(self.db); + let extern_crate = &item_tree[item_tree_id.value]; diagnosed_extern_crates.insert(extern_crate.name.clone()); self.def_map.diagnostics.push(DefDiagnostic::unresolved_extern_crate( directive.module_id, - InFile::new(krate.file_id(), extern_crate.ast_id), + InFile::new(item_tree_id.file_id(), extern_crate.ast_id), )); } } for directive in &self.unresolved_imports { - if let ImportSource::Use { id: import, use_tree } = directive.import.source { + if let ImportSource::Use { use_tree, id, is_prelude: _, kind: _ } = + directive.import.source + { if matches!( (directive.import.path.segments().first(), &directive.import.path.kind), (Some(krate), PathKind::Plain | PathKind::Abs) if diagnosed_extern_crates.contains(krate) ) { continue; } - + let item_tree_id = id.lookup(self.db).id; self.def_map.diagnostics.push(DefDiagnostic::unresolved_import( directive.module_id, - import, + item_tree_id, use_tree, )); } @@ -1519,72 +1531,66 @@ impl ModCollector<'_, '_> { self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone()); // Prelude module is always considered to be `#[macro_use]`. - if let Some(prelude_module) = self.def_collector.def_map.prelude { + if let Some((prelude_module, _use)) = self.def_collector.def_map.prelude { if prelude_module.krate != krate && is_crate_root { cov_mark::hit!(prelude_is_macro_use); - self.def_collector.import_macros_from_extern_crate(prelude_module.krate, None); - } - } - - // This should be processed eagerly instead of deferred to resolving. - // `#[macro_use] extern crate` is hoisted to imports macros before collecting - // any other items. - // - // If we're not at the crate root, `macro_use`d extern crates are an error so let's just - // ignore them. - if is_crate_root { - for &item in items { - if let ModItem::ExternCrate(id) = item { - self.process_macro_use_extern_crate(id); - } + self.def_collector.import_macros_from_extern_crate( + prelude_module.krate, + None, + None, + ); } } + let db = self.def_collector.db; + let module_id = self.module_id; + let update_def = + |def_collector: &mut DefCollector<'_>, id, name: &Name, vis, has_constructor| { + def_collector.def_map.modules[module_id].scope.declare(id); + def_collector.update( + module_id, + &[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor, None))], + vis, + None, + ) + }; + let resolve_vis = |def_map: &DefMap, visibility| { + def_map + .resolve_visibility(db, module_id, visibility, false) + .unwrap_or(Visibility::Public) + }; - for &item in items { - let attrs = self.item_tree.attrs(self.def_collector.db, krate, item.into()); + let mut process_mod_item = |item: ModItem| { + let attrs = self.item_tree.attrs(db, krate, item.into()); if let Some(cfg) = attrs.cfg() { if !self.is_cfg_enabled(&cfg) { self.emit_unconfigured_diagnostic(item, &cfg); - continue; + return; } } if let Err(()) = self.resolve_attributes(&attrs, item, container) { // Do not process the item. It has at least one non-builtin attribute, so the // fixed-point algorithm is required to resolve the rest of them. - continue; + return; } - let db = self.def_collector.db; - let module = self.def_collector.def_map.module_id(self.module_id); + let module = self.def_collector.def_map.module_id(module_id); let def_map = &mut self.def_collector.def_map; - let update_def = - |def_collector: &mut DefCollector<'_>, id, name: &Name, vis, has_constructor| { - def_collector.def_map.modules[self.module_id].scope.declare(id); - def_collector.update( - self.module_id, - &[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor))], - vis, - ImportType::Named, - ) - }; - let resolve_vis = |def_map: &DefMap, visibility| { - def_map - .resolve_visibility(db, self.module_id, visibility, false) - .unwrap_or(Visibility::Public) - }; match item { ModItem::Mod(m) => self.collect_module(m, &attrs), - ModItem::Use(import_id) => { - let _import_id = - UseLoc { container: module, id: ItemTreeId::new(self.tree_id, import_id) } - .intern(db); + ModItem::Use(item_tree_id) => { + let id = UseLoc { + container: module, + id: ItemTreeId::new(self.tree_id, item_tree_id), + } + .intern(db); + let is_prelude = attrs.by_key("prelude_import").exists(); Import::from_use( - db, - krate, self.item_tree, - ItemTreeId::new(self.tree_id, import_id), + ItemTreeId::new(self.tree_id, item_tree_id), + id, + is_prelude, |import| { self.def_collector.unresolved_imports.push(ImportDirective { module_id: self.module_id, @@ -1594,22 +1600,29 @@ impl ModCollector<'_, '_> { }, ) } - ModItem::ExternCrate(import_id) => { - let extern_crate_id = ExternCrateLoc { + ModItem::ExternCrate(item_tree_id) => { + let id = ExternCrateLoc { container: module, - id: ItemTreeId::new(self.tree_id, import_id), + id: ItemTreeId::new(self.tree_id, item_tree_id), } .intern(db); + if is_crate_root { + self.process_macro_use_extern_crate( + item_tree_id, + id, + attrs.by_key("macro_use").attrs(), + ); + } + self.def_collector.def_map.modules[self.module_id] .scope - .define_extern_crate_decl(extern_crate_id); + .define_extern_crate_decl(id); self.def_collector.unresolved_imports.push(ImportDirective { module_id: self.module_id, import: Import::from_extern_crate( - db, - krate, self.item_tree, - ItemTreeId::new(self.tree_id, import_id), + ItemTreeId::new(self.tree_id, item_tree_id), + id, ), status: PartialResolvedImport::Unresolved, }) @@ -1768,21 +1781,34 @@ impl ModCollector<'_, '_> { ); } } + }; + + // extern crates should be processed eagerly instead of deferred to resolving. + // `#[macro_use] extern crate` is hoisted to imports macros before collecting + // any other items. + if is_crate_root { + items + .iter() + .filter(|it| matches!(it, ModItem::ExternCrate(..))) + .copied() + .for_each(&mut process_mod_item); + items + .iter() + .filter(|it| !matches!(it, ModItem::ExternCrate(..))) + .copied() + .for_each(process_mod_item); + } else { + items.iter().copied().for_each(process_mod_item); } } - fn process_macro_use_extern_crate(&mut self, extern_crate: FileItemTreeId<ExternCrate>) { + fn process_macro_use_extern_crate<'a>( + &mut self, + extern_crate: FileItemTreeId<ExternCrate>, + extern_crate_id: ExternCrateId, + macro_use_attrs: impl Iterator<Item = &'a Attr>, + ) { let db = self.def_collector.db; - let attrs = self.item_tree.attrs( - db, - self.def_collector.def_map.krate, - ModItem::from(extern_crate).into(), - ); - if let Some(cfg) = attrs.cfg() { - if !self.is_cfg_enabled(&cfg) { - return; - } - } let target_crate = match self.def_collector.resolve_extern_crate(&self.item_tree[extern_crate].name) { @@ -1798,11 +1824,11 @@ impl ModCollector<'_, '_> { let mut single_imports = Vec::new(); let hygiene = Hygiene::new_unhygienic(); - for attr in attrs.by_key("macro_use").attrs() { + for attr in macro_use_attrs { let Some(paths) = attr.parse_path_comma_token_tree(db.upcast(), &hygiene) else { // `#[macro_use]` (without any paths) found, forget collected names and just import // all visible macros. - self.def_collector.import_macros_from_extern_crate(target_crate, None); + self.def_collector.import_macros_from_extern_crate(target_crate, None, Some(extern_crate_id)); return; }; for path in paths { @@ -1812,7 +1838,11 @@ impl ModCollector<'_, '_> { } } - self.def_collector.import_macros_from_extern_crate(target_crate, Some(single_imports)); + self.def_collector.import_macros_from_extern_crate( + target_crate, + Some(single_imports), + Some(extern_crate_id), + ); } fn collect_module(&mut self, module_id: FileItemTreeId<Mod>, attrs: &Attrs) { @@ -1824,7 +1854,7 @@ impl ModCollector<'_, '_> { ModKind::Inline { items } => { let module_id = self.push_child_module( module.name.clone(), - AstId::new(self.file_id(), module.ast_id), + module.ast_id, None, &self.item_tree[module.visibility], module_id, @@ -1862,7 +1892,7 @@ impl ModCollector<'_, '_> { if is_enabled { let module_id = self.push_child_module( module.name.clone(), - ast_id, + ast_id.value, Some((file_id, is_mod_rs)), &self.item_tree[module.visibility], module_id, @@ -1889,7 +1919,7 @@ impl ModCollector<'_, '_> { Err(candidates) => { self.push_child_module( module.name.clone(), - ast_id, + ast_id.value, None, &self.item_tree[module.visibility], module_id, @@ -1906,7 +1936,7 @@ impl ModCollector<'_, '_> { fn push_child_module( &mut self, name: Name, - declaration: AstId<ast::Module>, + declaration: FileAstId<ast::Module>, definition: Option<(FileId, bool)>, visibility: &crate::visibility::RawVisibility, mod_tree_id: FileItemTreeId<Mod>, @@ -1948,9 +1978,9 @@ impl ModCollector<'_, '_> { def_map.modules[self.module_id].scope.declare(def); self.def_collector.update( self.module_id, - &[(Some(name), PerNs::from_def(def, vis, false))], + &[(Some(name), PerNs::from_def(def, vis, false, None))], vis, - ImportType::Named, + None, ); res } @@ -2198,7 +2228,7 @@ impl ModCollector<'_, '_> { map[module].scope.get_legacy_macro(name)?.last().copied() }) .or_else(|| def_map[self.module_id].scope.get(name).take_macros()) - .or_else(|| def_map.macro_use_prelude.get(name).copied()) + .or_else(|| Some(def_map.macro_use_prelude.get(name).copied()?.0)) .filter(|&id| { sub_namespace_match( Some(MacroSubNs::from_id(db, id)), |