Replace the generator's phantom-typed parse tree with a plain validated tree - #580
Merged
Conversation
Smaug123
force-pushed
the
argparser-resolve-before-convert
branch
from
July 25, 2026 10:26
c5fe1dd to
4dc9677
Compare
Smaug123
force-pushed
the
argparser-plain-tree
branch
from
July 25, 2026 10:26
0bd831b to
e4b89d7
Compare
Smaug123
force-pushed
the
argparser-resolve-before-convert
branch
from
July 25, 2026 10:33
4dc9677 to
26e61b4
Compare
Smaug123
force-pushed
the
argparser-plain-tree
branch
from
July 25, 2026 10:33
e4b89d7 to
1782f33
Compare
Smaug123
force-pushed
the
argparser-resolve-before-convert
branch
from
July 25, 2026 10:52
26e61b4 to
23f5c42
Compare
Smaug123
force-pushed
the
argparser-plain-tree
branch
from
July 25, 2026 10:52
1782f33 to
92e10f4
Compare
Smaug123
force-pushed
the
argparser-resolve-before-convert
branch
from
July 25, 2026 11:21
23f5c42 to
3273cdf
Compare
Smaug123
force-pushed
the
argparser-plain-tree
branch
from
July 25, 2026 11:21
d2e3e68 to
20d5cf3
Compare
…ed tree The HasPositional/HasNoPositional Teq indexing, the BranchPos constructor, the crate/eval machinery and assertNoPositional all existed to prove "at most one positional sink, never inside a union" in the type system — an invariant which is now the runtime schema's numeric capacity rule, not expressible with that phantom scheme once sinks may sit inside Sum cases. ParseTree.branch enforces the capacity rule at construction (and keeps the positional-claiming field after its siblings, where positional args have always appeared in help text and in the erased schema); positional parsers accumulate as a list; descriptors, accumulator bindings, callback dispatch and help all walk the one tree recursively. No change to accepted schemas or to generated output: regenerating ConsumePlugin produces a byte-identical tree, and the union-case surface rejection is retained verbatim. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Smaug123
force-pushed
the
argparser-plain-tree
branch
from
July 25, 2026 13:27
20d5cf3 to
572ac48
Compare
Smaug123
enabled auto-merge (squash)
July 25, 2026 13:31
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.
Stage 6 of the positional-args-with-unions stack (7/8). Stacked on #579.
Pure refactor of the generator, net −144 lines: the
Teq-based phantom-typed parse tree (HasPositional/HasNoPositionalwitnesses, crates,ParseTreeEval,TeqUtils) is replaced by a plain tree with a smart constructor:The phantom machinery existed to prove "at most one positional leaf" at compile time, but that invariant is about to become positional per-interpretation (Stage 7 allows one sink per union case), which the type-level encoding can't express.
ParseTree.branchnow enforces the old invariant dynamically, with the same "Multiple entries tried to claim positional args!" failure, and orders positional-containing fields last exactly as before.Correctness oracle is a golden test: the regenerated ConsumePlugin output is byte-identical — the only file that changes in this PR's generator path is
ArgParserGenerator.fsitself.🤖 Generated with Claude Code