Files
scriptc/tests/corpus/3069-tuple-spread.ts
Chris Tate 4070ef701c fix(compiler): unblock self-hosting analysis and tuple construction (#488)
* fix(compiler): unblock self-hosting analysis and tuple construction

- Bound type diagnostics to handle deeply nested and shared compiler types.
- Compile fixed tuple spreads and preserve const tuple inference under satisfies.
- Add native compiler-component and differential regression coverage.

* fix(tests): record tuple spread frontend parity baseline

- Record module order and preflight diagnostics for the new tuple spread regression fixture.
2026-09-27 10:29:10 -05:00

65 lines
2.2 KiB
TypeScript

// Fixed tuple spreads preserve positions, source order, and fresh storage.
let calls = 0;
const source: [string, number] = ["before", 2];
function take(): [string, number] {
calls++;
console.log("take", calls);
return source;
}
function change(): string {
console.log("change");
source[0] = "after";
source[1] = 9;
return "tail";
}
function prefix(): boolean {
console.log("prefix");
return true;
}
const tuple: [boolean, string, number, string, string, number] = [prefix(), ...take(), change(), ...take()];
console.log(JSON.stringify(tuple), calls);
source[0] = "later";
tuple[1] = "copy";
console.log(JSON.stringify(source), JSON.stringify(tuple));
// Lexical field ordering must not reorder positions 10 and 11 before 2.
const many = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] as const;
const combined = ["start", ...many, "end"] as const;
console.log(JSON.stringify(combined));
// The compiler builds its IR kind tables with this exact type-only pattern.
const kinds = ["number", "string"] as const satisfies readonly string[];
const moreKinds = [...kinds, "boolean"] as const;
console.log(JSON.stringify(moreKinds));
function empty(): [] {
console.log("empty");
return [];
}
const withEmpty: [number, string] = [...empty(), 3, ...empty(), "yes", ...empty()];
console.log(JSON.stringify(withEmpty));
// Spread slots use their destination types, including union wrapping.
const pair: [number, string] = [1, "two"];
const widened: [number | string, number | string, boolean] = [...pair, false];
console.log(JSON.stringify(widened));
// Elements are copied shallowly: referenced records retain their identity.
const record = { value: 1 };
const refs: [typeof record, string] = [record, "ref"];
const copied: [typeof record, string, number] = [...refs, 5];
record.value = 8;
console.log(JSON.stringify(copied));
// A throwing source prevents later elements from being evaluated.
function fail(): [number, string] {
console.log("fail");
throw new Error("spread failed");
}
try {
const stopped: [boolean, number, string, string] = [prefix(), ...fail(), change()];
console.log(JSON.stringify(stopped));
} catch (error) {
if (error instanceof Error) console.log(error.message);
}