Skip to content

Commit bed088a

Browse files
authored
Merge pull request #2846 from rust-lang/tshepang/sembr
sembr some files
2 parents 613e260 + c3680de commit bed088a

7 files changed

Lines changed: 193 additions & 134 deletions

File tree

src/coherence.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ Coherence checking is what detects both of trait impls and inherent impls overla
88
Overlapping trait impls always produce an error,
99
while overlapping inherent impls result in an error only if they have methods with the same name.
1010

11-
Checking for overlaps is split in two parts. First there's the [overlap check(s)](#overlap-checks),
11+
Checking for overlaps is split in two parts.
12+
First there's the [overlap check(s)](#overlap-checks),
1213
which finds overlaps between traits and inherent implementations that the compiler currently knows about.
1314

1415
However, Coherence also results in an error if any other impls **could** exist,
15-
even if they are currently unknown.
16+
even if they are currently unknown.
1617
This affects impls which may get added to upstream crates in a backwards compatible way,
17-
and impls from downstream crates.
18+
and impls from downstream crates.
1819
This is called the Orphan check.
1920

2021
## Overlap checks
@@ -25,7 +26,7 @@ Overlap checks always consider pairs of implementations, comparing them to each
2526

2627
Overlap checking for inherent impl blocks is done through `fn check_item` (in coherence/inherent_impls_overlap.rs),
2728
where you can very clearly see that (at least for small `n`), the check really performs `n^2`
28-
comparisons between impls.
29+
comparisons between impls.
2930

3031
In the case of traits, this check is currently done as part of building the [specialization graph](traits/specialization.md),
3132
to handle specializing impls overlapping with their parent, but this may change in the future.
@@ -37,7 +38,7 @@ Overlapping is sometimes partially allowed:
3738
1. for marker traits
3839
2. under [specialization](traits/specialization.md)
3940

40-
but normally isn't.
41+
It normally isn't.
4142

4243
The overlap check has various modes (see [`OverlapMode`]).
4344
Importantly, there's the explicit negative impl check, and the implicit negative impl check.
@@ -47,9 +48,9 @@ Both try to prove that an overlap is definitely impossible.
4748

4849
### The explicit negative impl check
4950

50-
This check is done in [`impl_intersection_has_negative_obligation`].
51+
This check is done in [`impl_intersection_has_negative_obligation`].
5152

52-
This check tries to find a negative trait implementation.
53+
This check tries to find a negative trait implementation.
5354
For example:
5455

