@@ -124,7 +124,7 @@ impl Types {
124124 usize:: try_from ( limits. max_rec_groups ) . expect ( "max_rec_groups is too large" ) ;
125125 let max_types = usize:: try_from ( limits. max_types ) . expect ( "max_types is too large" ) ;
126126
127- // 1. Trim excess types and remove them from rec group member sets, i.e .
127+ // 1. Trim excess types.
128128 while self . type_defs . len ( ) > max_types {
129129 if let Some ( ( tid, _) ) = self . type_defs . pop_last ( ) {
130130 for members in self . rec_groups . values_mut ( ) {
@@ -133,42 +133,35 @@ impl Types {
133133 }
134134 }
135135
136- // 2. Drop dangling member set entries that reference types that do not exist.
136+ // 2. Drop dangling references and deduplicate across groups.
137+ let mut seen = BTreeSet :: new ( ) ;
137138 for members in self . rec_groups . values_mut ( ) {
138- members. retain ( |tid| self . type_defs . contains_key ( tid) ) ;
139+ members. retain ( |tid| self . type_defs . contains_key ( tid) && seen . insert ( * tid ) ) ;
139140 }
140141
141- // 3. Trim excess rec groups and collect their members as orphans.
142- let mut rec_group_orphans = BTreeSet :: new ( ) ;
142+ // 3. Trim excess rec groups.
143143 while self . rec_groups . len ( ) > max_rec_groups {
144- if let Some ( ( _gid, members) ) = self . rec_groups . pop_last ( ) {
145- rec_group_orphans. extend ( members) ;
146- }
147- }
148-
149- // 4. Find corruption orphans that are not in any group.
150- let mut all_members = BTreeSet :: new ( ) ;
151- for members in self . rec_groups . values ( ) {
152- all_members. extend ( members. iter ( ) . copied ( ) ) ;
144+ self . rec_groups . pop_last ( ) ;
153145 }
154146
155- // Exclude rec_group_orphans that are already accounted for in the step 3.
156- let corruption_orphans: BTreeSet < TypeId > = self
147+ // 4. Find all orphans (from trimmed groups or never in any group).
148+ let housed: BTreeSet < TypeId > = self
149+ . rec_groups
150+ . values ( )
151+ . flat_map ( |m| m. iter ( ) . copied ( ) )
152+ . collect ( ) ;
153+ let orphans: Vec < TypeId > = self
157154 . type_defs
158155 . keys ( )
159- . filter ( |tid| !all_members . contains ( tid ) && !rec_group_orphans . contains ( tid) )
156+ . filter ( |tid| !housed . contains ( tid) )
160157 . copied ( )
161158 . collect ( ) ;
162159
163- // 5. Adopt into the first rec group: corruption orphans first,
164- // then rec group orphans. Both are already within max_types from step 1.
165- if let Some ( gid) = self . rec_groups . keys ( ) . next ( ) . copied ( ) {
166- let members = self . rec_groups . get_mut ( & gid) . unwrap ( ) ;
167- members. extend ( corruption_orphans) ;
168- members. extend ( rec_group_orphans) ;
160+ // 5. Adopt orphans or drop them.
161+ if let Some ( first_members) = self . rec_groups . values_mut ( ) . next ( ) {
162+ first_members. extend ( orphans) ;
169163 } else {
170- // No rec groups at all — drop everything.
171- for tid in corruption_orphans. iter ( ) . chain ( rec_group_orphans. iter ( ) ) {
164+ for tid in & orphans {
172165 self . type_defs . remove ( tid) ;
173166 }
174167 }
@@ -184,24 +177,32 @@ impl Types {
184177 if self . rec_groups . len ( )
185178 > usize:: try_from ( limits. max_rec_groups ) . expect ( "max_rec_groups is too large" )
186179 {
180+ log:: debug!( "[-] Failed: rec_groups.len() > max_rec_groups" ) ;
187181 return false ;
188182 }
189183 if self . type_defs . len ( ) > usize:: try_from ( limits. max_types ) . expect ( "max_types is too large" )
190184 {
185+ log:: debug!( "[-] Failed: type_defs.len() > max_types" ) ;
191186 return false ;
192187 }
193188 let mut all = BTreeSet :: new ( ) ;
194189 for members in self . rec_groups . values ( ) {
195190 for tid in members {
196191 if !self . type_defs . contains_key ( tid) {
192+ log:: debug!( "[-] Failed: type_defs.contains_key(tid) is false" ) ;
197193 return false ;
198194 }
199195 if !all. insert ( * tid) {
196+ log:: debug!( "[-] Failed: all.insert(tid) is false" ) ;
200197 return false ;
201198 }
202199 }
203200 }
204- self . type_defs . keys ( ) . all ( |tid| all. contains ( tid) )
201+ if !self . type_defs . keys ( ) . all ( |tid| all. contains ( tid) ) {
202+ log:: debug!( "[-] Failed: type_defs.keys().all(|tid| all.contains(tid)) is false" ) ;
203+ return false ;
204+ }
205+ true
205206 }
206207}
207208
0 commit comments