@@ -62,65 +62,31 @@ impl scc::Annotations<RegionVid> for SccAnnotations<'_, '_, RegionTracker> {
6262}
6363
6464#[ derive( Copy , Debug , Clone , PartialEq , Eq ) ]
65- enum PlaceholderReachability {
66- /// This SCC reaches no placeholders.
67- NoPlaceholders ,
68- /// This SCC reaches at least one placeholder.
69- Placeholders {
70- /// The largest-universed placeholder we can reach
71- max_universe : ( UniverseIndex , RegionVid ) ,
72-
73- /// The placeholder with the smallest ID
74- min_placeholder : RegionVid ,
75-
76- /// The placeholder with the largest ID
77- max_placeholder : RegionVid ,
78- } ,
65+ struct PlaceholderReachability {
66+ /// The largest-universed placeholder we can reach
67+ max_universe : ( UniverseIndex , RegionVid ) ,
68+
69+ /// The placeholder with the smallest ID
70+ min_placeholder : RegionVid ,
71+
72+ /// The placeholder with the largest ID
73+ max_placeholder : RegionVid ,
7974}
8075
8176impl PlaceholderReachability {
8277 /// Merge the reachable placeholders of two graph components.
83- fn merge ( self , other : PlaceholderReachability ) -> PlaceholderReachability {
84- use PlaceholderReachability :: * ;
85- match ( self , other) {
86- ( NoPlaceholders , NoPlaceholders ) => NoPlaceholders ,
87- ( NoPlaceholders , p @ Placeholders { .. } )
88- | ( p @ Placeholders { .. } , NoPlaceholders ) => p,
89- (
90- Placeholders {
91- min_placeholder : min_pl,
92- max_placeholder : max_pl,
93- max_universe : max_u,
94- } ,
95- Placeholders { min_placeholder, max_placeholder, max_universe } ,
96- ) => Placeholders {
97- min_placeholder : min_pl. min ( min_placeholder) ,
98- max_placeholder : max_pl. max ( max_placeholder) ,
99- max_universe : max_u. max ( max_universe) ,
100- } ,
101- }
102- }
103-
104- fn max_universe ( & self ) -> Option < ( UniverseIndex , RegionVid ) > {
105- match self {
106- Self :: NoPlaceholders => None ,
107- Self :: Placeholders { max_universe, .. } => Some ( * max_universe) ,
108- }
109- }
110-
111- /// If we have reached placeholders, determine if they can
112- /// be named from this universe.
113- fn can_be_named_by ( & self , from : UniverseIndex ) -> bool {
114- self . max_universe ( )
115- . is_none_or ( |( max_placeholder_universe, _) | from. can_name ( max_placeholder_universe) )
78+ fn merge ( & mut self , other : & Self ) {
79+ self . max_universe = self . max_universe . max ( other. max_universe ) ;
80+ self . min_placeholder = self . min_placeholder . min ( other. min_placeholder ) ;
81+ self . max_placeholder = self . max_placeholder . max ( other. max_placeholder ) ;
11682 }
11783}
11884
11985/// An annotation for region graph SCCs that tracks
12086/// the values of its elements. This annotates a single SCC.
12187#[ derive( Copy , Debug , Clone ) ]
12288pub ( crate ) struct RegionTracker {
123- reachable_placeholders : PlaceholderReachability ,
89+ reachable_placeholders : Option < PlaceholderReachability > ,
12490
12591 /// The largest universe nameable from this SCC.
12692 /// It is the smallest nameable universes of all
@@ -135,13 +101,13 @@ impl RegionTracker {
135101 pub ( crate ) fn new ( rvid : RegionVid , definition : & RegionDefinition < ' _ > ) -> Self {
136102 let reachable_placeholders =
137103 if matches ! ( definition. origin, NllRegionVariableOrigin :: Placeholder ( _) ) {
138- PlaceholderReachability :: Placeholders {
104+ Some ( PlaceholderReachability {
139105 max_universe : ( definition. universe , rvid) ,
140106 min_placeholder : rvid,
141107 max_placeholder : rvid,
142- }
108+ } )
143109 } else {
144- PlaceholderReachability :: NoPlaceholders
110+ None
145111 } ;
146112
147113 Self {
@@ -159,11 +125,13 @@ impl RegionTracker {
159125 }
160126
161127 pub ( crate ) fn max_placeholder_universe_reached ( self ) -> UniverseIndex {
162- if let Some ( ( universe, _) ) = self . reachable_placeholders . max_universe ( ) {
163- universe
164- } else {
165- UniverseIndex :: ROOT
166- }
128+ self . reachable_placeholders . map ( |pls| pls. max_universe . 0 ) . unwrap_or ( UniverseIndex :: ROOT )
129+ }
130+
131+ /// Can all reachable placeholders be named from `from`?
132+ /// True vacuously in case no placeholders were reached.
133+ fn placeholders_can_be_named_by ( & self , from : UniverseIndex ) -> bool {
134+ self . reachable_placeholders . is_none_or ( |pls| from. can_name ( pls. max_universe . 0 ) )
167135 }
168136
169137 /// Determine if the tracked universes of the two SCCs are compatible.
@@ -172,34 +140,31 @@ impl RegionTracker {
172140 // of `other`. This only exists to avoid errors in case that scc already
173141 // depends on a placeholder it cannot name itself.
174142 self . max_nameable_universe ( ) . can_name ( other. max_nameable_universe ( ) )
175- || other. reachable_placeholders . can_be_named_by ( self . max_nameable_universe ( ) )
143+ || other. placeholders_can_be_named_by ( self . max_nameable_universe ( ) )
176144 }
177145
178146 /// If this SCC reaches a placeholder it can't name, return it.
179147 fn unnameable_placeholder ( & self ) -> Option < ( UniverseIndex , RegionVid ) > {
180- self . reachable_placeholders . max_universe ( ) . filter ( | & ( placeholder_universe , _ ) | {
181- !self . max_nameable_universe ( ) . can_name ( placeholder_universe )
182- } )
148+ self . reachable_placeholders
149+ . filter ( |pls| !self . max_nameable_universe ( ) . can_name ( pls . max_universe . 0 ) )
150+ . map ( |pls| pls . max_universe )
183151 }
184152}
185153
186154impl scc:: Annotation for RegionTracker {
187- fn merge_scc ( self , other : Self ) -> Self {
155+ fn update_scc ( & mut self , other : & Self ) {
188156 trace ! ( "{:?} << {:?}" , self . representative, other. representative) ;
189-
190- Self {
191- representative : self . representative . min ( other. representative ) ,
192- max_nameable_universe : self . max_nameable_universe . min ( other. max_nameable_universe ) ,
193- reachable_placeholders : self . reachable_placeholders . merge ( other. reachable_placeholders ) ,
194- }
157+ self . representative = self . representative . min ( other. representative ) ;
158+ self . update_reachable ( other) ;
195159 }
196160
197- fn merge_reached ( self , other : Self ) -> Self {
198- Self {
199- max_nameable_universe : self . max_nameable_universe . min ( other. max_nameable_universe ) ,
200- reachable_placeholders : self . reachable_placeholders . merge ( other. reachable_placeholders ) ,
201- representative : self . representative ,
202- }
161+ fn update_reachable ( & mut self , other : & Self ) {
162+ self . max_nameable_universe = self . max_nameable_universe . min ( other. max_nameable_universe ) ;
163+ match ( self . reachable_placeholders . as_mut ( ) , other. reachable_placeholders . as_ref ( ) ) {
164+ ( None , None ) | ( Some ( _) , None ) => ( ) ,
165+ ( None , Some ( theirs) ) => self . reachable_placeholders = Some ( * theirs) ,
166+ ( Some ( ours) , Some ( theirs) ) => ours. merge ( theirs) ,
167+ } ;
203168 }
204169}
205170
0 commit comments