]> git.proxmox.com Git - rustc.git/blobdiff - src/doc/rustc-dev-guide/src/name-resolution.md
New upstream version 1.52.0~beta.3+dfsg1
[rustc.git] / src / doc / rustc-dev-guide / src / name-resolution.md
index f3aacba001706b3e0c850cab14ec7b59043cac14..2eb76384c0f3fb36b6920a5e8211750b0ecdae0c 100644 (file)
@@ -1,5 +1,30 @@
 # Name resolution
 
+<!-- toc -->
+
+In the previous chapters, we saw how the AST is built with all macros expanded.
+We saw how doing that requires doing some name resolution to resolve imports
+and macro names. In this chapter, we show how this is actually done and more.
+
+In fact, we don't do full name resolution during macro expansion -- we only
+resolve imports and macros at that time. This is required to know what to even
+expand. Later, after we have the whole AST, we do full name resolution to
+resolve all names in the crate. This happens in [`rustc_resolve::late`][late].
+Unlike during macro expansion, in this late expansion, we only need to try to
+resolve a name once, since no new names can be added. If we fail to resolve a
+name now, then it is a compiler error.
+
+Name resolution can be complex. There are a few different namespaces (e.g.
+macros, values, types, lifetimes), and names may be valid at different (nested)
+scopes. Also, different types of names can fail to be resolved differently, and
+failures can happen differently at different scopes. For example, for a module
+scope, failure means no unexpanded macros and no unresolved glob imports in
+that module. On the other hand, in a function body, failure requires that a
+name be absent from the block we are in, all outer scopes, and the global
+scope.
+
+[late]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/index.html
+
 ## Basics
 
 In our programs we can refer to variables, types, functions, etc, by giving them
@@ -20,7 +45,7 @@ namespaces and therefore can co-exist.
 The name resolution in Rust is a two-phase process. In the first phase, which runs
 during macro expansion, we build a tree of modules and resolve imports. Macro
 expansion and name resolution communicate with each other via the
-[`Resolver`] trait.
+[`ResolverAstLowering`] trait.
 
 The input to the second phase is the syntax tree, produced by parsing input
 files and expanding macros. This phase produces links from all the names in the
@@ -32,11 +57,11 @@ A successful run of the second phase ([`Resolver::resolve_crate`]) creates kind
 of an index the rest of the compilation may use to ask about the present names
 (through the `hir::lowering::Resolver` interface).
 
-The name resolution lives in the `librustc_resolve` crate, with the meat in
+The name resolution lives in the `rustc_resolve` crate, with the meat in
 `lib.rs` and some helpers or symbol-type specific logic in the other modules.
 
 [`Resolver::resolve_crate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/struct.Resolver.html#method.resolve_crate
-[`Resolver`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/trait.Resolver.html
+[`ResolverAstLowering`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/trait.ResolverAstLowering.html
 
 ## Namespaces
 
@@ -122,6 +147,23 @@ the code can be processed.
 
 Therefore, the resolution is performed in multiple stages.
 
+## Speculative crate loading
+
+To give useful errors, rustc suggests importing paths into scope if they're
+not found. How does it do this? It looks through every module of every crate
+and looks for possible matches. This even includes crates that haven't yet
+been loaded!
+
+Loading crates for import suggestions that haven't yet been loaded is called
+_speculative crate loading_, because any errors it encounters shouldn't be
+reported: resolve decided to load them, not the user. The function that does
+this is `lookup_import_candidates` and lives in
+`rustc_resolve/src/diagnostics.rs`.
+
+To tell the difference between speculative loads and loads initiated by the
+user, resolve passes around a `record_used` parameter, which is `false` when
+the load is speculative.
+
 ## TODO:
 
 This is a result of the first pass of learning the code. It is definitely