@scriptc/compiler 0.0.11 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +12 -9
  2. package/ambient/scriptc.d.ts +2 -2
  3. package/dist/backend/cc.d.ts +2 -2
  4. package/dist/backend/emission/emit-async.js +1 -1
  5. package/dist/backend/emission/emit-exprs.js +97 -52
  6. package/dist/backend/emission/emit-exprs.js.map +1 -1
  7. package/dist/backend/emission/emit-island.js +1 -1
  8. package/dist/backend/emission/emit-shapes.js +1 -1
  9. package/dist/backend/emission/emit-walkers.d.ts +14 -14
  10. package/dist/backend/emission/emit-walkers.js +44 -44
  11. package/dist/backend/emission/emit-walkers.js.map +1 -1
  12. package/dist/backend/emission/emitter.d.ts +3 -3
  13. package/dist/backend/emission/emitter.js +8 -8
  14. package/dist/backend/emission/may-throw.js +1 -1
  15. package/dist/backend/llvm/dyn.d.ts +10 -10
  16. package/dist/backend/llvm/dyn.js +26 -26
  17. package/dist/backend/llvm/dyn.js.map +1 -1
  18. package/dist/backend/llvm/emitter.js +97 -43
  19. package/dist/backend/llvm/emitter.js.map +1 -1
  20. package/dist/backend/llvm/shapes.js +1 -1
  21. package/dist/backend/llvm/walkers.js +2 -2
  22. package/dist/backend/llvm/walkers.js.map +1 -1
  23. package/dist/diagnostics/diagnostic.d.ts +1 -1
  24. package/dist/diagnostics/diagnostic.js +4 -3
  25. package/dist/diagnostics/diagnostic.js.map +1 -1
  26. package/dist/frontend/lowering/lib-boundary.js +5 -5
  27. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  28. package/dist/frontend/lowering/lower-assert.js +12 -12
  29. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  30. package/dist/frontend/lowering/lower-builtins.d.ts +7 -7
  31. package/dist/frontend/lowering/lower-builtins.js +92 -31
  32. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  33. package/dist/frontend/lowering/lower-calls.d.ts +4 -4
  34. package/dist/frontend/lowering/lower-calls.js +66 -66
  35. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  36. package/dist/frontend/lowering/lower-classes.js +31 -5
  37. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  38. package/dist/frontend/lowering/lower-containers.d.ts +5 -5
  39. package/dist/frontend/lowering/lower-containers.js +19 -19
  40. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  41. package/dist/frontend/lowering/lower-emitter.js +2 -2
  42. package/dist/frontend/lowering/lower-emitter.js.map +1 -1
  43. package/dist/frontend/lowering/lower-exprs.d.ts +7 -7
  44. package/dist/frontend/lowering/lower-exprs.js +158 -112
  45. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  46. package/dist/frontend/lowering/lower-inspect.js +5 -5
  47. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  48. package/dist/frontend/lowering/lower-island.js +12 -3
  49. package/dist/frontend/lowering/lower-island.js.map +1 -1
  50. package/dist/frontend/lowering/lower-modules.js +16 -16
  51. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  52. package/dist/frontend/lowering/lower-namespaces.d.ts +11 -1
  53. package/dist/frontend/lowering/lower-namespaces.js +41 -6
  54. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  55. package/dist/frontend/lowering/lower-server.js +11 -11
  56. package/dist/frontend/lowering/lower-server.js.map +1 -1
  57. package/dist/frontend/lowering/lower-stmts.d.ts +1 -1
  58. package/dist/frontend/lowering/lower-stmts.js +191 -30
  59. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  60. package/dist/frontend/lowering/lower-stream.js +66 -22
  61. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  62. package/dist/frontend/lowering/lowerer.d.ts +10 -10
  63. package/dist/frontend/lowering/lowerer.js +51 -37
  64. package/dist/frontend/lowering/lowerer.js.map +1 -1
  65. package/dist/frontend/lowering/surfaces.js +2 -2
  66. package/dist/frontend/lowering/surfaces.js.map +1 -1
  67. package/dist/frontend/program.js +1 -1
  68. package/dist/frontend/shared.js +7 -7
  69. package/dist/frontend/shared.js.map +1 -1
  70. package/dist/frontend/types.d.ts +2 -2
  71. package/dist/frontend/types.js +15 -15
  72. package/dist/frontend/types.js.map +1 -1
  73. package/dist/index.js +38 -7
  74. package/dist/index.js.map +1 -1
  75. package/dist/ir/nodes.d.ts +110 -98
  76. package/dist/ir/nodes.js +48 -21
  77. package/dist/ir/nodes.js.map +1 -1
  78. package/dist/ir/validate.js +44 -34
  79. package/dist/ir/validate.js.map +1 -1
  80. package/dist/library/int-infer.js +13 -0
  81. package/dist/library/int-infer.js.map +1 -1
  82. package/dist/library/profile.d.ts +8 -6
  83. package/dist/library/profile.js.map +1 -1
  84. package/dist/library/sidecar-validate.js +1 -1
  85. package/dist/library/sidecar-validate.js.map +1 -1
  86. package/dist/library/sidecar.d.ts +1 -1
  87. package/dist/library/sidecar.js +20 -7
  88. package/dist/library/sidecar.js.map +1 -1
  89. package/package.json +2 -2
  90. package/surface-manifest.json +4 -4
