fix: stop an unresolved refinement being reported as a cycle [minor] - #196
Merged
Merged
Conversation
Refines() stops walking for two reasons - a type it has already seen, and a link naming something the schema does not declare - and ValidateRefinement could tell them apart only by whether the chain reached a non-semantic type, which both answer the same way. So `A` refines `B` refines `Missing` reported a cycle that does not exist, on `A`, while `B` - the declaration with the typo in it - was named only by the second message. RefinesItself() asks the question the message makes: the chain ended on a cycle exactly when the deepest type it reached still refines something that resolves, since that is the link Refines() refused to follow twice. An unresolved tail is left to the declaration that names it, which is where the fix is, keeping it one message rather than two. Fixes #171 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CCVJEzptkDVM2wWtGTY7Av
|
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.



Fixes #171
What was wrong
ValidateRefinementinferred "cycle" fromRefines()never reaching a non-semantic type. ButRefines()has two exits, not one — its loop condition isso it stops both at a type it has already seen (a real cycle) and at a link whose
Declarationisnull(a name the schema does not declare). Both chains look identical from the call site.So
ArefinesB,BrefinesMissing, andschema.Validate()answered:There is no cycle anywhere. The first message sends the author looking for one, and it names
A— which is fine — rather thanB, which is the declaration with the typo in it.The fix
SchemaSemanticType.RefinesItself()asks the question the message actually makes: did the chain come back to a type it had already seen?The chain ended on a cycle exactly when the deepest type it reached still refines something that resolves, since that is the link
Refines()refused to follow a second time. An unresolved tail leaves aSemanticwith a nullDeclarationthere instead, and is left to the declaration that names it — which keeps it one message rather than two, the same rule CLAUDE.md states for an unresolved semantic type generally.It is written in terms of
Refines()rather than walking again, and reuses theLastOrDefault() ?? thisidiom already inRepresentation()so the directArefinesAcase (which yields nothing) is covered by the same line.Tests
AnUnresolvedRefinementDeeperInAChainIsNotACycle— the two-linkWeight → ForceMagnitude → Missingchain the issue describes, asserting exactly one issue, that it is the "does not declare" one, and that it is reported againstForceMagnitude. The existingAnUnresolvedRefinementIsRejectedis depth 1 and never reaches this branch.ARefinementChainThatRevisitsATypeStillReportsItself—A → B → C → B, where the cycle does not include the type being asked, so the fix cannot narrow the check to self-reference.Verified the first test fails without the change (
Sequence contains more than one element— the spurious cycle error) and passes with it.Schema.Testis 478/478 green andSchema.Cpp.Testis 102/102 green onnet10.0. Thenet8.0/net9.0legs could not be launched in this container (only the .NET 10 runtime is installed), so CI covers those.🤖 Generated with Claude Code
https://claude.ai/code/session_01CCVJEzptkDVM2wWtGTY7Av
Generated by Claude Code