You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
_Name resolution_ is the process of tying paths and other identifiers to the declarations of those entities. Names are segregated into different [namespaces], allowing entities in different namespaces to share the same name without conflict. Each name is valid within a [scope], or a region of source text where that name may be referenced. Access to certain names may be restricted based on their[visibility].
5
+
_Name resolution_ is the process of tying paths and other identifiers to the declarations of those entities. Names are segregated into different [namespaces], allowing entities in different namespaces to share the same name without conflict. Each name is valid within a [scope], or a region of source text where that name may be referenced. Access to a name may be restricted based on its[visibility].
6
6
7
-
Name resolution is split into three stages throughout the compilation process. The first stage, *expansion-time resolution*, resolves all [`use` declarations] and [macro invocations]. The second stage, *primary resolution*, resolves all names that have not yet been resolved that do not depend on type information to resolve. The last stage, *type-relative resolution*, resolves the remaining names once type information is available.
7
+
Name resolution is split into three stages throughout the compilation process. The first stage, *expansion-time resolution*, resolves all [`use` declarations] and [macro invocations]. The second stage, *primary resolution*, resolves all names that have not yet been resolved and that do not depend on type information to resolve. The last stage, *type-relative resolution*, resolves the remaining names once type information is available.
8
8
9
9
> [!NOTE]
10
-
>
11
-
> * Expansion-time resolution is also known as "early resolution".
12
-
> * Primary resolution is also known as "late resolution".
10
+
> Expansion-time resolution is also known as *early resolution*. Primary resolution is also known as *late resolution*.
13
11
14
12
r[names.resolution.general]
15
13
## General
16
14
17
15
r[names.resolution.general.intro]
18
-
The following rules apply to all stages of name resolution.
16
+
The rules within this section apply to all stages of name resolution.
19
17
20
18
r[names.resolution.general.scopes]
21
19
### Scopes
22
20
23
21
r[names.resolution.general.scopes.intro]
24
22
> [!NOTE]
25
-
> This is a placeholder for future expansion about resolution of names through various scopes.
23
+
> This is a placeholder for future expansion about resolution of names within various scopes.
26
24
27
25
r[names.resolution.expansion]
28
26
## Expansion-time name resolution
29
27
30
28
r[names.resolution.expansion.intro]
31
-
Expansion-time name resolution is the stage of name resolution necessary to complete macro expansion and fully generate a crate's AST. This stage requires the resolution of macro invocations and `use` declarations. Resolving `use` declarations is required to resolve [path-based scope] macro invocations. Resolving macro invocations is required in order to expand them.
29
+
Expansion-time name resolution is the stage of name resolution necessary to complete macro expansion and fully generate a crate's [AST]. This stage requires the resolution of macro invocations and `use` declarations. Resolving `use` declarations is required for macro invocations that resolve via [path-based scope]. Resolving macro invocations is required in order to expand them.
After expansion-time name resolution, the AST must not contain any unexpanded macro invocations. Every macro invocation resolves to a valid definition that exists in the final AST or an external crate.
32
+
After expansion-time name resolution, the AST must not contain any unexpanded macro invocations. Every macro invocation resolves to a valid definition that exists in the final AST or in an external crate.
35
33
36
34
```rust,compile_fail
37
-
fn main() {
38
-
foo!(); // ERROR: cannot find macro `foo` in this scope
39
-
}
35
+
m!(); // ERROR: Cannot find macro `m` in this scope.
The resolution of names must be *stable*. After expansion, names in the fully expanded AST must resolve to the same definition, regardless of the order in which macros are expanded.
39
+
The resolution of names must be stable. After expansion, names in the fully expanded AST must resolve to the same definition regardless of the order in which macros are expanded and imports are resolved.
44
40
45
41
r[names.resolution.expansion.speculation]
46
42
All name resolution candidates selected during macro expansion are considered speculative. Once the crate has been fully expanded, all speculative import resolutions are validated to ensure that macro expansion did not introduce any new ambiguities.
47
43
48
44
> [!NOTE]
49
-
>
50
-
> Due to the iterative nature of macro expansion, this causes so called time traveling ambiguities, such as when a macro or glob import introduces an item that is ambiguous with its own base path.
45
+
> Due to the iterative nature of macro expansion, this causes so-called time traveling ambiguities, such as when a macro or glob import introduces an item that is ambiguous with its own base path.
51
46
>
52
47
> ```rust,compile_fail,E0659
53
-
> macro_rules! m {
54
-
> () => { mod bar {} }
48
+
> # fn main() {}
49
+
> macro_rules! f {
50
+
> () => {
51
+
> mod m {
52
+
> pub(crate) use f;
53
+
> }
54
+
> }
55
55
> }
56
+
> f!();
56
57
>
57
-
> mod bar {
58
-
> pub(crate) use m;
59
-
> }
60
-
>
61
-
> fn f() {
62
-
> // * Initially speculatively resolve `bar` to the module in the crate root.
63
-
> // * Expansion of `m` introduces a second bar module inside the body of `f`.
64
-
> // * Expansion-time resolution finalizes resolutions by re-resolving all
65
-
> // imports and macro invocations, sees the introduced ambiguity
66
-
> // and reports it as an error.
67
-
> bar::m!(); // ERROR: `bar` is ambiguous
68
-
> }
58
+
> const _: () = {
59
+
> // Initially, we speculatively resolve `m` to the module in
60
+
> // the crate root.
61
+
> //
62
+
> // Expansion of `f` introduces a second `m` module inside this
63
+
> // body.
64
+
> //
65
+
> // Expansion-time resolution finalizes resolutions by re-
66
+
> // resolving all imports and macro invocations, sees the
67
+
> // introduced ambiguity and reports it as an error.
68
+
> m::f!(); // ERROR: `bar` is ambiguous.
69
+
> };
69
70
> ```
70
71
71
72
r[names.resolution.expansion.imports]
72
73
### Imports
73
74
r[names.resolution.expansion.imports.intro]
74
-
All `use` declarations are fully resolved during this stage of resolution. Type-relative paths cannot be resolved at this stage of compilation and will produce an error.
75
+
All `use` declarations are fully resolved during this stage of resolution. [Type-relative paths] cannot be resolved at this stage and will produce an error.
75
76
76
77
```rust
77
-
mod my_mod {
78
-
pub const CONST: () = ();
79
-
80
-
pub enum MyEnum {
81
-
MyVariant
78
+
mod m {
79
+
pub const C: () = ();
80
+
pub enum E { V }
81
+
pub type A = E;
82
+
impl E {
83
+
pub const C: () = ();
82
84
}
83
-
84
-
impl MyEnum {
85
-
pub const CONST: () = ();
86
-
}
87
-
88
-
pub type TypeAlias = MyEnum;
89
85
}
90
86
91
87
// Valid imports resolved at expansion-time:
92
-
use my_mod::MyEnum; // OK
93
-
use my_mod::MyEnum::MyVariant; // OK
94
-
use my_mod::TypeAlias; // OK
95
-
use my_mod::CONST; // OK
88
+
use m::C; // OK.
89
+
use m::E; // OK.
90
+
use m::A; // OK.
91
+
use m::E::V; // OK.
96
92
97
93
// Valid expressions resolved during type-relative resolution:
98
-
let _ = my_mod::TypeAlias::MyVariant; // OK
99
-
let _ = my_mod::MyEnum::CONST; // OK
94
+
let _ = m::A::V; // OK.
95
+
let _ = m::E::C; // OK.
100
96
```
101
97
102
98
```rust,compile_fail,E0432
103
-
# mod my_mod {
104
-
# pub const CONST: () = ();
105
-
#
106
-
# pub enum MyEnum {
107
-
# MyVariant
99
+
# mod m {
100
+
# pub const C: () = ();
101
+
# pub enum E { V }
102
+
# pub type A = E;
103
+
# impl E {
104
+
# pub const C: () = ();
108
105
# }
109
-
#
110
-
# impl MyEnum {
111
-
# pub const CONST: () = ();
112
-
# }
113
-
#
114
-
# pub type TypeAlias = MyEnum;
115
106
# }
116
107
// Invalid type-relative imports that can't resolve at expansion-time:
117
-
use my_mod::TypeAlias::MyVariant; // ERROR: unresolved import `my_mod::TypeAlias`
118
-
use my_mod::MyEnum::CONST; // ERROR: unresolved import `my_mod::MyEnum::CONST`
108
+
use m::E::C; // ERROR: Unresolved import `m::E::C`.
109
+
use m::A::V; // ERROR: Unresolved import `m::A::V`.
119
110
```
120
111
121
112
r[names.resolution.expansion.imports.shadowing]
122
-
The following is a list of situations where shadowing of `use` declarations is permitted:
113
+
Shadowing of names with a `use` declaration is permitted only with:
114
+
115
+
-[`use` glob shadowing]
116
+
-[Macro textual scope shadowing]
117
+
- TODO: Also `use` declarations in anonymous scopes.
118
+
119
+
Example for the TODO:
120
+
121
+
```rust
122
+
pubmodfoo {
123
+
pubmodbaz {
124
+
pubstructName;
125
+
}
126
+
}
123
127
124
-
*[`use` glob shadowing]
125
-
*[Macro textual scope shadowing]
128
+
pubmodbar {
129
+
pubmodbaz {
130
+
pubstructName;
131
+
}
132
+
}
133
+
134
+
usefoo::baz::Name;
135
+
fnf() {
136
+
usebar::baz::Name;
137
+
Name;
138
+
}
139
+
```
126
140
127
141
r[names.resolution.expansion.imports.ambiguity]
128
142
#### Ambiguities
@@ -159,7 +173,7 @@ fn ambiguous_shadow() {
159
173
}
160
174
```
161
175
162
-
Multiple glob imports are allowed to import the same name, and that name is allowed to be used, if the imports are of the same item (following re-exports). The visibility of the name is the maximum visibility of the imports. For example:
176
+
Multiple glob imports are allowed to import the same name, and that name is allowed to be used if the imports are of the same item (following re-exports). The visibility of the name is the maximum visibility of the imports. For example:
Names may not be resolved through glob imports when there is another candidate available in an [outer scope].
186
200
187
201
```rust,compile_fail,E0659
@@ -223,7 +237,7 @@ pub fn qux() {
223
237
```
224
238
225
239
> [!NOTE]
226
-
> These ambiguity errors are specific to imports, even though they are only observed when those imports are used. Having multiple candidates available for a given name during later stages of resolution is not considered an error, so long as none of the imports themselves are ambiguous, there will always be a single unambiguous closest resolution.
240
+
> These ambiguity errors are specific to imports, even though they are only observed when those imports are used. Having multiple candidates available for a given name during later stages of resolution is not considered an error. So long as none of the imports themselves are ambiguous, there will always be a single unambiguous closest resolution.
0 commit comments