Skip to content

Commit 7e5d864

Browse files
authored
Address assertion failure in the types fixup(): Dedup A TypeId that appears in multiple rec groups' member sets. (#12900)
1 parent 92bfb73 commit 7e5d864

1 file changed

Lines changed: 27 additions & 26 deletions

File tree

  • crates/fuzzing/src/generators/gc_ops

crates/fuzzing/src/generators/gc_ops/types.rs

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)