5556
```rust
@@ -64,7 +65,7 @@ In this example, we'd get:
6465
`MyCustomErrorType: From<&str>` and `MyCustomErrorType: From<?E>`, giving `?E = &str`.
6566

6667
And thus, these two implementations would overlap.
67-
However, libstd provides `&str: !Error`, and therefore guarantees that there
68+
However, libstd provides `&str: !Error`, and therefore guarantees that there
6869
will never be a positive implementation of `&str: Error`, and thus there is no overlap.
6970

7071
Note that for this kind of negative impl check, we must have explicit negative implementations provided.
@@ -77,18 +78,17 @@ This is not currently stable.
7778
This check is done in [`impl_intersection_has_impossible_obligation`],
7879
and does not rely on negative trait implementations and is stable.
7980

80-
Let's say there's a
81+
Let's say there's a
8182
```rust
8283
impl From<MyLocalType> for Box<dyn Error> {} // in your own crate
8384
impl<E> From<E> for Box<dyn Error> where E: Error {} // in std
8485
```
8586

86-
This would give: `Box<dyn Error>: From<MyLocalType>`, and `Box<dyn Error>: From<?E>`,
87+
This would give: `Box<dyn Error>: From<MyLocalType>`, and `Box<dyn Error>: From<?E>`,
8788
giving `?E = MyLocalType`.
8889

8990
In your crate there's no `MyLocalType: Error`, downstream crates cannot implement `Error` (a remote trait) for `MyLocalType` (a remote type).
9091
Therefore, these two impls do not overlap.
9192
Importantly, this works even if there isn't a `impl !Error for MyLocalType`.
9293

9394
[`impl_intersection_has_impossible_obligation`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_trait_selection/traits/coherence/fn.impl_intersection_has_impossible_obligation.html
94-

src/hir/lowering.md

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
The AST lowering step converts AST to [HIR](../hir.md).
44
This means many structures are removed if they are irrelevant
5-
for type analysis or similar syntax agnostic analyses. Examples
6-
of such structures include but are not limited to
5+
for type analysis or similar syntax-agnostic analyses.
6+
Examples of such structures include but are not limited to
77

88
* Parenthesis
99
* Removed without replacement, the tree structure makes order explicit
@@ -19,37 +19,42 @@ The implementation of AST lowering is in the [`rustc_ast_lowering`] crate.
1919
The entry point is [`lower_to_hir`], which retrieves the post-expansion AST
2020
and resolver data from [`TyCtxt`] and builds the [`hir::Crate`] for the whole crate.
2121

22-
Lowering is organized around HIR owners. [`lower_to_hir`] first indexes the
22+
Lowering is organized around HIR owners.
23+
[`lower_to_hir`] first indexes the
2324
crate and then [`ItemLowerer::lower_node`] lowers each crate, item, associated
2425
item, and foreign item.
2526

26-
Most of the lowering logic lives on [`LoweringContext`]. The implementation is
27+
Most of the lowering logic lives on [`LoweringContext`].
28+
The implementation is
2729
split across multiple files in the [`rustc_ast_lowering`] crate such as `item.rs`,
2830
`expr.rs`, `pat.rs`, `path.rs`, and others, but they all share the same [`LoweringContext`]
2931
state and ID‑lowering machinery.
3032

31-
Each owner is lowered in its own [`with_hir_id_owner`] scope. This is why the
33+
Each owner is lowered in its own [`with_hir_id_owner`] scope.
34+
This is why the
3235
`HirId` invariants below matter: `lower_node_id` maps AST `NodeId`s into the
3336
current owner, while `next_id` creates fresh HIR-only nodes introduced during
3437
desugaring.
3538

3639
Lowering needs to uphold several invariants in order to not trigger the
3740
sanity checks in [`compiler/rustc_passes/src/hir_id_validator.rs`][hir_id_validator]:
3841

39-
1. A `HirId` must be used if created. So if you use the `lower_node_id`,
40-
you *must* use the resulting `NodeId` or `HirId` (either is fine, since
41-
any `NodeId`s in the `HIR` are checked for existing `HirId`s)
42+
1. A `HirId` must be used if created.
43+
So, if you use the `lower_node_id`,
44+
you *must* use the resulting `NodeId` or `HirId` (either is fine, since
45+
any `NodeId`s in the `HIR` are checked for existing `HirId`s).
4246
2. Lowering a `HirId` must be done in the scope of the *owning* item.
43-
This means you need to use `with_hir_id_owner` if you are creating parts
44-
of an item other than the one being currently lowered. This happens for
45-
example during the lowering of existential `impl Trait`
47+
This means you need to use `with_hir_id_owner` if you are creating parts
48+
of an item other than the one being currently lowered.
49+
This happens, for example, during the lowering of existential `impl Trait`.
4650
3. A `NodeId` that will be placed into a HIR structure must be lowered,
47-
even if its `HirId` is unused. Calling
48-
`let _ = self.lower_node_id(node_id);` is perfectly legitimate.
51+
even if its `HirId` is unused.
52+
Calling `let _ = self.lower_node_id(node_id);` is perfectly legitimate.
4953
4. If you are creating new nodes that didn't exist in the `AST`, you *must*
50-
create new ids for them. This is done by calling the `next_id` method,
51-
which produces both a new `NodeId` as well as automatically lowering it
52-
for you so you also get the `HirId`.
54+
create new ids for them.
55+
This is done by calling the `next_id` method,
56+
which produces both a new `NodeId` as well as automatically lowering it
57+
for you so you also get the `HirId`.
5358

5459
[`rustc_ast_lowering`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/index.html
5560
[`lower_to_hir`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/fn.lower_to_hir.html
@@ -62,12 +67,16 @@ sanity checks in [`compiler/rustc_passes/src/hir_id_validator.rs`][hir_id_valida
6267

6368
If you are creating new `DefId`s, since each `DefId` needs to have a
6469
corresponding `NodeId`, it is advisable to add these `NodeId`s to the
65-
`AST` so you don't have to generate new ones during lowering. This has
70+
`AST` so you don't have to generate new ones during lowering.
71+
This has
6672
the advantage of creating a way to find the `DefId` of something via its
67-
`NodeId`. If lowering needs this `DefId` in multiple places, you can't
73+
`NodeId`.
74+
If lowering needs this `DefId` in multiple places, you can't
6875
generate a new `NodeId` in all those places because you'd also get a new
69-
`DefId` then. With a `NodeId` from the `AST` this is not an issue.
76+
`DefId` then.
77+
With a `NodeId` from the `AST`, this is not an issue.
7078

7179
Having the `NodeId` also allows the `DefCollector` to generate the `DefId`s
72-
instead of lowering having to do it on the fly. Centralizing the `DefId`
80+
instead of lowering having to do it on the fly.
81+
Centralizing the `DefId`
7382
generation in one place makes it easier to refactor and reason about.

src/name-resolution.md

Lines changed: 69 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,68 @@
11
# Name resolution
22

33
In the previous chapters, we saw how the [*Abstract Syntax Tree* (`AST`)][ast]
4-
is built with all macros expanded. We saw how doing that requires doing some
5-
name resolution to resolve imports and macro names. In this chapter, we show
6-
how this is actually done and more.
4+
is built with all macros expanded.
5+
We saw how doing that requires doing some
6+
name resolution to resolve imports and macro names.
7+
In this chapter, we show how this is actually done and more.
78

89
[ast]: ./ast-validation.md
910

1011
In fact, we don't do full name resolution during macro expansion -- we only
11-
resolve imports and macros at that time. This is required to know what to even
12-
expand. Later, after we have the whole AST, we do full name resolution to
13-
resolve all names in the crate. This happens in [`rustc_resolve::late`][late].
12+
resolve imports and macros at that time.
13+
This is required to know what to even expand.
14+
Later, after we have the whole AST, we do full name resolution to
15+
resolve all names in the crate.
16+
This happens in [`rustc_resolve::late`][late].
1417
Unlike during macro expansion, in this late expansion, we only need to try to
15-
resolve a name once, since no new names can be added. If we fail to resolve a
16-
name, then it is a compiler error.
18+
resolve a name once, since no new names can be added.
19+
If we fail to resolve a name, then it is a compiler error.
1720

1821
Name resolution is complex. There are different namespaces (e.g.
1922
macros, values, types, lifetimes), and names may be valid at different (nested)
20-
scopes. Also, different types of names can fail resolution differently, and
21-
failures can happen differently at different scopes. For example, in a module
22-
scope, failure means no unexpanded macros and no unresolved glob imports in
23-
that module. On the other hand, in a function body scope, failure requires that a
24-
name be absent from the block we are in, all outer scopes, and the global
25-
scope.
23+
scopes.
24+
Also, different types of names can fail resolution differently, and
25+
failures can happen differently at different scopes.
26+
For example, in a module scope,
27+
failure means no unexpanded macros and no unresolved glob imports in
28+
that module.
29+
On the other hand, in a function body scope, failure requires that a
30+
name be absent from the block we are in, all outer scopes, and the global scope.
2631

2732
[late]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/index.html
2833

2934
## Basics
3035

3136
In our programs we refer to variables, types, functions, etc, by giving them
32-
a name. These names are not always unique. For example, take this valid Rust
33-
program:
37+
a name.
38+
These names are not always unique.
39+
For example, take this valid Rust program:
3440

3541
```rust
3642
type x = u32;
3743
let x: x = 1;
3844
let y: x = 2;
3945
```
4046

41-
How do we know on line 3 whether `x` is a type (`u32`) or a value (1)? These
42-
conflicts are resolved during name resolution. In this specific case, name
43-
resolution defines that type names and variable names live in separate
47+
How do we know on line 3 whether `x` is a type (`u32`) or a value (1)?
48+
These conflicts are resolved during name resolution.
49+
In this specific case,
50+
name resolution defines that type names and variable names live in separate
4451
namespaces and therefore can co-exist.
4552

46-
The name resolution in Rust is a two-phase process. In the first phase, which runs
47-
during `macro` expansion, we build a tree of modules and resolve imports. Macro
48-
expansion and name resolution communicate with each other via the
53+
The name resolution in Rust is a two-phase process.
54+
In the first phase,
55+
which runs during `macro` expansion,
56+
we build a tree of modules and resolve imports.
57+
Macro expansion and name resolution communicate with each other via the
4958
[`ResolverAstLoweringExt`] trait.
5059

5160
The input to the second phase is the syntax tree, produced by parsing input
52-
files and expanding `macros`. This phase produces links from all the names in the
53-
source to relevant places where the name was introduced. It also generates
54-
helpful error messages, like typo suggestions, traits to import or lints about
61+
files and expanding `macros`.
62+
This phase produces links from all the names in the
63+
source to relevant places where the name was introduced.
64+
It also generates helpful error messages,
65+
like typo suggestions, traits to import or lints about
5566
unused items.
5667

5768
A successful run of the second phase ([`Resolver::resolve_crate`]) creates kind
@@ -68,9 +79,11 @@ The name resolution lives in the [`rustc_resolve`] crate, with the bulk in
6879
## Namespaces
6980

7081
Different kind of symbols live in different namespaces ‒ e.g. types don't
71-
clash with variables. This usually doesn't happen, because variables start with
82+
clash with variables.
83+
This usually doesn't happen, because variables start with
7284
lower-case letter while types with upper-case one, but this is only a
73-
convention. This is legal Rust code that will compile (with warnings):
85+
convention.
86+
This is legal Rust code that will compile (with warnings):
7487

7588
```rust
7689
type x = u32;
@@ -83,19 +96,21 @@ namespaces, the resolver keeps them separated and builds separate structures for
8396
them.
8497

