You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Result: the program builds, runs, and silently produces wrong output. The user has no signal that they've stepped off the implemented surface area.
Why not just ship a .d.ts?
That's the Bun/Deno model and it works for them because the editor + tsc is the gatekeeper. Perry's compiler is the gatekeeper — .d.ts is downstream. The compiler already knows what's implemented; the source of truth should live there, not in a parallel file that can drift.
Proposal
Build an in-compiler manifest of implemented stdlib symbols (modules, classes, methods, properties), consulted during HIR lowering or early codegen. When the resolver fails to find a symbol on a known stdlib module, emit:
error: `crypto.subtle` is not implemented in Perry
--> app.ts:42:17
|
42 | const ct = await crypto.subtle.encrypt(...);
| ^^^^^^^^^^^^^
= note: see https://perryts.dev/api for the supported surface
= help: track via #455
The manifest can be assembled from existing sources rather than hand-maintained:
crates/perry-codegen dispatch tables (CLASS_VTABLE_REGISTRY, HANDLE_METHOD_DISPATCH, HANDLE_PROPERTY_DISPATCH, the perry_dispatch_* tables).
Some symbols exist but are no-ops by design (cross-platform UI on the wrong platform). Those shouldn't compile-error — they should warn at runtime on first call. That's the companion stub-registry issue. The compile-time error in this issue fires only for symbols not in either bucket.
Acceptance
crypto.subtle reference produces a compile error pointing at the source line.
Unimplemented fs / crypto / dgram / etc. methods do the same.
Implemented APIs continue to compile (regression test on the gap suite + a representative sample of stdlib calls).
Manifest is derived, not hand-authored — adding a new stdlib binding automatically removes the error.
Followups (separate issues)
Stub registry + first-call runtime diagnostic for legitimate no-ops.
Generated API docs / editor .d.ts emitted from this same manifest.
Spun out of #455 (DX feedback from @justin0mcateer).
Problem
When user code references an API Perry doesn't implement (e.g.
crypto.subtle.encrypt(...)), the compiler accepts the program and either:Result: the program builds, runs, and silently produces wrong output. The user has no signal that they've stepped off the implemented surface area.
Why not just ship a
.d.ts?That's the Bun/Deno model and it works for them because the editor + tsc is the gatekeeper. Perry's compiler is the gatekeeper —
.d.tsis downstream. The compiler already knows what's implemented; the source of truth should live there, not in a parallel file that can drift.Proposal
Build an in-compiler manifest of implemented stdlib symbols (modules, classes, methods, properties), consulted during HIR lowering or early codegen. When the resolver fails to find a symbol on a known stdlib module, emit:
The manifest can be assembled from existing sources rather than hand-maintained:
crates/perry-codegendispatch tables (CLASS_VTABLE_REGISTRY,HANDLE_METHOD_DISPATCH,HANDLE_PROPERTY_DISPATCH, theperry_dispatch_*tables).crates/perry-stdlibexported symbols.direct_call_stubsincrates/perry-runtime/build.rs(these are intentional no-ops — flag them differently; see Stub registry + first-call runtime diagnostic for no-op stubs #464).Distinguishing intentional stubs from gaps
Some symbols exist but are no-ops by design (cross-platform UI on the wrong platform). Those shouldn't compile-error — they should warn at runtime on first call. That's the companion stub-registry issue. The compile-time error in this issue fires only for symbols not in either bucket.
Acceptance
crypto.subtlereference produces a compile error pointing at the source line.fs/crypto/dgram/ etc. methods do the same.Followups (separate issues)
.d.tsemitted from this same manifest.