提交 bfc696ad 编写于 作者: N Niko Matsakis

add comments to `region_infer`, restructure a bit

上级 cafbd99c
......@@ -61,15 +61,16 @@ pub struct Constraint {
point: Location,
}
impl<'tcx> RegionInferenceContext<'tcx> {
impl<'a, 'gcx, 'tcx> RegionInferenceContext<'tcx> {
/// Creates a new region inference context with a total of
/// `num_region_variables` valid inference variables; the first N
/// of those will be constant regions representing the free
/// regions defined in `free_regions`.
pub fn new(free_regions: &FreeRegions<'tcx>,
num_region_variables: usize,
mir: &Mir<'tcx>)
-> Self {
pub fn new(
free_regions: &FreeRegions<'tcx>,
num_region_variables: usize,
mir: &Mir<'tcx>,
) -> Self {
let mut result = Self {
definitions: (0..num_region_variables)
.map(|_| RegionDefinition::default())
......@@ -83,33 +84,49 @@ pub fn new(free_regions: &FreeRegions<'tcx>,
result
}
fn init_free_regions(&mut self,
free_regions: &FreeRegions<'tcx>,
mir: &Mir<'tcx>)
{
let &FreeRegions { ref indices, ref free_region_map } = free_regions;
// For each free region variable X, it should contain:
//
// (a) the entire CFG
// (b) `end(Y)` for all regions Y such that X: Y (or Y <= X)
//
// we add however the regions for clause (b) somewhat in
// reverse, because of how the data structure in
// `free_regions` is organized.
/// Initializes the region variables for each free region
/// (lifetime parameter). The first N variables always correspond
/// to the free regions appearing in the function signature (both
/// named and anonymous) and where clauses. This function iterates
/// over those regions and initializes them with minimum values.
///
/// For example:
///
/// fn foo<'a, 'b>(..) where 'a: 'b
///
/// would initialize two variables like so:
///
/// R0 = { CFG, R0 } // 'a
/// R1 = { CFG, R0, R1 } // 'b
///
/// Here, R0 represents `'a`, and it contains (a) the entire CFG
/// and (b) any free regions that it outlives, which in this case
/// is just itself. R1 (`'b`) in contrast also outlives `'a` and
/// hence contains R0 and R1.
fn init_free_regions(&mut self, free_regions: &FreeRegions<'tcx>, mir: &Mir<'tcx>) {
let &FreeRegions {
ref indices,
ref free_region_map,
} = free_regions;
// For each free region X:
for (free_region, index) in indices {
let variable = RegionIndex::new(*index);
self.free_regions.push(variable);
// Initialize the name and a few other details.
self.definitions[variable].name = Some(free_region);
self.definitions[variable].constant = true;
// Add all nodes in the CFG to `definition.value`.
for (block, block_data) in mir.basic_blocks().iter_enumerated() {
let definition = &mut self.definitions[variable];
for statement_index in 0 .. block_data.statements.len() + 1 {
let location = Location { block, statement_index };
for statement_index in 0..block_data.statements.len() + 1 {
let location = Location {
block,
statement_index,
};
definition.value.add_point(location);
}
}
......@@ -121,13 +138,17 @@ fn init_free_regions(&mut self,
// Y: X is true). Add `end(X)` into the set for `Y`.
for superregion in free_region_map.regions_that_outlive(&free_region) {
let superregion_index = RegionIndex::new(indices[superregion]);
self.definitions[superregion_index].value.add_free_region(variable);
self.definitions[superregion_index]
.value
.add_free_region(variable);
}
debug!("init_free_regions: region variable for `{:?}` is `{:?}` with value `{:?}`",
free_region,
variable,
self.definitions[variable].value);
debug!(
"init_free_regions: region variable for `{:?}` is `{:?}` with value `{:?}`",
free_region,
variable,
self.definitions[variable].value
);
}
}
......@@ -157,15 +178,15 @@ pub(super) fn add_outlives(&mut self, sup: RegionIndex, sub: RegionIndex, point:
}
/// Perform region inference.
pub(super) fn solve<'a, 'gcx>(
&mut self,
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
mir: &'a Mir<'tcx>,
)
where
'gcx: 'tcx + 'a,
'tcx: 'a,
{
pub(super) fn solve(&mut self, infcx: &InferCtxt<'a, 'gcx, 'tcx>, mir: &Mir<'tcx>) {
self.propagate_constraints(infcx, mir);
}
/// Propagate the region constraints: this will grow the values
/// for each region variable until all the constraints are
/// satisfied. Note that some values may grow **too** large to be
/// feasible, but we check this later.
fn propagate_constraints(&mut self, infcx: &InferCtxt<'a, 'gcx, 'tcx>, mir: &Mir<'tcx>) {
let mut changed = true;
let mut dfs = Dfs::new(infcx, mir);
while changed {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册