@@ -282,7 +282,7 @@ export function neverTaintedJsType(L, node, t) {
282
282
  };
283
283
  return walk(t, 4);
284
284
  }
285
- /** The DOM undefined value — what an uninitialized checked-dynamic
285
+ /** The dyn undefined value — what an uninitialized checked-dynamic
286
286
  * binding holds (JS: declared bindings read `undefined` before any
287
287
  * assignment). A NULL dyn slot is a trap, never a value, so every dyn
288
288
  * binding that is READABLE before its first assignment must start here:
@@ -349,10 +349,10 @@ export function ladderFenceExpr(L, surface, node, hint) {
349
349
  * only unmappable pieces are `any` (`(value: any) => value is string` —
350
350
  * the arrow the binding holds lowers those params to dyn, so the binding
351
351
  * keeps its func-ness with the same per-piece fallback). The honest
352
- * static subset of `any` is a binding whose VALUES are DOM-representable:
352
+ * static subset of `any` is a binding whose VALUES are dyn-representable:
353
353
  * the binding is 'unknown' storage with the boundary conversions
354
354
  * coerceToExpected already applies (dynFrom into the slot, validated
355
- * dynCheck out) and per-site SC2011 fences for the operations the DOM
355
+ * dynCheck out) and per-site SC2011 fences for the operations the checked-dynamic tree
356
356
  * cannot carry JS-exactly (the island still lifts those). Every OTHER
357
357
  * unmappable TS type keeps its own diagnostic — annotations exist there,
358
358
  * and the fence names the real blocker. `--dynamic` builds never reach
@@ -376,8 +376,8 @@ export function dynFallbackType(L, node, t) {
376
376
  ((elem.flags & ts.TypeFlags.Never) !== 0 || neverTaintedJsType(L, node, elem));
377
377
  const mappedElem = elem !== undefined && !elemTainted ? L.mapTypeOf(elem) : null;
378
378
  // A mappable element keeps the static array; an unmappable one makes
379
- // the WHOLE value dyn (the DOM has real arrays — length/index/push
380
- // read through the keyed-DOM paths; dyn-element STATIC arrays have no
379
+ // the WHOLE value dyn (the checked-dynamic tree has real arrays — length/index/push
380
+ // read through the keyed-dyn paths; dyn-element STATIC arrays have no
381
381
  // backend representation).
382
382
  if (mappedElem)
383
383
  return { kind: "array", elem: mappedElem };
@@ -2317,7 +2317,7 @@ export class Lowerer {
2317
2317
  // The reverse — a TYPED value flowing into an 'unknown' slot
2318
2318
  // (`const u: unknown = 5`, an unknown-typed param/return) — IS tsc-clean
2319
2319
  // and rejected here: a typed value has no dynamic representation
2320
- // (constructing a DOM from static values is deliberately out this
2320
+ // (constructing a dyn from static values is deliberately out this
2321
2321
  // round; only JSON.parse results are dyn).
2322
2322
  if (actual.kind === "dyn") {
2323
2323
  this.unsupported("SC1100", node, `passing 'unknown' values where '${this.fmt(expected)}' is expected`);
@@ -2426,8 +2426,8 @@ export class Lowerer {
2426
2426
  }
2427
2427
  // A CHECKED-DYNAMIC (dyn/'unknown') value entering the island (the
2428
2428
  // `isJson ? JSON.parse(text) : islandParser(text)` config ternary):
2429
- // the DOM tree deep-copies into engine values — data kinds only; a
2430
- // DOM carrying a boxed function/handle/promise throws the catchable
2429
+ // the dyn tree deep-copies into engine values — data kinds only; a
2430
+ // dyn carrying a boxed function/handle/promise throws the catchable
2431
2431
  // TypeError at runtime (trust-but-verify, like every boundary).
2432
2432
  if (expr.type.kind === "dyn") {
2433
2433
  return { kind: "jsMarshal", value: expr, type: JSVAL, loc: expr.loc };
@@ -2460,21 +2460,35 @@ export class Lowerer {
2460
2460
  return expr;
2461
2461
  }
2462
2462
  if (expr.type.kind === "jsval" && expected.kind !== "jsval") {
2463
- // The jsval→DOM crossing (the world unification's engine-handle
2463
+ // The jsval→dyn crossing (the world unification's engine-handle
2464
2464
  // kind): an 'any'-typed engine value flowing into an 'unknown'/
2465
- // 'object'/JS-residue slot wraps BY REFERENCE as the DOM's island
2466
- // kind — engine scalars normalize to native DOM kinds at wrap time,
2467
- // typeof/truthiness/String()/=== route to the engine, un-armed DOM
2465
+ // 'object'/JS-residue slot wraps BY REFERENCE as the checked-dynamic tree's island
2466
+ // kind — engine scalars normalize to native dyn kinds at wrap time,
2467
+ // typeof/truthiness/String()/=== route to the engine, un-armed dyn
2468
2468
  // walks fence loudly, and the value unwraps back identity-preserved
2469
2469
  // (scr_jsval_from_dyn). Monotone under evolution/widening: a value
2470
2470
  // wraps once at its first dyn edge and stays valid through every
2471
2471
  // subsequent dyn slot; narrowing never changes representation.
2472
2472
  // This wrap RETIRES the silent-wrong-answer fence-closure box for
2473
- // jsval members of DOM object literals (lowerDynObjectLiteral's
2473
+ // jsval members of dyn object literals (lowerDynObjectLiteral's
2474
2474
  // coercion lands here first).
2475
2475
  if (expected.kind === "dyn") {
2476
2476
  return { kind: "dynFromJsval", value: expr, type: DYN, loc: expr.loc };
2477
2477
  }
2478
+ // An island value flowing into a PROMISE-typed slot (the inferred
2479
+ // `loadPlugins` return — `Promise.all(...)` lowered engine-side
2480
+ // against a Promise<any[]> inference): the island→static promise
2481
+ // bridge — the engine promise settles a fresh static promise (void
2482
+ // fulfillments drop, `any[]`-declared fulfillments exit
2483
+ // Array.isArray-gated by reference at the settle, 'any' parks as an
2484
+ // island handle). Only inner shapes the bridge can deliver take the
2485
+ // arm; the rest keep the exit fence with the type named.
2486
+ if (expected.kind === "promise" &&
2487
+ (expected.inner.kind === "void" ||
2488
+ expected.inner.kind === "jsval" ||
2489
+ (expected.inner.kind === "array" && expected.inner.elem.kind === "jsval"))) {
2490
+ return { kind: "jsBridgePromise", value: expr, type: expected, loc: expr.loc };
2491
+ }
2478
2492
  // The exit set: everything round-trippable, plus bare undefined-armed
2479
2493
  // unions of JSON-safe data arms (the engine's undefined takes the
2480
2494
  // undefined arm before the JSON detour) — canExitIslandToType.
@@ -2485,10 +2499,10 @@ export class Lowerer {
2485
2499
  }
2486
2500
  // A TYPED value flowing into an 'unknown' slot (`const u: unknown = 5`,
2487
2501
  // an unknown-typed param/return, a dyn-valued index slot): the
2488
- // static→DOM conversion — dynFrom, a DEEP COPY (the jsMarshal aliasing
2502
+ // static→dyn conversion — dynFrom, a DEEP COPY (the jsMarshal aliasing
2489
2503
  // stance intoIndexValueSlot documents; SEMANTICS.md). Bare
2490
- // undefined/null literals store the DOM unit values. Types outside the
2491
- // DOM's domain (bytes, classes, Maps, ...) fall through to
2504
+ // undefined/null literals store the dyn unit values. Types outside the
2505
+ // dyn's domain (bytes, classes, Maps, ...) fall through to
2492
2506
  // requireExactShape's SC1101 fence.
2493
2507
  // A promise flowing into a VOID-promise slot (an inferred
2494
2508
  // Promise<never> return holding a `return Promise.reject(value)` the
@@ -2576,7 +2590,7 @@ export class Lowerer {
2576
2590
  // JS func-into-func mismatches ride the checked-dynamic function
2577
2591
  // boundary: box the value (dynFrom), adapt to the slot (dynCheck) —
2578
2592
  // the thunk delivers JS arity exactly (extras ignored, missing args
2579
- // the undefined DOM value), so `return _return` fits _mustCallInner's
2593
+ // the undefined dyn value), so `return _return` fits _mustCallInner's
2580
2594
  // inferred (unknown) => unknown slot even though the wrapper declares
2581
2595
  // (). JS files only: TypeScript signatures keep the exact-shape
2582
2596
  // fences (a mismatch there is a compile-time story, not a boundary).
@@ -2884,7 +2898,7 @@ export class Lowerer {
2884
2898
  * arr — array into array whose element pair lifts (per-element
2885
2899
  * copy loop, arrayWidthHelper)
2886
2900
  * dynIn — a typed value into an 'unknown' (dyn) slot — the same
2887
- * static→DOM deep copy coerceToExpected applies top-level
2901
+ * static→dyn deep copy coerceToExpected applies top-level
2888
2902
  * upcast — a derived class instance into a base-typed slot (the
2889
2903
  * prefix-layout pointer reinterpret, no copy)
2890
2904
  * funcAdapt — a function into a slot whose signature differs only by
@@ -2894,7 +2908,7 @@ export class Lowerer {
2894
2908
  widthLiftPlan(src, dst) {
2895
2909
  if (typeEquals(src, dst))
2896
2910
  return { how: "copy" };
2897
- // An 'unknown' (dyn) DESTINATION slot: the static→DOM conversion —
2911
+ // An 'unknown' (dyn) DESTINATION slot: the static→dyn conversion —
2898
2912
  // dynFrom, a DEEP COPY (`{ v: 5 }` into `{ v: unknown }`, `number[]`
2899
2913
  // into `unknown[]` — tsc's top type over the width family's copies).
2900
2914
  if (dst.kind === "dyn" && src.kind !== "dyn" && this.dynConvertible(src)) {
@@ -3156,7 +3170,7 @@ export class Lowerer {
3156
3170
  // A target field MISSING on the source: legal exactly when it is
3157
3171
  // optional-flavored (an undefined-armed union) — the unset field
3158
3172
  // IS the undefined arm, the same rule literal completion applies
3159
- // — or 'unknown' (a dyn slot holds the DOM undefined, exactly
3173
+ // — or 'unknown' (a dyn slot holds the dyn undefined, exactly
3160
3174
  // the absent-property read: the options-record call shape
3161
3175
  // against `{ plugins: unknown, ... }`). Never for tuples: a
3162
3176
  // completed position would change .length and JSON where Node
@@ -3312,7 +3326,7 @@ export class Lowerer {
3312
3326
  fields: to.fields.map((f) => {
3313
3327
  const lift = plan.get(f.name);
3314
3328
  if ("absentDyn" in lift) {
3315
- // The unset 'unknown' field: the DOM undefined — exactly
3329
+ // The unset 'unknown' field: the dyn undefined — exactly
3316
3330
  // the absent-property read's answer.
3317
3331
  return { name: f.name, value: dynUndefinedExpr(loc) };
3318
3332
  }
@@ -3897,7 +3911,7 @@ export class Lowerer {
3897
3911
  if (typeEquals(src, dst))
3898
3912
  return true;
3899
3913
  // The island boundary joins the mechanical set: values that MARSHAL
3900
- // in (units, the checked-dynamic DOM copy, JSON-safe data, liftable
3914
+ // in (units, the checked-dynamic deep copy, JSON-safe data, liftable
3901
3915
  // composites, marshalable closures — coerceToExpected's jsval-IN
3902
3916
  // block) and island handles whose exits VALIDATE (boundaryExitSafe) —
3903
3917
  // the `defaultFallback(cfg) { return { login, id, scopes } }` shape,
@@ -3982,7 +3996,7 @@ export class Lowerer {
3982
3996
  // never-called mismatched callback is exact; divergence 38's stance
3983
3997
  // extended to calls).
3984
3998
  // - voidRet "dyn"/"jsval": calling yields JS's undefined — the exact
3985
- // undefined DOM/engine value after the call's effects.
3999
+ // undefined dyn/engine value after the call's effects.
3986
4000
  // - voidRet "strand": a void result where the slot promises a typed
3987
4001
  // value — the call runs (a `never` thrower never comes back, so the
3988
4002
  // trap is unreachable there), then the stranded TypeError.
@@ -4767,7 +4781,7 @@ export class Lowerer {
4767
4781
  return { kind: "call", callee: helper, args: [e], type: JSVAL, loc };
4768
4782
  }
4769
4783
  // Checked-dynamic values and marshalable closures ride jsMarshal
4770
- // directly (the DOM deep copy / the host-function wrap).
4784
+ // directly (the checked-dynamic tree deep copy / the host-function wrap).
4771
4785
  if (e.type.kind === "dyn" || e.type.kind === "func") {
4772
4786
  return { kind: "jsMarshal", value: e, type: JSVAL, loc };
4773
4787
  }
@@ -5208,9 +5222,9 @@ export class Lowerer {
5208
5222
  }
5209
5223
  // An OBJECT LITERAL against a checked-dynamic slot in a JS file (the
5210
5224
  // getSupportInfo options argument — a dyn-ABI param): the value's
5211
- // world IS the DOM — build the DOM literal directly, before the
5225
+ // world IS the checked-dynamic tree — build the dyn literal directly, before the
5212
5226
  // island gate could claim the checker's `any` context (an island
5213
- // build could never land in the slot: no engine→DOM crossing).
5227
+ // build could never land in the slot: no engine→dyn crossing).
5214
5228
  if (expected?.kind === "dyn") {
5215
5229
  let x = node;
5216
5230
  while (ts.isParenthesizedExpression(x))
@@ -5260,7 +5274,7 @@ export class Lowerer {
5260
5274
  }
5261
5275
  /** A value flowing into an index-signature VALUE slot (an overflow
5262
5276
  * literal entry, a dynamic-keyed record write). dyn slots (`unknown`
5263
- * signatures — ModelPricing's) take a DOM conversion: dyn values pass
5277
+ * signatures — ModelPricing's) take a dyn conversion: dyn values pass
5264
5278
  * through, JSON-safe static values convert with dynFrom (a deep copy —
5265
5279
  * the jsMarshal aliasing stance), everything else keeps the dyn-boundary
5266
5280
  * fence. Typed slots ride the ordinary coercion path (union slots wrap
@@ -5270,12 +5284,12 @@ export class Lowerer {
5270
5284
  return this.coerceInto(node, value, indexValue);
5271
5285
  if (value.type.kind === "dyn")
5272
5286
  return value;
5273
- // Bare `undefined`/`null` literals store the DOM unit values (JS keeps
5287
+ // Bare `undefined`/`null` literals store the dyn unit values (JS keeps
5274
5288
  // the key; JSON.stringify drops an undefined-valued one, like Node).
5275
5289
  if (value.kind === "unitLit") {
5276
5290
  return { kind: "dynFrom", value, type: DYN, loc: value.loc };
5277
5291
  }
5278
- // An ISLAND ('any') value: the by-reference jsval→DOM wrap — the same
5292
+ // An ISLAND ('any') value: the by-reference jsval→dyn wrap — the same
5279
5293
  // edge coerceToExpected converts (dyn slots accept engine values).
5280
5294
  if (value.type.kind === "jsval") {
5281
5295
  return { kind: "dynFromJsval", value, type: DYN, loc: value.loc };
@@ -5291,13 +5305,13 @@ export class Lowerer {
5291
5305
  withUndefinedArmOf(t) {
5292
5306
  return withUndefinedArmCanonical(t, this.unions);
5293
5307
  }
5294
- /** True when a static type converts to a dyn DOM value (the dynFrom
5295
- * walker's domain): JSON-safe, bytes<u8> (Uint8Array/Buffer — the DOM's
5308
+ /** True when a static type converts to a dyn value (the dynFrom
5309
+ * walker's domain): JSON-safe, bytes<u8> (Uint8Array/Buffer — the checked-dynamic tree's
5296
5310
  * bytes kind, payload copied; stdin chunks into unknown-typed helpers),
5297
5311
  * an undefined-armed union whose other arms are JSON-safe — the
5298
- * undefined arm becomes the undefined DOM singleton — or a BOXABLE
5312
+ * undefined arm becomes the undefined dyn singleton — or a BOXABLE
5299
5313
  * function type (the checked-dynamic function boundary: the closure
5300
- * crosses as the DOM's callable kind, identity preserved). */
5314
+ * crosses as the checked-dynamic tree's callable kind, identity preserved). */
5301
5315
  dynConvertible(t) {
5302
5316
  return canConvertToDyn(t, (id) => this.shapes.get(id), (id) => this.unions.get(id));
5303
5317
  }
