Files
scriptc/tests/diagnostics/component-fences.ts
Chris Tate e81e4f5ab5 Ambient roots trap whole chains; dead and nullish generic bindings lower to their runtime truth
- ambientUndefVarRootOf walks calls, `new`, optional chains, assertions, instantiation expressions, and tagged templates, and accepts `declare function` and trap-binding roots: Node erases the declaration, so the root read IS the crash — lowerCall, member reads, assignments, and variable declarations lower the whole statement to the catchable ReferenceError, arguments never evaluate, and the never-initialized binding registers as a trap whose references can never run
- never-read unmappable bindings with value-only initializers and writes emit nothing: Node builds the value and drops it, so `var xs2: typeof Array;` and the write-only `var f2: { <T, U>(x: T, y: U): T }` compile instead of fencing on a type the program never consumes
- null!/as-any bindings whose types keep generic signatures (or intern empty record shapes) register no storage; generic-method calls and member reads through them compile to Node's exact TypeError, nullish-to-nullish flows to nothing, heritage-clause uses decline the family so mixin resolution keeps its fence, and checked-dynamic (`any`) bindings keep their dyn story untouched
- assertion-shaped generic arrows (`< <T>(x: T) => T >((x) => x)`) register like annotated bindings and monomorphize per call; stdlib generic members (Promise.then, Object.defineProperty) take the SC2020 lib fence, and Function.prototype.apply/call/bind on compiled function values name the direct-call spelling
- diagnostics fixtures that used `declare` to conjure unconstructible values now conjure them by cast so each fence family keeps its pin; snapshots re-recorded, the deferred checker-panic diagnostic now flushes at its first reference as designed
2026-07-24 02:29:48 -05:00

46 lines
1.4 KiB
TypeScript

// SC2009: supported shapes over a component type outside its slot — the
// container is not the blocker, and each message names the component.
// Map keys are limited to numbers and strings.
const byFlag = new Map<boolean, string>();
console.log(byFlag);
// Map values have no slot for functions.
const listeners = new Map<string, () => void>();
console.log(listeners);
// Set elements are limited to numbers and strings.
const flags = new Set<boolean>();
console.log(flags);
// Arrays cannot hold Map elements yet.
const rows: Map<string, number>[] = [];
console.log(rows);
// A Map arm has no home in a compiled union.
function report(maybe: Map<string, number> | undefined): number {
return maybe === undefined ? 0 : maybe.size;
}
console.log(report(undefined));
// A rest parameter has no compiled calling convention.
const sum = (...xs: number[]): number => xs.length;
const storedSum = sum;
console.log(storedSum(1, 2));
// A function's return type carries the failure. The value arrives through
// a cast, not an ambient declare (a declare-rooted chain would compile to
// Node's ReferenceError at the root instead).
const makeWeak = (0 as unknown) as () => WeakMap<object, number>;
const storedMake = makeWeak;
console.log(storedMake());
// A record member's type carries the failure.
interface Holder {
label: string;
cache: WeakMap<object, number>;
}
const held = (0 as unknown) as Holder;
const kept = held;
console.log(kept.label);