@@ -8,10 +8,10 @@ Rust-specific context.
88
99## What is a control-flow graph?
1010
11- A control-flow graph is a common term from compilers. If you've ever
11+ A control-flow graph (CFG) is a common term from compilers. If you've ever
1212used a flow-chart, then the concept of a control-flow graph will be
1313pretty familiar to you. It's a representation of your program that
14- exposes the underlying control flow in a very clear way .
14+ clearly exposes the underlying control flow.
1515
1616A control-flow graph is structured as a set of ** basic blocks**
1717connected by edges. The key idea of a basic block is that it is a set
@@ -44,12 +44,17 @@ if some_variable {
4444d = 1;
4545```
4646
47- This would compile into four basic blocks:
47+ This would compile into four basic blocks in MIR. In textual form, it looks like
48+ this:
4849
4950``` mir
5051BB0 : {
5152 a = 1;
52- if some_variable { goto BB1 } else { goto BB2 }
53+ if some_variable {
54+ goto BB1;
55+ } else {
56+ goto BB2;
57+ }
5358}
5459
5560BB1 : {
@@ -64,10 +69,33 @@ BB2: {
6469
6570BB3 : {
6671 d = 1;
67- ...;
72+ ...
6873}
6974```
7075
76+ In graphical form, it looks like this:
77+
78+ ```
79+ BB0
80+ +--------------------+
81+ | a = 1; |
82+ +--------------------+
83+ / \
84+ if some_variable else
85+ / \
86+ BB1 / \ BB2
87+ +-----------+ +-----------+
88+ | b = 1; | | c = 1; |
89+ +-----------+ +-----------+
90+ \ /
91+ \ /
92+ \ BB3 /
93+ +----------+
94+ | d = 1; |
95+ | ... |
96+ +----------+
97+ ```
98+
7199When using a control-flow graph, a loop simply appears as a cycle in
72100the graph, and the ` break ` keyword translates into a path out of that
73101cycle.
@@ -82,10 +110,10 @@ and Michael I. Schwartzbach is an incredible resource!
82110_ Dataflow analysis_ is a type of static analysis that is common in many
83111compilers. It describes a general technique, rather than a particular analysis.
84112
85- The basic idea is that we can walk over a [ CFG] ( #cfg ) and keep track of what
86- some value could be. At the end of the walk, we might have shown that some
87- claim is true or not necessarily true (e.g. "this variable must be
88- initialized"). ` rustc ` tends to do dataflow analyses over the MIR, since that
113+ The basic idea is that we can walk over a [ control-flow graph ( CFG) ] ( #cfg ) and
114+ keep track of what some value could be. At the end of the walk, we might have
115+ shown that some claim is true or not necessarily true (e.g. "this variable must
116+ be initialized"). ` rustc ` tends to do dataflow analyses over the MIR, since MIR
89117is already a CFG.
90118
91119For example, suppose we want to check that ` x ` is initialized before it is used
@@ -207,17 +235,17 @@ such that the function is well-typed: `∃ T: (T: Debug) and well_typed(foo)`.
207235
208236<a name =" variance " ></a >
209237
210- ## What is a DeBruijn Index?
238+ ## What is a de Bruijn Index?
211239
212- DeBruijn indices are a way of representing which variables are bound in
213- which binders using only integers . They were [ originally invented] [ wikideb ] for
214- use in lambda calculus evaluation. In ` rustc ` , we use a similar idea for the
215- [ representation of generic types] [ sub ] .
240+ [ De Bruijn indices] [ wikideb ] are a way of representing using only integers which
241+ variables are bound in which binders . They were originally invented for use in
242+ lambda calculus evaluation (see [ this Wikipedia article ] [ wikideb ] for more). In
243+ ` rustc ` , we use a similar idea for the [ representation of generic types] [ sub ] .
216244
217245[ wikideb ] : https://en.wikipedia.org/wiki/De_Bruijn_index
218246[ sub ] : ../generics.md
219247
220- Here is a basic example of how DeBruijn indices might be used for closures (we
248+ Here is a basic example of how de Bruijn indices might be used for closures (we
221249don't actually do this in ` rustc ` though):
222250
223251``` rust,ignore
@@ -231,7 +259,7 @@ don't actually do this in `rustc` though):
231259}
232260```
233261
234- ## What is co- and contra-variance?
262+ ## What are co- and contra-variance?
235263
236264Check out the subtyping chapter from the
237265[ Rust Nomicon] ( https://doc.rust-lang.org/nomicon/subtyping.html ) .
@@ -246,17 +274,16 @@ the type checker handles variance.
246274Let's describe the concepts of free vs bound in terms of program
247275variables, since that's the thing we're most familiar with.
248276
249- - Consider this expression, which creates a closure: `|a,
250- b| a + b` . Here, the ` a` and ` b` in ` a + b` refer to the arguments
251- that the closure will be given when it is called. We say that the
252- ` a ` and ` b ` there are ** bound** to the closure, and that the closure
253- signature ` |a, b| ` is a ** binder** for the names ` a ` and ` b `
254- (because any references to ` a ` or ` b ` within refer to the variables
255- that it introduces).
256- - Consider this expression: ` a + b ` . In this expression, ` a ` and ` b `
257- refer to local variables that are defined * outside* of the
258- expression. We say that those variables ** appear free** in the
259- expression (i.e., they are ** free** , not ** bound** (tied up)).
277+ - Consider this expression, which creates a closure: ` |a, b| a + b ` .
278+ Here, the ` a ` and ` b ` in ` a + b ` refer to the arguments that the closure will
279+ be given when it is called. We say that the ` a ` and ` b ` there are ** bound** to
280+ the closure, and that the closure signature ` |a, b| ` is a ** binder** for the
281+ names ` a ` and ` b ` (because any references to ` a ` or ` b ` within refer to the
282+ variables that it introduces).
283+ - Consider this expression: ` a + b ` . In this expression, ` a ` and ` b ` refer to
284+ local variables that are defined * outside* of the expression. We say that
285+ those variables ** appear free** in the expression (i.e., they are ** free** ,
286+ not ** bound** (tied up)).
260287
261288So there you have it: a variable "appears free" in some
262289expression/statement/whatever if it refers to something defined
0 commit comments