Repository navigation
Read typescript-go's unreadable match-or-empty unions through their widened members; compile tuple spreads, Stats arrays, primitive then handlers and fielded error inspection - #1516
Merged
Conversation
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…idened members; compile tuple spreads, Stats arrays, primitive then handlers and fielded error inspection
- `s.match(re) ?? []` / `|| []` made typescript-go's API panic whenever the
union's members were serialized (the empty literal is a tuple clone
without tuple data), poisoning the statement with SC0004. The members
of the union's widened type are readable and describe the same values,
so constituent reads answer with them; the empty tuple beside a match
array is one of its values. `checker-panic-tuple.ts` compiles and moves
to the corpus.
- Spreading a fixed tuple into an array literal copies its positions
into the literal's element type.
- fs.Stats values are an array element kind, so `Promise.all` over
`stat()` promises and `Stats[].reduce` compile.
- `.then(String)`, `.then(Number)` and `.then(Boolean)` over a number or
boolean settled value convert it through an interned closure.
- Inspecting (util.format, %s, util.inspect) an Error-typed value whose
runtime class declares fields prints the stackless base with Node's
constructor-name header (`[Bailable [Error]: m]`) and the own
properties, `[Bailable [Error]: m] { bail: true }`; it was refused. A
subclass whose own fields cannot render (functions, or a field Node's
error inspector treats specially) throws a named refusal on its own
instances only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cramforce
force-pushed
the
opt/bc-r3-misc
branch
from
October 20, 2026 12:41
0fb5cf1 to
db68255
Compare
…heir cycles as Node does fieldedErrorReason checked each field of a fielded error class with a fresh inspectSupport walk, so a field typed as the class itself (`next: Chain`) recursed until the compiler's stack overflowed. It now continues the caller's walk, where the class is a recursive shape. The fielded error helper then rendered a cycle by expanding it to the depth budget, where Node prints `<ref *1>` and `[Circular *1]`. Classes whose fields reach the class or one of its bases now run the circular machinery other cycle-capable objects use (circCheck before the depth answer, seenPush, refWrap), which also covers a cycle through a base-typed field of a subclass. New corpus program 6526-error-subclass-cycles.ts. 6187-js-match-or-empty-array.js compiles without its deferred fence now that the match-or-empty union reads through its widened members: the `@deferred-fences: 1` header goes, and the program calls the function the fence used to cover.
This branch was successfully deployed
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.
The typescript-go panic behind
s.match(re) ?? []In
s.match(re) ?? [](and|| []), the empty literal is contextually typed by the tuple-like match result. typescript-go clones an empty tuple as an array literal, and the clone keeps the tuple flag without tuple data. The API then panics whenever it serializes the union's members (interface conversion: checker.TypeData is *checker.TypeReference, not *checker.TupleType, ininternal/api/proto.go). An earlier fix kept the panic from failing the whole program, but every statement that needed the members still reported SC0004.When
getTypesOfTypepanics, the constituent read now asks for the union's widened type instead. Its members are readable and describe the same values, so they become the union's members. If widening does not help, the existing behavior stays. The empty tuple beside aRegExpMatchArray/RegExpExecArrayis one of the match array's own values, as it already was beside a plain array. With both changes,const matches = text.match(re) ?? []is a plain match array, andchecker-panic-tuple.tsnow compiles and moves to the corpus.Smaller gaps
[...TUPLE, ...rest], whereTUPLE: [string, string, string, string, string], copies the tuple's positions into the literal's element type.fs.Statsarrays:fs.Statsis now an array element kind. Stats are refcounted handles, so arrays use their retain/release adapters and need no tracing.await Promise.all(files.map((f) => stat(f)))andstats.reduce(...)compile.thenhandlers:.then(String),.then(Number)and.then(Boolean)over a number or boolean settled value convert it through an interned closure. A string settled value already fit the constructors' value form and keeps its old path.util.format(err),%sandutil.inspectof an Error-typed value were refused when any error subclass in the program declares fields. Now, for each fielded subclass (most-derived first), aninstanceofarm prints the stackless error base, then the own properties, using the same single-line/multi-line rule as any object, counting the base:[Bailable [Error]: m] { bail: true }.Bailable [Error]vsFetchFailedError).[Name].class Plain extends Error {}prints[Plain [Error]: m]and not[Error: m]. 6525 covers this.Evidence
checker-panic-tuple.ts)4642-acyclic-contract.tsfails on both sides, as it already does on main. Self-hosted compile time -0.01%. The bench timing interval came out inconclusive, but every program is byte-identical, so the difference is noise.pnpm lintandpnpm format:checkare clean.pnpm test:ts7 --baselines-onlypasses, with the new baselines recorded and the moved fixture's baseline moved.diagnostics.test.ts: 203/203.tests/harness/self-hosting-native-driver.test.tspasses.🤖 Generated with Claude Code