Satisfy tidy checks
This commit is contained in:
parent
3166fb9d3e
commit
1a5993b9ca
12
src/hir.md
12
src/hir.md
|
|
@ -1,13 +1,13 @@
|
||||||
# The HIR
|
# The HIR
|
||||||
|
|
||||||
The HIR – "High-Level Intermediate Representation" – is the primary IR used in
|
The HIR – "High-Level Intermediate Representation" – is the primary IR used
|
||||||
most of rustc. It is a compiler-friendly representation of the abstract syntax
|
in most of rustc. It is a compiler-friendly representation of the abstract
|
||||||
tree (AST) that is generated after parsing, macro expansion, and name
|
syntax tree (AST) that is generated after parsing, macro expansion, and name
|
||||||
resolution (see [Lowering](./lowering.md) for how the HIR is created).
|
resolution (see [Lowering](./lowering.md) for how the HIR is created).
|
||||||
Many parts of HIR resemble Rust surface syntax quite closely, with
|
Many parts of HIR resemble Rust surface syntax quite closely, with
|
||||||
the exception that some of Rust's expression forms have been desugared away. For
|
the exception that some of Rust's expression forms have been desugared away.
|
||||||
example, `for` loops are converted into a `loop` and do not appear in the HIR.
|
For example, `for` loops are converted into a `loop` and do not appear in
|
||||||
This makes HIR more amenable to analysis than a normal AST.
|
the HIR. This makes HIR more amenable to analysis than a normal AST.
|
||||||
|
|
||||||
This chapter covers the main concepts of the HIR.
|
This chapter covers the main concepts of the HIR.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@ of such structures include but are not limited to
|
||||||
* `if let`
|
* `if let`
|
||||||
* Converted to `match`
|
* Converted to `match`
|
||||||
* Universal `impl Trait`
|
* Universal `impl Trait`
|
||||||
* Converted to generic arguments (but with some flags, to know that the user didn't write them)
|
* Converted to generic arguments
|
||||||
|
(but with some flags, to know that the user didn't write them)
|
||||||
* Existential `impl Trait`
|
* Existential `impl Trait`
|
||||||
* Converted to a virtual `existential type` declaration
|
* Converted to a virtual `existential type` declaration
|
||||||
|
|
||||||
|
|
@ -34,14 +35,14 @@ sanity checks in `src/librustc/hir/map/hir_id_validator.rs`:
|
||||||
which produces both a new `NodeId` as well as automatically lowering it
|
which produces both a new `NodeId` as well as automatically lowering it
|
||||||
for you so you also get the `HirId`.
|
for you so you also get the `HirId`.
|
||||||
|
|
||||||
If you are creating new `DefId`s, since each `DefId` needs to have a corresponding
|
If you are creating new `DefId`s, since each `DefId` needs to have a
|
||||||
`NodeId`, it is adviseable to add these `NodeId`s to the `AST` so you don't have
|
corresponding `NodeId`, it is adviseable to add these `NodeId`s to the
|
||||||
to generate new ones during lowering. This has the advantage of creating a
|
`AST` so you don't have to generate new ones during lowering. This has
|
||||||
way to find the `DefId` of something via its `NodeId`. If lowering needs this
|
the advantage of creating a way to find the `DefId` of something via its
|
||||||
`DefId` in multiple places, you can't generate a new `NodeId` in all those places
|
`NodeId`. If lowering needs this `DefId` in multiple places, you can't
|
||||||
because you'd also get a new `DefId` then. With a `NodeId` from the `AST` this is
|
generate a new `NodeId` in all those places because you'd also get a new
|
||||||
not an issue.
|
`DefId` then. With a `NodeId` from the `AST` this is not an issue.
|
||||||
|
|
||||||
Having the `NodeId` also allows the `DefCollector` to generate the `DefId`s instead
|
Having the `NodeId` also allows the `DefCollector` to generate the `DefId`s
|
||||||
of lowering having to do it on the fly. Centralizing the `DefId` generation in one
|
instead of lowering having to do it on the fly. Centralizing the `DefId`
|
||||||
place makes it easier to refactor and reason about.
|
generation in one place makes it easier to refactor and reason about.
|
||||||
|
|
@ -36,9 +36,9 @@ hierarchy, it's types vs. values vs. macros.
|
||||||
## Scopes and ribs
|
## Scopes and ribs
|
||||||
|
|
||||||
A name is visible only in certain area in the source code. This forms a
|
A name is visible only in certain area in the source code. This forms a
|
||||||
hierarchical structure, but not necessarily a simple one ‒ if one scope is part
|
hierarchical structure, but not necessarily a simple one ‒ if one scope is
|
||||||
of another, it doesn't mean the name visible in the outer one is also visible in
|
part of another, it doesn't mean the name visible in the outer one is also
|
||||||
the inner one, or that it refers to the same thing.
|
visible in the inner one, or that it refers to the same thing.
|
||||||
|
|
||||||
To cope with that, the compiler introduces the concept of Ribs. This is
|
To cope with that, the compiler introduces the concept of Ribs. This is
|
||||||
abstraction of a scope. Every time the set of visible names potentially changes,
|
abstraction of a scope. Every time the set of visible names potentially changes,
|
||||||
|
|
@ -54,9 +54,9 @@ example:
|
||||||
When searching for a name, the stack of ribs is traversed from the innermost
|
When searching for a name, the stack of ribs is traversed from the innermost
|
||||||
outwards. This helps to find the closest meaning of the name (the one not
|
outwards. This helps to find the closest meaning of the name (the one not
|
||||||
shadowed by anything else). The transition to outer rib may also change the
|
shadowed by anything else). The transition to outer rib may also change the
|
||||||
rules what names are usable ‒ if there are nested functions (not closures), the
|
rules what names are usable ‒ if there are nested functions (not closures),
|
||||||
inner one can't access parameters and local bindings of the outer one, even
|
the inner one can't access parameters and local bindings of the outer one,
|
||||||
though they should be visible by ordinary scoping rules. An example:
|
even though they should be visible by ordinary scoping rules. An example:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
fn do_something<T: Default>(val: T) { // <- New rib in both types and values (1)
|
fn do_something<T: Default>(val: T) { // <- New rib in both types and values (1)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue