Skip to content

Commit bfc696a

Browse files
committed
add comments to region_infer, restructure a bit
1 parent cafbd99 commit bfc696a

File tree

1 file changed

+56
-35
lines changed

1 file changed

+56
-35
lines changed

Diff for: src/librustc_mir/transform/nll/region_infer.rs

+56-35
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,16 @@ pub struct Constraint {
6161
point: Location,
6262
}
6363

64-
impl<'tcx> RegionInferenceContext<'tcx> {
64+
impl<'a, 'gcx, 'tcx> RegionInferenceContext<'tcx> {
6565
/// Creates a new region inference context with a total of
6666
/// `num_region_variables` valid inference variables; the first N
6767
/// of those will be constant regions representing the free
6868
/// regions defined in `free_regions`.
69-
pub fn new(free_regions: &FreeRegions<'tcx>,
70-
num_region_variables: usize,
71-
mir: &Mir<'tcx>)
72-
-> Self {
69+
pub fn new(
70+
free_regions: &FreeRegions<'tcx>,
71+
num_region_variables: usize,
72+
mir: &Mir<'tcx>,
73+
) -> Self {
7374
let mut result = Self {
7475
definitions: (0..num_region_variables)
7576
.map(|_| RegionDefinition::default())
@@ -83,33 +84,49 @@ impl<'tcx> RegionInferenceContext<'tcx> {
8384
result
8485
}
8586

86-
fn init_free_regions(&mut self,
87-
free_regions: &FreeRegions<'tcx>,
88-
mir: &Mir<'tcx>)
89-
{
90-
let &FreeRegions { ref indices, ref free_region_map } = free_regions;
91-
92-
// For each free region variable X, it should contain:
93-
//
94-
// (a) the entire CFG
95-
// (b) `end(Y)` for all regions Y such that X: Y (or Y <= X)
96-
//
97-
// we add however the regions for clause (b) somewhat in
98-
// reverse, because of how the data structure in
99-
// `free_regions` is organized.
87+
/// Initializes the region variables for each free region
88+
/// (lifetime parameter). The first N variables always correspond
89+
/// to the free regions appearing in the function signature (both
90+
/// named and anonymous) and where clauses. This function iterates
91+
/// over those regions and initializes them with minimum values.
92+
///
93+
/// For example:
94+
///
95+
/// fn foo<'a, 'b>(..) where 'a: 'b
96+
///
97+
/// would initialize two variables like so:
98+
///
99+
/// R0 = { CFG, R0 } // 'a
100+
/// R1 = { CFG, R0, R1 } // 'b
101+
///
102+
/// Here, R0 represents `'a`, and it contains (a) the entire CFG
103+
/// and (b) any free regions that it outlives, which in this case
104+
/// is just itself. R1 (`'b`) in contrast also outlives `'a` and
105+
/// hence contains R0 and R1.
106+
fn init_free_regions(&mut self, free_regions: &FreeRegions<'tcx>, mir: &Mir<'tcx>) {
107+
let &FreeRegions {
108+
ref indices,
109+
ref free_region_map,
110+
} = free_regions;
111+
112+
// For each free region X:
100113
for (free_region, index) in indices {
101114
let variable = RegionIndex::new(*index);
102115

103116
self.free_regions.push(variable);
104117

118+
// Initialize the name and a few other details.
105119
self.definitions[variable].name = Some(free_region);
106120
self.definitions[variable].constant = true;
107121

108122
// Add all nodes in the CFG to `definition.value`.
109123
for (block, block_data) in mir.basic_blocks().iter_enumerated() {
110124
let definition = &mut self.definitions[variable];
111-
for statement_index in 0 .. block_data.statements.len() + 1 {
112-
let location = Location { block, statement_index };
125+
for statement_index in 0..block_data.statements.len() + 1 {
126+
let location = Location {
127+
block,
128+
statement_index,
129+
};
113130
definition.value.add_point(location);
114131
}
115132
}
@@ -121,13 +138,17 @@ impl<'tcx> RegionInferenceContext<'tcx> {
121138
// Y: X is true). Add `end(X)` into the set for `Y`.
122139
for superregion in free_region_map.regions_that_outlive(&free_region) {
123140
let superregion_index = RegionIndex::new(indices[superregion]);
124-
self.definitions[superregion_index].value.add_free_region(variable);
141+
self.definitions[superregion_index]
142+
.value
143+
.add_free_region(variable);
125144
}
126145

127-
debug!("init_free_regions: region variable for `{:?}` is `{:?}` with value `{:?}`",
128-
free_region,
129-
variable,
130-
self.definitions[variable].value);
146+
debug!(
147+
"init_free_regions: region variable for `{:?}` is `{:?}` with value `{:?}`",
148+
free_region,
149+
variable,
150+
self.definitions[variable].value
151+
);
131152
}
132153
}
133154

@@ -157,15 +178,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
157178
}
158179

159180
/// Perform region inference.
160-
pub(super) fn solve<'a, 'gcx>(
161-
&mut self,
162-
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
163-
mir: &'a Mir<'tcx>,
164-
)
165-
where
166-
'gcx: 'tcx + 'a,
167-
'tcx: 'a,
168-
{
181+
pub(super) fn solve(&mut self, infcx: &InferCtxt<'a, 'gcx, 'tcx>, mir: &Mir<'tcx>) {
182+
self.propagate_constraints(infcx, mir);
183+
}
184+
185+
/// Propagate the region constraints: this will grow the values
186+
/// for each region variable until all the constraints are
187+
/// satisfied. Note that some values may grow **too** large to be
188+
/// feasible, but we check this later.
189+
fn propagate_constraints(&mut self, infcx: &InferCtxt<'a, 'gcx, 'tcx>, mir: &Mir<'tcx>) {
169190
let mut changed = true;
170191
let mut dfs = Dfs::new(infcx, mir);
171192
while changed {

0 commit comments

Comments
 (0)