rust/src/librustc_mir/transform/nll/constraint_generation.rs

65 lines
2.4 KiB
Rust
Raw Normal View History

// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use rustc::mir::Mir;
use rustc::infer::InferCtxt;
use util::liveness::LivenessResult;
use super::ToRegionIndex;
use super::region_infer::RegionInferenceContext;
pub fn generate_constraints<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
regioncx: &mut RegionInferenceContext,
mir: &Mir<'tcx>,
liveness: &LivenessResult)
{
ConstraintGeneration { infcx, regioncx, mir, liveness }.add_constraints();
}
struct ConstraintGeneration<'constrain, 'gcx: 'tcx, 'tcx: 'constrain> {
infcx: &'constrain InferCtxt<'constrain, 'gcx, 'tcx>,
regioncx: &'constrain mut RegionInferenceContext,
mir: &'constrain Mir<'tcx>,
liveness: &'constrain LivenessResult,
}
impl<'constrain, 'gcx, 'tcx> ConstraintGeneration<'constrain, 'gcx, 'tcx> {
fn add_constraints(&mut self) {
// To start, add the liveness constraints.
self.add_liveness_constraints();
}
/// Liveness constraints:
///
/// > If a variable V is live at point P, then all regions R in the type of V
/// > must include the point P.
fn add_liveness_constraints(&mut self) {
let tcx = self.infcx.tcx;
debug!("add_liveness_constraints()");
for bb in self.mir.basic_blocks().indices() {
debug!("add_liveness_constraints: bb={:?}", bb);
self.liveness.simulate_block(self.mir, bb, |location, live_locals| {
debug!("add_liveness_constraints: location={:?} live_locals={:?}",
location, live_locals);
for live_local in live_locals.iter() {
let live_local_ty = self.mir.local_decls[live_local].ty;
tcx.for_each_free_region(&live_local_ty, |live_region| {
let vid = live_region.to_region_index();
self.regioncx.add_live_point(vid, location);
})
}
});
}
}
}