@@ -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,43 +125,46 @@ 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 we can name all the placeholders in `other`.
170138 pub ( crate ) fn can_name_all_placeholders ( & self , other : Self ) -> bool {
171- other. reachable_placeholders . can_be_named_by ( self . max_nameable_universe . 0 )
139+ // HACK: We first check whether we can name the highest existential universe
140+ // of `other`. This only exists to avoid errors in case that scc already
141+ // depends on a placeholder it cannot name itself.
142+ self . max_nameable_universe ( ) . can_name ( other. max_nameable_universe ( ) )
143+ || other. placeholders_can_be_named_by ( self . max_nameable_universe . 0 )
172144 }
173145
174146 /// If this SCC reaches a placeholder it can't name, return it.
175147 fn unnameable_placeholder ( & self ) -> Option < ( UniverseIndex , RegionVid ) > {
176- self . reachable_placeholders . max_universe ( ) . filter ( | & ( placeholder_universe , _ ) | {
177- !self . max_nameable_universe ( ) . can_name ( placeholder_universe )
178- } )
148+ self . reachable_placeholders
149+ . filter ( |pls| !self . max_nameable_universe ( ) . can_name ( pls . max_universe . 0 ) )
150+ . map ( |pls| pls . max_universe )
179151 }
180152}
181153
182154impl scc:: Annotation for RegionTracker {
183- fn merge_scc ( self , other : Self ) -> Self {
155+ fn update_scc ( & mut self , other : & Self ) {
184156 trace ! ( "{:?} << {:?}" , self . representative, other. representative) ;
185-
186- Self {
187- representative : self . representative . min ( other. representative ) ,
188- max_nameable_universe : self . max_nameable_universe . min ( other. max_nameable_universe ) ,
189- reachable_placeholders : self . reachable_placeholders . merge ( other. reachable_placeholders ) ,
190- }
157+ self . representative = self . representative . min ( other. representative ) ;
158+ self . update_reachable ( other) ;
191159 }
192160
193- fn merge_reached ( self , other : Self ) -> Self {
194- Self {
195- max_nameable_universe : self . max_nameable_universe . min ( other. max_nameable_universe ) ,
196- reachable_placeholders : self . reachable_placeholders . merge ( other. reachable_placeholders ) ,
197- representative : self . representative ,
198- }
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+ } ;
199168 }
200169}
201170
0 commit comments