@scriptc/compiler 0.1.2 → 0.1.4

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 (206) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +258 -64
  2. package/dist/backend/c/async.d.ts +30 -0
  3. package/dist/backend/c/async.js +224 -0
  4. package/dist/backend/c/async.js.map +1 -1
  5. package/dist/backend/c/c-emitter.d.ts +13 -0
  6. package/dist/backend/c/c-emitter.js +28 -9
  7. package/dist/backend/c/c-emitter.js.map +1 -1
  8. package/dist/backend/c/exprs.d.ts +8 -1
  9. package/dist/backend/c/exprs.js +445 -60
  10. package/dist/backend/c/exprs.js.map +1 -1
  11. package/dist/backend/c/shapes.js +15 -13
  12. package/dist/backend/c/shapes.js.map +1 -1
  13. package/dist/backend/c/types.d.ts +4 -0
  14. package/dist/backend/c/types.js +20 -1
  15. package/dist/backend/c/types.js.map +1 -1
  16. package/dist/backend/c/types.test.js +8 -1
  17. package/dist/backend/c/types.test.js.map +1 -1
  18. package/dist/backend/c/walkers.js +32 -11
  19. package/dist/backend/c/walkers.js.map +1 -1
  20. package/dist/backend/json-literal.d.ts +7 -0
  21. package/dist/backend/json-literal.js +17 -0
  22. package/dist/backend/json-literal.js.map +1 -0
  23. package/dist/backend/json-literal.test.d.ts +1 -0
  24. package/dist/backend/json-literal.test.js +17 -0
  25. package/dist/backend/json-literal.test.js.map +1 -0
  26. package/dist/backend/link-plan.d.ts +2 -1
  27. package/dist/backend/link-plan.js +6 -1
  28. package/dist/backend/link-plan.js.map +1 -1
  29. package/dist/backend/llvm/classes.js +8 -7
  30. package/dist/backend/llvm/classes.js.map +1 -1
  31. package/dist/backend/llvm/common.d.ts +4 -0
  32. package/dist/backend/llvm/common.js +6 -0
  33. package/dist/backend/llvm/common.js.map +1 -1
  34. package/dist/backend/llvm/common.test.d.ts +1 -0
  35. package/dist/backend/llvm/common.test.js +9 -0
  36. package/dist/backend/llvm/common.test.js.map +1 -0
  37. package/dist/backend/llvm/dyn.d.ts +4 -0
  38. package/dist/backend/llvm/dyn.js +24 -13
  39. package/dist/backend/llvm/dyn.js.map +1 -1
  40. package/dist/backend/llvm/emitter.js +54 -12
  41. package/dist/backend/llvm/emitter.js.map +1 -1
  42. package/dist/backend/llvm/expr-bytes.d.ts +1 -1
  43. package/dist/backend/llvm/expr-bytes.js +8 -8
  44. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  45. package/dist/backend/llvm/expr-callbacks.d.ts +9 -0
  46. package/dist/backend/llvm/expr-callbacks.js +125 -0
  47. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  48. package/dist/backend/llvm/expr-context.d.ts +18 -2
  49. package/dist/backend/llvm/expr-dispatch.js +1 -0
  50. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  51. package/dist/backend/llvm/expr-dynamic.js +9 -0
  52. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  53. package/dist/backend/llvm/expr-primitives.d.ts +1 -1
  54. package/dist/backend/llvm/expr-primitives.js +38 -9
  55. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  56. package/dist/backend/llvm/expr-primitives.test.d.ts +1 -0
  57. package/dist/backend/llvm/expr-primitives.test.js +38 -0
  58. package/dist/backend/llvm/expr-primitives.test.js.map +1 -0
  59. package/dist/backend/llvm/expr-records.js +3 -3
  60. package/dist/backend/llvm/expr-records.js.map +1 -1
  61. package/dist/backend/llvm/expr-stream-bridges.js +2 -1
  62. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  63. package/dist/backend/llvm/expr-stream-callbacks.d.ts +6 -0
  64. package/dist/backend/llvm/expr-stream-callbacks.js +122 -0
  65. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  66. package/dist/backend/llvm/lib-dispatch.js +22 -0
  67. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  68. package/dist/backend/llvm/lib-filesystem.js +68 -10
  69. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  70. package/dist/backend/llvm/lib-network.js +18 -2
  71. package/dist/backend/llvm/lib-network.js.map +1 -1
  72. package/dist/backend/llvm/lib-process.js +206 -11
  73. package/dist/backend/llvm/lib-process.js.map +1 -1
  74. package/dist/backend/llvm/lib-shared.js +82 -0
  75. package/dist/backend/llvm/lib-shared.js.map +1 -1
  76. package/dist/backend/llvm/lib-stream.js +23 -0
  77. package/dist/backend/llvm/lib-stream.js.map +1 -1
  78. package/dist/backend/llvm/shapes.js +10 -8
  79. package/dist/backend/llvm/shapes.js.map +1 -1
  80. package/dist/backend/llvm/walkers.js +7 -5
  81. package/dist/backend/llvm/walkers.js.map +1 -1
  82. package/dist/backend/native-link-info.d.ts +2 -1
  83. package/dist/backend/native-link-info.js +4 -0
  84. package/dist/backend/native-link-info.js.map +1 -1
  85. package/dist/backend/native-link-info.test.js +24 -1
  86. package/dist/backend/native-link-info.test.js.map +1 -1
  87. package/dist/backend/native-toolchain.d.ts +11 -6
  88. package/dist/backend/native-toolchain.js +30 -13
  89. package/dist/backend/native-toolchain.js.map +1 -1
  90. package/dist/backend/native-toolchain.test.js +36 -1
  91. package/dist/backend/native-toolchain.test.js.map +1 -1
  92. package/dist/backend/runtime-pack-targets.test.js +1 -1
  93. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  94. package/dist/backend/runtime-pack.test.js +29 -10
  95. package/dist/backend/runtime-pack.test.js.map +1 -1
  96. package/dist/backend/targets.d.ts +9 -0
  97. package/dist/backend/targets.js +22 -0
  98. package/dist/backend/targets.js.map +1 -1
  99. package/dist/backend/targets.test.js +13 -1
  100. package/dist/backend/targets.test.js.map +1 -1
  101. package/dist/coverage/surface-manifest.js +9 -0
  102. package/dist/coverage/surface-manifest.js.map +1 -1
  103. package/dist/diagnostics/diagnostic.js +4 -4
  104. package/dist/diagnostics/diagnostic.js.map +1 -1
  105. package/dist/executable/executable-cache.d.ts +3 -0
  106. package/dist/executable/executable-cache.js +4 -0
  107. package/dist/executable/executable-cache.js.map +1 -1
  108. package/dist/executable/executable-cache.test.js +1 -0
  109. package/dist/executable/executable-cache.test.js.map +1 -1
  110. package/dist/frontend/fork-target.d.ts +17 -0
  111. package/dist/frontend/fork-target.js +256 -0
  112. package/dist/frontend/fork-target.js.map +1 -0
  113. package/dist/frontend/lowering/abstract-equality.d.ts +6 -0
  114. package/dist/frontend/lowering/abstract-equality.js +250 -0
  115. package/dist/frontend/lowering/abstract-equality.js.map +1 -0
  116. package/dist/frontend/lowering/containers/bytes.d.ts +0 -4
  117. package/dist/frontend/lowering/containers/bytes.js +112 -28
  118. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  119. package/dist/frontend/lowering/lower-assert.js +87 -12
  120. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  121. package/dist/frontend/lowering/lower-builtins.d.ts +72 -44
  122. package/dist/frontend/lowering/lower-builtins.js +1323 -165
  123. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  124. package/dist/frontend/lowering/lower-calls.d.ts +37 -27
  125. package/dist/frontend/lowering/lower-calls.js +682 -132
  126. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  127. package/dist/frontend/lowering/lower-classes.js +39 -8
  128. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  129. package/dist/frontend/lowering/lower-containers.js +162 -8
  130. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  131. package/dist/frontend/lowering/lower-event-emitter.js +212 -21
  132. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  133. package/dist/frontend/lowering/lower-exprs.js +238 -87
  134. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  135. package/dist/frontend/lowering/lower-inspect.d.ts +4 -0
  136. package/dist/frontend/lowering/lower-inspect.js +8 -1
  137. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  138. package/dist/frontend/lowering/lower-island.d.ts +6 -3
  139. package/dist/frontend/lowering/lower-island.js +165 -6
  140. package/dist/frontend/lowering/lower-island.js.map +1 -1
  141. package/dist/frontend/lowering/lower-modules.d.ts +6 -0
  142. package/dist/frontend/lowering/lower-modules.js +192 -38
  143. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  144. package/dist/frontend/lowering/lower-namespaces.js +7 -0
  145. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  146. package/dist/frontend/lowering/lower-server.d.ts +1 -1
  147. package/dist/frontend/lowering/lower-server.js +130 -27
  148. package/dist/frontend/lowering/lower-server.js.map +1 -1
  149. package/dist/frontend/lowering/lower-stmts.d.ts +5 -4
  150. package/dist/frontend/lowering/lower-stmts.js +141 -21
  151. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  152. package/dist/frontend/lowering/lower-stream.d.ts +3 -0
  153. package/dist/frontend/lowering/lower-stream.js +7 -0
  154. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  155. package/dist/frontend/lowering/lowerer.d.ts +90 -13
  156. package/dist/frontend/lowering/lowerer.js +416 -76
  157. package/dist/frontend/lowering/lowerer.js.map +1 -1
  158. package/dist/frontend/lowering/surfaces.d.ts +31 -3
  159. package/dist/frontend/lowering/surfaces.js +173 -90
  160. package/dist/frontend/lowering/surfaces.js.map +1 -1
  161. package/dist/frontend/npm-static-declarations.d.ts +4 -0
  162. package/dist/frontend/npm-static-declarations.js +83 -14
  163. package/dist/frontend/npm-static-declarations.js.map +1 -1
  164. package/dist/frontend/npm-static-declarations.test.js +33 -2
  165. package/dist/frontend/npm-static-declarations.test.js.map +1 -1
  166. package/dist/frontend/npm-static.js +6 -5
  167. package/dist/frontend/npm-static.js.map +1 -1
  168. package/dist/frontend/npm.d.ts +15 -3
  169. package/dist/frontend/npm.js +80 -8
  170. package/dist/frontend/npm.js.map +1 -1
  171. package/dist/frontend/npm.test.js +76 -9
  172. package/dist/frontend/npm.test.js.map +1 -1
  173. package/dist/frontend/program.js +110 -12
  174. package/dist/frontend/program.js.map +1 -1
  175. package/dist/frontend/resolve.d.ts +28 -7
  176. package/dist/frontend/resolve.js +90 -26
  177. package/dist/frontend/resolve.js.map +1 -1
  178. package/dist/frontend/resolve.test.js +21 -1
  179. package/dist/frontend/resolve.test.js.map +1 -1
  180. package/dist/frontend/type-mapper.d.ts +5 -0
  181. package/dist/frontend/type-mapper.js +115 -33
  182. package/dist/frontend/type-mapper.js.map +1 -1
  183. package/dist/index.d.ts +5 -0
  184. package/dist/index.js +30 -3
  185. package/dist/index.js.map +1 -1
  186. package/dist/ir/analysis.js +1 -0
  187. package/dist/ir/analysis.js.map +1 -1
  188. package/dist/ir/ir.d.ts +155 -66
  189. package/dist/ir/ir.js +143 -6
  190. package/dist/ir/ir.js.map +1 -1
  191. package/dist/ir/ir.test.js +14 -1
  192. package/dist/ir/ir.test.js.map +1 -1
  193. package/dist/ir/serialize.d.ts +1 -1
  194. package/dist/ir/serialize.js +1 -1
  195. package/dist/ir/serialize.js.map +1 -1
  196. package/dist/ir/validate.js +242 -18
  197. package/dist/ir/validate.js.map +1 -1
  198. package/dist/library/int-infer.test.js +4 -4
  199. package/dist/library/int-infer.test.js.map +1 -1
  200. package/dist/library/library-cache.d.ts +1 -0
  201. package/dist/library/library-cache.js +1 -0
  202. package/dist/library/library-cache.js.map +1 -1
  203. package/dist/library/library-cache.test.js +18 -5
  204. package/dist/library/library-cache.test.js.map +1 -1
  205. package/package.json +17 -17
  206. package/surface-manifest.json +163 -54
