ReviewOS

home-lang/home

fix(ts): keep instantiated alias metadata distinct across shared structural types

#909
Open glennmichael123 opened this 8 days ago ·
8 days ago

Related: #832, #66.

Exact pinned TypeScript fixture conditionalTypes1 still fails one diagnostic on current main 1b07917: line 135 TS2542 displays DeepReadonlyArray<t>[P][number]> instead of DeepReadonlyArray<part>. A direct checker reduction reproduces the same mismatch.

Trace: registerAliasDisplayNameInner receives structural TypeId 253 first with symbolic argument T[P][number], then again with concrete argument Part. The first display wins. That same TypeId is later re-registered symbolically, so a simple last-writer policy is also wrong.

Two candidate mutations were rejected and fully reverted: replacing both alias_display_names and alias_type_args fixes TS2542 but loses the required line 136 TS2540 readonly-property diagnostic; changing only alias_display_names has the same semantic regression. These maps participate in semantic lookup, so a diagnostic-string substitution is not a valid fix.

Guarded exact six-variant control before/after candidate: four pass, one upstream skip, conditionalTypes1 fails. Original mismatch is only line 135 wording; candidate mismatch is missing line 136 TS2540. Peak process-tree footprint stayed below 2.3 GB with a 3,840 MB ceiling. No candidate code is retained or pushed.

Acceptance: preserve separate semantic instantiation ownership for structurally interned types; match all diagnostics in the original conditionalTypes1 fixture, including both TS2542 and TS2540; add direct checker and exact-corpus regressions; run unfiltered checker and Program tests under the memory guard. No fixture edits, diagnostic special cases, or weakening of readonly checks.

8 days ago

Fresh current-main check after 4751ce3: the unchanged exact conditionalTypes1 fixture still has one mismatch. Home emits line 135 TS2542 with DeepReadonlyArray<t>[P][number]> where the pinned baseline requires DeepReadonlyArray<part>; line 136 TS2540 and every other listed diagnostic remain present. The guarded run exited 1 as intended, peak tree footprint 1,995 MB below the 3,840 MB ceiling. Independent installed TypeScript 5.7.3 API inspection of the unchanged fixture reports part.subparts as a distinct generic interface reference (typeToString DeepReadonlyArray<part>, target id 164, typeArguments Part), while part.subparts[0] is a separately instantiated DeepReadonlyObject<part>. In Home, generic interface lookup at check.zig:82016 substitutes the body and registers alias metadata on its resulting TypeId; substitution at check.zig:57165 propagates display/argument metadata to the new structural object. This supports fixing interface instantiation ownership before display registration rather than swapping alias_display_names on a shared TypeId. No source, fixture, or baseline edits made; installed TypeScript 5.7.3 is a corroborating API probe, not a rebuilt pinned compiler.

8 days ago

Follow-up current-main trace under the unchanged guarded conditionalTypes1 fixture: early DeepReadonlyArray lookups used body 1211 and produced separate result TypeIds, but later lookups used body 1350 and returned that identical body TypeId for several distinct arguments (including symbolic and concrete). The local declaration owner existed, yet its reserved GenericDefinition still had body=none on every observed lookup. A general prototype that returned a declaration+arguments instantiation only for unchanged-body generic interfaces, plus ordinary receiver resolution, was rejected: the original one-line display mismatch grew into five TS7053 indexed-read errors and lost required line-136 TS2540. All experimental source edits were removed; tracked main is clean. This narrows the required repair: complete/publish generic interface definition ownership before substituting/caching references, and make indexed/member operations consume that completed semantic body. Simply returning a fresh instantiation wrapper or replacing the shared display map is not sufficient.

8 days ago

Additional bounded conformance evidence: DeepReadonlyArray registrations with distinct arguments (including Part and T[P][number]) converge on the same object TypeId 1362. First-write alias metadata leaves TS2542 displaying DeepReadonlyArray<t>[P][number]> where TypeScript expects DeepReadonlyArray<part>. Cloning that object to give the later instantiation a distinct identity fixes the TS2542 name, but loses the adjacent TS2540 readonly-property diagnostic, even when copied without a second substitution. The attempted clone was removed; no code or baseline changes were retained. A correct fix must preserve both per-instantiation display identity and the nested readonly semantics. Guarded exact conditionalTypes1 remains one mismatch; main is unchanged.

8 days ago

Follow-up bounded exact-fixture probe (no source retained): forcing a distinct object identity for colliding DeepReadonlyArray arguments, while explicitly retaining original member TypeIds, string/number/symbol indexers, declaration base, readonly-index flag, and alias metadata, again corrected the TS2542 alias text to DeepReadonlyArray<part> but removed the required adjacent TS2540 on part.subparts[0].id. This rules out nested substitution alone as the cause of the clone regression; additional identity-keyed readonly/member provenance is involved. The experiment was reverted with git diff --exit-code clean before the separate #884 storage commit. #909 remains open; no passing conformance claim.

Sign in to comment on this issue.