Skip to content

Conformance decodes any generated type's shape, by a run-time Type - #32

Merged
Kinflou merged 1 commit into
mainfrom
feat/conformance-type-seed
Oct 25, 2026
Merged

Kinflou merged 1 commit into
mainfrom
feat/conformance-type-seed

Conversation

@Kinflou

@Kinflou Kinflou commented Oct 25, 2026

Copy link
Copy Markdown
Member

Stacked on #31. Stage 1 of runtime#29.

  • TypeSeed decodes bytes by a Type known only at run time, making exactly the calls a serde derive makes, through each format's decode_seed (Json and MsgPack decode through a seed, as Packed does #31). Before this, the reference could decode only three hand-written reader types, and every other shape was NotImplemented.
  • Type now covers every shape generated Rust has: all scalars up to 128 bits, unit, option, T[], and T[N] (including N > 32, which needs serde_big_array), plus struct and enum. Value gains u128, i128 and unit. Unions are left out, since the Rust generator refuses them.
  • tests/seed_vs_derive.rs holds TypeSeed to real derives: the old readers plus the generation goldens' shapes (Scalars, Bag, Sample, error structs, unit). Each format is tried on valid bytes, every single-byte mutation, every truncation, a trailing byte, and hand-written JSON and MessagePack maps. Three deliberately planted seed bugs each fail it.
  • Names go through an interner instead of Box::leak on every encode, so a long-running comline-reference process doesn't grow.
  • answer() asks the reference one question, for the binary in the next step.
  • Vectors: 14 new cases per format for the new shapes. No existing case changed (diffed by id).

One finding, left as it is here: msgpack@1 accepts trailing bytes after a value, because rmp_serde never checks the end of input. packed@1 and json@1 refuse them. That's a strictness gap in the reference itself.

The reference could decode only three hand-written reader types, so any
other shape was NotImplemented. TypeSeed decodes by a Type known at run
time, making exactly the calls a serde derive makes, through each
format's decode_seed; a stage 1 fuzzer can now ask about any schema.

- Type covers every shape generated Rust has: all scalars to 128 bits,
  unit, option, T[], T[N] (N > 32 included), struct and enum. Value gains
  u128, i128 and unit.
- tests/seed_vs_derive.rs holds TypeSeed to real derives (the old
  readers, plus the generation goldens' shapes) on valid bytes, every
  single-byte mutation, truncation, a trailing byte, and hand-written
  JSON and MessagePack maps; three deliberate seed bugs each fail it.
- Names go through an interner instead of leaking per call.
- answer() asks one question, for the comline-reference binary.
- 14 new cases per format, for the new shapes; no existing case changed.
@Kinflou
Kinflou changed the base branch from feat/decode-seed-all-formats to main October 25, 2026 06:33
@Kinflou
Kinflou merged commit 87de0ab into main Oct 25, 2026
6 checks passed
@Kinflou
Kinflou deleted the feat/conformance-type-seed branch October 25, 2026 06:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant