Files
logos-test-modules/test-fullapi-ext-module-rust
Dario Gabriel LipicarandClaude Opus 5 156b493c7b test(conformance): the LIDL optional contract, as cases, before the implementation
`?T` is declared by every contract and read by no generator, in any language.
This writes down what it must mean, as 17 cells in the full_api_ext table plus
the contract delta on both ext providers, so the implementation has a target
instead of a behaviour to bless.

The contract these cells encode:

  * `?T` is TWO-state — a value of T, or empty — never three-state. Forced by
    "one LIDL type maps to one type per language": every target has exactly one
    empty inhabitant (None / nullopt / invalid QVariant / undefined).
  * Omitted and explicit-null are the SAME state on DECODE and DIFFERENT on
    ENCODE. Empty is spelled by OMITTING the key in a NAMED slot (a record
    field) and by null in a POSITIONAL one (arg, return) — a positional slot has
    no key to omit and the arity must never change. The round trip is therefore
    CANONICALISING, not identity, and several expectations here are deliberately
    not the argument echoed back.
  * A present-but-wrong-typed value in an optional slot is STILL AN ERROR.
    Optional widens the domain by exactly one inhabitant; it does not disable
    type checking. `hostile/Optional/scalar/wrong-type` is the cell that stops
    `?T` = `any` from passing, which is what all three backends do today.
  * The two spellings the spec binds to one meaning (`? name: T` and `name: ?T`)
    must emit identical code. Both are in the contract on purpose: today they do
    not even agree at runtime — the field flag is checked against the base type,
    the type kind falls to `Ty::Any` and is not checked at all.

Both ext providers are authored AT THE TARGET, which means neither compiles
until the generator work lands, and the ext check is red at build time until
then. That is recorded in known-ext.json (OPT0) rather than hidden: a fixture
written against the current behaviour cannot be the thing the fix is measured
against. Every cell that cannot pass is registered (OPT1: optionality is
unimplemented; OPT2: an empty optional in a positional slot is unspeakable on a
wire where null already means METHOD_FAILED, and the py driver cannot send a
top-level null at all), so the suite is honestly red now and reports xpass —
which fails the run — the day the generators are right.

The registry entries record what was MEASURED about the generators by executing
them: --header-to-lidl silently derives `any` from std::optional, the cdylib
gate rejects `?T` outright, and the emitted record codec ignores the field flag
in both directions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 21:15:40 -03:00
..