Stop boxing types that recurse only through an array or dictionary - #910
Merged
simonjbeaumont merged 2 commits intoJul 3, 2026
Merged
Conversation
Arrays and dictionaries already break the reference cycle, so a type that reaches itself only through one of them does not need CopyOnWriteBox storage. The recursion detector now skips array and dictionary references when collecting cycle-forming edges, which matches the behavior described in Supporting-recursive-types.md. Direct and optional self-references are still boxed. Closes apple#682
simonjbeaumont
left a comment
Collaborator
There was a problem hiding this comment.
This looks good and is a really nice catch. Thanks!
Could we extend the tests to include the mixed case where the schema recurses through a direct ref AND a container.
Node:
type: object
properties:
parent: { $ref: '#/components/schemas/Node' } # direct -> must still box
children:
type: array
items: { $ref: '#/components/schemas/Node' } # container -> must not prevent the box
This presumably should still box.
Contributor
Author
|
Added two mixed-case tests, a |
simonjbeaumont
approved these changes
Jul 3, 2026
simonjbeaumont
left a comment
Collaborator
There was a problem hiding this comment.
Thanks for the contribution!
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.
Motivation
The generator boxes a type whose only self-reference is reached through an array or dictionary. Swift arrays and dictionaries keep their elements in heap-allocated storage, so a reference reached only through them cannot form a value-type cycle and the type does not need a
CopyOnWriteBox.Supporting-recursive-types.mdalready notes that arrays and dictionaries can be considered boxed, so the containing type does not require boxing. Fixes #682.Modifications
ExistingTypeDescription.referencedSchemaComponentName, returnnilfor.arrayand.dictionaryValueinstead of recursing into them..optionaland.anystill recurse.Result
A type that recurses only through an array or dictionary is generated as a plain struct with stored properties, not a boxed type.
Test Plan
Added two snippet reference tests covering recursion through an array and through a dictionary.