11use std:: collections:: { BTreeMap , BTreeSet } ;
22
3- use either:: Either ;
43use rustc_data_structures:: fx:: { FxHashMap , FxHashSet , FxIndexSet } ;
54use rustc_middle:: mir:: visit:: Visitor ;
65use rustc_middle:: mir:: {
@@ -30,7 +29,7 @@ pub(super) fn compute_loan_liveness<'tcx>(
3029 // edges when visualizing the constraint graph anyways.
3130 let kills = collect_kills ( body, tcx, borrow_set) ;
3231
33- let graph = index_constraints ( & localized_outlives_constraints) ;
32+ let graph = LocalizedConstraintGraph :: new ( & localized_outlives_constraints) ;
3433 let mut visited = FxHashSet :: default ( ) ;
3534 let mut stack = Vec :: new ( ) ;
3635
@@ -109,7 +108,7 @@ pub(super) fn compute_loan_liveness<'tcx>(
109108 let is_loan_killed =
110109 kills. get ( & current_location) . is_some_and ( |kills| kills. contains ( & loan_idx) ) ;
111110
112- for succ in outgoing_edges ( & graph , node) {
111+ for succ in graph . outgoing_edges ( node) {
113112 // If the loan is killed at this point, it is killed _on exit_. But only during
114113 // forward traversal.
115114 if is_loan_killed {
@@ -126,9 +125,12 @@ pub(super) fn compute_loan_liveness<'tcx>(
126125 live_loans
127126}
128127
129- /// The localized constraint graph is currently the per-node map of its physical edges. In the
130- /// future, we'll add logical edges to model constraints that hold at all points in the CFG.
131- type LocalizedConstraintGraph = FxHashMap < LocalizedNode , FxIndexSet < LocalizedNode > > ;
128+ /// The localized constraint graph indexes the physical edges to compute a given node's successors
129+ /// during traversal.
130+ struct LocalizedConstraintGraph {
131+ /// The actual, physical, edges we have recorded for a given node.
132+ edges : FxHashMap < LocalizedNode , FxIndexSet < LocalizedNode > > ,
133+ }
132134
133135/// A node in the graph to be traversed, one of the two vertices of a localized outlives constraint.
134136#[ derive( Copy , Clone , PartialEq , Eq , Hash , Debug ) ]
@@ -137,27 +139,22 @@ struct LocalizedNode {
137139 point : PointIndex ,
138140}
139141
140- /// Traverses the constraints and returns the indexable graph of edges per node.
141- fn index_constraints ( constraints : & LocalizedOutlivesConstraintSet ) -> LocalizedConstraintGraph {
142- let mut edges = LocalizedConstraintGraph :: default ( ) ;
143- for constraint in & constraints. outlives {
144- let source = LocalizedNode { region : constraint. source , point : constraint. from } ;
145- let target = LocalizedNode { region : constraint. target , point : constraint. to } ;
146- edges. entry ( source) . or_default ( ) . insert ( target) ;
147- }
142+ impl LocalizedConstraintGraph {
143+ /// Traverses the constraints and returns the indexed graph of edges per node.
144+ fn new ( constraints : & LocalizedOutlivesConstraintSet ) -> Self {
145+ let mut edges: FxHashMap < _ , FxIndexSet < _ > > = FxHashMap :: default ( ) ;
146+ for constraint in & constraints. outlives {
147+ let source = LocalizedNode { region : constraint. source , point : constraint. from } ;
148+ let target = LocalizedNode { region : constraint. target , point : constraint. to } ;
149+ edges. entry ( source) . or_default ( ) . insert ( target) ;
150+ }
148151
149- edges
150- }
152+ LocalizedConstraintGraph { edges }
153+ }
151154
152- /// Returns the outgoing edges of a given node, not its transitive closure.
153- fn outgoing_edges (
154- graph : & LocalizedConstraintGraph ,
155- node : LocalizedNode ,
156- ) -> impl Iterator < Item = LocalizedNode > + use < ' _ > {
157- if let Some ( edges) = graph. get ( & node) {
158- Either :: Left ( edges. iter ( ) . copied ( ) )
159- } else {
160- Either :: Right ( std:: iter:: empty ( ) )
155+ /// Returns the outgoing edges of a given node, not its transitive closure.
156+ fn outgoing_edges ( & self , node : LocalizedNode ) -> impl Iterator < Item = LocalizedNode > + use < ' _ > {
157+ self . edges . get ( & node) . into_iter ( ) . flat_map ( |targets| targets. iter ( ) . copied ( ) )
161158 }
162159}
163160
0 commit comments