8598
In other words, when the code talks about namespaces, it doesn't mean the module
86-
hierarchy, it's types vs. values vs. macros.
99+
hierarchy, it's types versus values versus macros.
87100

88101
## Scopes and ribs
89102

90-
A name is visible only in certain area in the source code. This forms a
91-
hierarchical structure, but not necessarily a simple one ‒ if one scope is
103+
A name is visible only in certain area in the source code.
104+
This forms a hierarchical structure,
105+
but not necessarily a simple one ‒ if one scope is
92106
part of another, it doesn't mean a name visible in the outer scope is also
93107
visible in the inner scope, or that it refers to the same thing.
94108

95-
To cope with that, the compiler introduces the concept of [`Rib`]s. This is
96-
an abstraction of a scope. Every time the set of visible names potentially changes,
97-
a new [`Rib`] is pushed onto a stack. The places where this can happen include for
98-
example:
109+
To cope with that, the compiler introduces the concept of [`Rib`]s.
110+
This is an abstraction of a scope.
111+
Every time the set of visible names potentially changes,
112+
a new [`Rib`] is pushed onto a stack.
113+
The places where this can happen include for example:
99114

100115
[`Rib`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/struct.Rib.html
101116

@@ -106,11 +121,14 @@ example:
106121
* Macro expansion border ‒ to cope with macro hygiene.
107122

108123
When searching for a name, the stack of [`ribs`] is traversed from the innermost
109-
outwards. This helps to find the closest meaning of the name (the one not
110-
shadowed by anything else). The transition to outer [`Rib`] may also affect
124+
outwards.
125+
This helps to find the closest meaning of the name (the one not
126+
shadowed by anything else).
127+
The transition to outer [`Rib`] may also affect
111128
what names are usable ‒ if there are nested functions (not closures),
112129
the inner one can't access parameters and local bindings of the outer one,
113-
even though they should be visible by ordinary scoping rules. An example:
130+
even though they should be visible by ordinary scoping rules.
131+
An example:
114132

115133
[`ribs`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/struct.LateResolutionVisitor.html#structfield.ribs
116134

@@ -139,11 +157,13 @@ blocks), which isn't a full namespace in its own right.
139157
## Overall strategy
140158

141159
To perform the name resolution of the whole crate, the syntax tree is traversed
142-
top-down and every encountered name is resolved. This works for most kinds of
143-
names, because at the point of use of a name it is already introduced in the [`Rib`]
160+
top-down and every encountered name is resolved.
161+
This works for most kinds of names,
162+
because at the point of use of a name it is already introduced in the [`Rib`]
144163
hierarchy.
145164

146-
There are some exceptions to this. Items are bit tricky, because they can be
165+
There are some exceptions to this.
166+
Items are bit tricky, because they can be
147167
used even before encountered ‒ therefore every block needs to be first scanned
148168
for items to fill in its [`Rib`].
149169

@@ -156,14 +176,15 @@ Therefore, the resolution is performed in multiple stages.
156176
## Speculative crate loading
157177

158178
To give useful errors, rustc suggests importing paths into scope if they're
159-
not found. How does it do this? It looks through every module of every crate
160-
and looks for possible matches. This even includes crates that haven't yet
161-
been loaded!
179+
not found.
180+
How does it do this?
181+
It looks through every module of every crate and looks for possible matches.
182+
This even includes crates that haven't yet been loaded!
162183

163184
Eagerly loading crates to include import suggestions that haven't yet been
164185
loaded is called _speculative crate loading_, because any errors it encounters
165-
shouldn't be reported: [`rustc_resolve`] decided to load them, not the user. The function
166-
that does this is [`lookup_import_candidates`] and lives in
186+
shouldn't be reported: [`rustc_resolve`] decided to load them, not the user.
187+
The function that does this is [`lookup_import_candidates`] and lives in
167188
[`rustc_resolve::diagnostics`].
168189

169190
[`rustc_resolve`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/index.html
@@ -176,8 +197,9 @@ the load is speculative.
176197

177198
## TODO: [#16](https://github.com/rust-lang/rustc-dev-guide/issues/16)
178199

179-
This is a result of the first pass of learning the code. It is definitely
180-
incomplete and not detailed enough. It also might be inaccurate in places.
200+
This is a result of the first pass of learning the code.
201+
It is definitely incomplete and not detailed enough.
202+
It also might be inaccurate in places.
181203
Still, it probably provides useful first guidepost to what happens in there.
182204

183205
* What exactly does it link to and how is that published and consumed by

0 commit comments

Comments
 (0)