@@ -95,6 +95,11 @@ export function lowerArrayMethodCall(lowerer, call, access) {
95
95
  probedUntyped = true;
96
96
  }
97
97
  }
98
+ if (receiverIr?.kind === "union") {
99
+ const unionHof = lowerArrayUnionHofCall(lowerer, call, access, receiverIr);
100
+ if (unionHof)
101
+ return unionHof;
102
+ }
98
103
  if (receiverIr?.kind !== "array")
99
104
  return null;
100
105
  if (!probedUntyped && !lowerer.isStdlibMember(access))
@@ -541,7 +546,7 @@ function lowerArraySearchCall(lowerer, call, access, method, elem) {
541
546
  }
542
547
  // Preserve the existing fast path for an ordinary, non-union needle. Its
543
548
  // runtime implementation already has exact primitive/reference equality.
544
- if (elem.kind !== "union" && typeEquals(needle.type, elem)) {
549
+ if (elem.kind !== "union" && elem.kind !== "bigint" && typeEquals(needle.type, elem)) {
545
550
  return {
546
551
  kind: "arrIntrinsic",
547
552
  method,
@@ -828,6 +833,18 @@ function hofCallbackArg(lowerer, argNode, lead, arrT, bindUntyped = false) {
828
833
  }
829
834
  lowerer.implicitParamTypes = previousImplicit;
830
835
  }
836
+ // Array storage widens indexed reads with undefined so holes remain
837
+ // observable. The HOF helper guards every callback behind arrayHas,
838
+ // so an exact-ABI builtin closure may safely adapt from its declared
839
+ // parameter to that guarded union. Keep this exception scoped to the
840
+ // compiler-generated builtin values; ordinary callback-value policy is
841
+ // unchanged.
842
+ if (fnArg.type.kind === "func" && lowerer.isBuiltinCallableValue(fnArg)) {
843
+ const callbackType = funcOf(full.slice(0, fnArg.type.params.length), fnArg.type.ret);
844
+ if (!typeEquals(fnArg.type, callbackType)) {
845
+ fnArg = lowerer.coerceToExpected(fnArg, callbackType);
846
+ }
847
+ }
831
848
  if (fnArg.type.kind !== "func" ||
832
849
  fnArg.type.params.length > full.length ||
833
850
  !fnArg.type.params.every((p, i) => typeEquals(p, full[i]))) {
@@ -986,8 +1003,9 @@ function truthyFilterCallback(lowerer, valueT, loc) {
986
1003
  }
987
1004
  /** The predicate result kinds `.filter()` accepts. JS applies ToBoolean to
988
1005
  * whatever the callback answers, so a bool is not required: the scalars and
989
- * the reference kinds have constant or by-value answers, and a union is fine
990
- * when every arm does. void/dyn/jsval/caught stay out — see below. */
1006
+ * the reference kinds have constant or by-value answers, checked-dynamic
1007
+ * values ask their runtime kind, and a union is fine when every arm does.
1008
+ * void/jsval/caught stay out — see below. */
991
1009
  function filterPredicateOk(lowerer, ret) {
992
1010
  if (ret.kind === "bool")
993
1011
  return true;
@@ -997,10 +1015,13 @@ function filterPredicateOk(lowerer, ret) {
997
1015
  // compiled ABI has already discarded it. Treating void as constantly
998
1016
  // falsy would silently answer [] where Node answers [1]. Fenced until
999
1017
  // the returned value can be preserved through the void ABI.
1000
- // dyn/jsval/caught stay out too: no native ToBoolean to compile against.
1018
+ // A checked-dynamic value retains its runtime kind, so scr_dyn_truthy can
1019
+ // apply JavaScript ToBoolean exactly. Island and caught values stay out.
1001
1020
  if (ret.kind === "void")
1002
1021
  return false;
1003
- if (ret.kind === "dyn" || ret.kind === "jsval" || ret.kind === "caught")
1022
+ if (ret.kind === "dyn")
1023
+ return true;
1024
+ if (ret.kind === "jsval" || ret.kind === "caught")
1004
1025
  return false;
1005
1026
  if (ret.kind === "union") {
1006
1027
  const def = lowerer.unions.get(ret.unionId);
@@ -1020,9 +1041,9 @@ function filterCond(call, fnRet, loc) {
1020
1041
  // `void` returns to void and a standalone `null` return to the unit-ONLY
1021
1042
  // UNION, which routes through toBool below; ir/validate.ts rejects a
1022
1043
  // bare unit return type outright). filterPredicateOk already rejected
1023
- // the arms with no native ToBoolean (dyn/caught) — which is exactly what
1024
- // requireTruthyUnion checks — and it did so at the call site, where a
1025
- // real node exists for the diagnostic.
1044
+ // unsafe union arms (dyn/caught) at the call site, where a real node
1045
+ // exists for the diagnostic. A bare dyn value is handled directly by
1046
+ // the runtime's kind-aware ToBoolean.
1026
1047
  return { kind: "toBool", operand: call, type: BOOL, loc };
1027
1048
  }
1028
1049
  /** Interned synthetic loop function for one (method, elem, fnRet, arity)
@@ -1039,6 +1060,139 @@ function arrayHofHelper(lowerer, method, elem, fnRet, arity, loc, outElem = fnRe
1039
1060
  lowerer.liftedFns.push(buildArrayHofFn(lowerer, name, method, elem, fnRet, arity, loc, outElem));
1040
1061
  return name;
1041
1062
  }
1063
+ /** The TS 5.2+ callable-union array rule: a `T[] | U[]` receiver exposes
1064
+ * common HOFs with a callback over `T | U`. The runtime value remains the
1065
+ * original concrete array arm — never a copied `(T | U)[]` — and an
1066
+ * arm-specific function adapter wraps the element and receiver arguments
1067
+ * into the union-wide callback ABI. That preserves sparse-array reads,
1068
+ * callback mutation, and the callback's third-argument identity. */
1069
+ function lowerArrayUnionHofCall(lowerer, call, access, receiverT) {
1070
+ const method = access.name.text;
1071
+ if (method !== "map" && method !== "forEach")
1072
+ return null;
1073
+ if (!lowerer.isStdlibMember(access))
1074
+ return null;
1075
+ const def = lowerer.unions.get(receiverT.unionId);
1076
+ if (!def || def.arms.length < 2 || !def.arms.every((arm) => arm.kind === "array"))
1077
+ return null;
1078
+ if (call.arguments.length !== 1 || !call.arguments[0])
1079
+ return null;
1080
+ const arrays = def.arms;
1081
+ const valueArms = [];
1082
+ const addValueArm = (type) => {
1083
+ if (type.kind === "dyn" || type.kind === "jsval" || type.kind === "caught" || type.kind === "void")
1084
+ return false;
1085
+ if (type.kind === "union") {
1086
+ const inner = lowerer.unions.get(type.unionId);
1087
+ if (!inner)
1088
+ return false;
1089
+ for (const arm of inner.arms) {
1090
+ if (!valueArms.some((candidate) => typeEquals(candidate, arm)))
1091
+ valueArms.push(arm);
1092
+ }
1093
+ return true;
1094
+ }
1095
+ if (!valueArms.some((candidate) => typeEquals(candidate, type)))
1096
+ valueArms.push(type);
1097
+ return true;
1098
+ };
1099
+ for (const array of arrays) {
1100
+ if (!addValueArm(array.elem))
1101
+ return null;
1102
+ }
1103
+ const valueT = valueArms.length === 1
1104
+ ? valueArms[0]
1105
+ : { kind: "union", unionId: lowerer.unions.intern(valueArms) };
1106
+ const argNode = call.arguments[0];
1107
+ const { fnArg, arity } = hofCallbackArg(lowerer, argNode, [valueT], receiverT);
1108
+ const fnRet = fnArg.type.ret;
1109
+ if (method === "map" && (fnRet.kind === "void" || fnRet.kind === "func")) {
1110
+ lowerer.badType(call, lowerer.typeOf(call));
1111
+ }
1112
+ if (method === "map")
1113
+ fenceProducedArrayElem(lowerer, call, "'.map()'", fnRet);
1114
+ const outElem = method === "map" ? callbackArrayElem(lowerer, call, fnRet) : VOID;
1115
+ const resultT = method === "map" ? arrayOf(outElem) : VOID;
1116
+ for (const array of arrays) {
1117
+ const armFnT = funcOf([arrayValueType(lowerer, array.elem), F64, array].slice(0, arity), fnRet);
1118
+ if (!lowerer.cleanFuncAdaptable(fnArg.type, armFnT))
1119
+ return null;
1120
+ }
1121
+ const helper = arrayUnionHofHelper(lowerer, method, receiverT, arrays, fnArg.type, arity, fnRet, outElem, locOf(call));
1122
+ return {
1123
+ kind: "call",
1124
+ callee: helper,
1125
+ args: [lowerer.coerceInto(access.expression, lowerer.lowerExpr(access.expression), receiverT), fnArg],
1126
+ type: resultT,
1127
+ loc: locOf(call),
1128
+ };
1129
+ }
1130
+ function arrayUnionHofHelper(lowerer, method, receiverT, arrays, callbackT, arity, fnRet, outElem, loc) {
1131
+ const resultT = method === "map" ? arrayOf(outElem) : VOID;
1132
+ const key = `union:${method}:${receiverT.unionId}:${typeKey(callbackT)}:${typeKey(resultT)}`;
1133
+ const existing = lowerer.arrHofHelpers.get(key);
1134
+ if (existing)
1135
+ return existing;
1136
+ const name = `%arr.union.${lowerer.arrHofHelpers.size}`;
1137
+ lowerer.arrHofHelpers.set(key, name);
1138
+ const receiver = varRef("a.0", receiverT, loc);
1139
+ const callback = varRef("f.0", callbackT, loc);
1140
+ const branch = (array) => {
1141
+ const tag = lowerer.armTag(receiverT.unionId, array);
1142
+ const concrete = {
1143
+ kind: "unionNarrow",
1144
+ unionId: receiverT.unionId,
1145
+ tag,
1146
+ value: receiver,
1147
+ type: array,
1148
+ loc,
1149
+ };
1150
+ const armFnT = funcOf([arrayValueType(lowerer, array.elem), F64, array].slice(0, arity), fnRet);
1151
+ const adapted = lowerer.coerceToExpected(callback, armFnT);
1152
+ if (!typeEquals(adapted.type, armFnT)) {
1153
+ throw new InternalCompilerError("lowerer bug: union-array callback stopped adapting");
1154
+ }
1155
+ const callee = arrayHofHelper(lowerer, method, array.elem, fnRet, arity, loc, outElem);
1156
+ const invoke = { kind: "call", callee, args: [concrete, adapted], type: resultT, loc };
1157
+ return resultT.kind === "void"
1158
+ ? [{ kind: "exprStmt", expr: invoke, loc }, { kind: "return", value: null, loc }]
1159
+ : [{ kind: "return", value: invoke, loc }];
1160
+ };
1161
+ let body = branch(arrays[arrays.length - 1]);
1162
+ for (let i = arrays.length - 2; i >= 0; i--) {
1163
+ const array = arrays[i];
1164
+ body = [{
1165
+ kind: "if",
1166
+ cond: {
1167
+ kind: "unionIsTag",
1168
+ unionId: receiverT.unionId,
1169
+ tag: lowerer.armTag(receiverT.unionId, array),
1170
+ negated: false,
1171
+ value: receiver,
1172
+ type: BOOL,
1173
+ loc,
1174
+ },
1175
+ then: branch(array),
1176
+ else_: body,
1177
+ loc,
1178
+ }];
1179
+ }
1180
+ lowerer.liftedFns.push({
1181
+ name,
1182
+ params: [
1183
+ { localId: "a.0", name: "a", type: receiverT },
1184
+ { localId: "f.0", name: "f", type: callbackT },
1185
+ ],
1186
+ returnType: resultT,
1187
+ locals: [
1188
+ { id: "a.0", name: "a", type: receiverT, mutable: false },
1189
+ { id: "f.0", name: "f", type: callbackT, mutable: false },
1190
+ ],
1191
+ body,
1192
+ loc,
1193
+ });
1194
+ return name;
1195
+ }
1042
1196
  /** READ-ONLY array methods on TUPLE receivers — `t.slice(...)` and
1043
1197
  * `t.map(f)`: a tuple is a fixed-shape record, but these methods never
1044
1198
  * write, so the positions snapshot into a fresh array (the for-of-over-