//! This module implements import-resolution/macro expansion algorithm. //! //! The result of this module is `CrateDefMap`: a data structure which contains: //! //! * a tree of modules for the crate //! * for each module, a set of items visible in the module (directly declared //! or imported) //! //! Note that `CrateDefMap` contains fully macro expanded code. //! //! Computing `CrateDefMap` can be partitioned into several logically //! independent "phases". The phases are mutually recursive though, there's no //! strict ordering. //! //! ## Collecting RawItems //! //! This happens in the `raw` module, which parses a single source file into a //! set of top-level items. Nested imports are desugared to flat imports in //! this phase. Macro calls are represented as a triple of (Path, Option, //! TokenTree). //! //! ## Collecting Modules //! //! This happens in the `collector` module. In this phase, we recursively walk //! tree of modules, collect raw items from submodules, populate module scopes //! with defined items (so, we assign item ids in this phase) and record the set //! of unresolved imports and macros. //! //! While we walk tree of modules, we also record macro_rules definitions and //! expand calls to macro_rules defined macros. //! //! ## Resolving Imports //! //! We maintain a list of currently unresolved imports. On every iteration, we //! try to resolve some imports from this list. If the import is resolved, we //! record it, by adding an item to current module scope and, if necessary, by //! recursively populating glob imports. //! //! ## Resolving Macros //! //! macro_rules from the same crate use a global mutable namespace. We expand //! them immediately, when we collect modules. //! //! Macros from other crates (including proc-macros) can be used with //! `foo::bar!` syntax. We handle them similarly to imports. There's a list of //! unexpanded macros. On every iteration, we try to resolve each macro call //! path and, upon success, we run macro expansion and "collect module" phase //! on the result pub use hir_def::nameres::{ per_ns::{Namespace, PerNs}, raw::ImportId, };