Skip to content

Commit b6acfd7

Browse files
committed
WIP: Editorial revisions
1 parent 04a4cfd commit b6acfd7

File tree

2 files changed

+111
-92
lines changed

2 files changed

+111
-92
lines changed

src/glossary.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Glossary
22

3+
r[glossary.ast]
34
### Abstract syntax tree
45

56
An ‘abstract syntax tree’, or ‘AST’, is an intermediate representation of

src/names/name-resolution.md

Lines changed: 110 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -2,127 +2,141 @@ r[names.resolution]
22
# Name resolution
33

44
r[names.resolution.intro]
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 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].
66

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.
88

99
> [!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*.
1311
1412
r[names.resolution.general]
1513
## General
1614

1715
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.
1917

2018
r[names.resolution.general.scopes]
2119
### Scopes
2220

2321
r[names.resolution.general.scopes.intro]
2422
> [!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.
2624
2725
r[names.resolution.expansion]
2826
## Expansion-time name resolution
2927

3028
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.
3230

3331
r[names.resolution.expansion.unresolved-invocations]
34-
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.
3533

3634
```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.
4036
```
4137

4238
r[names.resolution.expansion.expansion-order-stability]
43-
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.
4440

4541
r[names.resolution.expansion.speculation]
4642
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.
4743

4844
> [!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.
5146
>
5247
> ```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+
> }
5555
> }
56+
> f!();
5657
>
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+
> };
6970
> ```
7071
7172
r[names.resolution.expansion.imports]
7273
### Imports
7374
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.
7576
7677
```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: () = ();
8284
}
83-
84-
impl MyEnum {
85-
pub const CONST: () = ();
86-
}
87-
88-
pub type TypeAlias = MyEnum;
8985
}
9086
9187
// 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.
9692
9793
// 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.
10096
```
10197
10298
```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: () = ();
108105
# }
109-
#
110-
# impl MyEnum {
111-
# pub const CONST: () = ();
112-
# }
113-
#
114-
# pub type TypeAlias = MyEnum;
115106
# }
116107
// 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`.
119110
```
120111

121112
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+
pub mod foo {
123+
pub mod baz {
124+
pub struct Name;
125+
}
126+
}
123127

124-
* [`use` glob shadowing]
125-
* [Macro textual scope shadowing]
128+
pub mod bar {
129+
pub mod baz {
130+
pub struct Name;
131+
}
132+
}
133+
134+
use foo::baz::Name;
135+
fn f() {
136+
use bar::baz::Name;
137+
Name;
138+
}
139+
```
126140

127141
r[names.resolution.expansion.imports.ambiguity]
128142
#### Ambiguities
@@ -159,7 +173,7 @@ fn ambiguous_shadow() {
159173
}
160174
```
161175

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:
163177

164178
```rust
165179
mod foo {
@@ -181,7 +195,7 @@ fn main() {
181195
}
182196
```
183197

184-
r[names.resolution.expansion.imports.ambiguity.globvsouter]
198+
r[names.resolution.expansion.imports.ambiguity.glob-vs-outer]
185199
Names may not be resolved through glob imports when there is another candidate available in an [outer scope].
186200

187201
```rust,compile_fail,E0659
@@ -223,7 +237,7 @@ pub fn qux() {
223237
```
224238

225239
> [!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.
227241
>
228242
> ```rust
229243
> mod bar {
@@ -243,29 +257,7 @@ pub fn qux() {
243257
> }
244258
> ```
245259
246-
r[names.resolution.expansion.imports.ambiguity.moreexpandedvsouter]
247-
Name bindings from macro expansions to may not shadow name bindings from outside of those expansions.
248-
249-
```rust,compile_fail,E0659
250-
macro_rules! name {
251-
() => {}
252-
}
253-
254-
macro_rules! define_name {
255-
() => {
256-
macro_rules! name {
257-
() => {}
258-
}
259-
}
260-
}
261-
262-
fn foo() {
263-
define_name!();
264-
name!(); // ERROR: `name` is ambiguous
265-
}
266-
```
267-
268-
r[names.resolution.expansion.imports.ambiguity.pathvstextualmacro]
260+
r[names.resolution.expansion.imports.ambiguity.path-vs-textual-macro]
269261
Path-based scope bindings for macros may not shadow textual scope bindings to macros. For bindings from [`use` declarations], this applies regardless of their [sub-namespace].
270262
271263
```rust,compile_fail,E0659
@@ -347,16 +339,42 @@ Derive helper scopes are not visited when resolving derive macros in the parent
347339
r[names.resolution.expansion.macros.reserved-names]
348340
The names `cfg` and `cfg_attr` are reserved in the macro attribute [sub-namespace].
349341

342+
r[names.resolution.expansion.macros.ambiguity]
343+
#### Ambiguities
344+
345+
r[names.resolution.expansion.macros.ambiguity.more-expanded-vs-outer]
346+
Name bindings from macro expansions may not shadow name bindings from outside of those expansions.
347+
348+
```rust,compile_fail,E0659
349+
macro_rules! name {
350+
() => {}
351+
}
352+
353+
macro_rules! define_name {
354+
() => {
355+
macro_rules! name {
356+
() => {}
357+
}
358+
}
359+
}
360+
361+
fn foo() {
362+
define_name!();
363+
name!(); // ERROR: `name` is ambiguous
364+
}
365+
```
366+
350367
r[names.resolution.primary]
351368
## Primary name resolution
352369
> [!NOTE]
353370
> This is a placeholder for future expansion about primary name resolution.
354371
355-
r[names.resolution.type-dependent]
356-
# Type-dependent resolution
372+
r[names.resolution.type-relative]
373+
# Type-relative resolution
357374
> [!NOTE]
358375
> This is a placeholder for future expansion about type-dependent resolution.
359376
377+
[AST]: glossary.ast
360378
[Builtin attributes]: ./preludes.md#r-names.preludes.lang
361379
[Derive helpers]: ../procedural-macros.md#r-macro.proc.derive.attributes
362380
[Macros]: ../macros.md
@@ -377,5 +395,5 @@ r[names.resolution.type-dependent]
377395
[permitted]: name-resolution.md#r-names.resolution.expansion.imports.shadowing
378396
[scope]: ../names/scopes.md
379397
[sub-namespace]: ../names/namespaces.md#r-names.namespaces.sub-namespaces
398+
[type-relative paths]: names.resolution.type-relative
380399
[visibility]: ../visibility-and-privacy.md
381-

0 commit comments

Comments
 (0)