fix(compilers/openapi): keep a conflicting redeclaration's losing type - #436
Open
fuad-daoud wants to merge 1 commit into
Open
fix(compilers/openapi): keep a conflicting redeclaration's losing type#436fuad-daoud wants to merge 1 commit into
fuad-daoud wants to merge 1 commit into
Conversation
When allOf branches declare one field with incompatible types the merge keeps the first declaration and warns, naming both pointers. The losing declaration was then dropped: it reached the IR in no form at all, so a consumer reading the document rather than the diagnostic stream saw no trace of it — and a diff across two revisions in which only the losing branch's type moved reported no change. GitHub's published spec writes this shape 102 times. Every other degradation in this compiler keeps what it could not model. This one now does too: the discarded ir.TypeRef is written to the merged property's Unmodeled under ReasonDegradedLowering, keyed by the redeclaration's own pointer so sibling branches never overwrite one another, and stamped with the losing declaration's provenance. The constraint half of the same diagnostic is deliberately left alone. It also discards the redeclaration's keyword, but the recorded direction there is to intersect the bounds so the merged field satisfies both branches (#10), and preserving the loser instead would settle a decision that already has one. The code comment on keepLosingType says so. Fixes #424 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SYeBgDsskwnyitLgPGCPn1
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.
Closes #424. Not breaking.
When
allOfbranches declare the same field with incompatible types, the first declaration wins, a warning names both pointers, and the losing type was simply dropped — not written toUnmodeled.Every other degradation in this compiler keeps what it could not model. That is the discipline: an
Unmodeledentry with aReason, so nothing reaches the IR in no form. This path was the exception, and it was silent to any consumer reading the document rather than the diagnostic stream.102 occurrences in GitHub's published spec — e.g.
webhook-fork/properties/forkee/allOf/1/properties/clone_url, wheret/prim/urlandt/prim/stringdisagree and the first wins. A consumer diffing two versions of that document sees "no change" across a release where the losing branch's type moved.The whole
ir.TypeRefis kept (soNullablesurvives, not just the target ID), keyed by the redeclaration's own pointer so three conflicting branches keep three entries rather than the last overwriting the rest.Scope note: the constraint half of the same diagnostic still discards its loser. That is left alone deliberately — #10 records the direction for it (intersect the bounds), and preserving the loser instead would settle a decision that already has one.
Stack 2 of 8. Base
stack/1-detection— review and merge bottom-up. Every commit here passedmake gatewhen it landed, and the full gate was re-run on the top of the stack. Run it asGOTOOLCHAIN=go1.26.3 make gate; this machine's Go 1.27 fails it for reasons unrelated to any change (#431).🤖 Generated with Claude Code
https://claude.ai/code/session_01SYeBgDsskwnyitLgPGCPn1