Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/src/app/limitations/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ These are rejected at compile time with an `SC` code, a code frame, and usually
- Block- and function-scoped `using` and `await using` compile for statically represented classes with zero-parameter disposal methods and for the supported FileHandle, timer, immediate, child-process, and readline handles. Array `for (using ... of ...)` loops compile. Top-level and switch-clause declarations, disposal through an engine-held package value, and the `DisposableStack` constructors remain fenced; a caught `SuppressedError` exposes its Node-compatible `name` and `message`, while its `error` and `suppressed` payload properties remain outside the static catch surface.
- Typed async generator functions and methods compile with lazy execution, `await`, direct `yield`, queued `.next()`/`.return()`/`.throw()` requests, and `for await`. `for await` also consumes Node `Readable` streams, Web `ReadableStream` values, and statically represented class iterators whose zero-parameter `next()` returns a promise of a `{ value, done? }` record; abrupt completion runs the iterator's cleanup, including literal `destroyOnReturn` and `preventCancel` options. Async `yield*` delegation, stored Web/Node iterator handles, and other structural async-iterator objects remain fenced. The `node:timers/promises` `setInterval(delay, value)` async iterator compiles, while its AbortSignal options remain fenced.
- Generics monomorphize when the target resolves statically. The remaining edges include generic functions declared inside another function, generic class expressions, generic classes whose base depends on their own type parameters, and generic methods that would require dynamic dispatch.
- Generic function values must be pinned at use to a concrete signature and come from a never-reassigned binding; unpinned or rebound values remain fenced. Immutable aliases of overloaded program functions retain per-call overload resolution and function identity. Immutable aliases of table-backed Node builtins can be called directly, while escaping builtin values such as `array.map(path.basename)` remain fenced; `util.promisify` has compile-time projections for `child_process.execFile` and utf8 `fs.readFile`.
- Generic function values must be pinned at use to a concrete signature and come from a never-reassigned binding; unpinned or rebound values remain fenced. Immutable aliases of overloaded program functions retain per-call overload resolution and function identity. Exact-arity `node:path` functions such as `extname`, `isAbsolute`, and `relative` are first-class static values and can be stored, returned, and passed to higher-order functions; optional and variadic builtins such as `basename`, `join`, and `resolve` remain call-only. Other immutable aliases of table-backed Node builtins can be called directly, while escaping them remains fenced; `util.promisify` has compile-time projections for `child_process.execFile` and utf8 `fs.readFile`.
- Spread arguments compile when their arity is static: non-empty fixed tuples flatten into fixed signatures with left-to-right, evaluate-once semantics, while arrays, Sets, and statically represented class iterables spread into typed rest parameters. Runtime-length spreads into fixed signatures remain on the checked-dynamic or island paths in JavaScript and otherwise receive a compile-time diagnostic.

