Skip to content

Commit e7d8d65

Browse files
committed
add a comment explaining the idea
1 parent 75504ee commit e7d8d65

File tree

1 file changed

+33
-2
lines changed

1 file changed

+33
-2
lines changed

src/librustc_mir/borrow_check/nll/escaping_locals.rs

+33-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,39 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

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`).
1344
1445
use rustc::mir::visit::Visitor;
1546
use rustc::mir::*;

0 commit comments

Comments
 (0)