]> git.lizzy.rs Git - rust.git/blob - crates/hir_def/src/nameres/collector.rs
Handle attribute macros in `descend_into_macros`
[rust.git] / crates / hir_def / src / nameres / collector.rs
1 //! The core of the module-level name resolution algorithm.
2 //!
3 //! `DefCollector::collect` contains the fixed-point iteration loop which
4 //! resolves imports and expands macros.
5
6 use std::iter;
7
8 use base_db::{CrateId, Edition, FileId, ProcMacroId};
9 use cfg::{CfgExpr, CfgOptions};
10 use hir_expand::{
11     ast_id_map::FileAstId,
12     builtin_derive::find_builtin_derive,
13     builtin_macro::find_builtin_macro,
14     name::{name, AsName, Name},
15     proc_macro::ProcMacroExpander,
16     FragmentKind, HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
17 };
18 use hir_expand::{InFile, MacroCallLoc};
19 use itertools::Itertools;
20 use la_arena::Idx;
21 use rustc_hash::{FxHashMap, FxHashSet};
22 use syntax::ast;
23
24 use crate::{
25     attr::{Attr, AttrId, AttrInput, Attrs},
26     attr_macro_as_call_id, builtin_attr,
27     db::DefDatabase,
28     derive_macro_as_call_id,
29     intern::Interned,
30     item_scope::{ImportType, PerNsGlobImports},
31     item_tree::{
32         self, Fields, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, MacroDef, MacroRules, Mod,
33         ModItem, ModKind,
34     },
35     macro_call_as_call_id,
36     nameres::{
37         diagnostics::DefDiagnostic,
38         mod_resolution::ModDir,
39         path_resolution::ReachedFixedPoint,
40         proc_macro::{ProcMacroDef, ProcMacroKind},
41         BuiltinShadowMode, DefMap, ModuleData, ModuleOrigin, ResolveMode,
42     },
43     path::{ImportAlias, ModPath, PathKind},
44     per_ns::PerNs,
45     visibility::{RawVisibility, Visibility},
46     AdtId, AstId, AstIdWithPath, ConstLoc, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern,
47     LocalModuleId, ModuleDefId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc,
48     UnresolvedMacro,
49 };
50
51 const GLOB_RECURSION_LIMIT: usize = 100;
52 const EXPANSION_DEPTH_LIMIT: usize = 128;
53 const FIXED_POINT_LIMIT: usize = 8192;
54
55 pub(super) fn collect_defs(
56     db: &dyn DefDatabase,
57     mut def_map: DefMap,
58     block: Option<AstId<ast::BlockExpr>>,
59 ) -> DefMap {
60     let crate_graph = db.crate_graph();
61
62     if block.is_none() {
63         // populate external prelude
64         for dep in &crate_graph[def_map.krate].dependencies {
65             log::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id);
66             let dep_def_map = db.crate_def_map(dep.crate_id);
67             def_map
68                 .extern_prelude
69                 .insert(dep.as_name(), dep_def_map.module_id(dep_def_map.root).into());
70         }
71     }
72
73     let cfg_options = &crate_graph[def_map.krate].cfg_options;
74     let proc_macros = &crate_graph[def_map.krate].proc_macro;
75     let proc_macros = proc_macros
76         .iter()
77         .enumerate()
78         .map(|(idx, it)| {
79             // FIXME: a hacky way to create a Name from string.
80             let name = tt::Ident { text: it.name.clone(), id: tt::TokenId::unspecified() };
81             (name.as_name(), ProcMacroExpander::new(def_map.krate, ProcMacroId(idx as u32)))
82         })
83         .collect();
84
85     let mut collector = DefCollector {
86         db,
87         def_map,
88         glob_imports: FxHashMap::default(),
89         unresolved_imports: Vec::new(),
90         resolved_imports: Vec::new(),
91
92         unresolved_macros: Vec::new(),
93         mod_dirs: FxHashMap::default(),
94         cfg_options,
95         proc_macros,
96         exports_proc_macros: false,
97         from_glob_import: Default::default(),
98         skip_attrs: Default::default(),
99         derive_helpers_in_scope: Default::default(),
100         registered_attrs: Default::default(),
101         registered_tools: Default::default(),
102     };
103     match block {
104         Some(block) => {
105             collector.seed_with_inner(block);
106         }
107         None => {
108             collector.seed_with_top_level();
109         }
110     }
111     collector.collect();
112     let mut def_map = collector.finish();
113     def_map.shrink_to_fit();
114     def_map
115 }
116
117 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
118 enum PartialResolvedImport {
119     /// None of any namespaces is resolved
120     Unresolved,
121     /// One of namespaces is resolved
122     Indeterminate(PerNs),
123     /// All namespaces are resolved, OR it is came from other crate
124     Resolved(PerNs),
125 }
126
127 impl PartialResolvedImport {
128     fn namespaces(&self) -> PerNs {
129         match self {
130             PartialResolvedImport::Unresolved => PerNs::none(),
131             PartialResolvedImport::Indeterminate(ns) => *ns,
132             PartialResolvedImport::Resolved(ns) => *ns,
133         }
134     }
135 }
136
137 #[derive(Clone, Debug, Eq, PartialEq)]
138 enum ImportSource {
139     Import { id: ItemTreeId<item_tree::Import>, use_tree: Idx<ast::UseTree> },
140     ExternCrate(ItemTreeId<item_tree::ExternCrate>),
141 }
142
143 #[derive(Clone, Debug, Eq, PartialEq)]
144 struct Import {
145     path: Interned<ModPath>,
146     alias: Option<ImportAlias>,
147     visibility: RawVisibility,
148     is_glob: bool,
149     is_prelude: bool,
150     is_extern_crate: bool,
151     is_macro_use: bool,
152     source: ImportSource,
153 }
154
155 impl Import {
156     fn from_use(
157         db: &dyn DefDatabase,
158         krate: CrateId,
159         tree: &ItemTree,
160         id: ItemTreeId<item_tree::Import>,
161     ) -> Vec<Self> {
162         let it = &tree[id.value];
163         let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into());
164         let visibility = &tree[it.visibility];
165         let is_prelude = attrs.by_key("prelude_import").exists();
166
167         let mut res = Vec::new();
168         it.use_tree.expand(|idx, path, is_glob, alias| {
169             res.push(Self {
170                 path: Interned::new(path), // FIXME this makes little sense
171                 alias,
172                 visibility: visibility.clone(),
173                 is_glob,
174                 is_prelude,
175                 is_extern_crate: false,
176                 is_macro_use: false,
177                 source: ImportSource::Import { id, use_tree: idx },
178             });
179         });
180         res
181     }
182
183     fn from_extern_crate(
184         db: &dyn DefDatabase,
185         krate: CrateId,
186         tree: &ItemTree,
187         id: ItemTreeId<item_tree::ExternCrate>,
188     ) -> Self {
189         let it = &tree[id.value];
190         let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into());
191         let visibility = &tree[it.visibility];
192         Self {
193             path: Interned::new(ModPath::from_segments(
194                 PathKind::Plain,
195                 iter::once(it.name.clone()),
196             )),
197             alias: it.alias.clone(),
198             visibility: visibility.clone(),
199             is_glob: false,
200             is_prelude: false,
201             is_extern_crate: true,
202             is_macro_use: attrs.by_key("macro_use").exists(),
203             source: ImportSource::ExternCrate(id),
204         }
205     }
206 }
207
208 #[derive(Clone, Debug, Eq, PartialEq)]
209 struct ImportDirective {
210     module_id: LocalModuleId,
211     import: Import,
212     status: PartialResolvedImport,
213 }
214
215 #[derive(Clone, Debug, Eq, PartialEq)]
216 struct MacroDirective {
217     module_id: LocalModuleId,
218     depth: usize,
219     kind: MacroDirectiveKind,
220 }
221
222 #[derive(Clone, Debug, Eq, PartialEq)]
223 enum MacroDirectiveKind {
224     FnLike { ast_id: AstIdWithPath<ast::MacroCall>, fragment: FragmentKind },
225     Derive { ast_id: AstIdWithPath<ast::Item>, derive_attr: AttrId },
226     Attr { ast_id: AstIdWithPath<ast::Item>, attr: Attr, mod_item: ModItem },
227 }
228
229 struct DefData<'a> {
230     id: ModuleDefId,
231     name: &'a Name,
232     visibility: &'a RawVisibility,
233     has_constructor: bool,
234 }
235
236 /// Walks the tree of module recursively
237 struct DefCollector<'a> {
238     db: &'a dyn DefDatabase,
239     def_map: DefMap,
240     glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility)>>,
241     unresolved_imports: Vec<ImportDirective>,
242     resolved_imports: Vec<ImportDirective>,
243     unresolved_macros: Vec<MacroDirective>,
244     mod_dirs: FxHashMap<LocalModuleId, ModDir>,
245     cfg_options: &'a CfgOptions,
246     /// List of procedural macros defined by this crate. This is read from the dynamic library
247     /// built by the build system, and is the list of proc. macros we can actually expand. It is
248     /// empty when proc. macro support is disabled (in which case we still do name resolution for
249     /// them).
250     proc_macros: Vec<(Name, ProcMacroExpander)>,
251     exports_proc_macros: bool,
252     from_glob_import: PerNsGlobImports,
253     /// If we fail to resolve an attribute on a `ModItem`, we fall back to ignoring the attribute.
254     /// This map is used to skip all attributes up to and including the one that failed to resolve,
255     /// in order to not expand them twice.
256     ///
257     /// This also stores the attributes to skip when we resolve derive helpers and non-macro
258     /// non-builtin attributes in general.
259     skip_attrs: FxHashMap<InFile<ModItem>, AttrId>,
260     /// Tracks which custom derives are in scope for an item, to allow resolution of derive helper
261     /// attributes.
262     derive_helpers_in_scope: FxHashMap<AstId<ast::Item>, Vec<Name>>,
263     /// Custom attributes registered with `#![register_attr]`.
264     registered_attrs: Vec<String>,
265     /// Custom tool modules registered with `#![register_tool]`.
266     registered_tools: Vec<String>,
267 }
268
269 impl DefCollector<'_> {
270     fn seed_with_top_level(&mut self) {
271         let file_id = self.db.crate_graph()[self.def_map.krate].root_file_id;
272         let item_tree = self.db.file_item_tree(file_id.into());
273         let module_id = self.def_map.root;
274         self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id };
275
276         let attrs = item_tree.top_level_attrs(self.db, self.def_map.krate);
277         if attrs.cfg().map_or(true, |cfg| self.cfg_options.check(&cfg) != Some(false)) {
278             self.inject_prelude(&attrs);
279
280             // Process other crate-level attributes.
281             for attr in &*attrs {
282                 let attr_name = match attr.path.as_ident() {
283                     Some(name) => name,
284                     None => continue,
285                 };
286
287                 let registered_name = if *attr_name == hir_expand::name![register_attr]
288                     || *attr_name == hir_expand::name![register_tool]
289                 {
290                     match attr.input.as_deref() {
291                         Some(AttrInput::TokenTree(subtree)) => match &*subtree.token_trees {
292                             [tt::TokenTree::Leaf(tt::Leaf::Ident(name))] => name.as_name(),
293                             _ => continue,
294                         },
295                         _ => continue,
296                     }
297                 } else {
298                     continue;
299                 };
300
301                 if *attr_name == hir_expand::name![register_attr] {
302                     self.registered_attrs.push(registered_name.to_string());
303                     cov_mark::hit!(register_attr);
304                 } else {
305                     self.registered_tools.push(registered_name.to_string());
306                     cov_mark::hit!(register_tool);
307                 }
308             }
309
310             ModCollector {
311                 def_collector: &mut *self,
312                 macro_depth: 0,
313                 module_id,
314                 file_id: file_id.into(),
315                 item_tree: &item_tree,
316                 mod_dir: ModDir::root(),
317             }
318             .collect(item_tree.top_level_items());
319         }
320     }
321
322     fn seed_with_inner(&mut self, block: AstId<ast::BlockExpr>) {
323         let item_tree = self.db.file_item_tree(block.file_id);
324         let module_id = self.def_map.root;
325         self.def_map.modules[module_id].origin = ModuleOrigin::BlockExpr { block };
326         if item_tree
327             .top_level_attrs(self.db, self.def_map.krate)
328             .cfg()
329             .map_or(true, |cfg| self.cfg_options.check(&cfg) != Some(false))
330         {
331             ModCollector {
332                 def_collector: &mut *self,
333                 macro_depth: 0,
334                 module_id,
335                 file_id: block.file_id,
336                 item_tree: &item_tree,
337                 mod_dir: ModDir::root(),
338             }
339             .collect(item_tree.inner_items_of_block(block.value));
340         }
341     }
342
343     fn collect(&mut self) {
344         // main name resolution fixed-point loop.
345         let mut i = 0;
346         'outer: loop {
347             loop {
348                 self.db.unwind_if_cancelled();
349                 loop {
350                     if self.resolve_imports() == ReachedFixedPoint::Yes {
351                         break;
352                     }
353                 }
354                 if self.resolve_macros() == ReachedFixedPoint::Yes {
355                     break;
356                 }
357
358                 i += 1;
359                 if i == FIXED_POINT_LIMIT {
360                     log::error!("name resolution is stuck");
361                     break 'outer;
362                 }
363             }
364
365             if self.reseed_with_unresolved_attribute() == ReachedFixedPoint::Yes {
366                 break;
367             }
368         }
369
370         // Resolve all indeterminate resolved imports again
371         // As some of the macros will expand newly import shadowing partial resolved imports
372         // FIXME: We maybe could skip this, if we handle the indeterminate imports in `resolve_imports`
373         // correctly
374         let partial_resolved = self.resolved_imports.iter().filter_map(|directive| {
375             if let PartialResolvedImport::Indeterminate(_) = directive.status {
376                 let mut directive = directive.clone();
377                 directive.status = PartialResolvedImport::Unresolved;
378                 Some(directive)
379             } else {
380                 None
381             }
382         });
383         self.unresolved_imports.extend(partial_resolved);
384         self.resolve_imports();
385
386         let unresolved_imports = std::mem::replace(&mut self.unresolved_imports, Vec::new());
387         // show unresolved imports in completion, etc
388         for directive in &unresolved_imports {
389             self.record_resolved_import(directive)
390         }
391         self.unresolved_imports = unresolved_imports;
392
393         // FIXME: This condition should instead check if this is a `proc-macro` type crate.
394         if self.exports_proc_macros {
395             // A crate exporting procedural macros is not allowed to export anything else.
396             //
397             // Additionally, while the proc macro entry points must be `pub`, they are not publicly
398             // exported in type/value namespace. This function reduces the visibility of all items
399             // in the crate root that aren't proc macros.
400             let root = self.def_map.root;
401             let module_id = self.def_map.module_id(root);
402             let root = &mut self.def_map.modules[root];
403             root.scope.censor_non_proc_macros(module_id);
404         }
405     }
406
407     /// When the fixed-point loop reaches a stable state, we might still have some unresolved
408     /// attributes (or unexpanded attribute proc macros) left over. This takes one of them, and
409     /// feeds the item it's applied to back into name resolution.
410     ///
411     /// This effectively ignores the fact that the macro is there and just treats the items as
412     /// normal code.
413     ///
414     /// This improves UX when proc macros are turned off or don't work, and replicates the behavior
415     /// before we supported proc. attribute macros.
416     fn reseed_with_unresolved_attribute(&mut self) -> ReachedFixedPoint {
417         cov_mark::hit!(unresolved_attribute_fallback);
418
419         let mut unresolved_macros = std::mem::replace(&mut self.unresolved_macros, Vec::new());
420         let pos = unresolved_macros.iter().position(|directive| {
421             if let MacroDirectiveKind::Attr { ast_id, mod_item, attr } = &directive.kind {
422                 self.skip_attrs.insert(ast_id.ast_id.with_value(*mod_item), attr.id);
423
424                 let file_id = ast_id.ast_id.file_id;
425                 let item_tree = self.db.file_item_tree(file_id);
426                 let mod_dir = self.mod_dirs[&directive.module_id].clone();
427                 ModCollector {
428                     def_collector: &mut *self,
429                     macro_depth: directive.depth,
430                     module_id: directive.module_id,
431                     file_id,
432                     item_tree: &item_tree,
433                     mod_dir,
434                 }
435                 .collect(&[*mod_item]);
436                 true
437             } else {
438                 false
439             }
440         });
441
442         if let Some(pos) = pos {
443             unresolved_macros.remove(pos);
444         }
445
446         // The collection above might add new unresolved macros (eg. derives), so merge the lists.
447         self.unresolved_macros.extend(unresolved_macros);
448
449         if pos.is_some() {
450             // Continue name resolution with the new data.
451             ReachedFixedPoint::No
452         } else {
453             ReachedFixedPoint::Yes
454         }
455     }
456
457     fn inject_prelude(&mut self, crate_attrs: &Attrs) {
458         // See compiler/rustc_builtin_macros/src/standard_library_imports.rs
459
460         if crate_attrs.by_key("no_core").exists() {
461             // libcore does not get a prelude.
462             return;
463         }
464
465         let krate = if crate_attrs.by_key("no_std").exists() {
466             name![core]
467         } else {
468             let std = name![std];
469             if self.def_map.extern_prelude().any(|(name, _)| *name == std) {
470                 std
471             } else {
472                 // If `std` does not exist for some reason, fall back to core. This mostly helps
473                 // keep r-a's own tests minimal.
474                 name![core]
475             }
476         };
477
478         let edition = match self.def_map.edition {
479             Edition::Edition2015 => name![rust_2015],
480             Edition::Edition2018 => name![rust_2018],
481             Edition::Edition2021 => name![rust_2021],
482         };
483
484         let path_kind = if self.def_map.edition == Edition::Edition2015 {
485             PathKind::Plain
486         } else {
487             PathKind::Abs
488         };
489         let path = ModPath::from_segments(
490             path_kind.clone(),
491             [krate.clone(), name![prelude], edition].iter().cloned(),
492         );
493         // Fall back to the older `std::prelude::v1` for compatibility with Rust <1.52.0
494         // FIXME remove this fallback
495         let fallback_path =
496             ModPath::from_segments(path_kind, [krate, name![prelude], name![v1]].iter().cloned());
497
498         for path in &[path, fallback_path] {
499             let (per_ns, _) = self.def_map.resolve_path(
500                 self.db,
501                 self.def_map.root,
502                 &path,
503                 BuiltinShadowMode::Other,
504             );
505
506             match &per_ns.types {
507                 Some((ModuleDefId::ModuleId(m), _)) => {
508                     self.def_map.prelude = Some(*m);
509                     return;
510                 }
511                 _ => {
512                     log::debug!(
513                         "could not resolve prelude path `{}` to module (resolved to {:?})",
514                         path,
515                         per_ns.types
516                     );
517                 }
518             }
519         }
520     }
521
522     /// Adds a definition of procedural macro `name` to the root module.
523     ///
524     /// # Notes on procedural macro resolution
525     ///
526     /// Procedural macro functionality is provided by the build system: It has to build the proc
527     /// macro and pass the resulting dynamic library to rust-analyzer.
528     ///
529     /// When procedural macro support is enabled, the list of proc macros exported by a crate is
530     /// known before we resolve names in the crate. This list is stored in `self.proc_macros` and is
531     /// derived from the dynamic library.
532     ///
533     /// However, we *also* would like to be able to at least *resolve* macros on our own, without
534     /// help by the build system. So, when the macro isn't found in `self.proc_macros`, we instead
535     /// use a dummy expander that always errors. This comes with the drawback of macros potentially
536     /// going out of sync with what the build system sees (since we resolve using VFS state, but
537     /// Cargo builds only on-disk files). We could and probably should add diagnostics for that.
538     fn export_proc_macro(&mut self, def: ProcMacroDef, ast_id: AstId<ast::Fn>) {
539         let kind = def.kind.to_basedb_kind();
540         self.exports_proc_macros = true;
541         let macro_def = match self.proc_macros.iter().find(|(n, _)| n == &def.name) {
542             Some((_, expander)) => MacroDefId {
543                 krate: self.def_map.krate,
544                 kind: MacroDefKind::ProcMacro(*expander, kind, ast_id),
545                 local_inner: false,
546             },
547             None => MacroDefId {
548                 krate: self.def_map.krate,
549                 kind: MacroDefKind::ProcMacro(
550                     ProcMacroExpander::dummy(self.def_map.krate),
551                     kind,
552                     ast_id,
553                 ),
554                 local_inner: false,
555             },
556         };
557
558         self.define_proc_macro(def.name.clone(), macro_def);
559         self.def_map.exported_proc_macros.insert(macro_def, def);
560     }
561
562     /// Define a macro with `macro_rules`.
563     ///
564     /// It will define the macro in legacy textual scope, and if it has `#[macro_export]`,
565     /// then it is also defined in the root module scope.
566     /// You can `use` or invoke it by `crate::macro_name` anywhere, before or after the definition.
567     ///
568     /// It is surprising that the macro will never be in the current module scope.
569     /// These code fails with "unresolved import/macro",
570     /// ```rust,compile_fail
571     /// mod m { macro_rules! foo { () => {} } }
572     /// use m::foo as bar;
573     /// ```
574     ///
575     /// ```rust,compile_fail
576     /// macro_rules! foo { () => {} }
577     /// self::foo!();
578     /// crate::foo!();
579     /// ```
580     ///
581     /// Well, this code compiles, because the plain path `foo` in `use` is searched
582     /// in the legacy textual scope only.
583     /// ```rust
584     /// macro_rules! foo { () => {} }
585     /// use foo as bar;
586     /// ```
587     fn define_macro_rules(
588         &mut self,
589         module_id: LocalModuleId,
590         name: Name,
591         macro_: MacroDefId,
592         export: bool,
593     ) {
594         // Textual scoping
595         self.define_legacy_macro(module_id, name.clone(), macro_);
596
597         // Module scoping
598         // In Rust, `#[macro_export]` macros are unconditionally visible at the
599         // crate root, even if the parent modules is **not** visible.
600         if export {
601             self.update(
602                 self.def_map.root,
603                 &[(Some(name), PerNs::macros(macro_, Visibility::Public))],
604                 Visibility::Public,
605                 ImportType::Named,
606             );
607         }
608     }
609
610     /// Define a legacy textual scoped macro in module
611     ///
612     /// We use a map `legacy_macros` to store all legacy textual scoped macros visible per module.
613     /// It will clone all macros from parent legacy scope, whose definition is prior to
614     /// the definition of current module.
615     /// And also, `macro_use` on a module will import all legacy macros visible inside to
616     /// current legacy scope, with possible shadowing.
617     fn define_legacy_macro(&mut self, module_id: LocalModuleId, name: Name, mac: MacroDefId) {
618         // Always shadowing
619         self.def_map.modules[module_id].scope.define_legacy_macro(name, mac);
620     }
621
622     /// Define a macro 2.0 macro
623     ///
624     /// The scoped of macro 2.0 macro is equal to normal function
625     fn define_macro_def(
626         &mut self,
627         module_id: LocalModuleId,
628         name: Name,
629         macro_: MacroDefId,
630         vis: &RawVisibility,
631     ) {
632         let vis =
633             self.def_map.resolve_visibility(self.db, module_id, vis).unwrap_or(Visibility::Public);
634         self.update(module_id, &[(Some(name), PerNs::macros(macro_, vis))], vis, ImportType::Named);
635     }
636
637     /// Define a proc macro
638     ///
639     /// A proc macro is similar to normal macro scope, but it would not visible in legacy textual scoped.
640     /// And unconditionally exported.
641     fn define_proc_macro(&mut self, name: Name, macro_: MacroDefId) {
642         self.update(
643             self.def_map.root,
644             &[(Some(name), PerNs::macros(macro_, Visibility::Public))],
645             Visibility::Public,
646             ImportType::Named,
647         );
648     }
649
650     /// Import macros from `#[macro_use] extern crate`.
651     fn import_macros_from_extern_crate(
652         &mut self,
653         current_module_id: LocalModuleId,
654         extern_crate: &item_tree::ExternCrate,
655     ) {
656         log::debug!(
657             "importing macros from extern crate: {:?} ({:?})",
658             extern_crate,
659             self.def_map.edition,
660         );
661
662         let res = self.def_map.resolve_name_in_extern_prelude(self.db, &extern_crate.name);
663
664         if let Some(ModuleDefId::ModuleId(m)) = res.take_types() {
665             if m == self.def_map.module_id(current_module_id) {
666                 cov_mark::hit!(ignore_macro_use_extern_crate_self);
667                 return;
668             }
669
670             cov_mark::hit!(macro_rules_from_other_crates_are_visible_with_macro_use);
671             self.import_all_macros_exported(current_module_id, m.krate);
672         }
673     }
674
675     /// Import all exported macros from another crate
676     ///
677     /// Exported macros are just all macros in the root module scope.
678     /// Note that it contains not only all `#[macro_export]` macros, but also all aliases
679     /// created by `use` in the root module, ignoring the visibility of `use`.
680     fn import_all_macros_exported(&mut self, current_module_id: LocalModuleId, krate: CrateId) {
681         let def_map = self.db.crate_def_map(krate);
682         for (name, def) in def_map[def_map.root].scope.macros() {
683             // `macro_use` only bring things into legacy scope.
684             self.define_legacy_macro(current_module_id, name.clone(), def);
685         }
686     }
687
688     /// Tries to resolve every currently unresolved import.
689     fn resolve_imports(&mut self) -> ReachedFixedPoint {
690         let mut res = ReachedFixedPoint::Yes;
691         let imports = std::mem::replace(&mut self.unresolved_imports, Vec::new());
692         let imports = imports
693             .into_iter()
694             .filter_map(|mut directive| {
695                 directive.status = self.resolve_import(directive.module_id, &directive.import);
696                 match directive.status {
697                     PartialResolvedImport::Indeterminate(_) => {
698                         self.record_resolved_import(&directive);
699                         // FIXME: For avoid performance regression,
700                         // we consider an imported resolved if it is indeterminate (i.e not all namespace resolved)
701                         self.resolved_imports.push(directive);
702                         res = ReachedFixedPoint::No;
703                         None
704                     }
705                     PartialResolvedImport::Resolved(_) => {
706                         self.record_resolved_import(&directive);
707                         self.resolved_imports.push(directive);
708                         res = ReachedFixedPoint::No;
709                         None
710                     }
711                     PartialResolvedImport::Unresolved => Some(directive),
712                 }
713             })
714             .collect();
715         self.unresolved_imports = imports;
716         res
717     }
718
719     fn resolve_import(&self, module_id: LocalModuleId, import: &Import) -> PartialResolvedImport {
720         log::debug!("resolving import: {:?} ({:?})", import, self.def_map.edition);
721         if import.is_extern_crate {
722             let res = self.def_map.resolve_name_in_extern_prelude(
723                 self.db,
724                 &import
725                     .path
726                     .as_ident()
727                     .expect("extern crate should have been desugared to one-element path"),
728             );
729             if res.is_none() {
730                 PartialResolvedImport::Unresolved
731             } else {
732                 PartialResolvedImport::Resolved(res)
733             }
734         } else {
735             let res = self.def_map.resolve_path_fp_with_macro(
736                 self.db,
737                 ResolveMode::Import,
738                 module_id,
739                 &import.path,
740                 BuiltinShadowMode::Module,
741             );
742
743             let def = res.resolved_def;
744             if res.reached_fixedpoint == ReachedFixedPoint::No || def.is_none() {
745                 return PartialResolvedImport::Unresolved;
746             }
747
748             if let Some(krate) = res.krate {
749                 if krate != self.def_map.krate {
750                     return PartialResolvedImport::Resolved(def);
751                 }
752             }
753
754             // Check whether all namespace is resolved
755             if def.take_types().is_some()
756                 && def.take_values().is_some()
757                 && def.take_macros().is_some()
758             {
759                 PartialResolvedImport::Resolved(def)
760             } else {
761                 PartialResolvedImport::Indeterminate(def)
762             }
763         }
764     }
765
766     fn record_resolved_import(&mut self, directive: &ImportDirective) {
767         let module_id = directive.module_id;
768         let import = &directive.import;
769         let def = directive.status.namespaces();
770         let vis = self
771             .def_map
772             .resolve_visibility(self.db, module_id, &directive.import.visibility)
773             .unwrap_or(Visibility::Public);
774
775         if import.is_glob {
776             log::debug!("glob import: {:?}", import);
777             match def.take_types() {
778                 Some(ModuleDefId::ModuleId(m)) => {
779                     if import.is_prelude {
780                         // Note: This dodgily overrides the injected prelude. The rustc
781                         // implementation seems to work the same though.
782                         cov_mark::hit!(std_prelude);
783                         self.def_map.prelude = Some(m);
784                     } else if m.krate != self.def_map.krate {
785                         cov_mark::hit!(glob_across_crates);
786                         // glob import from other crate => we can just import everything once
787                         let item_map = m.def_map(self.db);
788                         let scope = &item_map[m.local_id].scope;
789
790                         // Module scoped macros is included
791                         let items = scope
792                             .resolutions()
793                             // only keep visible names...
794                             .map(|(n, res)| {
795                                 (n, res.filter_visibility(|v| v.is_visible_from_other_crate()))
796                             })
797                             .filter(|(_, res)| !res.is_none())
798                             .collect::<Vec<_>>();
799
800                         self.update(module_id, &items, vis, ImportType::Glob);
801                     } else {
802                         // glob import from same crate => we do an initial
803                         // import, and then need to propagate any further
804                         // additions
805                         let def_map;
806                         let scope = if m.block == self.def_map.block_id() {
807                             &self.def_map[m.local_id].scope
808                         } else {
809                             def_map = m.def_map(self.db);
810                             &def_map[m.local_id].scope
811                         };
812
813                         // Module scoped macros is included
814                         let items = scope
815                             .resolutions()
816                             // only keep visible names...
817                             .map(|(n, res)| {
818                                 (
819                                     n,
820                                     res.filter_visibility(|v| {
821                                         v.is_visible_from_def_map(self.db, &self.def_map, module_id)
822                                     }),
823                                 )
824                             })
825                             .filter(|(_, res)| !res.is_none())
826                             .collect::<Vec<_>>();
827
828                         self.update(module_id, &items, vis, ImportType::Glob);
829                         // record the glob import in case we add further items
830                         let glob = self.glob_imports.entry(m.local_id).or_default();
831                         if !glob.iter().any(|(mid, _)| *mid == module_id) {
832                             glob.push((module_id, vis));
833                         }
834                     }
835                 }
836                 Some(ModuleDefId::AdtId(AdtId::EnumId(e))) => {
837                     cov_mark::hit!(glob_enum);
838                     // glob import from enum => just import all the variants
839
840                     // XXX: urgh, so this works by accident! Here, we look at
841                     // the enum data, and, in theory, this might require us to
842                     // look back at the crate_def_map, creating a cycle. For
843                     // example, `enum E { crate::some_macro!(); }`. Luckily, the
844                     // only kind of macro that is allowed inside enum is a
845                     // `cfg_macro`, and we don't need to run name resolution for
846                     // it, but this is sheer luck!
847                     let enum_data = self.db.enum_data(e);
848                     let resolutions = enum_data
849                         .variants
850                         .iter()
851                         .map(|(local_id, variant_data)| {
852                             let name = variant_data.name.clone();
853                             let variant = EnumVariantId { parent: e, local_id };
854                             let res = PerNs::both(variant.into(), variant.into(), vis);
855                             (Some(name), res)
856                         })
857                         .collect::<Vec<_>>();
858                     self.update(module_id, &resolutions, vis, ImportType::Glob);
859                 }
860                 Some(d) => {
861                     log::debug!("glob import {:?} from non-module/enum {:?}", import, d);
862                 }
863                 None => {
864                     log::debug!("glob import {:?} didn't resolve as type", import);
865                 }
866             }
867         } else {
868             let name = match &import.alias {
869                 Some(ImportAlias::Alias(name)) => Some(name.clone()),
870                 Some(ImportAlias::Underscore) => None,
871                 None => match import.path.segments().last() {
872                     Some(last_segment) => Some(last_segment.clone()),
873                     None => {
874                         cov_mark::hit!(bogus_paths);
875                         return;
876                     }
877                 },
878             };
879
880             log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def);
881
882             // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658
883             if import.is_extern_crate && module_id == self.def_map.root {
884                 if let (Some(def), Some(name)) = (def.take_types(), name.as_ref()) {
885                     self.def_map.extern_prelude.insert(name.clone(), def);
886                 }
887             }
888
889             self.update(module_id, &[(name, def)], vis, ImportType::Named);
890         }
891     }
892
893     fn update(
894         &mut self,
895         module_id: LocalModuleId,
896         resolutions: &[(Option<Name>, PerNs)],
897         vis: Visibility,
898         import_type: ImportType,
899     ) {
900         self.db.unwind_if_cancelled();
901         self.update_recursive(module_id, resolutions, vis, import_type, 0)
902     }
903
904     fn update_recursive(
905         &mut self,
906         module_id: LocalModuleId,
907         resolutions: &[(Option<Name>, PerNs)],
908         // All resolutions are imported with this visibility; the visibilities in
909         // the `PerNs` values are ignored and overwritten
910         vis: Visibility,
911         import_type: ImportType,
912         depth: usize,
913     ) {
914         if depth > GLOB_RECURSION_LIMIT {
915             // prevent stack overflows (but this shouldn't be possible)
916             panic!("infinite recursion in glob imports!");
917         }
918         let mut changed = false;
919
920         for (name, res) in resolutions {
921             match name {
922                 Some(name) => {
923                     let scope = &mut self.def_map.modules[module_id].scope;
924                     changed |= scope.push_res_with_import(
925                         &mut self.from_glob_import,
926                         (module_id, name.clone()),
927                         res.with_visibility(vis),
928                         import_type,
929                     );
930                 }
931                 None => {
932                     let tr = match res.take_types() {
933                         Some(ModuleDefId::TraitId(tr)) => tr,
934                         Some(other) => {
935                             log::debug!("non-trait `_` import of {:?}", other);
936                             continue;
937                         }
938                         None => continue,
939                     };
940                     let old_vis = self.def_map.modules[module_id].scope.unnamed_trait_vis(tr);
941                     let should_update = match old_vis {
942                         None => true,
943                         Some(old_vis) => {
944                             let max_vis = old_vis.max(vis, &self.def_map).unwrap_or_else(|| {
945                                 panic!("`Tr as _` imports with unrelated visibilities {:?} and {:?} (trait {:?})", old_vis, vis, tr);
946                             });
947
948                             if max_vis == old_vis {
949                                 false
950                             } else {
951                                 cov_mark::hit!(upgrade_underscore_visibility);
952                                 true
953                             }
954                         }
955                     };
956
957                     if should_update {
958                         changed = true;
959                         self.def_map.modules[module_id].scope.push_unnamed_trait(tr, vis);
960                     }
961                 }
962             }
963         }
964
965         if !changed {
966             return;
967         }
968         let glob_imports = self
969             .glob_imports
970             .get(&module_id)
971             .into_iter()
972             .flat_map(|v| v.iter())
973             .filter(|(glob_importing_module, _)| {
974                 // we know all resolutions have the same visibility (`vis`), so we
975                 // just need to check that once
976                 vis.is_visible_from_def_map(self.db, &self.def_map, *glob_importing_module)
977             })
978             .cloned()
979             .collect::<Vec<_>>();
980
981         for (glob_importing_module, glob_import_vis) in glob_imports {
982             self.update_recursive(
983                 glob_importing_module,
984                 resolutions,
985                 glob_import_vis,
986                 ImportType::Glob,
987                 depth + 1,
988             );
989         }
990     }
991
992     fn resolve_macros(&mut self) -> ReachedFixedPoint {
993         let mut macros = std::mem::replace(&mut self.unresolved_macros, Vec::new());
994         let mut resolved = Vec::new();
995         let mut res = ReachedFixedPoint::Yes;
996         macros.retain(|directive| {
997             let resolver = |path| {
998                 let resolved_res = self.def_map.resolve_path_fp_with_macro(
999                     self.db,
1000                     ResolveMode::Other,
1001                     directive.module_id,
1002                     &path,
1003                     BuiltinShadowMode::Module,
1004                 );
1005                 resolved_res.resolved_def.take_macros()
1006             };
1007
1008             match &directive.kind {
1009                 MacroDirectiveKind::FnLike { ast_id, fragment } => {
1010                     match macro_call_as_call_id(
1011                         ast_id,
1012                         *fragment,
1013                         self.db,
1014                         self.def_map.krate,
1015                         &resolver,
1016                         &mut |_err| (),
1017                     ) {
1018                         Ok(Ok(call_id)) => {
1019                             resolved.push((directive.module_id, call_id, directive.depth));
1020                             res = ReachedFixedPoint::No;
1021                             return false;
1022                         }
1023                         Err(UnresolvedMacro { .. }) | Ok(Err(_)) => {}
1024                     }
1025                 }
1026                 MacroDirectiveKind::Derive { ast_id, derive_attr } => {
1027                     match derive_macro_as_call_id(
1028                         ast_id,
1029                         *derive_attr,
1030                         self.db,
1031                         self.def_map.krate,
1032                         &resolver,
1033                     ) {
1034                         Ok(call_id) => {
1035                             resolved.push((directive.module_id, call_id, directive.depth));
1036                             res = ReachedFixedPoint::No;
1037                             return false;
1038                         }
1039                         Err(UnresolvedMacro { .. }) => (),
1040                     }
1041                 }
1042                 MacroDirectiveKind::Attr { ast_id, mod_item, attr } => {
1043                     if let Some(ident) = ast_id.path.as_ident() {
1044                         if let Some(helpers) = self.derive_helpers_in_scope.get(&ast_id.ast_id) {
1045                             if helpers.contains(ident) {
1046                                 cov_mark::hit!(resolved_derive_helper);
1047
1048                                 // Resolved to derive helper. Collect the item's attributes again,
1049                                 // starting after the derive helper.
1050                                 let file_id = ast_id.ast_id.file_id;
1051                                 let item_tree = self.db.file_item_tree(file_id);
1052                                 let mod_dir = self.mod_dirs[&directive.module_id].clone();
1053                                 self.skip_attrs.insert(InFile::new(file_id, *mod_item), attr.id);
1054                                 ModCollector {
1055                                     def_collector: &mut *self,
1056                                     macro_depth: directive.depth,
1057                                     module_id: directive.module_id,
1058                                     file_id,
1059                                     item_tree: &item_tree,
1060                                     mod_dir,
1061                                 }
1062                                 .collect(&[*mod_item]);
1063
1064                                 // Remove the original directive since we resolved it.
1065                                 res = ReachedFixedPoint::No;
1066                                 return false;
1067                             }
1068                         }
1069                     }
1070
1071                     if !self.db.enable_proc_attr_macros() {
1072                         return true;
1073                     }
1074
1075                     // Not resolved to a derive helper, so try to resolve as a macro.
1076                     match attr_macro_as_call_id(
1077                         ast_id,
1078                         attr,
1079                         self.db,
1080                         self.def_map.krate,
1081                         &resolver,
1082                     ) {
1083                         Ok(call_id) => {
1084                             let loc: MacroCallLoc = self.db.lookup_intern_macro(call_id);
1085                             if let MacroDefKind::ProcMacro(exp, ..) = &loc.def.kind {
1086                                 if exp.is_dummy() {
1087                                     // Proc macros that cannot be expanded are treated as not
1088                                     // resolved, in order to fall back later.
1089                                     self.def_map.diagnostics.push(
1090                                         DefDiagnostic::unresolved_proc_macro(
1091                                             directive.module_id,
1092                                             loc.kind,
1093                                         ),
1094                                     );
1095
1096                                     let file_id = ast_id.ast_id.file_id;
1097                                     let item_tree = self.db.file_item_tree(file_id);
1098                                     let mod_dir = self.mod_dirs[&directive.module_id].clone();
1099                                     self.skip_attrs
1100                                         .insert(InFile::new(file_id, *mod_item), attr.id);
1101                                     ModCollector {
1102                                         def_collector: &mut *self,
1103                                         macro_depth: directive.depth,
1104                                         module_id: directive.module_id,
1105                                         file_id,
1106                                         item_tree: &item_tree,
1107                                         mod_dir,
1108                                     }
1109                                     .collect(&[*mod_item]);
1110
1111                                     // Remove the macro directive.
1112                                     return false;
1113                                 }
1114                             }
1115
1116                             self.def_map.modules[directive.module_id]
1117                                 .scope
1118                                 .add_attr_macro_invoc(ast_id.ast_id, call_id);
1119
1120                             resolved.push((directive.module_id, call_id, directive.depth));
1121                             res = ReachedFixedPoint::No;
1122                             return false;
1123                         }
1124                         Err(UnresolvedMacro { .. }) => (),
1125                     }
1126                 }
1127             }
1128
1129             true
1130         });
1131         // Attribute resolution can add unresolved macro invocations, so concatenate the lists.
1132         self.unresolved_macros.extend(macros);
1133
1134         for (module_id, macro_call_id, depth) in resolved {
1135             self.collect_macro_expansion(module_id, macro_call_id, depth);
1136         }
1137
1138         res
1139     }
1140
1141     fn collect_macro_expansion(
1142         &mut self,
1143         module_id: LocalModuleId,
1144         macro_call_id: MacroCallId,
1145         depth: usize,
1146     ) {
1147         if depth > EXPANSION_DEPTH_LIMIT {
1148             cov_mark::hit!(macro_expansion_overflow);
1149             log::warn!("macro expansion is too deep");
1150             return;
1151         }
1152         let file_id = macro_call_id.as_file();
1153
1154         // First, fetch the raw expansion result for purposes of error reporting. This goes through
1155         // `macro_expand_error` to avoid depending on the full expansion result (to improve
1156         // incrementality).
1157         let loc: MacroCallLoc = self.db.lookup_intern_macro(macro_call_id);
1158         let err = self.db.macro_expand_error(macro_call_id);
1159         if let Some(err) = err {
1160             let diag = match err {
1161                 hir_expand::ExpandError::UnresolvedProcMacro => {
1162                     // Missing proc macros are non-fatal, so they are handled specially.
1163                     DefDiagnostic::unresolved_proc_macro(module_id, loc.kind.clone())
1164                 }
1165                 _ => DefDiagnostic::macro_error(module_id, loc.kind.clone(), err.to_string()),
1166             };
1167
1168             self.def_map.diagnostics.push(diag);
1169         }
1170
1171         // If we've just resolved a derive, record its helper attributes.
1172         if let MacroCallKind::Derive { ast_id, .. } = &loc.kind {
1173             if loc.def.krate != self.def_map.krate {
1174                 let def_map = self.db.crate_def_map(loc.def.krate);
1175                 if let Some(def) = def_map.exported_proc_macros.get(&loc.def) {
1176                     if let ProcMacroKind::CustomDerive { helpers } = &def.kind {
1177                         self.derive_helpers_in_scope
1178                             .entry(*ast_id)
1179                             .or_default()
1180                             .extend(helpers.iter().cloned());
1181                     }
1182                 }
1183             }
1184         }
1185
1186         // Then, fetch and process the item tree. This will reuse the expansion result from above.
1187         let item_tree = self.db.file_item_tree(file_id);
1188         let mod_dir = self.mod_dirs[&module_id].clone();
1189         ModCollector {
1190             def_collector: &mut *self,
1191             macro_depth: depth,
1192             file_id,
1193             module_id,
1194             item_tree: &item_tree,
1195             mod_dir,
1196         }
1197         .collect(item_tree.top_level_items());
1198     }
1199
1200     fn finish(mut self) -> DefMap {
1201         // Emit diagnostics for all remaining unexpanded macros.
1202
1203         for directive in &self.unresolved_macros {
1204             match &directive.kind {
1205                 MacroDirectiveKind::FnLike { ast_id, fragment } => match macro_call_as_call_id(
1206                     ast_id,
1207                     *fragment,
1208                     self.db,
1209                     self.def_map.krate,
1210                     |path| {
1211                         let resolved_res = self.def_map.resolve_path_fp_with_macro(
1212                             self.db,
1213                             ResolveMode::Other,
1214                             directive.module_id,
1215                             &path,
1216                             BuiltinShadowMode::Module,
1217                         );
1218                         resolved_res.resolved_def.take_macros()
1219                     },
1220                     &mut |_| (),
1221                 ) {
1222                     Ok(_) => (),
1223                     Err(UnresolvedMacro { path }) => {
1224                         self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call(
1225                             directive.module_id,
1226                             ast_id.ast_id,
1227                             path,
1228                         ));
1229                     }
1230                 },
1231                 MacroDirectiveKind::Derive { .. } | MacroDirectiveKind::Attr { .. } => {
1232                     // FIXME: we might want to diagnose this too
1233                 }
1234             }
1235         }
1236
1237         // Emit diagnostics for all remaining unresolved imports.
1238
1239         // We'd like to avoid emitting a diagnostics avalanche when some `extern crate` doesn't
1240         // resolve. We first emit diagnostics for unresolved extern crates and collect the missing
1241         // crate names. Then we emit diagnostics for unresolved imports, but only if the import
1242         // doesn't start with an unresolved crate's name. Due to renaming and reexports, this is a
1243         // heuristic, but it works in practice.
1244         let mut diagnosed_extern_crates = FxHashSet::default();
1245         for directive in &self.unresolved_imports {
1246             if let ImportSource::ExternCrate(krate) = directive.import.source {
1247                 let item_tree = krate.item_tree(self.db);
1248                 let extern_crate = &item_tree[krate.value];
1249
1250                 diagnosed_extern_crates.insert(extern_crate.name.clone());
1251
1252                 self.def_map.diagnostics.push(DefDiagnostic::unresolved_extern_crate(
1253                     directive.module_id,
1254                     InFile::new(krate.file_id(), extern_crate.ast_id),
1255                 ));
1256             }
1257         }
1258
1259         for directive in &self.unresolved_imports {
1260             if let ImportSource::Import { id: import, use_tree } = &directive.import.source {
1261                 match (directive.import.path.segments().first(), &directive.import.path.kind) {
1262                     (Some(krate), PathKind::Plain) | (Some(krate), PathKind::Abs) => {
1263                         if diagnosed_extern_crates.contains(krate) {
1264                             continue;
1265                         }
1266                     }
1267                     _ => {}
1268                 }
1269
1270                 self.def_map.diagnostics.push(DefDiagnostic::unresolved_import(
1271                     directive.module_id,
1272                     *import,
1273                     *use_tree,
1274                 ));
1275             }
1276         }
1277
1278         self.def_map
1279     }
1280 }
1281
1282 /// Walks a single module, populating defs, imports and macros
1283 struct ModCollector<'a, 'b> {
1284     def_collector: &'a mut DefCollector<'b>,
1285     macro_depth: usize,
1286     module_id: LocalModuleId,
1287     file_id: HirFileId,
1288     item_tree: &'a ItemTree,
1289     mod_dir: ModDir,
1290 }
1291
1292 impl ModCollector<'_, '_> {
1293     fn collect(&mut self, items: &[ModItem]) {
1294         let krate = self.def_collector.def_map.krate;
1295
1296         // Note: don't assert that inserted value is fresh: it's simply not true
1297         // for macros.
1298         self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone());
1299
1300         // Prelude module is always considered to be `#[macro_use]`.
1301         if let Some(prelude_module) = self.def_collector.def_map.prelude {
1302             if prelude_module.krate != krate {
1303                 cov_mark::hit!(prelude_is_macro_use);
1304                 self.def_collector.import_all_macros_exported(self.module_id, prelude_module.krate);
1305             }
1306         }
1307
1308         // This should be processed eagerly instead of deferred to resolving.
1309         // `#[macro_use] extern crate` is hoisted to imports macros before collecting
1310         // any other items.
1311         for item in items {
1312             let attrs = self.item_tree.attrs(self.def_collector.db, krate, (*item).into());
1313             if attrs.cfg().map_or(true, |cfg| self.is_cfg_enabled(&cfg)) {
1314                 if let ModItem::ExternCrate(id) = item {
1315                     let import = self.item_tree[*id].clone();
1316                     let attrs = self.item_tree.attrs(
1317                         self.def_collector.db,
1318                         krate,
1319                         ModItem::from(*id).into(),
1320                     );
1321                     if attrs.by_key("macro_use").exists() {
1322                         self.def_collector.import_macros_from_extern_crate(self.module_id, &import);
1323                     }
1324                 }
1325             }
1326         }
1327
1328         for &item in items {
1329             let attrs = self.item_tree.attrs(self.def_collector.db, krate, item.into());
1330             if let Some(cfg) = attrs.cfg() {
1331                 if !self.is_cfg_enabled(&cfg) {
1332                     self.emit_unconfigured_diagnostic(item, &cfg);
1333                     continue;
1334                 }
1335             }
1336
1337             if let Err(()) = self.resolve_attributes(&attrs, item) {
1338                 // Do not process the item. It has at least one non-builtin attribute, so the
1339                 // fixed-point algorithm is required to resolve the rest of them.
1340                 continue;
1341             }
1342
1343             let module = self.def_collector.def_map.module_id(self.module_id);
1344
1345             let mut def = None;
1346             match item {
1347                 ModItem::Mod(m) => self.collect_module(&self.item_tree[m], &attrs),
1348                 ModItem::Import(import_id) => {
1349                     let module_id = self.module_id;
1350                     let imports = Import::from_use(
1351                         self.def_collector.db,
1352                         krate,
1353                         &self.item_tree,
1354                         ItemTreeId::new(self.file_id, import_id),
1355                     );
1356                     self.def_collector.unresolved_imports.extend(imports.into_iter().map(
1357                         |import| ImportDirective {
1358                             module_id,
1359                             import,
1360                             status: PartialResolvedImport::Unresolved,
1361                         },
1362                     ));
1363                 }
1364                 ModItem::ExternCrate(import_id) => {
1365                     self.def_collector.unresolved_imports.push(ImportDirective {
1366                         module_id: self.module_id,
1367                         import: Import::from_extern_crate(
1368                             self.def_collector.db,
1369                             krate,
1370                             &self.item_tree,
1371                             ItemTreeId::new(self.file_id, import_id),
1372                         ),
1373                         status: PartialResolvedImport::Unresolved,
1374                     })
1375                 }
1376                 ModItem::ExternBlock(block) => self.collect(&self.item_tree[block].children),
1377                 ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac]),
1378                 ModItem::MacroRules(id) => self.collect_macro_rules(id),
1379                 ModItem::MacroDef(id) => self.collect_macro_def(id),
1380                 ModItem::Impl(imp) => {
1381                     let module = self.def_collector.def_map.module_id(self.module_id);
1382                     let impl_id =
1383                         ImplLoc { container: module, id: ItemTreeId::new(self.file_id, imp) }
1384                             .intern(self.def_collector.db);
1385                     self.def_collector.def_map.modules[self.module_id].scope.define_impl(impl_id)
1386                 }
1387                 ModItem::Function(id) => {
1388                     let func = &self.item_tree[id];
1389
1390                     let ast_id = InFile::new(self.file_id, func.ast_id);
1391                     self.collect_proc_macro_def(&func.name, ast_id, &attrs);
1392
1393                     def = Some(DefData {
1394                         id: FunctionLoc {
1395                             container: module.into(),
1396                             id: ItemTreeId::new(self.file_id, id),
1397                         }
1398                         .intern(self.def_collector.db)
1399                         .into(),
1400                         name: &func.name,
1401                         visibility: &self.item_tree[func.visibility],
1402                         has_constructor: false,
1403                     });
1404                 }
1405                 ModItem::Struct(id) => {
1406                     let it = &self.item_tree[id];
1407
1408                     def = Some(DefData {
1409                         id: StructLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
1410                             .intern(self.def_collector.db)
1411                             .into(),
1412                         name: &it.name,
1413                         visibility: &self.item_tree[it.visibility],
1414                         has_constructor: !matches!(it.fields, Fields::Record(_)),
1415                     });
1416                 }
1417                 ModItem::Union(id) => {
1418                     let it = &self.item_tree[id];
1419
1420                     def = Some(DefData {
1421                         id: UnionLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
1422                             .intern(self.def_collector.db)
1423                             .into(),
1424                         name: &it.name,
1425                         visibility: &self.item_tree[it.visibility],
1426                         has_constructor: false,
1427                     });
1428                 }
1429                 ModItem::Enum(id) => {
1430                     let it = &self.item_tree[id];
1431
1432                     def = Some(DefData {
1433                         id: EnumLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
1434                             .intern(self.def_collector.db)
1435                             .into(),
1436                         name: &it.name,
1437                         visibility: &self.item_tree[it.visibility],
1438                         has_constructor: false,
1439                     });
1440                 }
1441                 ModItem::Const(id) => {
1442                     let it = &self.item_tree[id];
1443                     let const_id = ConstLoc {
1444                         container: module.into(),
1445                         id: ItemTreeId::new(self.file_id, id),
1446                     }
1447                     .intern(self.def_collector.db);
1448
1449                     match &it.name {
1450                         Some(name) => {
1451                             def = Some(DefData {
1452                                 id: const_id.into(),
1453                                 name,
1454                                 visibility: &self.item_tree[it.visibility],
1455                                 has_constructor: false,
1456                             });
1457                         }
1458                         None => {
1459                             // const _: T = ...;
1460                             self.def_collector.def_map.modules[self.module_id]
1461                                 .scope
1462                                 .define_unnamed_const(const_id);
1463                         }
1464                     }
1465                 }
1466                 ModItem::Static(id) => {
1467                     let it = &self.item_tree[id];
1468
1469                     def = Some(DefData {
1470                         id: StaticLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
1471                             .intern(self.def_collector.db)
1472                             .into(),
1473                         name: &it.name,
1474                         visibility: &self.item_tree[it.visibility],
1475                         has_constructor: false,
1476                     });
1477                 }
1478                 ModItem::Trait(id) => {
1479                     let it = &self.item_tree[id];
1480
1481                     def = Some(DefData {
1482                         id: TraitLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
1483                             .intern(self.def_collector.db)
1484                             .into(),
1485                         name: &it.name,
1486                         visibility: &self.item_tree[it.visibility],
1487                         has_constructor: false,
1488                     });
1489                 }
1490                 ModItem::TypeAlias(id) => {
1491                     let it = &self.item_tree[id];
1492
1493                     def = Some(DefData {
1494                         id: TypeAliasLoc {
1495                             container: module.into(),
1496                             id: ItemTreeId::new(self.file_id, id),
1497                         }
1498                         .intern(self.def_collector.db)
1499                         .into(),
1500                         name: &it.name,
1501                         visibility: &self.item_tree[it.visibility],
1502                         has_constructor: false,
1503                     });
1504                 }
1505             }
1506
1507             if let Some(DefData { id, name, visibility, has_constructor }) = def {
1508                 self.def_collector.def_map.modules[self.module_id].scope.define_def(id);
1509                 let vis = self
1510                     .def_collector
1511                     .def_map
1512                     .resolve_visibility(self.def_collector.db, self.module_id, visibility)
1513                     .unwrap_or(Visibility::Public);
1514                 self.def_collector.update(
1515                     self.module_id,
1516                     &[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor))],
1517                     vis,
1518                     ImportType::Named,
1519                 )
1520             }
1521         }
1522     }
1523
1524     fn collect_module(&mut self, module: &Mod, attrs: &Attrs) {
1525         let path_attr = attrs.by_key("path").string_value();
1526         let is_macro_use = attrs.by_key("macro_use").exists();
1527         match &module.kind {
1528             // inline module, just recurse
1529             ModKind::Inline { items } => {
1530                 let module_id = self.push_child_module(
1531                     module.name.clone(),
1532                     AstId::new(self.file_id, module.ast_id),
1533                     None,
1534                     &self.item_tree[module.visibility],
1535                 );
1536
1537                 if let Some(mod_dir) = self.mod_dir.descend_into_definition(&module.name, path_attr)
1538                 {
1539                     ModCollector {
1540                         def_collector: &mut *self.def_collector,
1541                         macro_depth: self.macro_depth,
1542                         module_id,
1543                         file_id: self.file_id,
1544                         item_tree: self.item_tree,
1545                         mod_dir,
1546                     }
1547                     .collect(&*items);
1548                     if is_macro_use {
1549                         self.import_all_legacy_macros(module_id);
1550                     }
1551                 }
1552             }
1553             // out of line module, resolve, parse and recurse
1554             ModKind::Outline {} => {
1555                 let ast_id = AstId::new(self.file_id, module.ast_id);
1556                 let db = self.def_collector.db;
1557                 match self.mod_dir.resolve_declaration(db, self.file_id, &module.name, path_attr) {
1558                     Ok((file_id, is_mod_rs, mod_dir)) => {
1559                         let item_tree = db.file_item_tree(file_id.into());
1560                         if item_tree
1561                             .top_level_attrs(db, self.def_collector.def_map.krate)
1562                             .cfg()
1563                             .map_or(true, |cfg| {
1564                                 self.def_collector.cfg_options.check(&cfg) != Some(false)
1565                             })
1566                         {
1567                             let module_id = self.push_child_module(
1568                                 module.name.clone(),
1569                                 ast_id,
1570                                 Some((file_id, is_mod_rs)),
1571                                 &self.item_tree[module.visibility],
1572                             );
1573                             ModCollector {
1574                                 def_collector: &mut *self.def_collector,
1575                                 macro_depth: self.macro_depth,
1576                                 module_id,
1577                                 file_id: file_id.into(),
1578                                 item_tree: &item_tree,
1579                                 mod_dir,
1580                             }
1581                             .collect(item_tree.top_level_items());
1582                             if is_macro_use
1583                                 || item_tree
1584                                     .top_level_attrs(db, self.def_collector.def_map.krate)
1585                                     .by_key("macro_use")
1586                                     .exists()
1587                             {
1588                                 self.import_all_legacy_macros(module_id);
1589                             }
1590                         }
1591                     }
1592                     Err(candidate) => {
1593                         self.def_collector.def_map.diagnostics.push(
1594                             DefDiagnostic::unresolved_module(self.module_id, ast_id, candidate),
1595                         );
1596                     }
1597                 };
1598             }
1599         }
1600     }
1601
1602     fn push_child_module(
1603         &mut self,
1604         name: Name,
1605         declaration: AstId<ast::Module>,
1606         definition: Option<(FileId, bool)>,
1607         visibility: &crate::visibility::RawVisibility,
1608     ) -> LocalModuleId {
1609         let vis = self
1610             .def_collector
1611             .def_map
1612             .resolve_visibility(self.def_collector.db, self.module_id, visibility)
1613             .unwrap_or(Visibility::Public);
1614         let modules = &mut self.def_collector.def_map.modules;
1615         let res = modules.alloc(ModuleData::default());
1616         modules[res].parent = Some(self.module_id);
1617         modules[res].origin = match definition {
1618             None => ModuleOrigin::Inline { definition: declaration },
1619             Some((definition, is_mod_rs)) => {
1620                 ModuleOrigin::File { declaration, definition, is_mod_rs }
1621             }
1622         };
1623         for (name, mac) in modules[self.module_id].scope.collect_legacy_macros() {
1624             modules[res].scope.define_legacy_macro(name, mac)
1625         }
1626         modules[self.module_id].children.insert(name.clone(), res);
1627         let module = self.def_collector.def_map.module_id(res);
1628         let def: ModuleDefId = module.into();
1629         self.def_collector.def_map.modules[self.module_id].scope.define_def(def);
1630         self.def_collector.update(
1631             self.module_id,
1632             &[(Some(name), PerNs::from_def(def, vis, false))],
1633             vis,
1634             ImportType::Named,
1635         );
1636         res
1637     }
1638
1639     /// Resolves attributes on an item.
1640     ///
1641     /// Returns `Err` when some attributes could not be resolved to builtins and have been
1642     /// registered as unresolved.
1643     ///
1644     /// If `ignore_up_to` is `Some`, attributes precending and including that attribute will be
1645     /// assumed to be resolved already.
1646     fn resolve_attributes(&mut self, attrs: &Attrs, mod_item: ModItem) -> Result<(), ()> {
1647         let mut ignore_up_to =
1648             self.def_collector.skip_attrs.get(&InFile::new(self.file_id, mod_item)).copied();
1649         let iter = attrs
1650             .iter()
1651             .dedup_by(|a, b| {
1652                 // FIXME: this should not be required, all attributes on an item should have a
1653                 // unique ID!
1654                 // Still, this occurs because `#[cfg_attr]` can "expand" to multiple attributes:
1655                 //     #[cfg_attr(not(off), unresolved, unresolved)]
1656                 //     struct S;
1657                 // We should come up with a different way to ID attributes.
1658                 a.id == b.id
1659             })
1660             .skip_while(|attr| match ignore_up_to {
1661                 Some(id) if attr.id == id => {
1662                     ignore_up_to = None;
1663                     true
1664                 }
1665                 Some(_) => true,
1666                 None => false,
1667             });
1668
1669         for attr in iter {
1670             if attr.path.as_ident() == Some(&hir_expand::name![derive]) {
1671                 self.collect_derive(attr, mod_item);
1672             } else if self.is_builtin_or_registered_attr(&attr.path) {
1673                 continue;
1674             } else {
1675                 log::debug!("non-builtin attribute {}", attr.path);
1676
1677                 let ast_id = AstIdWithPath::new(
1678                     self.file_id,
1679                     mod_item.ast_id(self.item_tree),
1680                     attr.path.as_ref().clone(),
1681                 );
1682                 self.def_collector.unresolved_macros.push(MacroDirective {
1683                     module_id: self.module_id,
1684                     depth: self.macro_depth + 1,
1685                     kind: MacroDirectiveKind::Attr { ast_id, attr: attr.clone(), mod_item },
1686                 });
1687
1688                 return Err(());
1689             }
1690         }
1691
1692         Ok(())
1693     }
1694
1695     fn is_builtin_or_registered_attr(&self, path: &ModPath) -> bool {
1696         if path.kind == PathKind::Plain {
1697             if let Some(tool_module) = path.segments().first() {
1698                 let tool_module = tool_module.to_string();
1699                 if builtin_attr::TOOL_MODULES
1700                     .iter()
1701                     .copied()
1702                     .chain(self.def_collector.registered_tools.iter().map(|s| &**s))
1703                     .any(|m| tool_module == *m)
1704                 {
1705                     return true;
1706                 }
1707             }
1708
1709             if let Some(name) = path.as_ident() {
1710                 let name = name.to_string();
1711                 if builtin_attr::INERT_ATTRIBUTES
1712                     .iter()
1713                     .chain(builtin_attr::EXTRA_ATTRIBUTES)
1714                     .copied()
1715                     .chain(self.def_collector.registered_attrs.iter().map(|s| &**s))
1716                     .any(|attr| name == *attr)
1717                 {
1718                     return true;
1719                 }
1720             }
1721         }
1722
1723         false
1724     }
1725
1726     fn collect_derive(&mut self, attr: &Attr, mod_item: ModItem) {
1727         let ast_id: FileAstId<ast::Item> = match mod_item {
1728             ModItem::Struct(it) => self.item_tree[it].ast_id.upcast(),
1729             ModItem::Union(it) => self.item_tree[it].ast_id.upcast(),
1730             ModItem::Enum(it) => self.item_tree[it].ast_id.upcast(),
1731             _ => {
1732                 // Cannot use derive on this item.
1733                 // FIXME: diagnose
1734                 return;
1735             }
1736         };
1737
1738         match attr.parse_derive() {
1739             Some(derive_macros) => {
1740                 for path in derive_macros {
1741                     let ast_id = AstIdWithPath::new(self.file_id, ast_id, path);
1742                     self.def_collector.unresolved_macros.push(MacroDirective {
1743                         module_id: self.module_id,
1744                         depth: self.macro_depth + 1,
1745                         kind: MacroDirectiveKind::Derive { ast_id, derive_attr: attr.id },
1746                     });
1747                 }
1748             }
1749             None => {
1750                 // FIXME: diagnose
1751                 log::debug!("malformed derive: {:?}", attr);
1752             }
1753         }
1754     }
1755
1756     /// If `attrs` registers a procedural macro, collects its definition.
1757     fn collect_proc_macro_def(&mut self, func_name: &Name, ast_id: AstId<ast::Fn>, attrs: &Attrs) {
1758         // FIXME: this should only be done in the root module of `proc-macro` crates, not everywhere
1759         if let Some(proc_macro) = attrs.parse_proc_macro_decl(func_name) {
1760             self.def_collector.export_proc_macro(proc_macro, ast_id);
1761         }
1762     }
1763
1764     fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) {
1765         let krate = self.def_collector.def_map.krate;
1766         let mac = &self.item_tree[id];
1767         let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into());
1768         let ast_id = InFile::new(self.file_id, mac.ast_id.upcast());
1769
1770         let export_attr = attrs.by_key("macro_export");
1771
1772         let is_export = export_attr.exists();
1773         let is_local_inner = if is_export {
1774             export_attr.tt_values().map(|it| &it.token_trees).flatten().any(|it| match it {
1775                 tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
1776                     ident.text.contains("local_inner_macros")
1777                 }
1778                 _ => false,
1779             })
1780         } else {
1781             false
1782         };
1783
1784         // Case 1: builtin macros
1785         if attrs.by_key("rustc_builtin_macro").exists() {
1786             // `#[rustc_builtin_macro = "builtin_name"]` overrides the `macro_rules!` name.
1787             let name;
1788             let name = match attrs.by_key("rustc_builtin_macro").string_value() {
1789                 Some(it) => {
1790                     // FIXME: a hacky way to create a Name from string.
1791                     name = tt::Ident { text: it.clone(), id: tt::TokenId::unspecified() }.as_name();
1792                     &name
1793                 }
1794                 None => &mac.name,
1795             };
1796             let krate = self.def_collector.def_map.krate;
1797             match find_builtin_macro(name, krate, ast_id) {
1798                 Some(macro_id) => {
1799                     self.def_collector.define_macro_rules(
1800                         self.module_id,
1801                         mac.name.clone(),
1802                         macro_id,
1803                         is_export,
1804                     );
1805                     return;
1806                 }
1807                 None => {
1808                     self.def_collector
1809                         .def_map
1810                         .diagnostics
1811                         .push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, ast_id));
1812                 }
1813             }
1814         }
1815
1816         // Case 2: normal `macro_rules!` macro
1817         let macro_id = MacroDefId {
1818             krate: self.def_collector.def_map.krate,
1819             kind: MacroDefKind::Declarative(ast_id),
1820             local_inner: is_local_inner,
1821         };
1822         self.def_collector.define_macro_rules(
1823             self.module_id,
1824             mac.name.clone(),
1825             macro_id,
1826             is_export,
1827         );
1828     }
1829
1830     fn collect_macro_def(&mut self, id: FileItemTreeId<MacroDef>) {
1831         let krate = self.def_collector.def_map.krate;
1832         let mac = &self.item_tree[id];
1833         let ast_id = InFile::new(self.file_id, mac.ast_id.upcast());
1834
1835         // Case 1: bulitin macros
1836         let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into());
1837         if attrs.by_key("rustc_builtin_macro").exists() {
1838             let macro_id = find_builtin_macro(&mac.name, krate, ast_id)
1839                 .or_else(|| find_builtin_derive(&mac.name, krate, ast_id));
1840
1841             match macro_id {
1842                 Some(macro_id) => {
1843                     self.def_collector.define_macro_def(
1844                         self.module_id,
1845                         mac.name.clone(),
1846                         macro_id,
1847                         &self.item_tree[mac.visibility],
1848                     );
1849                     return;
1850                 }
1851                 None => {
1852                     self.def_collector
1853                         .def_map
1854                         .diagnostics
1855                         .push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, ast_id));
1856                 }
1857             }
1858         }
1859
1860         // Case 2: normal `macro`
1861         let macro_id = MacroDefId {
1862             krate: self.def_collector.def_map.krate,
1863             kind: MacroDefKind::Declarative(ast_id),
1864             local_inner: false,
1865         };
1866
1867         self.def_collector.define_macro_def(
1868             self.module_id,
1869             mac.name.clone(),
1870             macro_id,
1871             &self.item_tree[mac.visibility],
1872         );
1873     }
1874
1875     fn collect_macro_call(&mut self, mac: &MacroCall) {
1876         let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, (*mac.path).clone());
1877
1878         // Case 1: try to resolve in legacy scope and expand macro_rules
1879         let mut error = None;
1880         match macro_call_as_call_id(
1881             &ast_id,
1882             mac.fragment,
1883             self.def_collector.db,
1884             self.def_collector.def_map.krate,
1885             |path| {
1886                 path.as_ident().and_then(|name| {
1887                     self.def_collector.def_map.with_ancestor_maps(
1888                         self.def_collector.db,
1889                         self.module_id,
1890                         &mut |map, module| map[module].scope.get_legacy_macro(&name),
1891                     )
1892                 })
1893             },
1894             &mut |err| {
1895                 error.get_or_insert(err);
1896             },
1897         ) {
1898             Ok(Ok(macro_call_id)) => {
1899                 // Legacy macros need to be expanded immediately, so that any macros they produce
1900                 // are in scope.
1901                 self.def_collector.collect_macro_expansion(
1902                     self.module_id,
1903                     macro_call_id,
1904                     self.macro_depth + 1,
1905                 );
1906
1907                 return;
1908             }
1909             Ok(Err(_)) => {
1910                 // Built-in macro failed eager expansion.
1911
1912                 // FIXME: don't parse the file here
1913                 let fragment = hir_expand::to_fragment_kind(
1914                     &ast_id.ast_id.to_node(self.def_collector.db.upcast()),
1915                 );
1916                 self.def_collector.def_map.diagnostics.push(DefDiagnostic::macro_error(
1917                     self.module_id,
1918                     MacroCallKind::FnLike { ast_id: ast_id.ast_id, fragment },
1919                     error.unwrap().to_string(),
1920                 ));
1921                 return;
1922             }
1923             Err(UnresolvedMacro { .. }) => (),
1924         }
1925
1926         // Case 2: resolve in module scope, expand during name resolution.
1927         // We rewrite simple path `macro_name` to `self::macro_name` to force resolve in module scope only.
1928         if ast_id.path.is_ident() {
1929             ast_id.path.kind = PathKind::Super(0);
1930         }
1931
1932         self.def_collector.unresolved_macros.push(MacroDirective {
1933             module_id: self.module_id,
1934             depth: self.macro_depth + 1,
1935             kind: MacroDirectiveKind::FnLike { ast_id, fragment: mac.fragment },
1936         });
1937     }
1938
1939     fn import_all_legacy_macros(&mut self, module_id: LocalModuleId) {
1940         let macros = self.def_collector.def_map[module_id].scope.collect_legacy_macros();
1941         for (name, macro_) in macros {
1942             self.def_collector.define_legacy_macro(self.module_id, name.clone(), macro_);
1943         }
1944     }
1945
1946     fn is_cfg_enabled(&self, cfg: &CfgExpr) -> bool {
1947         self.def_collector.cfg_options.check(cfg) != Some(false)
1948     }
1949
1950     fn emit_unconfigured_diagnostic(&mut self, item: ModItem, cfg: &CfgExpr) {
1951         let ast_id = item.ast_id(self.item_tree);
1952
1953         let ast_id = InFile::new(self.file_id, ast_id);
1954         self.def_collector.def_map.diagnostics.push(DefDiagnostic::unconfigured_code(
1955             self.module_id,
1956             ast_id,
1957             cfg.clone(),
1958             self.def_collector.cfg_options.clone(),
1959         ));
1960     }
1961 }
1962
1963 #[cfg(test)]
1964 mod tests {
1965     use crate::{db::DefDatabase, test_db::TestDB};
1966     use base_db::{fixture::WithFixture, SourceDatabase};
1967
1968     use super::*;
1969
1970     fn do_collect_defs(db: &dyn DefDatabase, def_map: DefMap) -> DefMap {
1971         let mut collector = DefCollector {
1972             db,
1973             def_map,
1974             glob_imports: FxHashMap::default(),
1975             unresolved_imports: Vec::new(),
1976             resolved_imports: Vec::new(),
1977             unresolved_macros: Vec::new(),
1978             mod_dirs: FxHashMap::default(),
1979             cfg_options: &CfgOptions::default(),
1980             proc_macros: Default::default(),
1981             exports_proc_macros: false,
1982             from_glob_import: Default::default(),
1983             skip_attrs: Default::default(),
1984             derive_helpers_in_scope: Default::default(),
1985             registered_attrs: Default::default(),
1986             registered_tools: Default::default(),
1987         };
1988         collector.seed_with_top_level();
1989         collector.collect();
1990         collector.def_map
1991     }
1992
1993     fn do_resolve(code: &str) -> DefMap {
1994         let (db, _file_id) = TestDB::with_single_file(&code);
1995         let krate = db.test_crate();
1996
1997         let edition = db.crate_graph()[krate].edition;
1998         let def_map = DefMap::empty(krate, edition);
1999         do_collect_defs(&db, def_map)
2000     }
2001
2002     #[test]
2003     fn test_macro_expand_will_stop_1() {
2004         do_resolve(
2005             r#"
2006         macro_rules! foo {
2007             ($($ty:ty)*) => { foo!($($ty)*); }
2008         }
2009         foo!(KABOOM);
2010         "#,
2011         );
2012     }
2013
2014     #[ignore] // this test does succeed, but takes quite a while :/
2015     #[test]
2016     fn test_macro_expand_will_stop_2() {
2017         do_resolve(
2018             r#"
2019         macro_rules! foo {
2020             ($($ty:ty)*) => { foo!($($ty)* $($ty)*); }
2021         }
2022         foo!(KABOOM);
2023         "#,
2024         );
2025     }
2026 }