Skip to content

fix: avoid duplicate nullable type emission#1012

Open
z23cc wants to merge 1 commit into
oxidecomputer:mainfrom
z23cc:fix/nullable-duplicate-type-emission
Open

fix: avoid duplicate nullable type emission#1012
z23cc wants to merge 1 commit into
oxidecomputer:mainfrom
z23cc:fix/nullable-duplicate-type-emission

Conversation

@z23cc
Copy link
Copy Markdown

@z23cc z23cc commented May 13, 2026

Summary

Fixes #1011.

This is a typify bug, not a progenitor bug. Progenitor converts OpenAPI nullable: true object schemas into JSON Schema type: ["object", "null"], which typify already treats as Option<T>. The failure was in typify's registration/output flow for named schemas.

Root cause

There are two related paths that could emit duplicate type definitions with the same Rust name:

  1. For a required nullable definition with a metadata title, typify intended to name the inner type <Name>Inner, but passed that as Name::Suggested. The schema title then won and the inner type reused the outer name, producing a self-recursive newtype such as:

    pub struct AutoMerge(pub Option<AutoMerge>);
    pub struct AutoMerge { ... }
  2. A referenced definition can be preallocated with one TypeId while an earlier inline schema with the same title has already registered the same Rust type name under another TypeId. Emitting every id_to_entry value then produced duplicate items.

Reproducer

The regression test adds a small JSON Schema equivalent to the OpenAPI shape from the GitHub spec:

  • auto-merge has title Auto merge and type ["object", "null"]
  • it references simple-user
  • an earlier inline author_association enum shares the title of a later referenced definition

The test asserts that AutoMerge wraps Option<AutoMergeInner>, does not wrap Option<AutoMerge>, and emits AuthorAssociation only once.

Verification

  • cargo fmt
  • RUSTC_WRAPPER= SCCACHE_DISABLE=1 cargo test -p typify-impl test_required_nullable_object_with_title_uses_distinct_inner_name
  • RUSTC_WRAPPER= SCCACHE_DISABLE=1 cargo test --workspace
  • RUSTC_WRAPPER= SCCACHE_DISABLE=1 cargo clippy --workspace
  • End-to-end check through the downstream Printing Press repro with local [patch.crates-io]:
    • minimal repro cargo check passes
    • generated GitHub output has bad_self_recursive = 0
    • checked duplicate names (AutoMerge, AuthorAssociation, IssueField, IssueType, CodespaceMachine) each emit once
      EOF 2>&1

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

Labels

None yet

Projects

None yet

1 participant