More long lines

This commit is contained in:
Mark Mansi 2018-03-26 10:41:14 -05:00 committed by Who? Me?!
parent 42ef2ad0b8
commit 2bb61a3f59
5 changed files with 55 additions and 44 deletions

View File

@ -69,11 +69,11 @@ want the `TypeckTables` node for some particular fn, so you might write:
RUST_DEP_GRAPH_FILTER='-> TypeckTables & bar' RUST_DEP_GRAPH_FILTER='-> TypeckTables & bar'
``` ```
This will select only the predecessors of `TypeckTables` nodes for functions with This will select only the predecessors of `TypeckTables` nodes for functions
`bar` in their name. with `bar` in their name.
Perhaps you are finding that when you change `foo` you need to re-type-check `bar`, Perhaps you are finding that when you change `foo` you need to re-type-check
but you don't think you should have to. In that case, you might do: `bar`, but you don't think you should have to. In that case, you might do:
``` ```
RUST_DEP_GRAPH_FILTER='Hir & foo -> TypeckTables & bar' RUST_DEP_GRAPH_FILTER='Hir & foo -> TypeckTables & bar'

View File

@ -6,7 +6,8 @@ enforcing a number of properties:
- That all variables are initialized before they are used. - That all variables are initialized before they are used.
- That you can't move the same value twice. - That you can't move the same value twice.
- That you can't move a value while it is borrowed. - That you can't move a value while it is borrowed.
- That you can't access a place while it is mutably borrowed (except through the reference). - That you can't access a place while it is mutably borrowed (except through
the reference).
- That you can't mutate a place while it is shared borrowed. - That you can't mutate a place while it is shared borrowed.
- etc - etc
@ -44,10 +45,12 @@ The overall flow of the borrow checker is as follows:
Among other things, this function will replace all of the regions in Among other things, this function will replace all of the regions in
the MIR with fresh [inference variables](./appendix-glossary.html). the MIR with fresh [inference variables](./appendix-glossary.html).
- (More details can be found in [the regionck section](./mir-regionck.html).) - (More details can be found in [the regionck section](./mir-regionck.html).)
- Next, we perform a number of [dataflow analyses](./appendix-background.html#dataflow) - Next, we perform a number of [dataflow
analyses](./appendix-background.html#dataflow)
that compute what data is moved and when. The results of these analyses that compute what data is moved and when. The results of these analyses
are needed to do both borrow checking and region inference. are needed to do both borrow checking and region inference.
- Using the move data, we can then compute the values of all the regions in the MIR. - Using the move data, we can then compute the values of all the regions in the
MIR.
- (More details can be found in [the NLL section](./mir-regionck.html).) - (More details can be found in [the NLL section](./mir-regionck.html).)
- Finally, the borrow checker itself runs, taking as input (a) the - Finally, the borrow checker itself runs, taking as input (a) the
results of move analysis and (b) the regions computed by the region results of move analysis and (b) the regions computed by the region

View File

@ -15,16 +15,19 @@ transformations. These suites represent useful intermediate points
where we want to access the MIR for type checking or other purposes: where we want to access the MIR for type checking or other purposes:
- `mir_build(D)` not a query, but this constructs the initial MIR - `mir_build(D)` not a query, but this constructs the initial MIR
- `mir_const(D)` applies some simple transformations to make MIR ready for constant evaluation; - `mir_const(D)` applies some simple transformations to make MIR ready for
- `mir_validated(D)` applies some more transformations, making MIR ready for borrow checking; constant evaluation;
- `optimized_mir(D)` the final state, after all optimizations have been performed. - `mir_validated(D)` applies some more transformations, making MIR ready for
borrow checking;
- `optimized_mir(D)` the final state, after all optimizations have been
performed.
### Seeing how the MIR changes as the compiler executes ### Seeing how the MIR changes as the compiler executes
`-Zdump-mir=F` is a handy compiler options that will let you view the MIR `-Zdump-mir=F` is a handy compiler options that will let you view the MIR for
for each function at each stage of compilation. `-Zdump-mir` takes a **filter** each function at each stage of compilation. `-Zdump-mir` takes a **filter** `F`
`F` which allows you to control which functions and which passes you are interesting which allows you to control which functions and which passes you are
in. For example: interesting in. For example:
```bash ```bash
> rustc -Zdump-mir=foo ... > rustc -Zdump-mir=foo ...
@ -58,8 +61,9 @@ rustc.main.000-000.CleanEndRegions.after.mir
def-path to the function etc being dumped def-path to the function etc being dumped
``` ```
You can also make more selective filters. For example, `main & CleanEndRegions` will select You can also make more selective filters. For example, `main & CleanEndRegions`
for things that reference *both* `main` and the pass `CleanEndRegions`: will select for things that reference *both* `main` and the pass
`CleanEndRegions`:
```bash ```bash
> rustc -Zdump-mir='main & CleanEndRegions' foo.rs > rustc -Zdump-mir='main & CleanEndRegions' foo.rs

View File

@ -418,16 +418,15 @@ variable `'?3`, but the variable `'?3` is not forced to outlive
anything else. Therefore, it simply starts and ends as the empty set anything else. Therefore, it simply starts and ends as the empty set
of elements, and hence the type-check succeeds here. of elements, and hence the type-check succeeds here.
(This should surprise you a little. It surprised me when I first (This should surprise you a little. It surprised me when I first realized it.
realized it. We are saying that if we are a fn that **needs both of We are saying that if we are a fn that **needs both of its arguments to have
its arguments to have the same region**, we can accept being called the same region**, we can accept being called with **arguments with two
with **arguments with two distinct regions**. That seems intuitively distinct regions**. That seems intuitively unsound. But in fact, it's fine, as
unsound. But in fact, it's fine, as I I tried to explain in [this issue][ohdeargoditsallbroken] on the Rust issue
[tried to explain in this issue on the Rust issue tracker long ago][ohdeargoditsallbroken]. tracker long ago. The reason is that even if we get called with arguments of
The reason is that even if we get called with arguments of two two distinct lifetimes, those two lifetimes have some intersection (the call
distinct lifetimes, those two lifetimes have some intersection (the itself), and that intersection can be our value of `'a` that we use as the
call itself), and that intersection can be our value of `'a` that we common lifetime of our arguments. -nmatsakis)
use as the common lifetime of our arguments. -nmatsakis)
[ohdeargoditsallbroken]: https://github.com/rust-lang/rust/issues/32330#issuecomment-202536977 [ohdeargoditsallbroken]: https://github.com/rust-lang/rust/issues/32330#issuecomment-202536977
@ -440,10 +439,10 @@ a return type:
<: <:
for<'b, 'c> fn(&'b u32, &'c u32) -> &'b u32 for<'b, 'c> fn(&'b u32, &'c u32) -> &'b u32
Despite seeming very similar to the previous example, this case is Despite seeming very similar to the previous example, this case is going to get
going to get an error. That's good: the problem is that we've gone an error. That's good: the problem is that we've gone from a fn that promises
from a fn that promises to return one of its two arguments, to a fn to return one of its two arguments, to a fn that is promising to return the
that is promising to return the first one. That is unsound. Let's see how it plays out. first one. That is unsound. Let's see how it plays out.
First, we skolemize the supertype: First, we skolemize the supertype:
@ -463,8 +462,8 @@ And now we create the subtyping relationships:
&'!2 u32 <: &'?3 u32 // arg 2 &'!2 u32 <: &'?3 u32 // arg 2
&'?3 u32 <: &'!1 u32 // return type &'?3 u32 <: &'!1 u32 // return type
And finally the outlives relationships. Here, let V1, V2, and V3 be the variables And finally the outlives relationships. Here, let V1, V2, and V3 be the
we assign to `!1`, `!2`, and `?3` respectively: variables we assign to `!1`, `!2`, and `?3` respectively:
V1: V3 V1: V3
V2: V3 V2: V3
@ -476,8 +475,8 @@ Those variables will have these initial values:
V2 in U2 = {skol(2)} V2 in U2 = {skol(2)}
V3 in U2 = {} V3 in U2 = {}
Now because of the `V3: V1` constraint, we have to add `skol(1)` into `V3` (and indeed Now because of the `V3: V1` constraint, we have to add `skol(1)` into `V3` (and
it is visible from `V3`), so we get: indeed it is visible from `V3`), so we get:
V3 in U2 = {skol(1)} V3 in U2 = {skol(1)}

View File

@ -34,14 +34,17 @@ This section introduces the key concepts of MIR, summarized here:
- **Basic blocks**: units of the control-flow graph, consisting of: - **Basic blocks**: units of the control-flow graph, consisting of:
- **statements:** actions with one successor - **statements:** actions with one successor
- **terminators:** actions with potentially multiple successors; always at the end of a block - **terminators:** actions with potentially multiple successors; always at
- (if you're not familiar with the term *basic block*, see the [background chapter][cfg]) the end of a block
- (if you're not familiar with the term *basic block*, see the [background
chapter][cfg])
- **Locals:** Memory locations alloated on the stack (conceptually, at - **Locals:** Memory locations alloated on the stack (conceptually, at
least), such as function arguments, local variables, and least), such as function arguments, local variables, and
temporaries. These are identified by an index, written with a temporaries. These are identified by an index, written with a
leading underscore, like `_1`. There is also a special "local" leading underscore, like `_1`. There is also a special "local"
(`_0`) allocated to store the return value. (`_0`) allocated to store the return value.
- **Places:** expressions that identify a location in memory, like `_1` or `_1.f`. - **Places:** expressions that identify a location in memory, like `_1` or
`_1.f`.
- **Rvalues:** expressions that produce a value. The "R" stands for - **Rvalues:** expressions that produce a value. The "R" stands for
the fact that these are the "right-hand side" of an assignment. the fact that these are the "right-hand side" of an assignment.
- **Operands:** the arguments to an rvalue, which can either be a - **Operands:** the arguments to an rvalue, which can either be a
@ -100,8 +103,9 @@ you their original name (`// "vec" in scope 1...`). The "scope" blocks
(e.g., `scope 1 { .. }`) describe the lexical structure of the source (e.g., `scope 1 { .. }`) describe the lexical structure of the source
program (which names were in scope when). program (which names were in scope when).
**Basic blocks.** Reading further, we see our first **basic block** (naturally it may look **Basic blocks.** Reading further, we see our first **basic block** (naturally
slightly different when you view it, and I am ignoring some of the comments): it may look slightly different when you view it, and I am ignoring some of the
comments):
``` ```
bb0: { bb0: {
@ -110,8 +114,8 @@ bb0: {
} }
``` ```
A basic block is defined by a series of **statements** and a final **terminator**. A basic block is defined by a series of **statements** and a final
In this case, there is one statement: **terminator**. In this case, there is one statement:
``` ```
StorageLive(_1); StorageLive(_1);
@ -146,8 +150,8 @@ bb2: {
} }
``` ```
Here there are two statements: another `StorageLive`, introducing the `_3` temporary, Here there are two statements: another `StorageLive`, introducing the `_3`
and then an assignment: temporary, and then an assignment:
``` ```
_3 = &mut _1; _3 = &mut _1;
@ -189,7 +193,8 @@ TMP1 = a + b
x = TMP1 + c x = TMP1 + c
``` ```
([Try it and see, though you may want to do release mode to skip over the overflow checks.][play-abc]) ([Try it and see][play-abc], though you may want to do release mode to skip
over the overflow checks.)
[play-abc]: https://play.rust-lang.org/?gist=1751196d63b2a71f8208119e59d8a5b6&version=stable [play-abc]: https://play.rust-lang.org/?gist=1751196d63b2a71f8208119e59d8a5b6&version=stable