9
9
// except according to those terms.
10
10
11
11
use rustc:: ty:: RegionVid ;
12
+ use rustc_data_structures:: graph:: scc:: Sccs ;
12
13
use rustc_data_structures:: indexed_vec:: { Idx , IndexVec } ;
13
14
use borrow_check:: nll:: type_check:: Locations ;
14
15
15
16
use std:: fmt;
16
17
use std:: ops:: Deref ;
17
18
19
+ mod full_graph;
20
+
18
21
#[ derive( Clone , Default ) ]
19
22
crate struct ConstraintSet {
20
23
constraints : IndexVec < ConstraintIndex , OutlivesConstraint > ,
21
24
}
22
25
23
26
impl ConstraintSet {
24
- pub fn push ( & mut self , constraint : OutlivesConstraint ) {
27
+ crate fn push ( & mut self , constraint : OutlivesConstraint ) {
25
28
debug ! (
26
29
"ConstraintSet::push({:?}: {:?} @ {:?}" ,
27
30
constraint. sup, constraint. sub, constraint. locations
@@ -32,12 +35,19 @@ impl ConstraintSet {
32
35
}
33
36
self . constraints . push ( constraint) ;
34
37
}
38
+
39
+ crate fn compute_sccs ( & self , num_region_vars : usize ) -> Sccs < RegionVid , ConstraintSccIndex > {
40
+ let graph = & full_graph:: FullConstraintGraph :: new ( self , num_region_vars) ;
41
+ Sccs :: new ( graph)
42
+ }
35
43
}
36
44
37
45
impl Deref for ConstraintSet {
38
46
type Target = IndexVec < ConstraintIndex , OutlivesConstraint > ;
39
47
40
- fn deref ( & self ) -> & Self :: Target { & self . constraints }
48
+ fn deref ( & self ) -> & Self :: Target {
49
+ & self . constraints
50
+ }
41
51
}
42
52
43
53
#[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
@@ -68,45 +78,4 @@ impl fmt::Debug for OutlivesConstraint {
68
78
69
79
newtype_index ! ( ConstraintIndex { DEBUG_FORMAT = "ConstraintIndex({})" } ) ;
70
80
71
- crate struct ConstraintGraph {
72
- first_constraints : IndexVec < RegionVid , Option < ConstraintIndex > > ,
73
- next_constraints : IndexVec < ConstraintIndex , Option < ConstraintIndex > > ,
74
- }
75
-
76
- impl ConstraintGraph {
77
- /// Constraint a graph where each region constraint `R1: R2` is
78
- /// treated as an edge `R2 -> R1`. This is useful for cheaply
79
- /// finding dirty constraints.
80
- crate fn new ( set : & ConstraintSet , num_region_vars : usize ) -> Self {
81
- let mut first_constraints = IndexVec :: from_elem_n ( None , num_region_vars) ;
82
- let mut next_constraints = IndexVec :: from_elem ( None , & set. constraints ) ;
83
-
84
- for ( idx, constraint) in set. constraints . iter_enumerated ( ) . rev ( ) {
85
- let mut head = & mut first_constraints[ constraint. sub ] ;
86
- let mut next = & mut next_constraints[ idx] ;
87
- debug_assert ! ( next. is_none( ) ) ;
88
- * next = * head;
89
- * head = Some ( idx) ;
90
- }
91
-
92
- ConstraintGraph { first_constraints, next_constraints }
93
- }
94
-
95
- /// Invokes `op` with the index of any constraints of the form
96
- /// `region_sup: region_sub`. These are the constraints that must
97
- /// be reprocessed when the value of `R1` changes. If you think of
98
- /// each constraint `R1: R2` as an edge `R2 -> R1`, then this
99
- /// gives the set of successors to R2.
100
- crate fn for_each_dependent (
101
- & self ,
102
- region_sub : RegionVid ,
103
- mut op : impl FnMut ( ConstraintIndex ) ,
104
- ) {
105
- let mut p = self . first_constraints [ region_sub] ;
106
- while let Some ( dep_idx) = p {
107
- op ( dep_idx) ;
108
- p = self . next_constraints [ dep_idx] ;
109
- }
110
- }
111
- }
112
-
81
+ newtype_index ! ( ConstraintSccIndex { DEBUG_FORMAT = "ConstraintSccIndex({})" } ) ;
0 commit comments