fix(rust): don't panic when there are no top-level types#3019
Merged
Conversation
Rust's emitLeadingComments() assumed at least one top-level type exists to name in its example-usage comment, panicking with "Defined value expected, but got undefined" whenever this.topLevels was empty. This is legitimate, reachable state: TypeScript sources without a #TopLevel marker (the common case) fall back to uris: ["#/definitions/"], producing a non-empty type graph with zero named top levels. Now the renderer simply skips the top-level-specific example comment when there is nothing to name. Co-Authored-By: gpt-5.6-sol via pi <noreply@openai.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What was broken
Generating Rust from a TypeScript source that has no
#TopLevel-markedinterface (the common case —
#TopLevelis an internal quicktypeconvention, not something users write) crashed with:
Repro (from the issue, using VS Code's
debugProtocol.d.ts):C# generation from the same input succeeds, confirming this was a
Rust-renderer-specific bug rather than a TypeScript-input or CLI issue (some
issue commenters chased an unrelated
--argument-parsing red herring).Root cause
When the TypeScript-to-JSON-Schema conversion finds no
#TopLevelmarker, itfalls back to
uris: ["#/definitions/"], which does not name any specifictop-level type — the renderer's
this.topLevelsmap ends up legitimatelyempty even though the type graph itself is non-empty.
RustRenderer'semitLeadingComments()unconditionally did:defined()panics whenever its argument isundefined, so an emptytopLevelsmap crashed the whole run. Other renderers (e.g. C#'semitDefaultLeadingComments) don't assume a top level exists for theirdefault leading comment, so only Rust was affected.
Fix
In
packages/quicktype-core/src/language/Rust/RustRenderer.ts,emitLeadingComments()now checks whether a top level exists and simplyskips the top-level-specific example comment when it doesn't, instead of
panicking:
This is a narrowly scoped change — no other renderer or shared code paths
were touched.
Test coverage
This condition (empty
topLevelswith a non-empty type graph) isn'treachable through the JSON/JSON-Schema fixture harness, since fixture
schemas always assign a concrete top-level name. Per repo convention this
makes a
test/unit/test the right coverage, following the same pattern astest/unit/typescript-input.test.tsandtest/unit/kotlin-klaxon-empty-object-map.test.ts.Added
test/unit/rust-empty-top-levels.test.ts, which drivesquicktype()directly with a
JSONSchemaInputbuilt the same wayquicktype-typescript-inputbuilds one when no#TopLevelmarker ispresent (
uris: ["#/definitions/"]), asserting:definitionsproduce notop-level type at all.
(regression guard).
Verification
npm run buildpasses.npx vitest run test/unit/rust-empty-top-levels.test.ts test/unit/typescript-input.test.ts— all pass.dist/index.jswith the real VS Code
debugProtocol.d.ts: previously crashed with the"Defined value expected" panic, now exits 0 and writes valid Rust source.
QUICKTEST=true FIXTURE=rust script/test(full Rust fixture suite, usingthe local
rustc/cargotoolchain) — run locally to confirm noregressions; CI will also validate this on the PR.
Fixes #1629
🤖 Generated with Claude Code