@@ -5800,7 +5814,7 @@ export class Lowerer {
5800
5814
  if (abi.kind === "dyn" || abi.kind === "jsval") {
5801
5815
  // A DYNAMIC-TIER pattern source (`function f({} = a)` with
5802
5816
  // `a: any` — jsval for island values, dyn for the checked-
5803
- // dynamic DOM): the slot holds its tier's undefined directly,
5817
+ // dynamic dyn): the slot holds its tier's undefined directly,
5804
5818
  // so the default test is the runtime undefined test — then
5805
5819
  // the pattern destructures the picked value.
5806
5820
  const dflt = this.lowerExprExpecting(decl.initializer, abi);
@@ -5868,7 +5882,7 @@ export class Lowerer {
5868
5882
  if (abi.kind === "dyn" || abi.kind === "jsval") {
5869
5883
  // A DYNAMIC-TIER defaulted param (`function f(x = a)` with
5870
5884
  // `a: any` — jsval for island values, dyn for the checked-
5871
- // dynamic DOM): the slot holds its tier's undefined directly —
5885
+ // dynamic dyn): the slot holds its tier's undefined directly —
5872
5886
  // the body local picks the default on the runtime test.
5873
5887
  const loc = locOf(decl);
5874
5888
  const slot = this.declareHiddenLocal(name, abi);
@@ -6053,7 +6067,7 @@ export class Lowerer {
6053
6067
  continue;
6054
6068
  // dyn captures ride an UNTRACED obj-box (scr_dyn_retain_v/release_v
6055
6069
  // — boxNewC): the mustCall wrapper closing over its implicit-any
6056
- // `fn` param. A DOM tree is pure data except the function kind,
6070
+ // `fn` param. A dyn tree is pure data except the function kind,
6057
6071
  // whose closure edge the collector never sees — cycles through a
6058
6072
  // captured dyn are uncollectable (leak, never dangle: trial
6059
6073
  // deletion treats untraced edges as external roots). SEMANTICS.md.
@@ -6388,7 +6402,7 @@ export class Lowerer {
6388
6402
  // The CHECKED-DYNAMIC twin of the handle rescue (the runtime-world
6389
6403
  // local rule): an unmappable declared type over a dyn initializer
6390
6404
  // (`const first = plugins[0]` — the checker spells 'string |
6391
- // object' while the read is a DOM keyed read) keeps the binding
6405
+ // object' while the read is a dyn keyed read) keeps the binding
6392
6406
  // dyn; typed use sites ride validated extractions and the routed
6393
6407
  // engine ops, exactly the JSON.parse-binding story.
6394
6408
  if (mapped === null && init.type.kind === "dyn") {