**Types and shapes**
Expand Down
52 changes: 39 additions & 13 deletions internal/compatibility/generated/node-v24-backlog.json
Original file line number Diff line number Diff line change
Expand Up @@ -65977,7 +65977,9 @@
"confidence": "high",
"source": "surface-manifest:node-builtin.path.basename",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -66014,7 +66016,9 @@
"confidence": "high",
"source": "surface-manifest:node-builtin.path.dirname",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -66051,7 +66055,9 @@
"confidence": "high",
"source": "surface-manifest:node-builtin.path.extname",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -66156,7 +66162,9 @@
"confidence": "high",
"source": "surface-manifest:node-builtin.path.isAbsolute",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -66193,7 +66201,9 @@
"confidence": "high",
"source": "surface-manifest:node-builtin.path.join",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -66230,7 +66240,9 @@
"confidence": "high",
"source": "surface-manifest:node-builtin.path.normalize",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -66302,7 +66314,9 @@
"confidence": "high",
"source": "surface-manifest:node-builtin.path.relative",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -66339,7 +66353,9 @@
"confidence": "high",
"source": "surface-manifest:node-builtin.path.resolve",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -66376,7 +66392,9 @@
"confidence": "high",
"source": "surface-manifest:node-builtin.path.toNamespacedPath",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -66413,7 +66431,9 @@
"confidence": "high",
"source": "surface-manifest:node-builtin.path.delimiter",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -66450,7 +66470,9 @@
"confidence": "high",
"source": "surface-manifest:node-builtin.path.posix",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -66487,7 +66509,9 @@
"confidence": "high",
"source": "surface-manifest:node-builtin.path.sep",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -66524,7 +66548,9 @@
"confidence": "high",
"source": "surface-manifest:node-builtin.path.win32",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down
54 changes: 41 additions & 13 deletions internal/compatibility/generated/node-v24-internal.json
Original file line number Diff line number Diff line change
Expand Up @@ -82352,6 +82352,8 @@
"status": "partial",
"evidence": "derived:descendants",
"tests": [
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts",
"tests/corpus/957-builtins-namespace.ts"
]
},
Expand Down Expand Up @@ -82412,7 +82414,9 @@
"status": "partial",
"evidence": "surface-manifest:node-builtin.path.basename",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -82445,7 +82449,9 @@
"status": "partial",
"evidence": "surface-manifest:node-builtin.path.dirname",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -82478,7 +82484,9 @@
"status": "partial",
"evidence": "surface-manifest:node-builtin.path.extname",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -82568,7 +82576,9 @@
"status": "partial",
"evidence": "surface-manifest:node-builtin.path.isAbsolute",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -82601,7 +82611,9 @@
"status": "partial",
"evidence": "surface-manifest:node-builtin.path.join",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -82634,7 +82646,9 @@
"status": "partial",
"evidence": "surface-manifest:node-builtin.path.normalize",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -82697,7 +82711,9 @@
"status": "partial",
"evidence": "surface-manifest:node-builtin.path.relative",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -82730,7 +82746,9 @@
"status": "partial",
"evidence": "surface-manifest:node-builtin.path.resolve",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -82763,7 +82781,9 @@
"status": "partial",
"evidence": "surface-manifest:node-builtin.path.toNamespacedPath",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -82796,7 +82816,9 @@
"status": "partial",
"evidence": "surface-manifest:node-builtin.path.delimiter",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -82829,7 +82851,9 @@
"status": "partial",
"evidence": "surface-manifest:node-builtin.path.posix",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -82862,7 +82886,9 @@
"status": "partial",
"evidence": "surface-manifest:node-builtin.path.sep",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down Expand Up @@ -82895,7 +82921,9 @@
"status": "partial",
"evidence": "surface-manifest:node-builtin.path.win32",
"tests": [
"tests/corpus/957-builtins-namespace.ts"
"tests/corpus/957-builtins-namespace.ts",
"tests/corpus/2915-path-function-values.ts",
"tests/corpus/2916-path-function-values-cjs.ts"
]
},
"dynamic": {
Expand Down
2 changes: 1 addition & 1 deletion internal/compatibility/static-support.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"node-builtin.module": ["tests/corpus/1598-cjs-builtin-require/main.js"],
"node-builtin.net": ["tests/corpus/2500-net-autosel-timeout.ts", "tests/corpus/2596-net-arg-ladders.cjs"],
"node-builtin.os": ["tests/corpus/1480-os-network-interfaces.ts"],
"node-builtin.path": ["tests/corpus/957-builtins-namespace.ts"],
"node-builtin.path": ["tests/corpus/957-builtins-namespace.ts", "tests/corpus/2915-path-function-values.ts", "tests/corpus/2916-path-function-values-cjs.ts"],
"node-builtin.perf_hooks": ["tests/corpus/957-builtins-namespace.ts"],
"node-builtin.process": ["tests/corpus/990-process-basics.ts", "tests/corpus/2314-process-introspection.ts"],
"node-builtin.querystring": ["tests/corpus/957-builtins-namespace.ts"],
Expand Down
14 changes: 14 additions & 0 deletions packages/compiler/src/frontend/lowering/lower-containers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,20 @@ function arraySearchHelper(
}
lowerer.implicitParamTypes = previousImplicit;
}
// Array storage widens indexed reads with undefined so holes remain
// observable. The HOF helper guards every callback behind arrayHas,
// so an exact-ABI builtin closure may safely adapt from its declared
// parameter to that guarded union. Keep this exception scoped to the
// compiler-generated builtin values; ordinary callback-value policy is
// unchanged.
if (
fnArg.type.kind === "func" && lowerer.isBuiltinCallableValue(fnArg)
) {
const callbackType = funcOf(full.slice(0, fnArg.type.params.length), fnArg.type.ret);
if (!typeEquals(fnArg.type, callbackType)) {
fnArg = lowerer.coerceToExpected(fnArg, callbackType);
}
}
if (
fnArg.type.kind !== "func" ||
fnArg.type.params.length > full.length ||
Expand Down
8 changes: 8 additions & 0 deletions packages/compiler/src/frontend/lowering/lower-exprs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,10 @@ function lowerExprInner(lowerer: Lowerer, expr: ts.Expression): IrExpr {
);
}
if (projection?.kind === "builtin-function") {
if (!isJsSourceFile(expr.getSourceFile())) {
const callable = lowerer.lowerBuiltinCallableValue(projection, loc);
if (callable) return callable;
}
lowerer.unsupported(
"SC1090",
expr,
Expand Down Expand Up @@ -950,6 +954,10 @@ function lowerExprInner(lowerer: Lowerer, expr: ts.Expression): IrExpr {
if (isJsSourceFile(expr.getSourceFile())) {
return { kind: "strLit", value: `[builtin ${bi.module}.${bi.member}]`, type: STRING, loc };
}
{
const callable = lowerer.lowerBuiltinCallableValue(bi, loc);
if (callable) return callable;
}
if (builtinModuleFnOf(lowerer, bi.module, bi.member)) {
lowerer.unsupported(
"SC1090",
Expand Down
Loading
Loading