Skip to content

Replace the generator's phantom-typed parse tree with a plain validated tree - #580

Merged
Smaug123 merged 1 commit into
mainfrom
argparser-plain-tree
Jul 25, 2026
Merged

Replace the generator's phantom-typed parse tree with a plain validated tree#580
Smaug123 merged 1 commit into
mainfrom
argparser-plain-tree

Conversation

@Smaug123

Copy link
Copy Markdown
Owner

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/HasNoPositional witnesses, crates, ParseTreeEval, TeqUtils) is replaced by a plain tree with a smart constructor:

type private ParseTree =
    | NonPositionalLeaf of ParseFunctionNonPositional
    | PositionalLeaf of ParseFunctionPositional
    | Branch of fields : (Ident * ParseTree) list * assemble : ...
    | Sum of sumId : int * cases : (Ident * ParseTree) list * assemble : ...

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.branch now 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.fs itself.

🤖 Generated with Claude Code

@Smaug123
Smaug123 force-pushed the argparser-resolve-before-convert branch from c5fe1dd to 4dc9677 Compare July 25, 2026 10:26
@Smaug123
Smaug123 force-pushed the argparser-plain-tree branch from 0bd831b to e4b89d7 Compare July 25, 2026 10:26
@Smaug123
Smaug123 force-pushed the argparser-resolve-before-convert branch from 4dc9677 to 26e61b4 Compare July 25, 2026 10:33
@Smaug123
Smaug123 force-pushed the argparser-plain-tree branch from e4b89d7 to 1782f33 Compare July 25, 2026 10:33
@Smaug123
Smaug123 force-pushed the argparser-resolve-before-convert branch from 26e61b4 to 23f5c42 Compare July 25, 2026 10:52
@Smaug123
Smaug123 force-pushed the argparser-plain-tree branch from 1782f33 to 92e10f4 Compare July 25, 2026 10:52
@Smaug123
Smaug123 force-pushed the argparser-resolve-before-convert branch from 23f5c42 to 3273cdf Compare July 25, 2026 11:21
@Smaug123
Smaug123 force-pushed the argparser-plain-tree branch from d2e3e68 to 20d5cf3 Compare July 25, 2026 11:21
Base automatically changed from argparser-resolve-before-convert to main July 25, 2026 13:24
…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
Smaug123 force-pushed the argparser-plain-tree branch from 20d5cf3 to 572ac48 Compare July 25, 2026 13:27
@Smaug123
Smaug123 enabled auto-merge (squash) July 25, 2026 13:31
@Smaug123
Smaug123 merged commit 7a53f27 into main Jul 25, 2026
19 checks passed
@Smaug123
Smaug123 deleted the argparser-plain-tree branch July 25, 2026 13:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant