|
8 | 8 | // option. This file may not be copied, modified, or distributed
|
9 | 9 | // except according to those terms.
|
10 | 10 |
|
11 |
| -//! A MIR walk gathering a union-crfind of assigned locals, for the purpose of locating the ones |
12 |
| -//! escaping into the output. |
| 11 | +//! Identify those variables whose entire value will eventually be |
| 12 | +//! returned from the fn via the RETURN_PLACE. As an optimization, we |
| 13 | +//! can skip computing liveness results for those variables. The idea |
| 14 | +//! is that the return type of the fn only ever contains free |
| 15 | +//! regions. Therefore, the types of those variables are going to |
| 16 | +//! ultimately be contrained to outlive those free regions -- since |
| 17 | +//! free regions are always live for the entire body, this implies |
| 18 | +//! that the liveness results are not important for those regions. |
| 19 | +//! This is most important in the "fns" that we create to represent static |
| 20 | +//! values, since those are often really quite large, and all regions in them |
| 21 | +//! will ultimately be constrained to be `'static`. Two examples: |
| 22 | +//! |
| 23 | +//! ``` |
| 24 | +//! fn foo() -> &'static [u32] { &[] } |
| 25 | +//! static FOO: &[u32] = &[]; |
| 26 | +//! ``` |
| 27 | +//! |
| 28 | +//! In both these cases, the return value will only have static lifetime. |
| 29 | +//! |
| 30 | +//! NB: The simple logic here relies on the fact that outlives |
| 31 | +//! relations in our analysis don't have locations. Otherwise, we |
| 32 | +//! would have to restrict ourselves to values that are |
| 33 | +//! *unconditionally* returned (which would still cover the "big |
| 34 | +//! static value" case). |
| 35 | +//! |
| 36 | +//! The way that this code works is to use union-find -- we iterate |
| 37 | +//! over the MIR and union together two variables X and Y if all |
| 38 | +//! regions in the value of Y are going to be stored into X -- that |
| 39 | +//! is, if `typeof(X): 'a` requires that `typeof(Y): 'a`. This means |
| 40 | +//! that e.g. we can union together `x` and `y` if we have something |
| 41 | +//! like `x = (y, 22)`, but not something like `x = y.f` (since there |
| 42 | +//! may be regions in the type of `y` that do not appear in the field |
| 43 | +//! `f`). |
13 | 44 |
|
14 | 45 | use rustc::mir::visit::Visitor;
|
15 | 46 | use rustc::mir::*;
|
|
0 commit comments