Skip to content

Compile-time error for unimplemented Node / Web APIs #463

Description

@proggeramlug

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.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).
  • crates/perry-stdlib exported symbols.
  • direct_call_stubs in crates/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.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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew capability or improvementparityCompatibility gap with Node.js, ECMAScript, or the supported ecosystemtoolingDeveloper tooling, CI, tests, or release infrastructure

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions