]> git.lizzy.rs Git - rust.git/blob - crates/hir_def/src/nameres/collector.rs
Make it opt-in
[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                                 return false;
1066                             }
1067                         }
1068                     }
1069
1070                     if !self.db.enable_proc_attr_macros() {
1071                         return true;
1072                     }
1073
1074                     // Not resolved to a derive helper, so try to resolve as a macro.
1075                     match attr_macro_as_call_id(
1076                         ast_id,
1077                         attr,
1078                         self.db,
1079                         self.def_map.krate,
1080                         &resolver,
1081                     ) {
1082                         Ok(call_id) => {
1083                             let loc: MacroCallLoc = self.db.lookup_intern_macro(call_id);
1084                             if let MacroDefKind::ProcMacro(exp, ..) = &loc.def.kind {
1085                                 if exp.is_dummy() {
1086                                     // Proc macros that cannot be expanded are treated as not
1087                                     // resolved, in order to fall back later.
1088                                     self.def_map.diagnostics.push(
1089                                         DefDiagnostic::unresolved_proc_macro(
1090                                             directive.module_id,
1091                                             loc.kind,
1092                                         ),
1093                                     );
1094
1095                                     let file_id = ast_id.ast_id.file_id;
1096                                     let item_tree = self.db.file_item_tree(file_id);
1097                                     let mod_dir = self.mod_dirs[&directive.module_id].clone();
1098                                     self.skip_attrs
1099                                         .insert(InFile::new(file_id, *mod_item), attr.id);
1100                                     ModCollector {
1101                                         def_collector: &mut *self,
1102                                         macro_depth: directive.depth,
1103                                         module_id: directive.module_id,
1104                                         file_id,
1105                                         item_tree: &item_tree,
1106                                         mod_dir,
1107                                     }
1108                                     .collect(&[*mod_item]);
1109
1110                                     // Remove the macro directive.
1111                                     return false;
1112                                 }
1113                             }
1114                             resolved.push((directive.module_id, call_id, directive.depth));
1115                             res = ReachedFixedPoint::No;
1116                             return false;
1117                         }
1118                         Err(UnresolvedMacro { .. }) => (),
1119                     }
1120                 }
1121             }
1122
1123             true
1124         });
1125         // Attribute resolution can add unresolved macro invocations, so concatenate the lists.
1126         self.unresolved_macros.extend(macros);
1127
1128         for (module_id, macro_call_id, depth) in resolved {
1129             self.collect_macro_expansion(module_id, macro_call_id, depth);
1130         }
1131
1132         res
1133     }
1134
1135     fn collect_macro_expansion(
1136         &mut self,
1137         module_id: LocalModuleId,
1138         macro_call_id: MacroCallId,
1139         depth: usize,
1140     ) {
1141         if depth > EXPANSION_DEPTH_LIMIT {
1142             cov_mark::hit!(macro_expansion_overflow);
1143             log::warn!("macro expansion is too deep");
1144             return;
1145         }
1146         let file_id = macro_call_id.as_file();
1147
1148         // First, fetch the raw expansion result for purposes of error reporting. This goes through
1149         // `macro_expand_error` to avoid depending on the full expansion result (to improve
1150         // incrementality).
1151         let loc: MacroCallLoc = self.db.lookup_intern_macro(macro_call_id);
1152         let err = self.db.macro_expand_error(macro_call_id);
1153         if let Some(err) = err {
1154             let diag = match err {
1155                 hir_expand::ExpandError::UnresolvedProcMacro => {
1156                     // Missing proc macros are non-fatal, so they are handled specially.
1157                     DefDiagnostic::unresolved_proc_macro(module_id, loc.kind.clone())
1158                 }
1159                 _ => DefDiagnostic::macro_error(module_id, loc.kind.clone(), err.to_string()),
1160             };
1161
1162             self.def_map.diagnostics.push(diag);
1163         }
1164
1165         // If we've just resolved a derive, record its helper attributes.
1166         if let MacroCallKind::Derive { ast_id, .. } = &loc.kind {
1167             if loc.def.krate != self.def_map.krate {
1168                 let def_map = self.db.crate_def_map(loc.def.krate);
1169                 if let Some(def) = def_map.exported_proc_macros.get(&loc.def) {
1170                     if let ProcMacroKind::CustomDerive { helpers } = &def.kind {
1171                         self.derive_helpers_in_scope
1172                             .entry(*ast_id)
1173                             .or_default()
1174                             .extend(helpers.iter().cloned());
1175                     }
1176                 }
1177             }
1178         }
1179
1180         // Then, fetch and process the item tree. This will reuse the expansion result from above.
1181         let item_tree = self.db.file_item_tree(file_id);
1182         let mod_dir = self.mod_dirs[&module_id].clone();
1183         ModCollector {
1184             def_collector: &mut *self,
1185             macro_depth: depth,
1186             file_id,
1187             module_id,
1188             item_tree: &item_tree,
1189             mod_dir,
1190         }
1191         .collect(item_tree.top_level_items());
1192     }
1193
1194     fn finish(mut self) -> DefMap {
1195         // Emit diagnostics for all remaining unexpanded macros.
1196
1197         for directive in &self.unresolved_macros {
1198             match &directive.kind {
1199                 MacroDirectiveKind::FnLike { ast_id, fragment } => match macro_call_as_call_id(
1200                     ast_id,
1201                     *fragment,
1202                     self.db,
1203                     self.def_map.krate,
1204                     |path| {
1205                         let resolved_res = self.def_map.resolve_path_fp_with_macro(
1206                             self.db,
1207                             ResolveMode::Other,
1208                             directive.module_id,
1209                             &path,
1210                             BuiltinShadowMode::Module,
1211                         );
1212                         resolved_res.resolved_def.take_macros()
1213                     },
1214                     &mut |_| (),
1215                 ) {
1216                     Ok(_) => (),
1217                     Err(UnresolvedMacro { path }) => {
1218                         self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call(
1219                             directive.module_id,
1220                             ast_id.ast_id,
1221                             path,
1222                         ));
1223                     }
1224                 },
1225                 MacroDirectiveKind::Derive { .. } | MacroDirectiveKind::Attr { .. } => {
1226                     // FIXME: we might want to diagnose this too
1227                 }
1228             }
1229         }
1230
1231         // Emit diagnostics for all remaining unresolved imports.
1232
1233         // We'd like to avoid emitting a diagnostics avalanche when some `extern crate` doesn't
1234         // resolve. We first emit diagnostics for unresolved extern crates and collect the missing
1235         // crate names. Then we emit diagnostics for unresolved imports, but only if the import
1236         // doesn't start with an unresolved crate's name. Due to renaming and reexports, this is a
1237         // heuristic, but it works in practice.
1238         let mut diagnosed_extern_crates = FxHashSet::default();
1239         for directive in &self.unresolved_imports {
1240             if let ImportSource::ExternCrate(krate) = directive.import.source {
1241                 let item_tree = krate.item_tree(self.db);
1242                 let extern_crate = &item_tree[krate.value];
1243
1244                 diagnosed_extern_crates.insert(extern_crate.name.clone());
1245
1246                 self.def_map.diagnostics.push(DefDiagnostic::unresolved_extern_crate(
1247                     directive.module_id,
1248                     InFile::new(krate.file_id(), extern_crate.ast_id),
1249                 ));
1250             }
1251         }
1252
1253         for directive in &self.unresolved_imports {
1254             if let ImportSource::Import { id: import, use_tree } = &directive.import.source {
1255                 match (directive.import.path.segments().first(), &directive.import.path.kind) {
1256                     (Some(krate), PathKind::Plain) | (Some(krate), PathKind::Abs) => {
1257                         if diagnosed_extern_crates.contains(krate) {
1258                             continue;
1259                         }
1260                     }
1261                     _ => {}
1262                 }
1263
1264                 self.def_map.diagnostics.push(DefDiagnostic::unresolved_import(
1265                     directive.module_id,
1266                     *import,
1267                     *use_tree,
1268                 ));
1269             }
1270         }
1271
1272         self.def_map
1273     }
1274 }
1275
1276 /// Walks a single module, populating defs, imports and macros
1277 struct ModCollector<'a, 'b> {
1278     def_collector: &'a mut DefCollector<'b>,
1279     macro_depth: usize,
1280     module_id: LocalModuleId,
1281     file_id: HirFileId,
1282     item_tree: &'a ItemTree,
1283     mod_dir: ModDir,
1284 }
1285
1286 impl ModCollector<'_, '_> {
1287     fn collect(&mut self, items: &[ModItem]) {
1288         let krate = self.def_collector.def_map.krate;
1289
1290         // Note: don't assert that inserted value is fresh: it's simply not true
1291         // for macros.
1292         self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone());
1293
1294         // Prelude module is always considered to be `#[macro_use]`.
1295         if let Some(prelude_module) = self.def_collector.def_map.prelude {
1296             if prelude_module.krate != krate {
1297                 cov_mark::hit!(prelude_is_macro_use);
1298                 self.def_collector.import_all_macros_exported(self.module_id, prelude_module.krate);
1299             }
1300         }
1301
1302         // This should be processed eagerly instead of deferred to resolving.
1303         // `#[macro_use] extern crate` is hoisted to imports macros before collecting
1304         // any other items.
1305         for item in items {
1306             let attrs = self.item_tree.attrs(self.def_collector.db, krate, (*item).into());
1307             if attrs.cfg().map_or(true, |cfg| self.is_cfg_enabled(&cfg)) {
1308                 if let ModItem::ExternCrate(id) = item {
1309                     let import = self.item_tree[*id].clone();
1310                     let attrs = self.item_tree.attrs(
1311                         self.def_collector.db,
1312                         krate,
1313                         ModItem::from(*id).into(),
1314                     );
1315                     if attrs.by_key("macro_use").exists() {
1316                         self.def_collector.import_macros_from_extern_crate(self.module_id, &import);
1317                     }
1318                 }
1319             }
1320         }
1321
1322         for &item in items {
1323             let attrs = self.item_tree.attrs(self.def_collector.db, krate, item.into());
1324             if let Some(cfg) = attrs.cfg() {
1325                 if !self.is_cfg_enabled(&cfg) {
1326                     self.emit_unconfigured_diagnostic(item, &cfg);
1327                     continue;
1328                 }
1329             }
1330
1331             if let Err(()) = self.resolve_attributes(&attrs, item) {
1332                 // Do not process the item. It has at least one non-builtin attribute, so the
1333                 // fixed-point algorithm is required to resolve the rest of them.
1334                 continue;
1335             }
1336
1337             let module = self.def_collector.def_map.module_id(self.module_id);
1338
1339             let mut def = None;
1340             match item {
1341                 ModItem::Mod(m) => self.collect_module(&self.item_tree[m], &attrs),
1342                 ModItem::Import(import_id) => {
1343                     let module_id = self.module_id;
1344                     let imports = Import::from_use(
1345                         self.def_collector.db,
1346                         krate,
1347                         &self.item_tree,
1348                         ItemTreeId::new(self.file_id, import_id),
1349                     );
1350                     self.def_collector.unresolved_imports.extend(imports.into_iter().map(
1351                         |import| ImportDirective {
1352                             module_id,
1353                             import,
1354                             status: PartialResolvedImport::Unresolved,
1355                         },
1356                     ));
1357                 }
1358                 ModItem::ExternCrate(import_id) => {
1359                     self.def_collector.unresolved_imports.push(ImportDirective {
1360                         module_id: self.module_id,
1361                         import: Import::from_extern_crate(
1362                             self.def_collector.db,
1363                             krate,
1364                             &self.item_tree,
1365                             ItemTreeId::new(self.file_id, import_id),
1366                         ),
1367                         status: PartialResolvedImport::Unresolved,
1368                     })
1369                 }
1370                 ModItem::ExternBlock(block) => self.collect(&self.item_tree[block].children),
1371                 ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac]),
1372                 ModItem::MacroRules(id) => self.collect_macro_rules(id),
1373                 ModItem::MacroDef(id) => self.collect_macro_def(id),
1374                 ModItem::Impl(imp) => {
1375                     let module = self.def_collector.def_map.module_id(self.module_id);
1376                     let impl_id =
1377                         ImplLoc { container: module, id: ItemTreeId::new(self.file_id, imp) }
1378                             .intern(self.def_collector.db);
1379                     self.def_collector.def_map.modules[self.module_id].scope.define_impl(impl_id)
1380                 }
1381                 ModItem::Function(id) => {
1382                     let func = &self.item_tree[id];
1383
1384                     let ast_id = InFile::new(self.file_id, func.ast_id);
1385                     self.collect_proc_macro_def(&func.name, ast_id, &attrs);
1386
1387                     def = Some(DefData {
1388                         id: FunctionLoc {
1389                             container: module.into(),
1390                             id: ItemTreeId::new(self.file_id, id),
1391                         }
1392                         .intern(self.def_collector.db)
1393                         .into(),
1394                         name: &func.name,
1395                         visibility: &self.item_tree[func.visibility],
1396                         has_constructor: false,
1397                     });
1398                 }
1399                 ModItem::Struct(id) => {
1400                     let it = &self.item_tree[id];
1401
1402                     def = Some(DefData {
1403                         id: StructLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
1404                             .intern(self.def_collector.db)
1405                             .into(),
1406                         name: &it.name,
1407                         visibility: &self.item_tree[it.visibility],
1408                         has_constructor: !matches!(it.fields, Fields::Record(_)),
1409                     });
1410                 }
1411                 ModItem::Union(id) => {
1412                     let it = &self.item_tree[id];
1413
1414                     def = Some(DefData {
1415                         id: UnionLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
1416                             .intern(self.def_collector.db)
1417                             .into(),
1418                         name: &it.name,
1419                         visibility: &self.item_tree[it.visibility],
1420                         has_constructor: false,
1421                     });
1422                 }
1423                 ModItem::Enum(id) => {
1424                     let it = &self.item_tree[id];
1425
1426                     def = Some(DefData {
1427                         id: EnumLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
1428                             .intern(self.def_collector.db)
1429                             .into(),
1430                         name: &it.name,
1431                         visibility: &self.item_tree[it.visibility],
1432                         has_constructor: false,
1433                     });
1434                 }
1435                 ModItem::Const(id) => {
1436                     let it = &self.item_tree[id];
1437                     let const_id = ConstLoc {
1438                         container: module.into(),
1439                         id: ItemTreeId::new(self.file_id, id),
1440                     }
1441                     .intern(self.def_collector.db);
1442
1443                     match &it.name {
1444                         Some(name) => {
1445                             def = Some(DefData {
1446                                 id: const_id.into(),
1447                                 name,
1448                                 visibility: &self.item_tree[it.visibility],
1449                                 has_constructor: false,
1450                             });
1451                         }
1452                         None => {
1453                             // const _: T = ...;
1454                             self.def_collector.def_map.modules[self.module_id]
1455                                 .scope
1456                                 .define_unnamed_const(const_id);
1457                         }
1458                     }
1459                 }
1460                 ModItem::Static(id) => {
1461                     let it = &self.item_tree[id];
1462
1463                     def = Some(DefData {
1464                         id: StaticLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
1465                             .intern(self.def_collector.db)
1466                             .into(),
1467                         name: &it.name,
1468                         visibility: &self.item_tree[it.visibility],
1469                         has_constructor: false,
1470                     });
1471                 }
1472                 ModItem::Trait(id) => {
1473                     let it = &self.item_tree[id];
1474
1475                     def = Some(DefData {
1476                         id: TraitLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
1477                             .intern(self.def_collector.db)
1478                             .into(),
1479                         name: &it.name,
1480                         visibility: &self.item_tree[it.visibility],
1481                         has_constructor: false,
1482                     });
1483                 }
1484                 ModItem::TypeAlias(id) => {
1485                     let it = &self.item_tree[id];
1486
1487                     def = Some(DefData {
1488                         id: TypeAliasLoc {
1489                             container: module.into(),
1490                             id: ItemTreeId::new(self.file_id, id),
1491                         }
1492                         .intern(self.def_collector.db)
1493                         .into(),
1494                         name: &it.name,
1495                         visibility: &self.item_tree[it.visibility],
1496                         has_constructor: false,
1497                     });
1498                 }
1499             }
1500
1501             if let Some(DefData { id, name, visibility, has_constructor }) = def {
1502                 self.def_collector.def_map.modules[self.module_id].scope.define_def(id);
1503                 let vis = self
1504                     .def_collector
1505                     .def_map
1506                     .resolve_visibility(self.def_collector.db, self.module_id, visibility)
1507                     .unwrap_or(Visibility::Public);
1508                 self.def_collector.update(
1509                     self.module_id,
1510                     &[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor))],
1511                     vis,
1512                     ImportType::Named,
1513                 )
1514             }
1515         }
1516     }
1517
1518     fn collect_module(&mut self, module: &Mod, attrs: &Attrs) {
1519         let path_attr = attrs.by_key("path").string_value();
1520         let is_macro_use = attrs.by_key("macro_use").exists();
1521         match &module.kind {
1522             // inline module, just recurse
1523             ModKind::Inline { items } => {
1524                 let module_id = self.push_child_module(
1525                     module.name.clone(),
1526                     AstId::new(self.file_id, module.ast_id),
1527                     None,
1528                     &self.item_tree[module.visibility],
1529                 );
1530
1531                 if let Some(mod_dir) = self.mod_dir.descend_into_definition(&module.name, path_attr)
1532                 {
1533                     ModCollector {
1534                         def_collector: &mut *self.def_collector,
1535                         macro_depth: self.macro_depth,
1536                         module_id,
1537                         file_id: self.file_id,
1538                         item_tree: self.item_tree,
1539                         mod_dir,
1540                     }
1541                     .collect(&*items);
1542                     if is_macro_use {
1543                         self.import_all_legacy_macros(module_id);
1544                     }
1545                 }
1546             }
1547             // out of line module, resolve, parse and recurse
1548             ModKind::Outline {} => {
1549                 let ast_id = AstId::new(self.file_id, module.ast_id);
1550                 let db = self.def_collector.db;
1551                 match self.mod_dir.resolve_declaration(db, self.file_id, &module.name, path_attr) {
1552                     Ok((file_id, is_mod_rs, mod_dir)) => {
1553                         let item_tree = db.file_item_tree(file_id.into());
1554                         if item_tree
1555                             .top_level_attrs(db, self.def_collector.def_map.krate)
1556                             .cfg()
1557                             .map_or(true, |cfg| {
1558                                 self.def_collector.cfg_options.check(&cfg) != Some(false)
1559                             })
1560                         {
1561                             let module_id = self.push_child_module(
1562                                 module.name.clone(),
1563                                 ast_id,
1564                                 Some((file_id, is_mod_rs)),
1565                                 &self.item_tree[module.visibility],
1566                             );
1567                             ModCollector {
1568                                 def_collector: &mut *self.def_collector,
1569                                 macro_depth: self.macro_depth,
1570                                 module_id,
1571                                 file_id: file_id.into(),
1572                                 item_tree: &item_tree,
1573                                 mod_dir,
1574                             }
1575                             .collect(item_tree.top_level_items());
1576                             if is_macro_use
1577                                 || item_tree
1578                                     .top_level_attrs(db, self.def_collector.def_map.krate)
1579                                     .by_key("macro_use")
1580                                     .exists()
1581                             {
1582                                 self.import_all_legacy_macros(module_id);
1583                             }
1584                         }
1585                     }
1586                     Err(candidate) => {
1587                         self.def_collector.def_map.diagnostics.push(
1588                             DefDiagnostic::unresolved_module(self.module_id, ast_id, candidate),
1589                         );
1590                     }
1591                 };
1592             }
1593         }
1594     }
1595
1596     fn push_child_module(
1597         &mut self,
1598         name: Name,
1599         declaration: AstId<ast::Module>,
1600         definition: Option<(FileId, bool)>,
1601         visibility: &crate::visibility::RawVisibility,
1602     ) -> LocalModuleId {
1603         let vis = self
1604             .def_collector
1605             .def_map
1606             .resolve_visibility(self.def_collector.db, self.module_id, visibility)
1607             .unwrap_or(Visibility::Public);
1608         let modules = &mut self.def_collector.def_map.modules;
1609         let res = modules.alloc(ModuleData::default());
1610         modules[res].parent = Some(self.module_id);
1611         modules[res].origin = match definition {
1612             None => ModuleOrigin::Inline { definition: declaration },
1613             Some((definition, is_mod_rs)) => {
1614                 ModuleOrigin::File { declaration, definition, is_mod_rs }
1615             }
1616         };
1617         for (name, mac) in modules[self.module_id].scope.collect_legacy_macros() {
1618             modules[res].scope.define_legacy_macro(name, mac)
1619         }
1620         modules[self.module_id].children.insert(name.clone(), res);
1621         let module = self.def_collector.def_map.module_id(res);
1622         let def: ModuleDefId = module.into();
1623         self.def_collector.def_map.modules[self.module_id].scope.define_def(def);
1624         self.def_collector.update(
1625             self.module_id,
1626             &[(Some(name), PerNs::from_def(def, vis, false))],
1627             vis,
1628             ImportType::Named,
1629         );
1630         res
1631     }
1632
1633     /// Resolves attributes on an item.
1634     ///
1635     /// Returns `Err` when some attributes could not be resolved to builtins and have been
1636     /// registered as unresolved.
1637     ///
1638     /// If `ignore_up_to` is `Some`, attributes precending and including that attribute will be
1639     /// assumed to be resolved already.
1640     fn resolve_attributes(&mut self, attrs: &Attrs, mod_item: ModItem) -> Result<(), ()> {
1641         let mut ignore_up_to =
1642             self.def_collector.skip_attrs.get(&InFile::new(self.file_id, mod_item)).copied();
1643         let iter = attrs
1644             .iter()
1645             .dedup_by(|a, b| {
1646                 // FIXME: this should not be required, all attributes on an item should have a
1647                 // unique ID!
1648                 // Still, this occurs because `#[cfg_attr]` can "expand" to multiple attributes:
1649                 //     #[cfg_attr(not(off), unresolved, unresolved)]
1650                 //     struct S;
1651                 // We should come up with a different way to ID attributes.
1652                 a.id == b.id
1653             })
1654             .skip_while(|attr| match ignore_up_to {
1655                 Some(id) if attr.id == id => {
1656                     ignore_up_to = None;
1657                     true
1658                 }
1659                 Some(_) => true,
1660                 None => false,
1661             });
1662
1663         for attr in iter {
1664             if attr.path.as_ident() == Some(&hir_expand::name![derive]) {
1665                 self.collect_derive(attr, mod_item);
1666             } else if self.is_builtin_or_registered_attr(&attr.path) {
1667                 continue;
1668             } else {
1669                 log::debug!("non-builtin attribute {}", attr.path);
1670
1671                 let ast_id = AstIdWithPath::new(
1672                     self.file_id,
1673                     mod_item.ast_id(self.item_tree),
1674                     attr.path.as_ref().clone(),
1675                 );
1676                 self.def_collector.unresolved_macros.push(MacroDirective {
1677                     module_id: self.module_id,
1678                     depth: self.macro_depth + 1,
1679                     kind: MacroDirectiveKind::Attr { ast_id, attr: attr.clone(), mod_item },
1680                 });
1681
1682                 return Err(());
1683             }
1684         }
1685
1686         Ok(())
1687     }
1688
1689     fn is_builtin_or_registered_attr(&self, path: &ModPath) -> bool {
1690         if path.kind == PathKind::Plain {
1691             if let Some(tool_module) = path.segments().first() {
1692                 let tool_module = tool_module.to_string();
1693                 if builtin_attr::TOOL_MODULES
1694                     .iter()
1695                     .copied()
1696                     .chain(self.def_collector.registered_tools.iter().map(|s| &**s))
1697                     .any(|m| tool_module == *m)
1698                 {
1699                     return true;
1700                 }
1701             }
1702
1703             if let Some(name) = path.as_ident() {
1704                 let name = name.to_string();
1705                 if builtin_attr::INERT_ATTRIBUTES
1706                     .iter()
1707                     .chain(builtin_attr::EXTRA_ATTRIBUTES)
1708                     .copied()
1709                     .chain(self.def_collector.registered_attrs.iter().map(|s| &**s))
1710                     .any(|attr| name == *attr)
1711                 {
1712                     return true;
1713                 }
1714             }
1715         }
1716
1717         false
1718     }
1719
1720     fn collect_derive(&mut self, attr: &Attr, mod_item: ModItem) {
1721         let ast_id: FileAstId<ast::Item> = match mod_item {
1722             ModItem::Struct(it) => self.item_tree[it].ast_id.upcast(),
1723             ModItem::Union(it) => self.item_tree[it].ast_id.upcast(),
1724             ModItem::Enum(it) => self.item_tree[it].ast_id.upcast(),
1725             _ => {
1726                 // Cannot use derive on this item.
1727                 // FIXME: diagnose
1728                 return;
1729             }
1730         };
1731
1732         match attr.parse_derive() {
1733             Some(derive_macros) => {
1734                 for path in derive_macros {
1735                     let ast_id = AstIdWithPath::new(self.file_id, ast_id, path);
1736                     self.def_collector.unresolved_macros.push(MacroDirective {
1737                         module_id: self.module_id,
1738                         depth: self.macro_depth + 1,
1739                         kind: MacroDirectiveKind::Derive { ast_id, derive_attr: attr.id },
1740                     });
1741                 }
1742             }
1743             None => {
1744                 // FIXME: diagnose
1745                 log::debug!("malformed derive: {:?}", attr);
1746             }
1747         }
1748     }
1749
1750     /// If `attrs` registers a procedural macro, collects its definition.
1751     fn collect_proc_macro_def(&mut self, func_name: &Name, ast_id: AstId<ast::Fn>, attrs: &Attrs) {
1752         // FIXME: this should only be done in the root module of `proc-macro` crates, not everywhere
1753         if let Some(proc_macro) = attrs.parse_proc_macro_decl(func_name) {
1754             self.def_collector.export_proc_macro(proc_macro, ast_id);
1755         }
1756     }
1757
1758     fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) {
1759         let krate = self.def_collector.def_map.krate;
1760         let mac = &self.item_tree[id];
1761         let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into());
1762         let ast_id = InFile::new(self.file_id, mac.ast_id.upcast());
1763
1764         let export_attr = attrs.by_key("macro_export");
1765
1766         let is_export = export_attr.exists();
1767         let is_local_inner = if is_export {
1768             export_attr.tt_values().map(|it| &it.token_trees).flatten().any(|it| match it {
1769                 tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
1770                     ident.text.contains("local_inner_macros")
1771                 }
1772                 _ => false,
1773             })
1774         } else {
1775             false
1776         };
1777
1778         // Case 1: builtin macros
1779         if attrs.by_key("rustc_builtin_macro").exists() {
1780             // `#[rustc_builtin_macro = "builtin_name"]` overrides the `macro_rules!` name.
1781             let name;
1782             let name = match attrs.by_key("rustc_builtin_macro").string_value() {
1783                 Some(it) => {
1784                     // FIXME: a hacky way to create a Name from string.
1785                     name = tt::Ident { text: it.clone(), id: tt::TokenId::unspecified() }.as_name();
1786                     &name
1787                 }
1788                 None => &mac.name,
1789             };
1790             let krate = self.def_collector.def_map.krate;
1791             match find_builtin_macro(name, krate, ast_id) {
1792                 Some(macro_id) => {
1793                     self.def_collector.define_macro_rules(
1794                         self.module_id,
1795                         mac.name.clone(),
1796                         macro_id,
1797                         is_export,
1798                     );
1799                     return;
1800                 }
1801                 None => {
1802                     self.def_collector
1803                         .def_map
1804                         .diagnostics
1805                         .push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, ast_id));
1806                 }
1807             }
1808         }
1809
1810         // Case 2: normal `macro_rules!` macro
1811         let macro_id = MacroDefId {
1812             krate: self.def_collector.def_map.krate,
1813             kind: MacroDefKind::Declarative(ast_id),
1814             local_inner: is_local_inner,
1815         };
1816         self.def_collector.define_macro_rules(
1817             self.module_id,
1818             mac.name.clone(),
1819             macro_id,
1820             is_export,
1821         );
1822     }
1823
1824     fn collect_macro_def(&mut self, id: FileItemTreeId<MacroDef>) {
1825         let krate = self.def_collector.def_map.krate;
1826         let mac = &self.item_tree[id];
1827         let ast_id = InFile::new(self.file_id, mac.ast_id.upcast());
1828
1829         // Case 1: bulitin macros
1830         let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into());
1831         if attrs.by_key("rustc_builtin_macro").exists() {
1832             let macro_id = find_builtin_macro(&mac.name, krate, ast_id)
1833                 .or_else(|| find_builtin_derive(&mac.name, krate, ast_id));
1834
1835             match macro_id {
1836                 Some(macro_id) => {
1837                     self.def_collector.define_macro_def(
1838                         self.module_id,
1839                         mac.name.clone(),
1840                         macro_id,
1841                         &self.item_tree[mac.visibility],
1842                     );
1843                     return;
1844                 }
1845                 None => {
1846                     self.def_collector
1847                         .def_map
1848                         .diagnostics
1849                         .push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, ast_id));
1850                 }
1851             }
1852         }
1853
1854         // Case 2: normal `macro`
1855         let macro_id = MacroDefId {
1856             krate: self.def_collector.def_map.krate,
1857             kind: MacroDefKind::Declarative(ast_id),
1858             local_inner: false,
1859         };
1860
1861         self.def_collector.define_macro_def(
1862             self.module_id,
1863             mac.name.clone(),
1864             macro_id,
1865             &self.item_tree[mac.visibility],
1866         );
1867     }
1868
1869     fn collect_macro_call(&mut self, mac: &MacroCall) {
1870         let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, (*mac.path).clone());
1871
1872         // Case 1: try to resolve in legacy scope and expand macro_rules
1873         let mut error = None;
1874         match macro_call_as_call_id(
1875             &ast_id,
1876             mac.fragment,
1877             self.def_collector.db,
1878             self.def_collector.def_map.krate,
1879             |path| {
1880                 path.as_ident().and_then(|name| {
1881                     self.def_collector.def_map.with_ancestor_maps(
1882                         self.def_collector.db,
1883                         self.module_id,
1884                         &mut |map, module| map[module].scope.get_legacy_macro(&name),
1885                     )
1886                 })
1887             },
1888             &mut |err| {
1889                 error.get_or_insert(err);
1890             },
1891         ) {
1892             Ok(Ok(macro_call_id)) => {
1893                 // Legacy macros need to be expanded immediately, so that any macros they produce
1894                 // are in scope.
1895                 self.def_collector.collect_macro_expansion(
1896                     self.module_id,
1897                     macro_call_id,
1898                     self.macro_depth + 1,
1899                 );
1900
1901                 return;
1902             }
1903             Ok(Err(_)) => {
1904                 // Built-in macro failed eager expansion.
1905
1906                 // FIXME: don't parse the file here
1907                 let fragment = hir_expand::to_fragment_kind(
1908                     &ast_id.ast_id.to_node(self.def_collector.db.upcast()),
1909                 );
1910                 self.def_collector.def_map.diagnostics.push(DefDiagnostic::macro_error(
1911                     self.module_id,
1912                     MacroCallKind::FnLike { ast_id: ast_id.ast_id, fragment },
1913                     error.unwrap().to_string(),
1914                 ));
1915                 return;
1916             }
1917             Err(UnresolvedMacro { .. }) => (),
1918         }
1919
1920         // Case 2: resolve in module scope, expand during name resolution.
1921         // We rewrite simple path `macro_name` to `self::macro_name` to force resolve in module scope only.
1922         if ast_id.path.is_ident() {
1923             ast_id.path.kind = PathKind::Super(0);
1924         }
1925
1926         self.def_collector.unresolved_macros.push(MacroDirective {
1927             module_id: self.module_id,
1928             depth: self.macro_depth + 1,
1929             kind: MacroDirectiveKind::FnLike { ast_id, fragment: mac.fragment },
1930         });
1931     }
1932
1933     fn import_all_legacy_macros(&mut self, module_id: LocalModuleId) {
1934         let macros = self.def_collector.def_map[module_id].scope.collect_legacy_macros();
1935         for (name, macro_) in macros {
1936             self.def_collector.define_legacy_macro(self.module_id, name.clone(), macro_);
1937         }
1938     }
1939
1940     fn is_cfg_enabled(&self, cfg: &CfgExpr) -> bool {
1941         self.def_collector.cfg_options.check(cfg) != Some(false)
1942     }
1943
1944     fn emit_unconfigured_diagnostic(&mut self, item: ModItem, cfg: &CfgExpr) {
1945         let ast_id = item.ast_id(self.item_tree);
1946
1947         let ast_id = InFile::new(self.file_id, ast_id);
1948         self.def_collector.def_map.diagnostics.push(DefDiagnostic::unconfigured_code(
1949             self.module_id,
1950             ast_id,
1951             cfg.clone(),
1952             self.def_collector.cfg_options.clone(),
1953         ));
1954     }
1955 }
1956
1957 #[cfg(test)]
1958 mod tests {
1959     use crate::{db::DefDatabase, test_db::TestDB};
1960     use base_db::{fixture::WithFixture, SourceDatabase};
1961
1962     use super::*;
1963
1964     fn do_collect_defs(db: &dyn DefDatabase, def_map: DefMap) -> DefMap {
1965         let mut collector = DefCollector {
1966             db,
1967             def_map,
1968             glob_imports: FxHashMap::default(),
1969             unresolved_imports: Vec::new(),
1970             resolved_imports: Vec::new(),
1971             unresolved_macros: Vec::new(),
1972             mod_dirs: FxHashMap::default(),
1973             cfg_options: &CfgOptions::default(),
1974             proc_macros: Default::default(),
1975             exports_proc_macros: false,
1976             from_glob_import: Default::default(),
1977             skip_attrs: Default::default(),
1978             derive_helpers_in_scope: Default::default(),
1979             registered_attrs: Default::default(),
1980             registered_tools: Default::default(),
1981         };
1982         collector.seed_with_top_level();
1983         collector.collect();
1984         collector.def_map
1985     }
1986
1987     fn do_resolve(code: &str) -> DefMap {
1988         let (db, _file_id) = TestDB::with_single_file(&code);
1989         let krate = db.test_crate();
1990
1991         let edition = db.crate_graph()[krate].edition;
1992         let def_map = DefMap::empty(krate, edition);
1993         do_collect_defs(&db, def_map)
1994     }
1995
1996     #[test]
1997     fn test_macro_expand_will_stop_1() {
1998         do_resolve(
1999             r#"
2000         macro_rules! foo {
2001             ($($ty:ty)*) => { foo!($($ty)*); }
2002         }
2003         foo!(KABOOM);
2004         "#,
2005         );
2006     }
2007
2008     #[ignore] // this test does succeed, but takes quite a while :/
2009     #[test]
2010     fn test_macro_expand_will_stop_2() {
2011         do_resolve(
2012             r#"
2013         macro_rules! foo {
2014             ($($ty:ty)*) => { foo!($($ty)* $($ty)*); }
2015         }
2016         foo!(KABOOM);
2017         "#,
2018         );
2019     }
2020 }