Skip to content

fix(web-sys): authoritative expansion model for stable/unstable WebIDL overrides#4964

Merged
guybedford merged 9 commits intomainfrom
fix-idl-stability
Feb 19, 2026
Merged

fix(web-sys): authoritative expansion model for stable/unstable WebIDL overrides#4964
guybedford merged 9 commits intomainfrom
fix-idl-stability

Conversation

@guybedford
Copy link
Contributor

@guybedford guybedford commented Feb 19, 2026

Summary

  • Fixes incorrect #[cfg(web_sys_unstable_apis)] gating on stable method signatures that share a WebIDL operation with unstable overloads
  • Replaces the old JS-name-based override detection with an authoritative expansion model where stable and unstable signature sets are built independently and compared
  • Adds typed generics (Promise<T>, Array<T>, Function<fn(...)>, etc.) to all unstable API methods
  • Adds missing Image Capture spec types: PhotoCapabilities, PhotoSettings, MediaSettingsRange, Point2D, RedEyeReduction, FillLightMode, MeteringMode
  • Fixes forward-reference problems in first pass by pre-registering interface/dictionary names
  • Fixes per-interface maplike/setlike callback name collisions

Problem

When a WebIDL operation like read(optional ClipboardUnsanitizedFormats formats = {}) expands, the 0-arg read() doesn't use any unstable types, so it's a valid stable API. But the old code saw that unstable signatures existed for the same JS name (read) and incorrectly gated all signatures — including the stable 0-arg version — with #[cfg(web_sys_unstable_apis)].

This affected Clipboard.read(), WebGL texImage2D/texSubImage2D/texImage3D/texSubImage3D (VideoFrame overloads), Performance.measure(), Window/WorkerGlobalScope timer methods, and others.

Solution

The new authoritative expansion model treats stable and unstable WebIDL expansions as independent, authoritative sets:

  1. Classify signatures as stable or unstable based on whether they come from unstable IDL definitions or use unstable types
  2. Detect siblings — signatures from the same WebIDL definition as an unstable signature are included in the unstable set even if they're individually stable (e.g., read() is a sibling of read(options))
  3. Build each set independently — naming disambiguation happens within each set
  4. Compare and gate:
    • Same signature in both sets → merge (no cfg gate, available always)
    • Only in stable set → #[cfg(not(web_sys_unstable_apis))]
    • Only in unstable set → #[cfg(web_sys_unstable_apis)]

Additional Fixes

  • Typed generics for unstable APIs: All unstable methods now use typed generics (Promise<T>, Array<T>, Function<fn(...)>) regardless of the generics compatibility mode for stable APIs
  • Image Capture types: Added PhotoCapabilities, PhotoSettings, MediaSettingsRange, Point2D, RedEyeReduction, FillLightMode, MeteringMode from the W3C Image Capture spec — these were referenced but never defined, causing methods to be silently skipped
  • Phase 0 pre-registration: Interface and dictionary names are pre-registered before processing members, fixing forward-reference failures (e.g., iterable over a type defined later in the same file)
  • Per-interface callback names: Maplike/setlike forEach callback type names are now per-interface ({Interface}MapLikeForEachCallback) instead of global singletons that overwrote each other
  • Error propagation: ArrayTuple type conversion now propagates errors instead of silently falling back to JsValue
  • Signature derives Eq/Hash: Replaced *const Signature pointer identity with proper structural equality via HashSet<&Signature>

Key Files Changed

  • crates/webidl/src/util.rs — authoritative expansion model in create_imports()
  • crates/webidl/src/generator.rssame_signature(), generics_compat logic for unstable APIs
  • crates/webidl/src/lib.rsOptions with Cell<bool>, generics_compat in dictionary/const/namespace/iterable code
  • crates/webidl/src/first_pass.rs — Phase 0 registration, per-interface callback names, Eq/Hash on Signature
  • crates/webidl/src/wbg_type.rs — error propagation in ArrayTuple
  • crates/web-sys/webidls/unstable/ImageCapture.webidl — added missing types from W3C spec
  • crates/web-sys/src/features/ — regenerated bindings

Testing

  • just test-web-idl-tests — stable mode tests pass
  • just test-web-idl-tests-unstable — unstable mode tests pass
  • just test-web-idl-tests-next — next mode tests pass
  • just generate-web-sys — regenerated bindings verified

@guybedford guybedford merged commit 7d391a7 into main Feb 19, 2026
62 checks passed
@guybedford guybedford deleted the fix-idl-stability branch February 19, 2026 22:35
@guybedford guybedford mentioned this pull request Feb 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants