Skip to content

Commit f7c64b6

Browse files
committed
rearrange to promote the borrow checker into its own section
1 parent 581b5fc commit f7c64b6

File tree

5 files changed

+599
-595
lines changed

5 files changed

+599
-595
lines changed

src/SUMMARY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@
5353
- [MIR borrowck](./mir/borrowck.md)
5454
- [MIR-based region checking (NLL)](./mir/regionck.md)
5555
- [MIR optimizations](./mir/optimizations.md)
56+
- [The borrow checker](./borrow_check.md)
57+
- [Region inference](./borrow_check/region_inference.md)
5658
- [Constant evaluation](./const-eval.md)
5759
- [miri const evaluator](./miri.md)
5860
- [Parameter Environments](./param_env.md)

src/borrow_check.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# MIR borrow check
2+
3+
The borrow check is Rust's "secret sauce" – it is tasked with
4+
enforcing a number of properties:
5+
6+
- That all variables are initialized before they are used.
7+
- That you can't move the same value twice.
8+
- That you can't move a value while it is borrowed.
9+
- That you can't access a place while it is mutably borrowed (except through
10+
the reference).
11+
- That you can't mutate a place while it is shared borrowed.
12+
- etc
13+
14+
At the time of this writing, the code is in a state of transition. The
15+
"main" borrow checker still works by processing [the HIR](hir.html),
16+
but that is being phased out in favor of the MIR-based borrow checker.
17+
Doing borrow checking on MIR has two key advantages:
18+
19+
- The MIR is *far* less complex than the HIR; the radical desugaring
20+
helps prevent bugs in the borrow checker. (If you're curious, you
21+
can see
22+
[a list of bugs that the MIR-based borrow checker fixes here][47366].)
23+
- Even more importantly, using the MIR enables ["non-lexical lifetimes"][nll],
24+
which are regions derived from the control-flow graph.
25+
26+
[47366]: https://github.com/rust-lang/rust/issues/47366
27+
[nll]: http://rust-lang.github.io/rfcs/2094-nll.html
28+
29+
### Major phases of the borrow checker
30+
31+
The borrow checker source is found in
32+
[the `rustc_mir::borrow_check` module][b_c]. The main entry point is
33+
the `mir_borrowck` query. At the time of this writing, MIR borrowck can operate
34+
in several modes, but this text will describe only the mode when NLL is enabled
35+
(what you get with `#![feature(nll)]`).
36+
37+
[b_c]: https://github.com/rust-lang/rust/tree/master/src/librustc_mir/borrow_check
38+
39+
The overall flow of the borrow checker is as follows:
40+
41+
- We first create a **local copy** C of the MIR. In the coming steps,
42+
we will modify this copy in place to modify the types and things to
43+
include references to the new regions that we are computing.
44+
- We then invoke `nll::replace_regions_in_mir` to modify this copy C.
45+
Among other things, this function will replace all of the regions in
46+
the MIR with fresh [inference variables](./appendix/glossary.html).
47+
- (More details can be found in [the regionck section](./mir/regionck.html).)
48+
- Next, we perform a number of [dataflow
49+
analyses](./appendix/background.html#dataflow)
50+
that compute what data is moved and when. The results of these analyses
51+
are needed to do both borrow checking and region inference.
52+
- Using the move data, we can then compute the values of all the regions in the
53+
MIR.
54+
- (More details can be found in [the NLL section](./mir/regionck.html).)
55+
- Finally, the borrow checker itself runs, taking as input (a) the
56+
results of move analysis and (b) the regions computed by the region
57+
checker. This allows us to figure out which loans are still in scope
58+
at any particular point.
59+

0 commit comments

Comments
 (0)