From 8e9e15446f110b01fc06ef0dc40b57f991acc0f3 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sun, 5 Nov 2017 05:23:53 -0500 Subject: [PATCH] region_inference: extract taint into a sub-module --- src/librustc/infer/region_inference/mod.rs | 89 +----------------- src/librustc/infer/region_inference/taint.rs | 96 ++++++++++++++++++++ 2 files changed, 100 insertions(+), 85 deletions(-) create mode 100644 src/librustc/infer/region_inference/taint.rs diff --git a/src/librustc/infer/region_inference/mod.rs b/src/librustc/infer/region_inference/mod.rs index ef888ea4b9f..91989d7b106 100644 --- a/src/librustc/infer/region_inference/mod.rs +++ b/src/librustc/infer/region_inference/mod.rs @@ -29,6 +29,8 @@ use std::fmt; use std::mem; use std::u32; +mod taint; + /// A constraint that influences the inference process. #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)] pub enum Constraint<'tcx> { @@ -268,89 +270,6 @@ impl TaintDirections { } } -struct TaintSet<'tcx> { - directions: TaintDirections, - regions: FxHashSet> -} - -impl<'a, 'gcx, 'tcx> TaintSet<'tcx> { - fn new(directions: TaintDirections, - initial_region: ty::Region<'tcx>) - -> Self { - let mut regions = FxHashSet(); - regions.insert(initial_region); - TaintSet { directions: directions, regions: regions } - } - - fn fixed_point(&mut self, - tcx: TyCtxt<'a, 'gcx, 'tcx>, - undo_log: &[UndoLogEntry<'tcx>], - verifys: &[Verify<'tcx>]) { - let mut prev_len = 0; - while prev_len < self.len() { - debug!("tainted: prev_len = {:?} new_len = {:?}", - prev_len, self.len()); - - prev_len = self.len(); - - for undo_entry in undo_log { - match undo_entry { - &AddConstraint(ConstrainVarSubVar(a, b)) => { - self.add_edge(tcx.mk_region(ReVar(a)), - tcx.mk_region(ReVar(b))); - } - &AddConstraint(ConstrainRegSubVar(a, b)) => { - self.add_edge(a, tcx.mk_region(ReVar(b))); - } - &AddConstraint(ConstrainVarSubReg(a, b)) => { - self.add_edge(tcx.mk_region(ReVar(a)), b); - } - &AddConstraint(ConstrainRegSubReg(a, b)) => { - self.add_edge(a, b); - } - &AddGiven(a, b) => { - self.add_edge(a, tcx.mk_region(ReVar(b))); - } - &AddVerify(i) => { - verifys[i].bound.for_each_region(&mut |b| { - self.add_edge(verifys[i].region, b); - }); - } - &Purged | - &AddCombination(..) | - &AddVar(..) | - &OpenSnapshot | - &CommitedSnapshot => {} - } - } - } - } - - fn into_set(self) -> FxHashSet> { - self.regions - } - - fn len(&self) -> usize { - self.regions.len() - } - - fn add_edge(&mut self, - source: ty::Region<'tcx>, - target: ty::Region<'tcx>) { - if self.directions.incoming { - if self.regions.contains(&target) { - self.regions.insert(source); - } - } - - if self.directions.outgoing { - if self.regions.contains(&source) { - self.regions.insert(target); - } - } - } -} - impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> RegionVarBindings<'a, 'gcx, 'tcx> { RegionVarBindings { @@ -863,11 +782,11 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { // `result_set` acts as a worklist: we explore all outgoing // edges and add any new regions we find to result_set. This // is not a terribly efficient implementation. - let mut taint_set = TaintSet::new(directions, r0); + let mut taint_set = taint::TaintSet::new(directions, r0); taint_set.fixed_point(self.tcx, &self.undo_log.borrow()[mark.length..], &self.verifys.borrow()); - debug!("tainted: result={:?}", taint_set.regions); + debug!("tainted: result={:?}", taint_set); return taint_set.into_set(); } } diff --git a/src/librustc/infer/region_inference/taint.rs b/src/librustc/infer/region_inference/taint.rs new file mode 100644 index 00000000000..acc930bfa3b --- /dev/null +++ b/src/librustc/infer/region_inference/taint.rs @@ -0,0 +1,96 @@ +// Copyright 2012-2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use super::*; + +#[derive(Debug)] +pub(super) struct TaintSet<'tcx> { + directions: TaintDirections, + regions: FxHashSet> +} + +impl<'a, 'gcx, 'tcx> TaintSet<'tcx> { + pub(super) fn new(directions: TaintDirections, + initial_region: ty::Region<'tcx>) + -> Self { + let mut regions = FxHashSet(); + regions.insert(initial_region); + TaintSet { directions: directions, regions: regions } + } + + pub(super) fn fixed_point(&mut self, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + undo_log: &[UndoLogEntry<'tcx>], + verifys: &[Verify<'tcx>]) { + let mut prev_len = 0; + while prev_len < self.len() { + debug!("tainted: prev_len = {:?} new_len = {:?}", + prev_len, self.len()); + + prev_len = self.len(); + + for undo_entry in undo_log { + match undo_entry { + &AddConstraint(Constraint::VarSubVar(a, b)) => { + self.add_edge(tcx.mk_region(ReVar(a)), + tcx.mk_region(ReVar(b))); + } + &AddConstraint(Constraint::RegSubVar(a, b)) => { + self.add_edge(a, tcx.mk_region(ReVar(b))); + } + &AddConstraint(Constraint::VarSubReg(a, b)) => { + self.add_edge(tcx.mk_region(ReVar(a)), b); + } + &AddConstraint(Constraint::RegSubReg(a, b)) => { + self.add_edge(a, b); + } + &AddGiven(a, b) => { + self.add_edge(a, tcx.mk_region(ReVar(b))); + } + &AddVerify(i) => { + verifys[i].bound.for_each_region(&mut |b| { + self.add_edge(verifys[i].region, b); + }); + } + &Purged | + &AddCombination(..) | + &AddVar(..) | + &OpenSnapshot | + &CommitedSnapshot => {} + } + } + } + } + + pub(super) fn into_set(self) -> FxHashSet> { + self.regions + } + + fn len(&self) -> usize { + self.regions.len() + } + + fn add_edge(&mut self, + source: ty::Region<'tcx>, + target: ty::Region<'tcx>) { + if self.directions.incoming { + if self.regions.contains(&target) { + self.regions.insert(source); + } + } + + if self.directions.outgoing { + if self.regions.contains(&source) { + self.regions.insert(target); + } + } + } +} +