Skip to content

gc_ops: Add support for struct subtypes#12931

Open
khagankhan wants to merge 2 commits intobytecodealliance:mainfrom
khagankhan:struct-subtyping-support
Open

gc_ops: Add support for struct subtypes#12931
khagankhan wants to merge 2 commits intobytecodealliance:mainfrom
khagankhan:struct-subtyping-support

Conversation

@khagankhan
Copy link
Copy Markdown
Contributor

Add struct subtype support

This adds is_final and supertype fields to SubType, enabling struct subtype hierarchies in the GC fuzzer.

Design change: DFS cycle breaking instead of SCC merging

The (unintentionally :/ ) deleted branch used SCC to find rec groups with cross-group supertype cycles and merge them. When I was analyzing the mutated modules, I saw that almost all groups end up in one huge merged group after a few iterations. The new approach runs a DFS on the rec-group dependency graph and drops only the supertype edges that form back edges, which is the minimum (apparently) needed to break cycles. Groups stay separate, and the cranelift-entity / StronglyConnectedComponents dependencies are removed. No SCC here at all.

Changes by file

mutator.rs

  • add_struct now generates is_final with a 25% chance and picks a random supertype from existing types.
  • Cycle breaking in fixup trims some of these, so we still get a healthy mix of root types.
  • duplicate_group now properly duplicates subtype info:
    • preserves is_final
    • remaps intra-group supertype edges to the cloned type IDs

ops.rs

  • Type encoding updated to emit types and rec groups in topologically sorted order:
    • supertypes before subtypes
    • depended-on groups before dependent groups
  • encode_ty_id now uses actual is_final and supertype instead of hardcoded true / None.

types.rs

  • Added two graph adapters for the existing Dfs / Graph infrastructure:
    • SupertypeGraph
    • RecGroupGraph
  • Added sort_types_by_supertype for topological sorting of types within a group.
  • Added sort_rec_groups_topo for topological sorting of rec groups between groups.
  • Added break_supertype_cycles to drop type-level back edges.
  • Added break_rec_group_cycles to drop cross-group back edges at the rec-group level.
  • Extended fixup with supertype validation:
    • final-supertype checks
    • cycle breaking

tests.rs

Added tests for:

  • type topological sorting
  • rec-group topological sorting
  • supertype cycle breaking
  • rec-group cycle breaking

cc @fitzgen @eeide

@khagankhan khagankhan requested a review from a team as a code owner April 1, 2026 19:21
@khagankhan khagankhan requested review from alexcrichton and removed request for a team April 1, 2026 19:21
@github-actions github-actions bot added the fuzzing Issues related to our fuzzing infrastructure label Apr 1, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 1, 2026

Subscribe to Label Action

cc @fitzgen

Details This issue or pull request has been labeled: "fuzzing"

Thus the following users have been cc'd because of the following labels:

  • fitzgen: fuzzing

To subscribe or unsubscribe from this label, edit the .github/subscribe-to-label.json configuration file.

Learn more.

Copy link
Copy Markdown
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! One small thing before we merge

Comment on lines +37 to +41
let supertype = if types.type_defs.is_empty() {
None
} else {
ctx.rng().choose(types.type_defs.keys()).copied()
};
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

choose already returns an None when there are no options given to it, so we don't need to have the empty check here.

Also, we don't want to always generate supertypes. Better to do it with some probability, maybe a quarter of the time?

Copy link
Copy Markdown
Contributor Author

@khagankhan khagankhan Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh cool! I wanted to do that because we already remove supertypes in cycle-checks so in the end we still end up with structs without supertypes. But I agree probability would be better.

@khagankhan
Copy link
Copy Markdown
Contributor Author

Thanks @fitzgen! Ready for review!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fuzzing Issues related to our fuzzing infrastructure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants