2
2
3
3
<!-- toc -->
4
4
5
- In the previous chapters, we saw how the AST is built with all macros expanded.
6
- We saw how doing that requires doing some name resolution to resolve imports
7
- and macro names. In this chapter, we show how this is actually done and more.
5
+ In the previous chapters, we saw how the [ * Abstract Syntax Tree* (` AST ` )] [ ast ]
6
+ is built with all ` macros ` expanded. We saw how doing that requires doing some
7
+ name resolution to resolve imports and ` macro ` names. In this chapter, we show
8
+ how this is actually done and more.
8
9
9
- In fact, we don't do full name resolution during macro expansion -- we only
10
- resolve imports and macros at that time. This is required to know what to even
11
- expand. Later, after we have the whole AST, we do full name resolution to
10
+ [ ast ] : https://en.wikipedia.org/wiki/Abstract_syntax_tree
11
+
12
+ In fact, we don't do full name resolution during ` macro ` expansion -- we only
13
+ resolve imports and ` macros ` at that time. This is required to know what to even
14
+ expand. Later, after we have the whole ` AST ` , we do full name resolution to
12
15
resolve all names in the crate. This happens in [ ` rustc_resolve::late ` ] [ late ] .
13
- Unlike during macro expansion, in this late expansion, we only need to try to
16
+ Unlike during ` macro ` expansion, in this late expansion, we only need to try to
14
17
resolve a name once, since no new names can be added. If we fail to resolve a
15
- name now , then it is a compiler error.
16
-
17
- Name resolution can be complex. There are a few different namespaces (e.g.
18
- macros, values, types, lifetimes), and names may be valid at different (nested)
19
- scopes. Also, different types of names can fail to be resolved differently, and
20
- failures can happen differently at different scopes. For example, for a module
21
- scope, failure means no unexpanded macros and no unresolved glob imports in
22
- that module. On the other hand, in a function body, failure requires that a
18
+ name, then it is a compiler error.
19
+
20
+ Name resolution can be complex. There are different namespaces (e.g.
21
+ ` macros ` , values, types, lifetimes), and names may be valid at different (nested)
22
+ scopes. Also, different types of names can fail resolution differently, and
23
+ failures can happen differently at different scopes. For example, in a module
24
+ scope, failure means no unexpanded ` macros ` and no unresolved glob imports in
25
+ that module. On the other hand, in a function body scope , failure requires that a
23
26
name be absent from the block we are in, all outer scopes, and the global
24
27
scope.
25
28
26
29
[ late ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/index.html
27
30
28
31
## Basics
29
32
30
- In our programs we can refer to variables, types, functions, etc, by giving them
33
+ In our programs we refer to variables, types, functions, etc, by giving them
31
34
a name. These names are not always unique. For example, take this valid Rust
32
35
program:
33
36
@@ -37,38 +40,39 @@ let x: x = 1;
37
40
let y : x = 2 ;
38
41
```
39
42
40
- How do we know on line 3 whether ` x ` is a type (u32) or a value (1)? These
43
+ How do we know on line 3 whether ` x ` is a type (` u32 ` ) or a value (1)? These
41
44
conflicts are resolved during name resolution. In this specific case, name
42
45
resolution defines that type names and variable names live in separate
43
46
namespaces and therefore can co-exist.
44
47
45
48
The name resolution in Rust is a two-phase process. In the first phase, which runs
46
- during macro expansion, we build a tree of modules and resolve imports. Macro
49
+ during ` macro ` expansion, we build a tree of modules and resolve imports. Macro
47
50
expansion and name resolution communicate with each other via the
48
51
[ ` ResolverAstLoweringExt ` ] trait.
49
52
50
53
The input to the second phase is the syntax tree, produced by parsing input
51
- files and expanding macros. This phase produces links from all the names in the
54
+ files and expanding ` macros ` . This phase produces links from all the names in the
52
55
source to relevant places where the name was introduced. It also generates
53
- helpful error messages, like typo suggestions, traits to import or lints about
56
+ helpful error messages, like typo suggestions, ` trait ` s to import or lints about
54
57
unused items.
55
58
56
59
A successful run of the second phase ([ ` Resolver::resolve_crate ` ] ) creates kind
57
60
of an index the rest of the compilation may use to ask about the present names
58
61
(through the ` hir::lowering::Resolver ` interface).
59
62
60
- The name resolution lives in the ` rustc_resolve ` crate, with the meat in
63
+ The name resolution lives in the [ ` rustc_resolve ` ] crate, with the bulk in
61
64
` lib.rs ` and some helpers or symbol-type specific logic in the other modules.
62
65
63
66
[ `Resolver::resolve_crate` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/struct.Resolver.html#method.resolve_crate
64
67
[ `ResolverAstLoweringExt` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/trait.ResolverAstLoweringExt.html
68
+ [ `rustc_resolve` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/index.html
65
69
66
70
## Namespaces
67
71
68
72
Different kind of symbols live in different namespaces ‒ e.g. types don't
69
73
clash with variables. This usually doesn't happen, because variables start with
70
- lower-case letter while types with upper case one, but this is only a
71
- convention. This is legal Rust code that'll compile (with warnings):
74
+ lower-case letter while types with upper- case one, but this is only a
75
+ convention. This is legal Rust code that will compile (with warnings):
72
76
73
77
``` rust
74
78
type x = u32 ;
@@ -81,33 +85,37 @@ namespaces, the resolver keeps them separated and builds separate structures for
81
85
them.
82
86
83
87
In other words, when the code talks about namespaces, it doesn't mean the module
84
- hierarchy, it's types vs. values vs. macros.
88
+ hierarchy, it's types vs. values vs. ` macros ` .
85
89
86
90
## Scopes and ribs
87
91
88
92
A name is visible only in certain area in the source code. This forms a
89
93
hierarchical structure, but not necessarily a simple one ‒ if one scope is
90
- part of another, it doesn't mean the name visible in the outer one is also
91
- visible in the inner one , or that it refers to the same thing.
94
+ part of another, it doesn't mean a name visible in the outer scope is also
95
+ visible in the inner scope , or that it refers to the same thing.
92
96
93
- To cope with that, the compiler introduces the concept of Ribs . This is
97
+ To cope with that, the compiler introduces the concept of [ ` Rib ` ] s . This is
94
98
an abstraction of a scope. Every time the set of visible names potentially changes,
95
- a new rib is pushed onto a stack. The places where this can happen include for
99
+ a new [ ` Rib ` ] is pushed onto a stack. The places where this can happen include for
96
100
example:
97
101
102
+ [ `Rib` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/struct.Rib.html
103
+
98
104
* The obvious places ‒ curly braces enclosing a block, function boundaries,
99
105
modules.
100
- * Introducing a let binding ‒ this can shadow another binding with the same
106
+ * Introducing a ` let ` binding ‒ this can shadow another binding with the same
101
107
name.
102
- * Macro expansion border ‒ to cope with macro hygiene.
108
+ * Macro expansion border ‒ to cope with ` macro ` hygiene.
103
109
104
- When searching for a name, the stack of ribs is traversed from the innermost
110
+ When searching for a name, the stack of [ ` ribs ` ] is traversed from the innermost
105
111
outwards. This helps to find the closest meaning of the name (the one not
106
- shadowed by anything else). The transition to outer rib may also affect
107
- what names are usable ‒ if there are nested functions (not closures ),
112
+ shadowed by anything else). The transition to outer [ ` Rib ` ] may also affect
113
+ what names are usable ‒ if there are nested functions (not ` closure ` s ),
108
114
the inner one can't access parameters and local bindings of the outer one,
109
115
even though they should be visible by ordinary scoping rules. An example:
110
116
117
+ [ `ribs` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/struct.LateResolutionVisitor.html#structfield.ribs
118
+
111
119
``` rust
112
120
fn do_something <T : Default >(val : T ) { // <- New rib in both types and values (1)
113
121
// `val` is accessible, as is the helper function
@@ -126,45 +134,49 @@ fn do_something<T: Default>(val: T) { // <- New rib in both types and values (1)
126
134
```
127
135
128
136
Because the rules for different namespaces are a bit different, each namespace
129
- has its own independent rib stack that is constructed in parallel to the others.
130
- In addition, there's also a rib stack for local labels (e.g. names of loops or
137
+ has its own independent [ ` Rib ` ] stack that is constructed in parallel to the others.
138
+ In addition, there's also a [ ` Rib ` ] stack for local labels (e.g. names of loops or
131
139
blocks), which isn't a full namespace in its own right.
132
140
133
141
## Overall strategy
134
142
135
143
To perform the name resolution of the whole crate, the syntax tree is traversed
136
144
top-down and every encountered name is resolved. This works for most kinds of
137
- names, because at the point of use of a name it is already introduced in the Rib
145
+ names, because at the point of use of a name it is already introduced in the [ ` Rib ` ]
138
146
hierarchy.
139
147
140
148
There are some exceptions to this. Items are bit tricky, because they can be
141
149
used even before encountered ‒ therefore every block needs to be first scanned
142
- for items to fill in its Rib.
150
+ for items to fill in its [ ` Rib ` ] .
143
151
144
152
Other, even more problematic ones, are imports which need recursive fixed-point
145
- resolution and macros, that need to be resolved and expanded before the rest of
153
+ resolution and ` macros ` , that need to be resolved and expanded before the rest of
146
154
the code can be processed.
147
155
148
156
Therefore, the resolution is performed in multiple stages.
149
157
150
158
## Speculative crate loading
151
159
152
- To give useful errors, rustc suggests importing paths into scope if they're
160
+ To give useful errors, ` rustc ` suggests importing paths into scope if they're
153
161
not found. How does it do this? It looks through every module of every crate
154
162
and looks for possible matches. This even includes crates that haven't yet
155
163
been loaded!
156
164
157
- Loading crates for import suggestions that haven't yet been loaded is called
158
- _ speculative crate loading_ , because any errors it encounters shouldn't be
159
- reported: resolve decided to load them, not the user. The function that does
160
- this is ` lookup_import_candidates ` and lives in
161
- ` rustc_resolve/src/diagnostics.rs ` .
165
+ Eagerly loading crates to include import suggestions that haven't yet been
166
+ loaded is called _ speculative crate loading_ , because any errors it encounters
167
+ shouldn't be reported: [ ` rustc_resolve ` ] decided to load them, not the user. The function
168
+ that does this is [ ` lookup_import_candidates ` ] and lives in
169
+ [ ` rustc_resolve::diagnostics ` ] .
170
+
171
+ [ `rustc_resolve` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/index.html
172
+ [ `lookup_import_candidates` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/struct.Resolver.html#method.lookup_import_candidates
173
+ [ `rustc_resolve::diagnostics` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/diagnostics/index.html
162
174
163
175
To tell the difference between speculative loads and loads initiated by the
164
- user, resolve passes around a ` record_used ` parameter, which is ` false ` when
176
+ user, [ ` rustc_resolve ` ] passes around a ` record_used ` parameter, which is ` false ` when
165
177
the load is speculative.
166
178
167
- ## TODO: [ #16 ] ( https://github.com/rust-lang/rustc-dev-guide/issues/16 )
179
+ <!-- ## TODO: [#16](https://github.com/rust-lang/rustc-dev-guide/issues/16)
168
180
169
181
This is a result of the first pass of learning the code. It is definitely
170
182
incomplete and not detailed enough. It also might be inaccurate in places.
@@ -178,4 +190,4 @@ Still, it probably provides useful first guidepost to what happens in there.
178
190
* The overall strategy description is a bit vague.
179
191
* Where does the name `Rib` come from?
180
192
* Does this thing have its own tests, or is it tested only as part of some e2e
181
- testing?
193
+ testing? -->
0 commit comments