1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
14 pub(super) struct TaintSet<'tcx> {
15 directions: TaintDirections,
16 regions: FxHashSet<ty::Region<'tcx>>,
19 impl<'tcx> TaintSet<'tcx> {
20 pub(super) fn new(directions: TaintDirections, initial_region: ty::Region<'tcx>) -> Self {
21 let mut regions = FxHashSet::default();
22 regions.insert(initial_region);
24 directions: directions,
29 pub(super) fn fixed_point(
31 tcx: TyCtxt<'_, '_, 'tcx>,
32 undo_log: &[UndoLog<'tcx>],
33 verifys: &[Verify<'tcx>],
36 while prev_len < self.len() {
38 "tainted: prev_len = {:?} new_len = {:?}",
43 prev_len = self.len();
45 for undo_entry in undo_log {
47 &AddConstraint(Constraint::VarSubVar(a, b)) => {
48 self.add_edge(tcx.mk_region(ReVar(a)), tcx.mk_region(ReVar(b)));
50 &AddConstraint(Constraint::RegSubVar(a, b)) => {
51 self.add_edge(a, tcx.mk_region(ReVar(b)));
53 &AddConstraint(Constraint::VarSubReg(a, b)) => {
54 self.add_edge(tcx.mk_region(ReVar(a)), b);
56 &AddConstraint(Constraint::RegSubReg(a, b)) => {
60 self.add_edge(a, tcx.mk_region(ReVar(b)));
64 verifys[i].origin.span(),
65 "we never add verifications while doing higher-ranked things",
68 &Purged | &AddCombination(..) | &AddVar(..) | &OpenSnapshot
69 | &CommitedSnapshot => {}
75 pub(super) fn into_set(self) -> FxHashSet<ty::Region<'tcx>> {
79 fn len(&self) -> usize {
83 fn add_edge(&mut self, source: ty::Region<'tcx>, target: ty::Region<'tcx>) {
84 if self.directions.incoming {
85 if self.regions.contains(&target) {
86 self.regions.insert(source);
90 if self.directions.outgoing {
91 if self.regions.contains(&source) {
92 self.regions.insert(target);