Skip to content

Commit 5f5e0b5

Browse files
authored
Reorganize the "Source Code Representation" chapters (#2142)
1 parent ffd9a44 commit 5f5e0b5

File tree

6 files changed

+80
-354
lines changed

6 files changed

+80
-354
lines changed

src/SUMMARY.md

+15-13
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,6 @@
9696
# Source Code Representation
9797

9898
- [Prologue](./part-3-intro.md)
99-
- [Command-line arguments](./cli.md)
100-
- [rustc_driver and rustc_interface](./rustc-driver/intro.md)
101-
- [Example: Type checking](./rustc-driver/interacting-with-the-ast.md)
102-
- [Example: Getting diagnostics](./rustc-driver/getting-diagnostics.md)
10399
- [Syntax and the AST](./syntax-intro.md)
104100
- [Lexing and Parsing](./the-parser.md)
105101
- [Macro expansion](./macro-expansion.md)
@@ -118,10 +114,22 @@
118114
- [MIR construction](./mir/construction.md)
119115
- [MIR visitor and traversal](./mir/visitor.md)
120116
- [MIR queries and passes: getting the MIR](./mir/passes.md)
121-
- [Identifiers in the Compiler](./identifiers.md)
122-
- [Closure expansion](./closure.md)
123117
- [Inline assembly](./asm.md)
124118

119+
# Supporting Infrastructure
120+
121+
- [Command-line arguments](./cli.md)
122+
- [rustc_driver and rustc_interface](./rustc-driver/intro.md)
123+
- [Example: Type checking](./rustc-driver/interacting-with-the-ast.md)
124+
- [Example: Getting diagnostics](./rustc-driver/getting-diagnostics.md)
125+
- [Errors and Lints](diagnostics.md)
126+
- [Diagnostic and subdiagnostic structs](./diagnostics/diagnostic-structs.md)
127+
- [Translation](./diagnostics/translation.md)
128+
- [`LintStore`](./diagnostics/lintstore.md)
129+
- [Error codes](./diagnostics/error-codes.md)
130+
- [Diagnostic items](./diagnostics/diagnostic-items.md)
131+
- [`ErrorGuaranteed`](./diagnostics/error-guaranteed.md)
132+
125133
# Analysis
126134

127135
- [Prologue](./part-4-intro.md)
@@ -190,13 +198,7 @@
190198
- [Closure constraints](./borrow_check/region_inference/closure_constraints.md)
191199
- [Error reporting](./borrow_check/region_inference/error_reporting.md)
192200
- [Two-phase-borrows](./borrow_check/two_phase_borrows.md)
193-
- [Errors and Lints](diagnostics.md)
194-
- [Diagnostic and subdiagnostic structs](./diagnostics/diagnostic-structs.md)
195-
- [Translation](./diagnostics/translation.md)
196-
- [`LintStore`](./diagnostics/lintstore.md)
197-
- [Error codes](./diagnostics/error-codes.md)
198-
- [Diagnostic items](./diagnostics/diagnostic-items.md)
199-
- [`ErrorGuaranteed`](./diagnostics/error-guaranteed.md)
201+
- [Closure capture inference](./closure.md)
200202
- [Async closures/"coroutine-closures"](coroutine-closures.md)
201203

202204
# MIR to Binaries

src/asm.md

+15-221
Original file line numberDiff line numberDiff line change
@@ -54,111 +54,26 @@ string parsing. The remaining options are mostly passed through to LLVM with lit
5454

5555
## AST
5656

57-
`InlineAsm` is represented as an expression in the AST:
58-
59-
```rust
60-
pub struct InlineAsm {
61-
pub template: Vec<InlineAsmTemplatePiece>,
62-
pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
63-
pub operands: Vec<(InlineAsmOperand, Span)>,
64-
pub clobber_abi: Option<(Symbol, Span)>,
65-
pub options: InlineAsmOptions,
66-
pub line_spans: Vec<Span>,
67-
}
68-
69-
pub enum InlineAsmRegOrRegClass {
70-
Reg(Symbol),
71-
RegClass(Symbol),
72-
}
73-
74-
pub enum InlineAsmOperand {
75-
In {
76-
reg: InlineAsmRegOrRegClass,
77-
expr: P<Expr>,
78-
},
79-
Out {
80-
reg: InlineAsmRegOrRegClass,
81-
late: bool,
82-
expr: Option<P<Expr>>,
83-
},
84-
InOut {
85-
reg: InlineAsmRegOrRegClass,
86-
late: bool,
87-
expr: P<Expr>,
88-
},
89-
SplitInOut {
90-
reg: InlineAsmRegOrRegClass,
91-
late: bool,
92-
in_expr: P<Expr>,
93-
out_expr: Option<P<Expr>>,
94-
},
95-
Const {
96-
anon_const: AnonConst,
97-
},
98-
Sym {
99-
expr: P<Expr>,
100-
},
101-
}
102-
```
57+
`InlineAsm` is represented as an expression in the AST with the [`ast::InlineAsm` type][inline_asm_ast].
10358

10459
The `asm!` macro is implemented in `rustc_builtin_macros` and outputs an `InlineAsm` AST node. The
10560
template string is parsed using `fmt_macros`, positional and named operands are resolved to
10661
explicit operand indices. Since target information is not available to macro invocations,
10762
validation of the registers and register classes is deferred to AST lowering.
10863

64+
[inline_asm_ast]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/struct.InlineAsm.html
65+
10966
## HIR
11067

111-
`InlineAsm` is represented as an expression in the HIR:
112-
113-
```rust
114-
pub struct InlineAsm<'hir> {
115-
pub template: &'hir [InlineAsmTemplatePiece],
116-
pub template_strs: &'hir [(Symbol, Option<Symbol>, Span)],
117-
pub operands: &'hir [(InlineAsmOperand<'hir>, Span)],
118-
pub options: InlineAsmOptions,
119-
pub line_spans: &'hir [Span],
120-
}
121-
122-
pub enum InlineAsmRegOrRegClass {
123-
Reg(InlineAsmReg),
124-
RegClass(InlineAsmRegClass),
125-
}
126-
127-
pub enum InlineAsmOperand<'hir> {
128-
In {
129-
reg: InlineAsmRegOrRegClass,
130-
expr: Expr<'hir>,
131-
},
132-
Out {
133-
reg: InlineAsmRegOrRegClass,
134-
late: bool,
135-
expr: Option<Expr<'hir>>,
136-
},
137-
InOut {
138-
reg: InlineAsmRegOrRegClass,
139-
late: bool,
140-
expr: Expr<'hir>,
141-
},
142-
SplitInOut {
143-
reg: InlineAsmRegOrRegClass,
144-
late: bool,
145-
in_expr: Expr<'hir>,
146-
out_expr: Option<Expr<'hir>>,
147-
},
148-
Const {
149-
anon_const: AnonConst,
150-
},
151-
Sym {
152-
expr: Expr<'hir>,
153-
},
154-
}
155-
```
68+
`InlineAsm` is represented as an expression in the HIR with the [`hir::InlineAsm` type][inline_asm_hir].
15669

15770
AST lowering is where `InlineAsmRegOrRegClass` is converted from `Symbol`s to an actual register or
15871
register class. If any modifiers are specified for a template string placeholder, these are
15972
validated against the set allowed for that operand type. Finally, explicit registers for inputs and
16073
outputs are checked for conflicts (same register used for different operands).
16174

75+
[inline_asm_hir]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.InlineAsm.html
76+
16277
## Type checking
16378

16479
Each register class has a whitelist of types that it may be used with. After the types of all
@@ -169,152 +84,29 @@ be used for an operand based on the type that was passed into it.
16984

17085
## THIR
17186

172-
`InlineAsm` is represented as an expression in the THIR:
173-
174-
```rust
175-
crate enum ExprKind<'tcx> {
176-
// [..]
177-
InlineAsm {
178-
template: &'tcx [InlineAsmTemplatePiece],
179-
operands: Box<[InlineAsmOperand<'tcx>]>,
180-
options: InlineAsmOptions,
181-
line_spans: &'tcx [Span],
182-
},
183-
}
184-
crate enum InlineAsmOperand<'tcx> {
185-
In {
186-
reg: InlineAsmRegOrRegClass,
187-
expr: ExprId,
188-
},
189-
Out {
190-
reg: InlineAsmRegOrRegClass,
191-
late: bool,
192-
expr: Option<ExprId>,
193-
},
194-
InOut {
195-
reg: InlineAsmRegOrRegClass,
196-
late: bool,
197-
expr: ExprId,
198-
},
199-
SplitInOut {
200-
reg: InlineAsmRegOrRegClass,
201-
late: bool,
202-
in_expr: ExprId,
203-
out_expr: Option<ExprId>,
204-
},
205-
Const {
206-
value: &'tcx Const<'tcx>,
207-
span: Span,
208-
},
209-
SymFn {
210-
expr: ExprId,
211-
},
212-
SymStatic {
213-
def_id: DefId,
214-
},
215-
}
216-
```
87+
`InlineAsm` is represented as an expression in the THIR with the [`InlineAsmExpr` type][inline_asm_thir].
21788

21889
The only significant change compared to HIR is that `Sym` has been lowered to either a `SymFn`
21990
whose `expr` is a `Literal` ZST of the `fn`, or a `SymStatic` which points to the `DefId` of a
22091
`static`.
22192

93+
[inline_asm_thir]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/thir/struct.InlineAsmExpr.html
94+
22295
## MIR
22396

224-
`InlineAsm` is represented as a `Terminator` in the MIR:
225-
226-
```rust
227-
pub enum TerminatorKind<'tcx> {
228-
// [..]
229-
230-
/// Block ends with an inline assembly block. This is a terminator since
231-
/// inline assembly is allowed to diverge.
232-
InlineAsm {
233-
/// The template for the inline assembly, with placeholders.
234-
template: &'tcx [InlineAsmTemplatePiece],
235-
236-
/// The operands for the inline assembly, as `Operand`s or `Place`s.
237-
operands: Vec<InlineAsmOperand<'tcx>>,
238-
239-
/// Miscellaneous options for the inline assembly.
240-
options: InlineAsmOptions,
241-
242-
/// Source spans for each line of the inline assembly code. These are
243-
/// used to map assembler errors back to the line in the source code.
244-
line_spans: &'tcx [Span],
245-
246-
/// Destination block after the inline assembly returns, unless it is
247-
/// diverging (InlineAsmOptions::NORETURN).
248-
destination: Option<BasicBlock>,
249-
},
250-
}
251-
252-
pub enum InlineAsmOperand<'tcx> {
253-
In {
254-
reg: InlineAsmRegOrRegClass,
255-
value: Operand<'tcx>,
256-
},
257-
Out {
258-
reg: InlineAsmRegOrRegClass,
259-
late: bool,
260-
place: Option<Place<'tcx>>,
261-
},
262-
InOut {
263-
reg: InlineAsmRegOrRegClass,
264-
late: bool,
265-
in_value: Operand<'tcx>,
266-
out_place: Option<Place<'tcx>>,
267-
},
268-
Const {
269-
value: Box<Constant<'tcx>>,
270-
},
271-
SymFn {
272-
value: Box<Constant<'tcx>>,
273-
},
274-
SymStatic {
275-
def_id: DefId,
276-
},
277-
}
278-
```
97+
`InlineAsm` is represented as a `Terminator` in the MIR with the [`TerminatorKind::InlineAsm` variant][inline_asm_mir]
27998

28099
As part of THIR lowering, `InOut` and `SplitInOut` operands are lowered to a split form with a
281100
separate `in_value` and `out_place`.
282101

283102
Semantically, the `InlineAsm` terminator is similar to the `Call` terminator except that it has
284103
multiple output places where a `Call` only has a single return place output.
285104

105+
[inline_asm_mir]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/enum.TerminatorKind.html#variant.InlineAsm
106+
286107
## Codegen
287108

288-
Operands are lowered one more time before being passed to LLVM codegen:
289-
290-
```rust
291-
pub enum InlineAsmOperandRef<'tcx, B: BackendTypes + ?Sized> {
292-
In {
293-
reg: InlineAsmRegOrRegClass,
294-
value: OperandRef<'tcx, B::Value>,
295-
},
296-
Out {
297-
reg: InlineAsmRegOrRegClass,
298-
late: bool,
299-
place: Option<PlaceRef<'tcx, B::Value>>,
300-
},
301-
InOut {
302-
reg: InlineAsmRegOrRegClass,
303-
late: bool,
304-
in_value: OperandRef<'tcx, B::Value>,
305-
out_place: Option<PlaceRef<'tcx, B::Value>>,
306-
},
307-
Const {
308-
string: String,
309-
},
310-
SymFn {
311-
instance: Instance<'tcx>,
312-
},
313-
SymStatic {
314-
def_id: DefId,
315-
},
316-
}
317-
```
109+
Operands are lowered one more time before being passed to LLVM codegen, this is represented by the [`InlineAsmOperandRef` type][inline_asm_codegen] from `rustc_codegen_ssa`.
318110

319111
The operands are lowered to LLVM operands and constraint codes as follow:
320112
- `out` and the output part of `inout` operands are added first, as required by LLVM. Late output
@@ -339,6 +131,8 @@ Note that LLVM is sometimes rather picky about what types it accepts for certain
339131
so we sometimes need to insert conversions to/from a supported type. See the target-specific
340132
ISelLowering.cpp files in LLVM for details of what types are supported for each register class.
341133

134+
[inline_asm_codegen]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/traits/enum.InlineAsmOperandRef.html
135+
342136
## Adding support for new architectures
343137

344138
Adding inline assembly support to an architecture is mostly a matter of defining the registers and

src/closure.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Closure Expansion in rustc
1+
# Closure Capture Inference
22

33
This section describes how rustc handles closures. Closures in Rust are
44
effectively "desugared" into structs that contain the values they use (or

src/hir.md

+29-7
Original file line numberDiff line numberDiff line change
@@ -78,18 +78,40 @@ the compiler a chance to observe that you accessed the data for
7878

7979
## Identifiers in the HIR
8080

81-
There are a bunch of different identifiers to refer to other nodes or definitions
82-
in the HIR. In short:
83-
- A [`DefId`] refers to a *definition* in any crate.
84-
- A [`LocalDefId`] refers to a *definition* in the currently compiled crate.
85-
- A [`HirId`] refers to *any node* in the HIR.
81+
The HIR uses a bunch of different identifiers that coexist and serve different purposes.
8682

87-
For more detailed information, check out the [chapter on identifiers][ids].
83+
- A [`DefId`], as the name suggests, identifies a particular definition, or top-level
84+
item, in a given crate. It is composed of two parts: a [`CrateNum`] which identifies
85+
the crate the definition comes from, and a [`DefIndex`] which identifies the definition
86+
within the crate. Unlike [`HirId`]s, there isn't a [`DefId`] for every expression, which
87+
makes them more stable across compilations.
88+
89+
- A [`LocalDefId`] is basically a [`DefId`] that is known to come from the current crate.
90+
This allows us to drop the [`CrateNum`] part, and use the type system to ensure that
91+
only local definitions are passed to functions that expect a local definition.
92+
93+
- A [`HirId`] uniquely identifies a node in the HIR of the current crate. It is composed
94+
of two parts: an `owner` and a `local_id` that is unique within the `owner`. This
95+
combination makes for more stable values which are helpful for incremental compilation.
96+
Unlike [`DefId`]s, a [`HirId`] can refer to [fine-grained entities][Node] like expressions,
97+
but stays local to the current crate.
98+
99+
- A [`BodyId`] identifies a HIR [`Body`] in the current crate. It is currently only
100+
a wrapper around a [`HirId`]. For more info about HIR bodies, please refer to the
101+
[HIR chapter][hir-bodies].
102+
103+
These identifiers can be converted into one another through the [HIR map][map].
88104

89105
[`DefId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.DefId.html
90106
[`LocalDefId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.LocalDefId.html
91107
[`HirId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir_id/struct.HirId.html
92-
[ids]: ./identifiers.md#in-the-hir
108+
[`BodyId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.BodyId.html
109+
[`CrateNum`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.CrateNum.html
110+
[`DefIndex`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.DefIndex.html
111+
[`Body`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Body.html
112+
[hir-map]: ./hir.md#the-hir-map
113+
[hir-bodies]: ./hir.md#hir-bodies
114+
[map]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html
93115

94116
## The HIR Map
95117

0 commit comments

Comments
 (0)