@scriptc/compiler 0.1.7 → 0.2.1

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 (1043) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +98 -39
  2. package/ambient/scriptc-overrides.d.ts +10 -6
  3. package/ambient/scriptc.d.ts +15 -0
  4. package/dist/backend/build-cache.d.ts +1 -3
  5. package/dist/backend/build-cache.js +3 -22
  6. package/dist/backend/build-cache.js.map +1 -1
  7. package/dist/backend/cache-root.d.ts +3 -0
  8. package/dist/backend/cache-root.js +23 -0
  9. package/dist/backend/cache-root.js.map +1 -0
  10. package/dist/backend/cycle-analysis.d.ts +15 -0
  11. package/dist/backend/cycle-analysis.js +108 -0
  12. package/dist/backend/cycle-analysis.js.map +1 -0
  13. package/dist/backend/cycle-analysis.test.js +124 -0
  14. package/dist/backend/cycle-analysis.test.js.map +1 -0
  15. package/dist/backend/executable-features.d.ts +4 -0
  16. package/dist/backend/executable-features.js +42 -0
  17. package/dist/backend/executable-features.js.map +1 -0
  18. package/dist/backend/external-c.d.ts +5 -27
  19. package/dist/backend/external-c.js +5 -40
  20. package/dist/backend/external-c.js.map +1 -1
  21. package/dist/backend/ffi-callbacks.d.ts +2 -3
  22. package/dist/backend/ffi-callbacks.js +2 -3
  23. package/dist/backend/ffi-callbacks.js.map +1 -1
  24. package/dist/backend/library-identity-markers.d.ts +4 -9
  25. package/dist/backend/library-identity-markers.js +11 -49
  26. package/dist/backend/library-identity-markers.js.map +1 -1
  27. package/dist/backend/library-pack.d.ts +5 -0
  28. package/dist/backend/library-pack.js +123 -0
  29. package/dist/backend/library-pack.js.map +1 -0
  30. package/dist/backend/link-plan-core.d.ts +20 -0
  31. package/dist/backend/link-plan-core.js +18 -0
  32. package/dist/backend/link-plan-core.js.map +1 -0
  33. package/dist/backend/link-plan.d.ts +1 -1
  34. package/dist/backend/link-plan.js +16 -17
  35. package/dist/backend/link-plan.js.map +1 -1
  36. package/dist/backend/link-trace.d.ts +2 -0
  37. package/dist/backend/link-trace.js +24 -0
  38. package/dist/backend/link-trace.js.map +1 -0
  39. package/dist/backend/linker.js +1 -1
  40. package/dist/backend/linker.js.map +1 -1
  41. package/dist/backend/literals.d.ts +9 -0
  42. package/dist/backend/literals.js +35 -0
  43. package/dist/backend/literals.js.map +1 -0
  44. package/dist/backend/literals.test.d.ts +1 -0
  45. package/dist/backend/literals.test.js +53 -0
  46. package/dist/backend/literals.test.js.map +1 -0
  47. package/dist/backend/llvm/blocks.d.ts +2 -0
  48. package/dist/backend/llvm/blocks.js +9 -4
  49. package/dist/backend/llvm/blocks.js.map +1 -1
  50. package/dist/backend/llvm/blocks.test.d.ts +1 -0
  51. package/dist/backend/llvm/blocks.test.js +91 -0
  52. package/dist/backend/llvm/blocks.test.js.map +1 -0
  53. package/dist/backend/llvm/classes.d.ts +14 -8
  54. package/dist/backend/llvm/classes.js +88 -30
  55. package/dist/backend/llvm/classes.js.map +1 -1
  56. package/dist/backend/llvm/common.d.ts +5 -1
  57. package/dist/backend/llvm/common.js +45 -4
  58. package/dist/backend/llvm/common.js.map +1 -1
  59. package/dist/backend/llvm/debug-info.js +2 -7
  60. package/dist/backend/llvm/debug-info.js.map +1 -1
  61. package/dist/backend/llvm/debug-info.test.d.ts +1 -0
  62. package/dist/backend/llvm/debug-info.test.js +110 -0
  63. package/dist/backend/llvm/debug-info.test.js.map +1 -0
  64. package/dist/backend/llvm/dyn.d.ts +21 -2
  65. package/dist/backend/llvm/dyn.js +647 -251
  66. package/dist/backend/llvm/dyn.js.map +1 -1
  67. package/dist/backend/llvm/emitter.d.ts +596 -1
  68. package/dist/backend/llvm/emitter.js +769 -425
  69. package/dist/backend/llvm/emitter.js.map +1 -1
  70. package/dist/backend/llvm/emitter.test.d.ts +1 -0
  71. package/dist/backend/llvm/emitter.test.js +179 -0
  72. package/dist/backend/llvm/emitter.test.js.map +1 -0
  73. package/dist/backend/llvm/expr-async.js +23 -14
  74. package/dist/backend/llvm/expr-async.js.map +1 -1
  75. package/dist/backend/llvm/expr-bytes.d.ts +2 -2
  76. package/dist/backend/llvm/expr-bytes.js +60 -31
  77. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  78. package/dist/backend/llvm/expr-callbacks.d.ts +1 -1
  79. package/dist/backend/llvm/expr-callbacks.js +25 -22
  80. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  81. package/dist/backend/llvm/expr-calls.js +136 -35
  82. package/dist/backend/llvm/expr-calls.js.map +1 -1
  83. package/dist/backend/llvm/expr-containers.d.ts +1 -1
  84. package/dist/backend/llvm/expr-containers.js +43 -14
  85. package/dist/backend/llvm/expr-containers.js.map +1 -1
  86. package/dist/backend/llvm/expr-context.d.ts +5 -260
  87. package/dist/backend/llvm/expr-control.js +10 -6
  88. package/dist/backend/llvm/expr-control.js.map +1 -1
  89. package/dist/backend/llvm/expr-dispatch.d.ts +1 -1
  90. package/dist/backend/llvm/expr-dispatch.js +2 -0
  91. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  92. package/dist/backend/llvm/expr-dynamic.js +78 -81
  93. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  94. package/dist/backend/llvm/expr-island.d.ts +1 -1
  95. package/dist/backend/llvm/expr-island.js +11 -7
  96. package/dist/backend/llvm/expr-island.js.map +1 -1
  97. package/dist/backend/llvm/expr-primitives.d.ts +1 -1
  98. package/dist/backend/llvm/expr-primitives.js +62 -31
  99. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  100. package/dist/backend/llvm/expr-primitives.test.js +1 -1
  101. package/dist/backend/llvm/expr-records.d.ts +5 -1
  102. package/dist/backend/llvm/expr-records.js +54 -7
  103. package/dist/backend/llvm/expr-records.js.map +1 -1
  104. package/dist/backend/llvm/expr-stream-bridges.d.ts +4 -4
  105. package/dist/backend/llvm/expr-stream-bridges.js +220 -131
  106. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  107. package/dist/backend/llvm/expr-stream-bridges.test.d.ts +1 -0
  108. package/dist/backend/llvm/expr-stream-bridges.test.js +55 -0
  109. package/dist/backend/llvm/expr-stream-bridges.test.js.map +1 -0
  110. package/dist/backend/llvm/expr-stream-callbacks.d.ts +1 -1
  111. package/dist/backend/llvm/expr-stream-callbacks.js +12 -12
  112. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  113. package/dist/backend/llvm/layouts.d.ts +19 -0
  114. package/dist/backend/llvm/layouts.js +12 -0
  115. package/dist/backend/llvm/layouts.js.map +1 -0
  116. package/dist/backend/llvm/lib-abi.d.ts +19 -0
  117. package/dist/backend/llvm/lib-abi.js +82 -0
  118. package/dist/backend/llvm/lib-abi.js.map +1 -0
  119. package/dist/backend/llvm/lib-connect.d.ts +2 -0
  120. package/dist/backend/llvm/lib-connect.js +51 -0
  121. package/dist/backend/llvm/lib-connect.js.map +1 -0
  122. package/dist/backend/llvm/lib-datagram.d.ts +2 -0
  123. package/dist/backend/llvm/lib-datagram.js +135 -0
  124. package/dist/backend/llvm/lib-datagram.js.map +1 -0
  125. package/dist/backend/llvm/lib-dispatch.js +50 -6
  126. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  127. package/dist/backend/llvm/lib-filesystem.js +30 -18
  128. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  129. package/dist/backend/llvm/lib-http2.d.ts +2 -0
  130. package/dist/backend/llvm/lib-http2.js +215 -0
  131. package/dist/backend/llvm/lib-http2.js.map +1 -0
  132. package/dist/backend/llvm/lib-lookup.d.ts +2 -0
  133. package/dist/backend/llvm/lib-lookup.js +39 -0
  134. package/dist/backend/llvm/lib-lookup.js.map +1 -0
  135. package/dist/backend/llvm/lib-network.js +25 -2
  136. package/dist/backend/llvm/lib-network.js.map +1 -1
  137. package/dist/backend/llvm/lib-process.js +44 -19
  138. package/dist/backend/llvm/lib-process.js.map +1 -1
  139. package/dist/backend/llvm/lib-shared.js +162 -3
  140. package/dist/backend/llvm/lib-shared.js.map +1 -1
  141. package/dist/backend/llvm/lib-stream.js +3 -2
  142. package/dist/backend/llvm/lib-stream.js.map +1 -1
  143. package/dist/backend/llvm/lib-test.d.ts +2 -0
  144. package/dist/backend/llvm/lib-test.js +34 -0
  145. package/dist/backend/llvm/lib-test.js.map +1 -0
  146. package/dist/backend/llvm/lib-tls.d.ts +2 -0
  147. package/dist/backend/llvm/lib-tls.js +82 -0
  148. package/dist/backend/llvm/lib-tls.js.map +1 -0
  149. package/dist/backend/llvm/shapes.d.ts +10 -9
  150. package/dist/backend/llvm/shapes.js +42 -131
  151. package/dist/backend/llvm/shapes.js.map +1 -1
  152. package/dist/backend/llvm/unsupported.d.ts +1 -0
  153. package/dist/backend/llvm/unsupported.js +1 -2
  154. package/dist/backend/llvm/unsupported.js.map +1 -1
  155. package/dist/backend/llvm/walkers.js +1 -7
  156. package/dist/backend/llvm/walkers.js.map +1 -1
  157. package/dist/backend/mangle.d.ts +2 -2
  158. package/dist/backend/mangle.js +16 -5
  159. package/dist/backend/mangle.js.map +1 -1
  160. package/dist/backend/{c/may-throw.d.ts → may-throw.d.ts} +1 -1
  161. package/dist/backend/{c/may-throw.js → may-throw.js} +51 -46
  162. package/dist/backend/may-throw.js.map +1 -0
  163. package/dist/backend/may-throw.test.d.ts +1 -0
  164. package/dist/backend/may-throw.test.js +58 -0
  165. package/dist/backend/may-throw.test.js.map +1 -0
  166. package/dist/backend/native-codegen-core.d.ts +22 -0
  167. package/dist/backend/native-codegen-core.js +44 -0
  168. package/dist/backend/native-codegen-core.js.map +1 -0
  169. package/dist/backend/native-codegen.d.ts +3 -19
  170. package/dist/backend/native-codegen.js +5 -44
  171. package/dist/backend/native-codegen.js.map +1 -1
  172. package/dist/backend/native-codegen.test.js +2 -2
  173. package/dist/backend/native-codegen.test.js.map +1 -1
  174. package/dist/backend/native-link-info-core.d.ts +94 -0
  175. package/dist/backend/native-link-info-core.js +62 -0
  176. package/dist/backend/native-link-info-core.js.map +1 -0
  177. package/dist/backend/native-link-info.d.ts +3 -88
  178. package/dist/backend/native-link-info.js +12 -243
  179. package/dist/backend/native-link-info.js.map +1 -1
  180. package/dist/backend/native-link-info.test.js +41 -146
  181. package/dist/backend/native-link-info.test.js.map +1 -1
  182. package/dist/backend/native-toolchain.d.ts +12 -30
  183. package/dist/backend/native-toolchain.js +83 -233
  184. package/dist/backend/native-toolchain.js.map +1 -1
  185. package/dist/backend/native-toolchain.test.js +77 -5
  186. package/dist/backend/native-toolchain.test.js.map +1 -1
  187. package/dist/backend/native-tools.d.ts +24 -0
  188. package/dist/backend/native-tools.js +33 -0
  189. package/dist/backend/native-tools.js.map +1 -0
  190. package/dist/backend/object-localize.js +19 -8
  191. package/dist/backend/object-localize.js.map +1 -1
  192. package/dist/backend/object-localize.test.js +22 -0
  193. package/dist/backend/object-localize.test.js.map +1 -1
  194. package/dist/backend/runtime-abi.d.ts +2 -2
  195. package/dist/backend/runtime-abi.js +2 -2
  196. package/dist/backend/runtime-pack-core.d.ts +101 -0
  197. package/dist/backend/runtime-pack-core.js +172 -0
  198. package/dist/backend/runtime-pack-core.js.map +1 -0
  199. package/dist/backend/runtime-pack-native.d.ts +21 -0
  200. package/dist/backend/runtime-pack-native.js +73 -0
  201. package/dist/backend/runtime-pack-native.js.map +1 -0
  202. package/dist/backend/runtime-pack-targets.test.js +1 -1
  203. package/dist/backend/runtime-pack.d.ts +3 -83
  204. package/dist/backend/runtime-pack.js +8 -151
  205. package/dist/backend/runtime-pack.js.map +1 -1
  206. package/dist/backend/runtime-pack.test.js +24 -1
  207. package/dist/backend/runtime-pack.test.js.map +1 -1
  208. package/dist/backend/target-diagnostics.d.ts +22 -0
  209. package/dist/backend/target-diagnostics.js +108 -0
  210. package/dist/backend/target-diagnostics.js.map +1 -0
  211. package/dist/backend/target-platform.d.ts +15 -0
  212. package/dist/backend/target-platform.js +72 -0
  213. package/dist/backend/target-platform.js.map +1 -0
  214. package/dist/backend/targets.d.ts +13 -4
  215. package/dist/backend/targets.js +103 -34
  216. package/dist/backend/targets.js.map +1 -1
  217. package/dist/backend/targets.test.js +72 -4
  218. package/dist/backend/targets.test.js.map +1 -1
  219. package/dist/backend/toolchain-environment.d.ts +6 -0
  220. package/dist/backend/toolchain-environment.js +99 -0
  221. package/dist/backend/toolchain-environment.js.map +1 -0
  222. package/dist/backend/vendor-archives.d.ts +1 -9
  223. package/dist/backend/vendor-archives.js +2 -9
  224. package/dist/backend/vendor-archives.js.map +1 -1
  225. package/dist/backend/vendor-inputs.d.ts +9 -0
  226. package/dist/backend/vendor-inputs.js +10 -0
  227. package/dist/backend/vendor-inputs.js.map +1 -0
  228. package/dist/backend/warm-cache.d.ts +3 -0
  229. package/dist/backend/warm-cache.js +41 -0
  230. package/dist/backend/warm-cache.js.map +1 -0
  231. package/dist/cli/command.d.ts +3 -0
  232. package/dist/cli/command.js +328 -0
  233. package/dist/cli/command.js.map +1 -0
  234. package/dist/cli/host.d.ts +24 -0
  235. package/dist/cli/host.js +2 -0
  236. package/dist/cli/host.js.map +1 -0
  237. package/dist/cli/output-options.d.ts +26 -0
  238. package/dist/cli/output-options.js +60 -0
  239. package/dist/cli/output-options.js.map +1 -0
  240. package/dist/cli/paths.d.ts +12 -0
  241. package/dist/cli/paths.js +42 -0
  242. package/dist/cli/paths.js.map +1 -0
  243. package/dist/cli/usage.d.ts +74 -0
  244. package/dist/cli/usage.js +86 -0
  245. package/dist/cli/usage.js.map +1 -0
  246. package/dist/cli/wasi-paths.d.ts +8 -0
  247. package/dist/cli/wasi-paths.js +41 -0
  248. package/dist/cli/wasi-paths.js.map +1 -0
  249. package/dist/cli/wasi-runner.d.ts +2 -0
  250. package/dist/cli/wasi-runner.js +28 -0
  251. package/dist/cli/wasi-runner.js.map +1 -0
  252. package/dist/compat/fetch-profile.js +37 -7
  253. package/dist/compat/fetch-profile.js.map +1 -1
  254. package/dist/compile-types.d.ts +162 -0
  255. package/dist/compile-types.js +2 -0
  256. package/dist/compile-types.js.map +1 -0
  257. package/dist/coverage/report.js +11 -5
  258. package/dist/coverage/report.js.map +1 -1
  259. package/dist/coverage/surface-manifest.js +5 -2
  260. package/dist/coverage/surface-manifest.js.map +1 -1
  261. package/dist/diagnostics/diagnostic.js +5 -10
  262. package/dist/diagnostics/diagnostic.js.map +1 -1
  263. package/dist/executable/executable-cache.d.ts +3 -4
  264. package/dist/executable/executable-cache.js +5 -6
  265. package/dist/executable/executable-cache.js.map +1 -1
  266. package/dist/executable/executable-cache.test.js +16 -17
  267. package/dist/executable/executable-cache.test.js.map +1 -1
  268. package/dist/executable/prepare.d.ts +14 -0
  269. package/dist/executable/prepare.js +66 -0
  270. package/dist/executable/prepare.js.map +1 -0
  271. package/dist/ffi/ffi-manifest.d.ts +11 -4
  272. package/dist/ffi/ffi-manifest.js +170 -58
  273. package/dist/ffi/ffi-manifest.js.map +1 -1
  274. package/dist/ffi/ffi-manifest.test.d.ts +1 -0
  275. package/dist/ffi/ffi-manifest.test.js +111 -0
  276. package/dist/ffi/ffi-manifest.test.js.map +1 -0
  277. package/dist/format-integer.d.ts +3 -0
  278. package/dist/format-integer.js +14 -0
  279. package/dist/format-integer.js.map +1 -0
  280. package/dist/frontend/analysis.d.ts +5 -0
  281. package/dist/frontend/analysis.js +88 -0
  282. package/dist/frontend/analysis.js.map +1 -0
  283. package/dist/frontend/arguments-usage.d.ts +1 -3
  284. package/dist/frontend/arguments-usage.js.map +1 -1
  285. package/dist/frontend/builtin-modules.d.ts +1 -1
  286. package/dist/frontend/builtin-modules.js +1 -1
  287. package/dist/frontend/builtin-modules.js.map +1 -1
  288. package/dist/frontend/cjs-lexer.d.ts +4 -25
  289. package/dist/frontend/cjs-lexer.js +6 -806
  290. package/dist/frontend/cjs-lexer.js.map +1 -1
  291. package/dist/frontend/cjs-resolve.d.ts +5 -0
  292. package/dist/frontend/cjs-resolve.js +429 -0
  293. package/dist/frontend/cjs-resolve.js.map +1 -0
  294. package/dist/frontend/cjs-syntax.d.ts +26 -0
  295. package/dist/frontend/cjs-syntax.js +806 -0
  296. package/dist/frontend/cjs-syntax.js.map +1 -0
  297. package/dist/frontend/comptime-node.d.ts +4 -0
  298. package/dist/frontend/comptime-node.js +16 -0
  299. package/dist/frontend/comptime-node.js.map +1 -0
  300. package/dist/frontend/comptime-node.test.d.ts +1 -0
  301. package/dist/frontend/comptime-node.test.js +37 -0
  302. package/dist/frontend/comptime-node.test.js.map +1 -0
  303. package/dist/frontend/dts-paths.d.ts +3 -4
  304. package/dist/frontend/dts-paths.js +15 -8
  305. package/dist/frontend/dts-paths.js.map +1 -1
  306. package/dist/frontend/fork-target.js +2 -2
  307. package/dist/frontend/fork-target.js.map +1 -1
  308. package/dist/frontend/helper-tokens.d.ts +1 -0
  309. package/dist/frontend/helper-tokens.js +147 -0
  310. package/dist/frontend/helper-tokens.js.map +1 -0
  311. package/dist/frontend/helper-tokens.test.d.ts +1 -0
  312. package/dist/frontend/helper-tokens.test.js +35 -0
  313. package/dist/frontend/helper-tokens.test.js.map +1 -0
  314. package/dist/frontend/inferred-js-diagnostics.d.ts +5 -0
  315. package/dist/frontend/inferred-js-diagnostics.js +69 -0
  316. package/dist/frontend/inferred-js-diagnostics.js.map +1 -0
  317. package/dist/frontend/inferred-js-diagnostics.test.d.ts +1 -0
  318. package/dist/frontend/inferred-js-diagnostics.test.js +58 -0
  319. package/dist/frontend/inferred-js-diagnostics.test.js.map +1 -0
  320. package/dist/frontend/input-tracker.d.ts +5 -2
  321. package/dist/frontend/input-tracker.js +24 -3
  322. package/dist/frontend/input-tracker.js.map +1 -1
  323. package/dist/frontend/input-tracker.test.js +23 -0
  324. package/dist/frontend/input-tracker.test.js.map +1 -1
  325. package/dist/frontend/lib-contract.js +32 -24
  326. package/dist/frontend/lib-contract.js.map +1 -1
  327. package/dist/frontend/literal-values.d.ts +4 -0
  328. package/dist/frontend/literal-values.js +21 -0
  329. package/dist/frontend/literal-values.js.map +1 -0
  330. package/dist/frontend/literal-values.test.d.ts +1 -0
  331. package/dist/frontend/literal-values.test.js +91 -0
  332. package/dist/frontend/literal-values.test.js.map +1 -0
  333. package/dist/frontend/lowering/abstract-equality.d.ts +1 -1
  334. package/dist/frontend/lowering/abstract-equality.js +3 -0
  335. package/dist/frontend/lowering/abstract-equality.js.map +1 -1
  336. package/dist/frontend/lowering/array-indexed-mutation.js +11 -6
  337. package/dist/frontend/lowering/array-indexed-mutation.js.map +1 -1
  338. package/dist/frontend/lowering/array-values.d.ts +4 -1
  339. package/dist/frontend/lowering/array-values.js +43 -1
  340. package/dist/frontend/lowering/array-values.js.map +1 -1
  341. package/dist/frontend/lowering/callback-arg.js +1 -0
  342. package/dist/frontend/lowering/callback-arg.js.map +1 -1
  343. package/dist/frontend/lowering/class-callbacks.d.ts +12 -0
  344. package/dist/frontend/lowering/class-callbacks.js +74 -0
  345. package/dist/frontend/lowering/class-callbacks.js.map +1 -0
  346. package/dist/frontend/lowering/class-construction.d.ts +12 -0
  347. package/dist/frontend/lowering/class-construction.js +156 -0
  348. package/dist/frontend/lowering/class-construction.js.map +1 -0
  349. package/dist/frontend/lowering/class-descriptors.d.ts +10 -0
  350. package/dist/frontend/lowering/class-descriptors.js +114 -0
  351. package/dist/frontend/lowering/class-descriptors.js.map +1 -0
  352. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +51 -0
  353. package/dist/frontend/lowering/class-dynamic-dispatch.js +1158 -0
  354. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -0
  355. package/dist/frontend/lowering/class-dynamic-dispatch.test.d.ts +1 -0
  356. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +93 -0
  357. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -0
  358. package/dist/frontend/lowering/class-instance-constructor.d.ts +7 -0
  359. package/dist/frontend/lowering/class-instance-constructor.js +67 -0
  360. package/dist/frontend/lowering/class-instance-constructor.js.map +1 -0
  361. package/dist/frontend/lowering/class-method-values.d.ts +13 -0
  362. package/dist/frontend/lowering/class-method-values.js +235 -0
  363. package/dist/frontend/lowering/class-method-values.js.map +1 -0
  364. package/dist/frontend/lowering/class-prototypes.d.ts +19 -0
  365. package/dist/frontend/lowering/class-prototypes.js +242 -0
  366. package/dist/frontend/lowering/class-prototypes.js.map +1 -0
  367. package/dist/frontend/lowering/class-runtime-statics.d.ts +8 -0
  368. package/dist/frontend/lowering/class-runtime-statics.js +66 -0
  369. package/dist/frontend/lowering/class-runtime-statics.js.map +1 -0
  370. package/dist/frontend/lowering/class-static-data.d.ts +6 -0
  371. package/dist/frontend/lowering/class-static-data.js +56 -0
  372. package/dist/frontend/lowering/class-static-data.js.map +1 -0
  373. package/dist/frontend/lowering/containers/buffer-numeric-methods.d.ts +4 -0
  374. package/dist/frontend/lowering/containers/buffer-numeric-methods.js +26 -0
  375. package/dist/frontend/lowering/containers/buffer-numeric-methods.js.map +1 -0
  376. package/dist/frontend/lowering/containers/bytes.d.ts +11 -7
  377. package/dist/frontend/lowering/containers/bytes.js +208 -163
  378. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  379. package/dist/frontend/lowering/containers/string-and-regexp.d.ts +2 -2
  380. package/dist/frontend/lowering/containers/string-and-regexp.js +58 -63
  381. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  382. package/dist/frontend/lowering/containers/string-replacement.d.ts +7 -0
  383. package/dist/frontend/lowering/containers/string-replacement.js +217 -0
  384. package/dist/frontend/lowering/containers/string-replacement.js.map +1 -0
  385. package/dist/frontend/lowering/error-methods.d.ts +14 -0
  386. package/dist/frontend/lowering/error-methods.js +177 -0
  387. package/dist/frontend/lowering/error-methods.js.map +1 -0
  388. package/dist/frontend/lowering/expressions/global-symbols.d.ts +6 -0
  389. package/dist/frontend/lowering/expressions/global-symbols.js +11 -0
  390. package/dist/frontend/lowering/expressions/global-symbols.js.map +1 -0
  391. package/dist/frontend/lowering/expressions/native-proxy.d.ts +7 -0
  392. package/dist/frontend/lowering/expressions/native-proxy.js +51 -0
  393. package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -0
  394. package/dist/frontend/lowering/expressions/nullish-assignment.d.ts +6 -0
  395. package/dist/frontend/lowering/expressions/nullish-assignment.js +132 -0
  396. package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -0
  397. package/dist/frontend/lowering/expressions/object-literals.d.ts +8 -8
  398. package/dist/frontend/lowering/expressions/object-literals.js +509 -183
  399. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  400. package/dist/frontend/lowering/expressions/optional-chains.d.ts +3 -4
  401. package/dist/frontend/lowering/expressions/optional-chains.js +88 -24
  402. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  403. package/dist/frontend/lowering/expressions/try-lower-expression.js +1 -0
  404. package/dist/frontend/lowering/expressions/try-lower-expression.js.map +1 -1
  405. package/dist/frontend/lowering/expressions/union-field-write.d.ts +8 -0
  406. package/dist/frontend/lowering/expressions/union-field-write.js +71 -0
  407. package/dist/frontend/lowering/expressions/union-field-write.js.map +1 -0
  408. package/dist/frontend/lowering/function-context.d.ts +101 -0
  409. package/dist/frontend/lowering/function-context.js +109 -0
  410. package/dist/frontend/lowering/function-context.js.map +1 -0
  411. package/dist/frontend/lowering/generator-delegation.d.ts +7 -0
  412. package/dist/frontend/lowering/generator-delegation.js +85 -0
  413. package/dist/frontend/lowering/generator-delegation.js.map +1 -0
  414. package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +11 -0
  415. package/dist/frontend/lowering/generator-dynamic-dispatch.js +143 -0
  416. package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -0
  417. package/dist/frontend/lowering/lib-boundary.d.ts +4 -1
  418. package/dist/frontend/lowering/lib-boundary.js +112 -20
  419. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  420. package/dist/frontend/lowering/lib-boundary.test.d.ts +1 -0
  421. package/dist/frontend/lowering/lib-boundary.test.js +45 -0
  422. package/dist/frontend/lowering/lib-boundary.test.js.map +1 -0
  423. package/dist/frontend/lowering/lower-array-sort.d.ts +1 -1
  424. package/dist/frontend/lowering/lower-assert.d.ts +1 -1
  425. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  426. package/dist/frontend/lowering/lower-async-iteration.d.ts +1 -1
  427. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
  428. package/dist/frontend/lowering/lower-builtin-values.d.ts +18 -0
  429. package/dist/frontend/lowering/lower-builtin-values.js +249 -0
  430. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -0
  431. package/dist/frontend/lowering/lower-builtins.d.ts +33 -46
  432. package/dist/frontend/lowering/lower-builtins.js +676 -365
  433. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  434. package/dist/frontend/lowering/lower-calls.d.ts +28 -22
  435. package/dist/frontend/lowering/lower-calls.js +1660 -412
  436. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  437. package/dist/frontend/lowering/lower-classes.d.ts +95 -57
  438. package/dist/frontend/lowering/lower-classes.js +1491 -404
  439. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  440. package/dist/frontend/lowering/lower-comptime.d.ts +1 -1
  441. package/dist/frontend/lowering/lower-comptime.js +23 -32
  442. package/dist/frontend/lowering/lower-comptime.js.map +1 -1
  443. package/dist/frontend/lowering/lower-containers.d.ts +36 -32
  444. package/dist/frontend/lowering/lower-containers.js +925 -181
  445. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  446. package/dist/frontend/lowering/lower-dgram.d.ts +1 -1
  447. package/dist/frontend/lowering/lower-dgram.js +3 -2
  448. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  449. package/dist/frontend/lowering/lower-enums.d.ts +1 -1
  450. package/dist/frontend/lowering/lower-enums.js.map +1 -1
  451. package/dist/frontend/lowering/lower-event-emitter.d.ts +30 -1
  452. package/dist/frontend/lowering/lower-event-emitter.js +58 -26
  453. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  454. package/dist/frontend/lowering/lower-expando.d.ts +7 -1
  455. package/dist/frontend/lowering/lower-expando.js +14 -6
  456. package/dist/frontend/lowering/lower-expando.js.map +1 -1
  457. package/dist/frontend/lowering/lower-exprs.d.ts +37 -13
  458. package/dist/frontend/lowering/lower-exprs.js +2163 -863
  459. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  460. package/dist/frontend/lowering/lower-generators.d.ts +2 -5
  461. package/dist/frontend/lowering/lower-generators.js +88 -46
  462. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  463. package/dist/frontend/lowering/lower-global-value.d.ts +7 -0
  464. package/dist/frontend/lowering/lower-global-value.js +17 -0
  465. package/dist/frontend/lowering/lower-global-value.js.map +1 -0
  466. package/dist/frontend/lowering/lower-inspect.d.ts +1 -1
  467. package/dist/frontend/lowering/lower-inspect.js +17 -8
  468. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  469. package/dist/frontend/lowering/lower-island.d.ts +7 -8
  470. package/dist/frontend/lowering/lower-island.js +66 -33
  471. package/dist/frontend/lowering/lower-island.js.map +1 -1
  472. package/dist/frontend/lowering/lower-mixins.d.ts +2 -2
  473. package/dist/frontend/lowering/lower-mixins.js +5 -3
  474. package/dist/frontend/lowering/lower-mixins.js.map +1 -1
  475. package/dist/frontend/lowering/lower-modules.d.ts +1 -1
  476. package/dist/frontend/lowering/lower-modules.js +445 -39
  477. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  478. package/dist/frontend/lowering/lower-modules.test.d.ts +1 -0
  479. package/dist/frontend/lowering/lower-modules.test.js +39 -0
  480. package/dist/frontend/lowering/lower-modules.test.js.map +1 -0
  481. package/dist/frontend/lowering/lower-namespaces.d.ts +1 -1
  482. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  483. package/dist/frontend/lowering/lower-node-module.d.ts +1 -1
  484. package/dist/frontend/lowering/lower-node-module.js +13 -10
  485. package/dist/frontend/lowering/lower-node-module.js.map +1 -1
  486. package/dist/frontend/lowering/lower-server.d.ts +1 -1
  487. package/dist/frontend/lowering/lower-server.js +6 -10
  488. package/dist/frontend/lowering/lower-server.js.map +1 -1
  489. package/dist/frontend/lowering/lower-stmts.d.ts +17 -17
  490. package/dist/frontend/lowering/lower-stmts.js +855 -514
  491. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  492. package/dist/frontend/lowering/lower-stream.d.ts +1 -1
  493. package/dist/frontend/lowering/lower-stream.js +20 -11
  494. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  495. package/dist/frontend/lowering/lower-test.d.ts +1 -1
  496. package/dist/frontend/lowering/lower-test.js.map +1 -1
  497. package/dist/frontend/lowering/lower-url.d.ts +6 -0
  498. package/dist/frontend/lowering/lower-url.js +77 -0
  499. package/dist/frontend/lowering/lower-url.js.map +1 -0
  500. package/dist/frontend/lowering/lowerer.d.ts +140 -190
  501. package/dist/frontend/lowering/lowerer.js +1193 -712
  502. package/dist/frontend/lowering/lowerer.js.map +1 -1
  503. package/dist/frontend/lowering/lowerer.test.d.ts +1 -0
  504. package/dist/frontend/lowering/lowerer.test.js +172 -0
  505. package/dist/frontend/lowering/lowerer.test.js.map +1 -0
  506. package/dist/frontend/lowering/native-ffi.d.ts +5 -0
  507. package/dist/frontend/lowering/native-ffi.js +40 -0
  508. package/dist/frontend/lowering/native-ffi.js.map +1 -0
  509. package/dist/frontend/lowering/object-enumeration-receiver.d.ts +7 -0
  510. package/dist/frontend/lowering/object-enumeration-receiver.js +33 -0
  511. package/dist/frontend/lowering/object-enumeration-receiver.js.map +1 -0
  512. package/dist/frontend/lowering/object-factory-new.d.ts +8 -0
  513. package/dist/frontend/lowering/object-factory-new.js +68 -0
  514. package/dist/frontend/lowering/object-factory-new.js.map +1 -0
  515. package/dist/frontend/lowering/optional-arguments.js +6 -1
  516. package/dist/frontend/lowering/optional-arguments.js.map +1 -1
  517. package/dist/frontend/lowering/pairs-snapshot.js +2 -1
  518. package/dist/frontend/lowering/pairs-snapshot.js.map +1 -1
  519. package/dist/frontend/lowering/runtime-optional-locals.d.ts +14 -0
  520. package/dist/frontend/lowering/runtime-optional-locals.js +41 -0
  521. package/dist/frontend/lowering/runtime-optional-locals.js.map +1 -0
  522. package/dist/frontend/lowering/runtime-optional-locals.test.d.ts +1 -0
  523. package/dist/frontend/lowering/runtime-optional-locals.test.js +85 -0
  524. package/dist/frontend/lowering/runtime-optional-locals.test.js.map +1 -0
  525. package/dist/frontend/lowering/sanitize-class-types.d.ts +8 -0
  526. package/dist/frontend/lowering/sanitize-class-types.js +79 -0
  527. package/dist/frontend/lowering/sanitize-class-types.js.map +1 -0
  528. package/dist/frontend/lowering/sanitize-class-types.test.d.ts +1 -0
  529. package/dist/frontend/lowering/sanitize-class-types.test.js +60 -0
  530. package/dist/frontend/lowering/sanitize-class-types.test.js.map +1 -0
  531. package/dist/frontend/lowering/static-this.d.ts +5 -1
  532. package/dist/frontend/lowering/static-this.js +28 -2
  533. package/dist/frontend/lowering/static-this.js.map +1 -1
  534. package/dist/frontend/lowering/string-index.d.ts +7 -0
  535. package/dist/frontend/lowering/string-index.js +39 -0
  536. package/dist/frontend/lowering/string-index.js.map +1 -0
  537. package/dist/frontend/lowering/surfaces.d.ts +10 -3
  538. package/dist/frontend/lowering/surfaces.js +86 -37
  539. package/dist/frontend/lowering/surfaces.js.map +1 -1
  540. package/dist/frontend/lowering/symbol-fields.d.ts +22 -0
  541. package/dist/frontend/lowering/symbol-fields.js +183 -0
  542. package/dist/frontend/lowering/symbol-fields.js.map +1 -0
  543. package/dist/frontend/lowering/symbol-methods.d.ts +7 -0
  544. package/dist/frontend/lowering/symbol-methods.js +30 -0
  545. package/dist/frontend/lowering/symbol-methods.js.map +1 -0
  546. package/dist/frontend/lowering/text-decoder-encoding.d.ts +12 -0
  547. package/dist/frontend/lowering/text-decoder-encoding.js +82 -0
  548. package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -0
  549. package/dist/frontend/lowering/text-decoder-encoding.test.d.ts +1 -0
  550. package/dist/frontend/lowering/text-decoder-encoding.test.js +38 -0
  551. package/dist/frontend/lowering/text-decoder-encoding.test.js.map +1 -0
  552. package/dist/frontend/lowering/union-narrow.d.ts +9 -0
  553. package/dist/frontend/lowering/union-narrow.js +59 -0
  554. package/dist/frontend/lowering/union-narrow.js.map +1 -0
  555. package/dist/frontend/lowering/union-narrow.test.d.ts +1 -0
  556. package/dist/frontend/lowering/union-narrow.test.js +72 -0
  557. package/dist/frontend/lowering/union-narrow.test.js.map +1 -0
  558. package/dist/frontend/lowering/union-retag.d.ts +43 -0
  559. package/dist/frontend/lowering/union-retag.js +259 -0
  560. package/dist/frontend/lowering/union-retag.js.map +1 -0
  561. package/dist/frontend/lowering/union-retag.test.d.ts +1 -0
  562. package/dist/frontend/lowering/union-retag.test.js +405 -0
  563. package/dist/frontend/lowering/union-retag.test.js.map +1 -0
  564. package/dist/frontend/lowering/unregistered-class-types.d.ts +14 -0
  565. package/dist/frontend/lowering/unregistered-class-types.js +94 -0
  566. package/dist/frontend/lowering/unregistered-class-types.js.map +1 -0
  567. package/dist/frontend/lowering/unregistered-class-types.test.d.ts +1 -0
  568. package/dist/frontend/lowering/unregistered-class-types.test.js +65 -0
  569. package/dist/frontend/lowering/unregistered-class-types.test.js.map +1 -0
  570. package/dist/frontend/lowering/width-lift.d.ts +40 -0
  571. package/dist/frontend/lowering/width-lift.js +2 -0
  572. package/dist/frontend/lowering/width-lift.js.map +1 -0
  573. package/dist/frontend/module-syntax.d.ts +58 -0
  574. package/dist/frontend/module-syntax.js +123 -0
  575. package/dist/frontend/module-syntax.js.map +1 -0
  576. package/dist/frontend/module-syntax.test.d.ts +1 -0
  577. package/dist/frontend/module-syntax.test.js +78 -0
  578. package/dist/frontend/module-syntax.test.js.map +1 -0
  579. package/dist/frontend/npm-fetch-analysis.d.ts +17 -0
  580. package/dist/frontend/npm-fetch-analysis.js +100 -0
  581. package/dist/frontend/npm-fetch-analysis.js.map +1 -0
  582. package/dist/frontend/npm-fetch-analysis.test.d.ts +1 -0
  583. package/dist/frontend/npm-fetch-analysis.test.js +107 -0
  584. package/dist/frontend/npm-fetch-analysis.test.js.map +1 -0
  585. package/dist/frontend/npm-fetch-node.d.ts +2 -0
  586. package/dist/frontend/npm-fetch-node.js +12 -0
  587. package/dist/frontend/npm-fetch-node.js.map +1 -0
  588. package/dist/frontend/npm-fetch-syntax.d.ts +6 -0
  589. package/dist/frontend/npm-fetch-syntax.js +207 -0
  590. package/dist/frontend/npm-fetch-syntax.js.map +1 -0
  591. package/dist/frontend/npm-node.d.ts +10 -0
  592. package/dist/frontend/npm-node.js +14 -0
  593. package/dist/frontend/npm-node.js.map +1 -0
  594. package/dist/frontend/npm-static-bundled-cjs.d.ts +8 -0
  595. package/dist/frontend/npm-static-bundled-cjs.js +236 -0
  596. package/dist/frontend/npm-static-bundled-cjs.js.map +1 -0
  597. package/dist/frontend/npm-static-bundled-cjs.test.d.ts +1 -0
  598. package/dist/frontend/npm-static-bundled-cjs.test.js +69 -0
  599. package/dist/frontend/npm-static-bundled-cjs.test.js.map +1 -0
  600. package/dist/frontend/npm-static-declaration-syntax.d.ts +57 -0
  601. package/dist/frontend/npm-static-declaration-syntax.js +944 -0
  602. package/dist/frontend/npm-static-declaration-syntax.js.map +1 -0
  603. package/dist/frontend/npm-static-declarations.d.ts +11 -39
  604. package/dist/frontend/npm-static-declarations.js +22 -561
  605. package/dist/frontend/npm-static-declarations.js.map +1 -1
  606. package/dist/frontend/npm-static-declarations.test.js +245 -6
  607. package/dist/frontend/npm-static-declarations.test.js.map +1 -1
  608. package/dist/frontend/npm-static-prune.d.ts +1 -1
  609. package/dist/frontend/npm-static-prune.js +121 -38
  610. package/dist/frontend/npm-static-prune.js.map +1 -1
  611. package/dist/frontend/npm-static-prune.test.js +9 -1
  612. package/dist/frontend/npm-static-prune.test.js.map +1 -1
  613. package/dist/frontend/npm-static-rewrite-host.d.ts +4 -0
  614. package/dist/frontend/npm-static-rewrite-host.js +179 -0
  615. package/dist/frontend/npm-static-rewrite-host.js.map +1 -0
  616. package/dist/frontend/npm-static-rewrite-syntax.d.ts +16 -0
  617. package/dist/frontend/npm-static-rewrite-syntax.js +905 -0
  618. package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -0
  619. package/dist/frontend/npm-static-rewrite.d.ts +0 -5
  620. package/dist/frontend/npm-static-rewrite.js +2 -1079
  621. package/dist/frontend/npm-static-rewrite.js.map +1 -1
  622. package/dist/frontend/npm-static-subtyping.d.ts +5 -0
  623. package/dist/frontend/npm-static-subtyping.js +55 -0
  624. package/dist/frontend/npm-static-subtyping.js.map +1 -0
  625. package/dist/frontend/npm-static-subtyping.test.d.ts +1 -0
  626. package/dist/frontend/npm-static-subtyping.test.js +58 -0
  627. package/dist/frontend/npm-static-subtyping.test.js.map +1 -0
  628. package/dist/frontend/npm-static.d.ts +7 -15
  629. package/dist/frontend/npm-static.js +19 -28
  630. package/dist/frontend/npm-static.js.map +1 -1
  631. package/dist/frontend/npm.d.ts +8 -69
  632. package/dist/frontend/npm.js +21 -361
  633. package/dist/frontend/npm.js.map +1 -1
  634. package/dist/frontend/npm.test.js +2 -2
  635. package/dist/frontend/npm.test.js.map +1 -1
  636. package/dist/frontend/pipeline-native.d.ts +6 -0
  637. package/dist/frontend/pipeline-native.js +32 -0
  638. package/dist/frontend/pipeline-native.js.map +1 -0
  639. package/dist/frontend/pipeline.d.ts +54 -0
  640. package/dist/frontend/pipeline.js +382 -0
  641. package/dist/frontend/pipeline.js.map +1 -0
  642. package/dist/frontend/pipeline.test.d.ts +1 -0
  643. package/dist/frontend/pipeline.test.js +77 -0
  644. package/dist/frontend/pipeline.test.js.map +1 -0
  645. package/dist/frontend/program-analysis.d.ts +10 -0
  646. package/dist/frontend/program-analysis.js +14 -0
  647. package/dist/frontend/program-analysis.js.map +1 -0
  648. package/dist/frontend/program-node.d.ts +9 -0
  649. package/dist/frontend/program-node.js +48 -0
  650. package/dist/frontend/program-node.js.map +1 -0
  651. package/dist/frontend/program.d.ts +39 -20
  652. package/dist/frontend/program.js +393 -189
  653. package/dist/frontend/program.js.map +1 -1
  654. package/dist/frontend/program.test.js +105 -2
  655. package/dist/frontend/program.test.js.map +1 -1
  656. package/dist/frontend/provenance-core.d.ts +9 -0
  657. package/dist/frontend/provenance-core.js +435 -0
  658. package/dist/frontend/provenance-core.js.map +1 -0
  659. package/dist/frontend/provenance.d.ts +0 -4
  660. package/dist/frontend/provenance.js +4 -459
  661. package/dist/frontend/provenance.js.map +1 -1
  662. package/dist/frontend/resolve.d.ts +3 -1
  663. package/dist/frontend/resolve.js +6 -3
  664. package/dist/frontend/resolve.js.map +1 -1
  665. package/dist/frontend/runtime-resolve.d.ts +4 -3
  666. package/dist/frontend/runtime-resolve.js +22 -18
  667. package/dist/frontend/runtime-resolve.js.map +1 -1
  668. package/dist/frontend/runtime-resolve.test.js +53 -0
  669. package/dist/frontend/runtime-resolve.test.js.map +1 -1
  670. package/dist/frontend/services-node.d.ts +5 -0
  671. package/dist/frontend/services-node.js +19 -0
  672. package/dist/frontend/services-node.js.map +1 -0
  673. package/dist/frontend/services-node.test.d.ts +1 -0
  674. package/dist/frontend/services-node.test.js +70 -0
  675. package/dist/frontend/services-node.test.js.map +1 -0
  676. package/dist/frontend/services.d.ts +44 -0
  677. package/dist/frontend/services.js +90 -0
  678. package/dist/frontend/services.js.map +1 -0
  679. package/dist/frontend/services.test.d.ts +1 -0
  680. package/dist/frontend/services.test.js +174 -0
  681. package/dist/frontend/services.test.js.map +1 -0
  682. package/dist/frontend/ts7/adapter.d.ts +3 -3
  683. package/dist/frontend/ts7/adapter.js +14 -31
  684. package/dist/frontend/ts7/adapter.js.map +1 -1
  685. package/dist/frontend/ts7/api.d.ts +16 -0
  686. package/dist/frontend/ts7/api.js +24 -0
  687. package/dist/frontend/ts7/api.js.map +1 -0
  688. package/dist/frontend/ts7/ast-bytes.d.ts +31 -0
  689. package/dist/frontend/ts7/ast-bytes.js +137 -0
  690. package/dist/frontend/ts7/ast-bytes.js.map +1 -0
  691. package/dist/frontend/ts7/ast-bytes.test.d.ts +1 -0
  692. package/dist/frontend/ts7/ast-bytes.test.js +73 -0
  693. package/dist/frontend/ts7/ast-bytes.test.js.map +1 -0
  694. package/dist/frontend/ts7/ast-guards.generated.d.ts +353 -0
  695. package/dist/frontend/ts7/ast-guards.generated.js +1951 -0
  696. package/dist/frontend/ts7/ast-guards.generated.js.map +1 -0
  697. package/dist/frontend/ts7/ast-guards.test.d.ts +1 -0
  698. package/dist/frontend/ts7/ast-guards.test.js +43 -0
  699. package/dist/frontend/ts7/ast-guards.test.js.map +1 -0
  700. package/dist/frontend/ts7/ast-node.d.ts +194 -0
  701. package/dist/frontend/ts7/ast-node.js +448 -0
  702. package/dist/frontend/ts7/ast-node.js.map +1 -0
  703. package/dist/frontend/ts7/ast-node.test.d.ts +1 -0
  704. package/dist/frontend/ts7/ast-node.test.js +266 -0
  705. package/dist/frontend/ts7/ast-node.test.js.map +1 -0
  706. package/dist/frontend/ts7/ast-schema.generated.d.ts +503 -0
  707. package/dist/frontend/ts7/ast-schema.generated.js +1446 -0
  708. package/dist/frontend/ts7/ast-schema.generated.js.map +1 -0
  709. package/dist/frontend/ts7/ast-text.d.ts +6 -0
  710. package/dist/frontend/ts7/ast-text.js +124 -0
  711. package/dist/frontend/ts7/ast-text.js.map +1 -0
  712. package/dist/frontend/ts7/ast-text.test.d.ts +1 -0
  713. package/dist/frontend/ts7/ast-text.test.js +38 -0
  714. package/dist/frontend/ts7/ast-text.test.js.map +1 -0
  715. package/dist/frontend/ts7/ast-tokens.generated.d.ts +2 -0
  716. package/dist/frontend/ts7/ast-tokens.generated.js +155 -0
  717. package/dist/frontend/ts7/ast-tokens.generated.js.map +1 -0
  718. package/dist/frontend/ts7/ast-types.d.ts +42 -0
  719. package/dist/frontend/ts7/ast-types.generated.d.ts +1615 -0
  720. package/dist/frontend/ts7/ast-types.generated.js +5 -0
  721. package/dist/frontend/ts7/ast-types.generated.js.map +1 -0
  722. package/dist/frontend/ts7/ast-types.js +3 -0
  723. package/dist/frontend/ts7/ast-types.js.map +1 -0
  724. package/dist/frontend/ts7/ast-wire.d.ts +58 -0
  725. package/dist/frontend/ts7/ast-wire.js +267 -0
  726. package/dist/frontend/ts7/ast-wire.js.map +1 -0
  727. package/dist/frontend/ts7/ast-wire.test.d.ts +1 -0
  728. package/dist/frontend/ts7/ast-wire.test.js +151 -0
  729. package/dist/frontend/ts7/ast-wire.test.js.map +1 -0
  730. package/dist/frontend/ts7/ast.d.ts +14 -14
  731. package/dist/frontend/ts7/ast.js +25 -18
  732. package/dist/frontend/ts7/ast.js.map +1 -1
  733. package/dist/frontend/ts7/census-check.js +1 -0
  734. package/dist/frontend/ts7/census-check.js.map +1 -1
  735. package/dist/frontend/ts7/checker-cache.d.ts +48 -0
  736. package/dist/frontend/ts7/checker-cache.js +92 -0
  737. package/dist/frontend/ts7/checker-cache.js.map +1 -0
  738. package/dist/frontend/ts7/checker.d.ts +19 -46
  739. package/dist/frontend/ts7/checker.js +231 -161
  740. package/dist/frontend/ts7/checker.js.map +1 -1
  741. package/dist/frontend/ts7/checker.test.d.ts +1 -0
  742. package/dist/frontend/ts7/checker.test.js +335 -0
  743. package/dist/frontend/ts7/checker.test.js.map +1 -0
  744. package/dist/frontend/ts7/enums.d.ts +4 -27
  745. package/dist/frontend/ts7/enums.generated.d.ts +878 -0
  746. package/dist/frontend/ts7/enums.generated.js +1313 -0
  747. package/dist/frontend/ts7/enums.generated.js.map +1 -0
  748. package/dist/frontend/ts7/enums.js +4 -45
  749. package/dist/frontend/ts7/enums.js.map +1 -1
  750. package/dist/frontend/ts7/enums.test.d.ts +1 -0
  751. package/dist/frontend/ts7/enums.test.js +48 -0
  752. package/dist/frontend/ts7/enums.test.js.map +1 -0
  753. package/dist/frontend/ts7/native-api.d.ts +10 -0
  754. package/dist/frontend/ts7/native-api.js +10 -0
  755. package/dist/frontend/ts7/native-api.js.map +1 -0
  756. package/dist/frontend/ts7/native-host.d.ts +2 -0
  757. package/dist/frontend/ts7/native-host.js +11 -0
  758. package/dist/frontend/ts7/native-host.js.map +1 -0
  759. package/dist/frontend/ts7/native-process.d.ts +14 -0
  760. package/dist/frontend/ts7/native-process.js +62 -0
  761. package/dist/frontend/ts7/native-process.js.map +1 -0
  762. package/dist/frontend/ts7/program-adapter.d.ts +10 -98
  763. package/dist/frontend/ts7/program-adapter.js +16 -310
  764. package/dist/frontend/ts7/program-adapter.js.map +1 -1
  765. package/dist/frontend/ts7/program-host.d.ts +115 -0
  766. package/dist/frontend/ts7/program-host.js +347 -0
  767. package/dist/frontend/ts7/program-host.js.map +1 -0
  768. package/dist/frontend/ts7/program-host.test.d.ts +1 -0
  769. package/dist/frontend/ts7/program-host.test.js +207 -0
  770. package/dist/frontend/ts7/program-host.test.js.map +1 -0
  771. package/dist/frontend/ts7/rpc-api.d.ts +12 -0
  772. package/dist/frontend/ts7/rpc-api.js +23 -0
  773. package/dist/frontend/ts7/rpc-api.js.map +1 -0
  774. package/dist/frontend/ts7/rpc-client.d.ts +27 -0
  775. package/dist/frontend/ts7/rpc-client.js +102 -0
  776. package/dist/frontend/ts7/rpc-client.js.map +1 -0
  777. package/dist/frontend/ts7/rpc-client.test.d.ts +1 -0
  778. package/dist/frontend/ts7/rpc-client.test.js +133 -0
  779. package/dist/frontend/ts7/rpc-client.test.js.map +1 -0
  780. package/dist/frontend/ts7/rpc-filesystem.d.ts +16 -0
  781. package/dist/frontend/ts7/rpc-filesystem.js +42 -0
  782. package/dist/frontend/ts7/rpc-filesystem.js.map +1 -0
  783. package/dist/frontend/ts7/rpc-filesystem.test.d.ts +1 -0
  784. package/dist/frontend/ts7/rpc-filesystem.test.js +89 -0
  785. package/dist/frontend/ts7/rpc-filesystem.test.js.map +1 -0
  786. package/dist/frontend/ts7/rpc-process.d.ts +2 -0
  787. package/dist/frontend/ts7/rpc-process.js +148 -0
  788. package/dist/frontend/ts7/rpc-process.js.map +1 -0
  789. package/dist/frontend/ts7/rpc-process.test.d.ts +1 -0
  790. package/dist/frontend/ts7/rpc-process.test.js +29 -0
  791. package/dist/frontend/ts7/rpc-process.test.js.map +1 -0
  792. package/dist/frontend/ts7/rpc-wire.d.ts +46 -0
  793. package/dist/frontend/ts7/rpc-wire.js +195 -0
  794. package/dist/frontend/ts7/rpc-wire.js.map +1 -0
  795. package/dist/frontend/ts7/rpc-wire.test.d.ts +1 -0
  796. package/dist/frontend/ts7/rpc-wire.test.js +168 -0
  797. package/dist/frontend/ts7/rpc-wire.test.js.map +1 -0
  798. package/dist/frontend/ts7/semantic-checker.d.ts +137 -0
  799. package/dist/frontend/ts7/semantic-checker.js +221 -0
  800. package/dist/frontend/ts7/semantic-checker.js.map +1 -0
  801. package/dist/frontend/ts7/semantic-checker.test.d.ts +1 -0
  802. package/dist/frontend/ts7/semantic-checker.test.js +119 -0
  803. package/dist/frontend/ts7/semantic-checker.test.js.map +1 -0
  804. package/dist/frontend/ts7/semantic-json.d.ts +5 -0
  805. package/dist/frontend/ts7/semantic-json.js +47 -0
  806. package/dist/frontend/ts7/semantic-json.js.map +1 -0
  807. package/dist/frontend/ts7/semantic-json.test.d.ts +1 -0
  808. package/dist/frontend/ts7/semantic-json.test.js +42 -0
  809. package/dist/frontend/ts7/semantic-json.test.js.map +1 -0
  810. package/dist/frontend/ts7/semantic-model.d.ts +222 -0
  811. package/dist/frontend/ts7/semantic-model.js +423 -0
  812. package/dist/frontend/ts7/semantic-model.js.map +1 -0
  813. package/dist/frontend/ts7/semantic-model.test.d.ts +1 -0
  814. package/dist/frontend/ts7/semantic-model.test.js +322 -0
  815. package/dist/frontend/ts7/semantic-model.test.js.map +1 -0
  816. package/dist/frontend/ts7/semantic-schema.generated.d.ts +283 -0
  817. package/dist/frontend/ts7/semantic-schema.generated.js +222 -0
  818. package/dist/frontend/ts7/semantic-schema.generated.js.map +1 -0
  819. package/dist/frontend/ts7/semantic-types.d.ts +5 -0
  820. package/dist/frontend/ts7/semantic-types.js +2 -0
  821. package/dist/frontend/ts7/semantic-types.js.map +1 -0
  822. package/dist/frontend/ts7/session-cache.d.ts +17 -0
  823. package/dist/frontend/ts7/session-cache.js +97 -0
  824. package/dist/frontend/ts7/session-cache.js.map +1 -0
  825. package/dist/frontend/ts7/session-cache.test.d.ts +1 -0
  826. package/dist/frontend/ts7/session-cache.test.js +87 -0
  827. package/dist/frontend/ts7/session-cache.test.js.map +1 -0
  828. package/dist/frontend/ts7/session-path.d.ts +18 -0
  829. package/dist/frontend/ts7/session-path.js +203 -0
  830. package/dist/frontend/ts7/session-path.js.map +1 -0
  831. package/dist/frontend/ts7/session-path.test.d.ts +1 -0
  832. package/dist/frontend/ts7/session-path.test.js +34 -0
  833. package/dist/frontend/ts7/session-path.test.js.map +1 -0
  834. package/dist/frontend/ts7/session-schema.generated.d.ts +167 -0
  835. package/dist/frontend/ts7/session-schema.generated.js +5 -0
  836. package/dist/frontend/ts7/session-schema.generated.js.map +1 -0
  837. package/dist/frontend/ts7/session-timing.d.ts +50 -0
  838. package/dist/frontend/ts7/session-timing.js +61 -0
  839. package/dist/frontend/ts7/session-timing.js.map +1 -0
  840. package/dist/frontend/ts7/session-timing.test.d.ts +1 -0
  841. package/dist/frontend/ts7/session-timing.test.js +52 -0
  842. package/dist/frontend/ts7/session-timing.test.js.map +1 -0
  843. package/dist/frontend/ts7/session.d.ts +105 -0
  844. package/dist/frontend/ts7/session.js +233 -0
  845. package/dist/frontend/ts7/session.js.map +1 -0
  846. package/dist/frontend/ts7/session.test.d.ts +1 -0
  847. package/dist/frontend/ts7/session.test.js +215 -0
  848. package/dist/frontend/ts7/session.test.js.map +1 -0
  849. package/dist/frontend/ts7/source-parser-node.d.ts +6 -0
  850. package/dist/frontend/ts7/source-parser-node.js +15 -0
  851. package/dist/frontend/ts7/source-parser-node.js.map +1 -0
  852. package/dist/frontend/ts7/source-parser.d.ts +25 -0
  853. package/dist/frontend/ts7/source-parser.js +96 -0
  854. package/dist/frontend/ts7/source-parser.js.map +1 -0
  855. package/dist/frontend/ts7/source-parser.test.d.ts +1 -0
  856. package/dist/frontend/ts7/source-parser.test.js +151 -0
  857. package/dist/frontend/ts7/source-parser.test.js.map +1 -0
  858. package/dist/frontend/ts7/syntax.d.ts +3 -0
  859. package/dist/frontend/ts7/syntax.js +4 -0
  860. package/dist/frontend/ts7/syntax.js.map +1 -0
  861. package/dist/frontend/tsc-codes.js +3 -0
  862. package/dist/frontend/tsc-codes.js.map +1 -1
  863. package/dist/frontend/type-mapper.d.ts +34 -18
  864. package/dist/frontend/type-mapper.js +552 -131
  865. package/dist/frontend/type-mapper.js.map +1 -1
  866. package/dist/frontend/type-mapper.test.js +146 -2
  867. package/dist/frontend/type-mapper.test.js.map +1 -1
  868. package/dist/frontend/union-discriminants.d.ts +16 -0
  869. package/dist/frontend/union-discriminants.js +98 -0
  870. package/dist/frontend/union-discriminants.js.map +1 -0
  871. package/dist/frontend/union-discriminants.test.d.ts +1 -0
  872. package/dist/frontend/union-discriminants.test.js +182 -0
  873. package/dist/frontend/union-discriminants.test.js.map +1 -0
  874. package/dist/index.d.ts +7 -198
  875. package/dist/index.js +369 -1572
  876. package/dist/index.js.map +1 -1
  877. package/dist/ir/analysis.d.ts +16 -4
  878. package/dist/ir/analysis.js +23 -4
  879. package/dist/ir/analysis.js.map +1 -1
  880. package/dist/ir/analysis.test.js +15 -2
  881. package/dist/ir/analysis.test.js.map +1 -1
  882. package/dist/ir/constant-tables.js +67 -49
  883. package/dist/ir/constant-tables.js.map +1 -1
  884. package/dist/ir/constant-tables.test.js +1 -1
  885. package/dist/ir/control-flow.d.ts +6 -0
  886. package/dist/ir/control-flow.js +142 -0
  887. package/dist/ir/control-flow.js.map +1 -0
  888. package/dist/ir/control-flow.test.d.ts +1 -0
  889. package/dist/ir/control-flow.test.js +113 -0
  890. package/dist/ir/control-flow.test.js.map +1 -0
  891. package/dist/ir/integer-loops.js +7 -18
  892. package/dist/ir/integer-loops.js.map +1 -1
  893. package/dist/ir/integer-ranges.js +53 -27
  894. package/dist/ir/integer-ranges.js.map +1 -1
  895. package/dist/ir/ir.d.ts +334 -176
  896. package/dist/ir/ir.js +710 -903
  897. package/dist/ir/ir.js.map +1 -1
  898. package/dist/ir/ir.test.js +162 -1
  899. package/dist/ir/ir.test.js.map +1 -1
  900. package/dist/ir/scalar-records.js +165 -134
  901. package/dist/ir/scalar-records.js.map +1 -1
  902. package/dist/ir/scalar-records.test.js +1 -1
  903. package/dist/ir/serialize.d.ts +4 -2
  904. package/dist/ir/serialize.js +33 -14
  905. package/dist/ir/serialize.js.map +1 -1
  906. package/dist/ir/serialize.test.d.ts +1 -0
  907. package/dist/ir/serialize.test.js +57 -0
  908. package/dist/ir/serialize.test.js.map +1 -0
  909. package/dist/ir/traverse.d.ts +41 -0
  910. package/dist/ir/traverse.js +660 -0
  911. package/dist/ir/traverse.js.map +1 -0
  912. package/dist/ir/traverse.test.d.ts +1 -0
  913. package/dist/ir/traverse.test.js +242 -0
  914. package/dist/ir/traverse.test.js.map +1 -0
  915. package/dist/ir/validate.js +2018 -1498
  916. package/dist/ir/validate.js.map +1 -1
  917. package/dist/ir/validate.test.js +536 -2
  918. package/dist/ir/validate.test.js.map +1 -1
  919. package/dist/library/cache-primitives.d.ts +2 -3
  920. package/dist/library/cache-primitives.js +4 -6
  921. package/dist/library/cache-primitives.js.map +1 -1
  922. package/dist/library/fence-eval.js +2 -2
  923. package/dist/library/fence-eval.js.map +1 -1
  924. package/dist/library/int-infer.js +7 -6
  925. package/dist/library/int-infer.js.map +1 -1
  926. package/dist/library/int-infer.test.js +4 -4
  927. package/dist/library/library-cache.d.ts +3 -2
  928. package/dist/library/library-cache.js +5 -17
  929. package/dist/library/library-cache.js.map +1 -1
  930. package/dist/library/library-cache.test.js +54 -41
  931. package/dist/library/library-cache.test.js.map +1 -1
  932. package/dist/library/library-profile.d.ts +3 -1
  933. package/dist/library/library-profile.js +15 -6
  934. package/dist/library/library-profile.js.map +1 -1
  935. package/dist/library/prepare.d.ts +15 -0
  936. package/dist/library/prepare.js +584 -0
  937. package/dist/library/prepare.js.map +1 -0
  938. package/dist/library/semantic-source.d.ts +1 -1
  939. package/dist/library/semantic-source.js +8 -6
  940. package/dist/library/semantic-source.js.map +1 -1
  941. package/dist/library/sidecar-validate.js +4 -4
  942. package/dist/library/sidecar-validate.js.map +1 -1
  943. package/dist/library/sidecar.d.ts +2 -0
  944. package/dist/library/sidecar.js +10 -3
  945. package/dist/library/sidecar.js.map +1 -1
  946. package/dist/native/cache.d.ts +11 -0
  947. package/dist/native/cache.js +113 -0
  948. package/dist/native/cache.js.map +1 -0
  949. package/dist/native/cache.test.d.ts +1 -0
  950. package/dist/native/cache.test.js +66 -0
  951. package/dist/native/cache.test.js.map +1 -0
  952. package/dist/native/cli.d.ts +1 -0
  953. package/dist/native/cli.js +112 -0
  954. package/dist/native/cli.js.map +1 -0
  955. package/dist/native/compiler.d.ts +15 -0
  956. package/dist/native/compiler.js +336 -0
  957. package/dist/native/compiler.js.map +1 -0
  958. package/dist/native/compiler.test.d.ts +1 -0
  959. package/dist/native/compiler.test.js +174 -0
  960. package/dist/native/compiler.test.js.map +1 -0
  961. package/dist/native/comptime.d.ts +5 -0
  962. package/dist/native/comptime.js +73 -0
  963. package/dist/native/comptime.js.map +1 -0
  964. package/dist/native/comptime.test.d.ts +1 -0
  965. package/dist/native/comptime.test.js +65 -0
  966. package/dist/native/comptime.test.js.map +1 -0
  967. package/dist/native/executable-cache.d.ts +26 -0
  968. package/dist/native/executable-cache.js +228 -0
  969. package/dist/native/executable-cache.js.map +1 -0
  970. package/dist/native/executable-cache.test.d.ts +1 -0
  971. package/dist/native/executable-cache.test.js +151 -0
  972. package/dist/native/executable-cache.test.js.map +1 -0
  973. package/dist/native/file-identity.d.ts +4 -0
  974. package/dist/native/file-identity.js +14 -0
  975. package/dist/native/file-identity.js.map +1 -0
  976. package/dist/native/file-identity.test.d.ts +1 -0
  977. package/dist/native/file-identity.test.js +43 -0
  978. package/dist/native/file-identity.test.js.map +1 -0
  979. package/dist/native/library.d.ts +22 -0
  980. package/dist/native/library.js +83 -0
  981. package/dist/native/library.js.map +1 -0
  982. package/dist/native/prepare.d.ts +21 -0
  983. package/dist/native/prepare.js +174 -0
  984. package/dist/native/prepare.js.map +1 -0
  985. package/dist/native/prepare.test.d.ts +1 -0
  986. package/dist/native/prepare.test.js +70 -0
  987. package/dist/native/prepare.test.js.map +1 -0
  988. package/dist/native/sanitizer.d.ts +11 -0
  989. package/dist/native/sanitizer.js +137 -0
  990. package/dist/native/sanitizer.js.map +1 -0
  991. package/dist/native/sanitizer.test.d.ts +1 -0
  992. package/dist/native/sanitizer.test.js +58 -0
  993. package/dist/native/sanitizer.test.js.map +1 -0
  994. package/dist/native/task.d.ts +4 -0
  995. package/dist/native/task.js +16 -0
  996. package/dist/native/task.js.map +1 -0
  997. package/dist/native/task.test.d.ts +1 -0
  998. package/dist/native/task.test.js +17 -0
  999. package/dist/native/task.test.js.map +1 -0
  1000. package/dist/native/toolchain.d.ts +45 -0
  1001. package/dist/native/toolchain.js +94 -0
  1002. package/dist/native/toolchain.js.map +1 -0
  1003. package/dist/native/toolchain.test.d.ts +1 -0
  1004. package/dist/native/toolchain.test.js +85 -0
  1005. package/dist/native/toolchain.test.js.map +1 -0
  1006. package/dist/startup-cache.d.ts +1 -1
  1007. package/dist/startup-cache.js +2 -5
  1008. package/dist/startup-cache.js.map +1 -1
  1009. package/dist/timing.d.ts +4 -0
  1010. package/dist/timing.js +19 -0
  1011. package/dist/timing.js.map +1 -0
  1012. package/dist/wasi-paths.js +10 -7
  1013. package/dist/wasi-paths.js.map +1 -1
  1014. package/package.json +28 -19
  1015. package/surface-manifest.json +107 -98
  1016. package/dist/backend/c/async.d.ts +0 -171
  1017. package/dist/backend/c/async.js +0 -1317
  1018. package/dist/backend/c/async.js.map +0 -1
  1019. package/dist/backend/c/c-emitter.d.ts +0 -536
  1020. package/dist/backend/c/c-emitter.js +0 -1932
  1021. package/dist/backend/c/c-emitter.js.map +0 -1
  1022. package/dist/backend/c/exprs.d.ts +0 -15
  1023. package/dist/backend/c/exprs.js +0 -8847
  1024. package/dist/backend/c/exprs.js.map +0 -1
  1025. package/dist/backend/c/island.d.ts +0 -45
  1026. package/dist/backend/c/island.js +0 -281
  1027. package/dist/backend/c/island.js.map +0 -1
  1028. package/dist/backend/c/may-throw.js.map +0 -1
  1029. package/dist/backend/c/shapes.d.ts +0 -142
  1030. package/dist/backend/c/shapes.js +0 -603
  1031. package/dist/backend/c/shapes.js.map +0 -1
  1032. package/dist/backend/c/stmts.d.ts +0 -76
  1033. package/dist/backend/c/stmts.js +0 -1108
  1034. package/dist/backend/c/stmts.js.map +0 -1
  1035. package/dist/backend/c/types.d.ts +0 -71
  1036. package/dist/backend/c/types.js +0 -459
  1037. package/dist/backend/c/types.js.map +0 -1
  1038. package/dist/backend/c/types.test.js +0 -32
  1039. package/dist/backend/c/types.test.js.map +0 -1
  1040. package/dist/backend/c/walkers.d.ts +0 -134
  1041. package/dist/backend/c/walkers.js +0 -1772
  1042. package/dist/backend/c/walkers.js.map +0 -1
  1043. /package/dist/backend/{c/types.test.d.ts → cycle-analysis.test.d.ts} +0 -0
@@ -1,3 +1,4 @@
1
+ import { objectEnumerationReceiver } from "./object-enumeration-receiver.js";
1
2
  import { InternalCompilerError } from "../../errors.js";
2
3
  /* Container-surface call lowering: array methods (including the HOF family
3
4
  * map/filter/forEach with their synthesized helper functions), Map/Set
@@ -7,16 +8,31 @@ import * as ts from "../ts7/adapter.js";
7
8
  import { BOOL, CAUGHT, DYN, F64, JSVAL, STRING, UNDEFINED_T, VOID, arrayOf, funcOf, isRefCounted, isSupportedArrayElem, isSupportedIndexValue, isUnitType, typeEquals } from "../../ir/ir.js";
8
9
  import { ARRAY_METHODS, MAP_METHODS, SET_COMBINE_METHODS, SET_METHODS } from "./surfaces.js";
9
10
  import { tryLowerExpression } from "./expressions/try-lower-expression.js";
10
- import { isSafeToRepeat } from "./expressions/evaluation-safety.js";
11
11
  import { forOfVarTarget, lowerDestructuringAssign } from "./lower-stmts.js";
12
12
  import { isJsSourceFile, locOf } from "../program.js";
13
13
  import { islandPrimitiveExit, lowerDynDispatchMethodCall } from "./lower-calls.js";
14
14
  import { buildArraySortFn } from "./lower-array-sort.js";
15
15
  import { arrayIndexPresent, arrayValueRead, arrayValueStore, arrayValueType, currentArrayIndexPresent } from "./array-values.js";
16
16
  import { typeKey } from "../type-mapper.js";
17
+ import { dynUndefinedExpr, newFnCtx, nodeThrowExpr } from "./lowerer.js";
17
18
  import { boolLit, countedFor, numLit, strLit, varRef } from "../../ir/build.js";
18
19
  import { defaultAfterUndefined, lowerPositionArgument, lowerStaticallyUndefinedArgument, positionNumber } from "./optional-arguments.js";
19
20
  import { lowerArrayCopyWithin, lowerArrayFill } from "./array-indexed-mutation.js";
21
+ /** Object() and new Object() preserve known object inputs. Primitive
22
+ * boxing and unproven checked-dynamic values retain their refusal. */
23
+ export function lowerObjectConstructor(lowerer, args, loc) {
24
+ if (args.length === 0) {
25
+ return { kind: "recordLit", fields: [], type: { kind: "record", shapeId: lowerer.shapes.intern([]) }, loc };
26
+ }
27
+ if (args.length !== 1 || ts.isSpreadElement(args[0]))
28
+ return null;
29
+ const value = lowerer.lowerExpr(args[0]);
30
+ if (value.kind === "dynObjLit" || value.kind === "dynArrLit")
31
+ return value;
32
+ if (["record", "array", "object", "regex", "date", "bytes", "map", "set", "func", "classval"].includes(value.type.kind))
33
+ return value;
34
+ return null;
35
+ }
20
36
  function primitivePositionType(lowerer, type) {
21
37
  if (type.kind === "union") {
22
38
  return lowerer.unions.get(type.unionId)?.arms.every((arm) => primitivePositionType(lowerer, arm)) ?? false;
@@ -79,7 +95,13 @@ function lowerArraySpreadItems(lowerer, nodes, elem, arrType, loc) {
79
95
  ];
80
96
  for (const node of nodes) {
81
97
  if (ts.isSpreadElement(node)) {
82
- const source = lowerer.lowerExpr(node.expression);
98
+ let source = lowerer.lowerExpr(node.expression);
99
+ if (source.type.kind === "set" && typeEquals(source.type.elem, elem)) {
100
+ source = { kind: "setIntrinsic", method: "toArray", receiver: source, args: [], type: arrType, loc };
101
+ }
102
+ if (source.type.kind === "record" && lowerer.shapes.get(source.type.shapeId)?.tuple) {
103
+ source = lowerer.widthCoerce(source, arrType) ?? source;
104
+ }
83
105
  if (!typeEquals(source.type, arrType)) {
84
106
  lowerer.noLowering(`Array insertion spread from '${lowerer.fmt(source.type)}'`, node);
85
107
  }
@@ -137,9 +159,6 @@ function lowerArrayJoinSeparator(lowerer, node, loc) {
137
159
  * directly from its IR return type. Fence element kinds ScrArr cannot hold
138
160
  * before constructing that array type. */
139
161
  function fenceProducedArrayElem(lowerer, node, producer, elem) {
140
- if (elem.kind === "dyn") {
141
- lowerer.unsupported("SC1090", node, `${producer} with a callback returning 'unknown'-typed values (the result array has no static element type — annotate the callback's return)`);
142
- }
143
162
  if (!isSupportedArrayElem(elem)) {
144
163
  lowerer.unsupported("SC1090", node, `${producer} with a callback returning '${lowerer.fmt(elem)}' values (arrays of this element kind have no representation — store the values individually)`);
145
164
  }
@@ -205,6 +224,21 @@ export function lowerArrayMethodCall(lowerer, call, access) {
205
224
  // static arrIntrinsic over a jsval (the validator ICE).
206
225
  {
207
226
  const receiver = lowerer.lowerExpr(access.expression);
227
+ if (receiver.type.kind === "union") {
228
+ const arms = lowerer.unions.get(receiver.type.unionId)?.arms;
229
+ const present = arms?.find((arm) => arm.kind === "array");
230
+ if (present?.kind === "array" && arms?.every((arm) => typeEquals(arm, present) || isUnitType(arm))) {
231
+ // A predicate can narrow the element type without changing the
232
+ // original array layout. Extract that stored array before choosing
233
+ // a helper, then adapt callback arguments at their actual ABI.
234
+ const array = lowerer.runtimeOptionalPropertyReceiver(access.expression, receiver, present, name) ??
235
+ lowerer.coerceInto(access.expression, receiver, present);
236
+ return lowerer.withExpressionOverride(access.expression, array, () => lowerArrayMethodCall(lowerer, call, access));
237
+ }
238
+ }
239
+ if (receiver.type.kind === "record" && lowerer.shapes.get(receiver.type.shapeId)?.tuple) {
240
+ return lowerTupleReadMethodCall(lowerer, call, access, receiver);
241
+ }
208
242
  if (receiver.type.kind === "jsval") {
209
243
  const loweredArgs = call.arguments.map((a) => lowerer.lowerExpr(a));
210
244
  if (name === "filter" && loweredArgs[0]?.type.kind === "func" && loweredArgs[0].type.ret.kind === "void") {
@@ -228,16 +262,11 @@ export function lowerArrayMethodCall(lowerer, call, access) {
228
262
  return dispatched;
229
263
  lowerer.noLowering(`.${name} on an array value held in a checked-dynamic binding`, call, "assign it to an array-typed binding first (the validated extraction), then call the method");
230
264
  }
231
- // An evolving-`any` array binding under --dynamic whose flow type
232
- // EVOLVED past `any[]` (`const fns = []; fns.push(() => 1);
233
- // fns.map(...)` — the binding lowered array<jsval> at its `any[]`
234
- // declaration, while tsc's evolving-array analysis answers the
235
- // pushed element type at this site): the VALUE's element type is
236
- // the truth — ride the explicit-`any[]` handle-element lowering
237
- // (pushes marshal in, HOF callbacks bind the handle, results exit
238
- // per the checker type), never a typed intrinsic over a jsval-
239
- // element array (the validator ICE).
240
- if (receiver.type.kind === "array" && receiver.type.elem.kind === "jsval" && !typeEquals(receiverIr, receiver.type)) {
265
+ // Flow predicates and evolving-any analysis can refine the checker
266
+ // element type without changing the array's storage. Helpers and
267
+ // callback array arguments must retain the original layout and
268
+ // identity; element conversions happen at the callback boundary.
269
+ if (receiver.type.kind === "array" && !typeEquals(receiverIr, receiver.type)) {
241
270
  receiverIr = receiver.type;
242
271
  elem = receiver.type.elem;
243
272
  }
@@ -445,6 +474,17 @@ export function lowerArrayMethodCall(lowerer, call, access) {
445
474
  loc,
446
475
  };
447
476
  }
477
+ if (call.arguments.some(ts.isSpreadElement)) {
478
+ // Finish argument evaluation before mutating the receiver. Each
479
+ // spread snapshots its elements immediately, so a later argument
480
+ // can mutate that source without changing already-collected values.
481
+ const items = lowerArraySpreadItems(lowerer, call.arguments, elem, receiverIr, loc);
482
+ return {
483
+ kind: "arrIntrinsic",
484
+ method: name === "push" ? "pushSpread" : "unshiftSpread",
485
+ receiver, args: [items], type: F64, loc,
486
+ };
487
+ }
448
488
  const valueProbes = call.arguments.map((arg) => tryLowerExpression(lowerer, arg));
449
489
  if (valueProbes.some((probe) => probe !== null && lowerer.runtimeOptionalWidening(probe.type, elem) !== null)) {
450
490
  const items = lowerArrayValueItems(lowerer, call.arguments.map((arg) => lowerer.lowerExpr(arg)), elem, receiverIr, loc);
@@ -471,12 +511,11 @@ export function lowerArrayMethodCall(lowerer, call, access) {
471
511
  };
472
512
  }
473
513
  if (name === "pop") {
474
- // Like shift(), pop() returns undefined for an empty array. Union
475
- // element arrays remain fenced here because their existing boxed
476
- // element already carries the result union and a second undefined
477
- // wrapper would lose the element identity contract.
514
+ // Widen a union payload through the normal array-read machinery
515
+ // before removing it. Reinterpreting the stored union's tag as the
516
+ // result union would confuse arms when undefined changes their order.
478
517
  if (elem.kind === "union" && lowerer.armTag(elem.unionId, UNDEFINED_T) < 0) {
479
- lowerer.unsupported("SC1090", call, "'.pop()' on union-element arrays without an undefined arm (read the last element and splice it after narrowing instead)");
518
+ return lowerUnionArrayRemoval(lowerer, access.expression, elem, false, loc);
480
519
  }
481
520
  const receiver = lowerer.lowerExpr(access.expression);
482
521
  return {
@@ -518,7 +557,12 @@ export function lowerArrayMethodCall(lowerer, call, access) {
518
557
  // IsArray says spread; no honest static answer exists.
519
558
  lowerer.unsupported("SC1090", argNode, "concat of a bare inner array onto an array-of-arrays (JS would SPREAD it one level — wrap it: a.concat([inner]))");
520
559
  }
521
- const arg = lowerer.lowerExpr(argNode);
560
+ // Declaration-backed JS methods can return checked values even
561
+ // when their public signature names a concrete array. Validate
562
+ // that boundary before spreading the represented elements.
563
+ let arg = lowerer.lowerExpr(argNode);
564
+ if (arg.type.kind === "dyn")
565
+ arg = lowerer.coerceInto(argNode, arg, argArrayType);
522
566
  if (arg.type.kind !== "array")
523
567
  lowerer.badType(argNode, lowerer.typeOf(argNode));
524
568
  shape.push("a");
@@ -580,19 +624,20 @@ export function lowerArrayMethodCall(lowerer, call, access) {
580
624
  return { kind: "arrIntrinsic", method: "spliceInsert", receiver, args: [...args, items], type: receiverIr, loc };
581
625
  }
582
626
  if (name === "shift") {
583
- // JS shift exactly: undefined on an empty array, else the first
584
- // element with the tail sliding down — the result is the interned
585
- // `elem | undefined` union, the env-read convention. Union-element
586
- // arrays are fenced: their shift result would collapse arms
587
- // (`(string | undefined)[]`'s shift is `string | undefined` too, and
588
- // the box can't say which world the undefined came from).
627
+ // Like pop, a union without undefined needs an explicit tag widening.
589
628
  if (elem.kind === "union" && lowerer.armTag(elem.unionId, UNDEFINED_T) < 0) {
590
- lowerer.unsupported("SC1090", call, "'.shift()' on union-element arrays without an undefined arm (read [0] and splice(0, 1) with the narrowed value instead)");
629
+ return lowerUnionArrayRemoval(lowerer, access.expression, elem, true, loc);
591
630
  }
592
631
  const receiver = lowerer.lowerExpr(access.expression);
593
632
  return { kind: "arrIntrinsic", method: "shift", receiver, args: [], type: arrayValueType(lowerer, elem), loc };
594
633
  }
595
634
  if (name === "join") {
635
+ if (elem.kind === "dyn") {
636
+ const receiver = lowerer.coerceToExpected(lowerer.lowerExpr(access.expression), DYN);
637
+ const args = call.arguments.length ? [lowerer.lowerExprExpecting(call.arguments[0], DYN)] : [];
638
+ return lowerer.coerceToExpected({ kind: "dynInvoke", recv: receiver, method: "join",
639
+ calleeName: access.getText(), args, type: DYN, loc }, STRING);
640
+ }
596
641
  // The ambient declares join on every Array<T> (a per-element-type
597
642
  // interface split isn't expressible there), so string-convertible
598
643
  // elements are enforced here: nested arrays would need JS's recursive
@@ -627,6 +672,38 @@ export function lowerArrayMethodCall(lowerer, call, access) {
627
672
  // reduce / reduceRight
628
673
  return lowerArrayReduceCall(lowerer, call, access, name, elem);
629
674
  }
675
+ /** Read before splice so removal cannot destroy the result's owned payload.
676
+ * The source is evaluated once and empty/sparse arrays yield undefined using
677
+ * the same slot-state checks as an indexed read. */
678
+ function lowerUnionArrayRemoval(lowerer, source, elem, first, loc) {
679
+ const receiver = lowerer.lowerExpr(source);
680
+ const arr = lowerer.declareHiddenLocal("%removeArray", receiver.type);
681
+ const arrRef = varRef(arr.id, arr.type, loc);
682
+ const index = lowerer.declareHiddenLocal("%removeIndex", F64);
683
+ const indexRef = varRef(index.id, F64, loc);
684
+ const value = arrayValueRead(lowerer, arrRef, indexRef, elem, loc);
685
+ const result = lowerer.declareHiddenLocal("%removedValue", value.type);
686
+ return {
687
+ kind: "seqExpr",
688
+ stmts: [
689
+ { kind: "varDecl", localId: arr.id, init: receiver, loc },
690
+ {
691
+ kind: "varDecl", localId: index.id,
692
+ init: first ? numLit(0, loc) : {
693
+ kind: "bin", op: "-",
694
+ left: { kind: "arrIntrinsic", method: "length", receiver: arrRef, args: [], type: F64, loc },
695
+ right: numLit(1, loc), type: F64, loc,
696
+ }, loc,
697
+ },
698
+ { kind: "varDecl", localId: result.id, init: value, loc },
699
+ {
700
+ kind: "exprStmt",
701
+ expr: { kind: "arrIntrinsic", method: "splice", receiver: arrRef, args: [indexRef, numLit(1, loc)], type: arr.type, loc }, loc,
702
+ },
703
+ ],
704
+ result: varRef(result.id, result.type, loc), type: result.type, loc,
705
+ };
706
+ }
630
707
  function literalFlatDepth(value) {
631
708
  if (value.kind === "numLit")
632
709
  return value.value;
@@ -709,10 +786,9 @@ function lowerArrayFlatCall(lowerer, call, access, receiverType) {
709
786
  function lowerArraySearchCall(lowerer, call, access, method, elem) {
710
787
  const loc = locOf(call);
711
788
  const receiver = lowerer.lowerExpr(access.expression);
712
- const argNode = call.arguments[0] ?? call;
713
789
  if (call.arguments.some(ts.isSpreadElement))
714
790
  lowerer.noLowering(`.${method} with spread arguments`, call);
715
- let needle = call.arguments[0]
791
+ const needle = call.arguments[0]
716
792
  ? lowerer.lowerExpr(call.arguments[0])
717
793
  : { kind: "unitLit", unit: "undefined", type: UNDEFINED_T, loc };
718
794
  const fromIndex = call.arguments[1]
@@ -720,6 +796,11 @@ function lowerArraySearchCall(lowerer, call, access, method, elem) {
720
796
  : method === "lastIndexOf"
721
797
  ? { kind: "bin", op: "/", left: numLit(1, loc), right: numLit(0, loc), type: F64, loc }
722
798
  : numLit(0, loc);
799
+ return lowerArraySearchValues(lowerer, call, method, elem, receiver, needle, fromIndex);
800
+ }
801
+ function lowerArraySearchValues(lowerer, call, method, elem, receiver, needle, fromIndex) {
802
+ const loc = locOf(call);
803
+ const argNode = call.arguments[0] ?? call;
723
804
  // A derived CLASS VALUE against a base-classval element widens (the same
724
805
  // pointer — identity search is exact); the coercion path owns the ABI gate.
725
806
  if (needle.type.kind === "classval" && elem.kind === "classval" && !typeEquals(needle.type, elem)) {
@@ -765,14 +846,15 @@ function lowerArraySearchCall(lowerer, call, access, method, elem) {
765
846
  : [needle.type];
766
847
  const scalarNeedle = needleArms.every((arm) => arm.kind === "f64" || arm.kind === "string" || arm.kind === "bool" ||
767
848
  arm.kind === "bigint" || arm.kind === "symbol" || isUnitType(arm));
768
- const valueArms = lowerer.unions.get(valueT.unionId).arms;
849
+ const valueDef = lowerer.unions.get(valueT.unionId);
850
+ const valueArms = valueDef.arms;
769
851
  if (scalarNeedle && !valueArms.some((arm) => arm.kind === "func" || arm.kind === "set")) {
770
852
  const arms = [...valueArms];
771
853
  for (const arm of needleArms)
772
854
  if (!arms.some((existing) => typeEquals(existing, arm)))
773
855
  arms.push(arm);
774
856
  if (arms.length !== valueArms.length)
775
- valueT = { kind: "union", unionId: lowerer.unions.intern(arms) };
857
+ valueT = { kind: "union", unionId: lowerer.unions.transform(valueDef, arms) };
776
858
  }
777
859
  const directNeedle = method === "lastIndexOf" && elem.kind !== "union" && typeEquals(needle.type, elem);
778
860
  const searchNeedle = directNeedle ? needle : lowerer.coerceInto(argNode, needle, valueT);
@@ -791,6 +873,12 @@ function lowerArraySearchCall(lowerer, call, access, method, elem) {
791
873
  * includes, where NaN equals NaN while +0 and -0 remain equal. */
792
874
  function arraySearchEquality(lowerer, left, right, sameValueZero, loc) {
793
875
  if (left.type.kind !== "union" || right.type.kind !== "union" || left.type.unionId !== right.type.unionId) {
876
+ if (left.type.kind === "string" && right.type.kind === "string") {
877
+ return { kind: "strEq", negated: false, left, right, type: BOOL, loc };
878
+ }
879
+ if (left.type.kind === "bigint" && right.type.kind === "bigint") {
880
+ return { kind: "bin", op: "===", left: { kind: "libCall", fn: "bigint.cmp", args: [left, right], type: F64, loc }, right: numLit(0, loc), type: BOOL, loc };
881
+ }
794
882
  return { kind: "bin", op: "===", left, right, type: BOOL, loc };
795
883
  }
796
884
  const unionId = left.type.unionId;
@@ -1004,7 +1092,7 @@ function arraySearchHelper(lowerer, method, elem, valueT, needleT, directNeedle,
1004
1092
  * loop passes exactly what it declares (JS passes everything; a callback
1005
1093
  * only sees the parameters it names). Returns the lowered callback and
1006
1094
  * its declared arity. */
1007
- function hofCallbackArg(lowerer, argNode, lead, arrT, bindUntyped = false) {
1095
+ function hofCallbackArg(lowerer, argNode, lead, arrT, bindUntyped = false, expectedReturn) {
1008
1096
  const full = [...lead, F64, arrT];
1009
1097
  // A DYN-receiver HOF's callback (`parsed.flatMap((value) => ...)`):
1010
1098
  // the contextual signature types the unannotated param `any` (the
@@ -1039,15 +1127,16 @@ function hofCallbackArg(lowerer, argNode, lead, arrT, bindUntyped = false) {
1039
1127
  lowerer.jsvalParamOverrides.add(p);
1040
1128
  });
1041
1129
  }
1042
- // A checker-untyped array expression whose lowered value supplies a
1043
- // concrete static element type still contextually types an inline HOF
1044
- // callback with any/unknown. Bind only unannotated parameters to the
1045
- // exact ABI the synthesized loop passes. The override is temporary:
1046
- // one callback AST may be lowered under several generic instances.
1130
+ // An untyped or flow-refined array can contextually type an inline
1131
+ // callback differently from the stored element and array layout. Bind
1132
+ // unannotated parameters to the helper's ABI when a boundary adapter
1133
+ // cannot carry it. Include the optional-read prepass's parameter type
1134
+ // in this comparison. The override is temporary because one callback
1135
+ // AST can lower under several generic instances.
1047
1136
  const contextual = [];
1048
1137
  const previousImplicit = lowerer.implicitParamTypes;
1049
1138
  let contextualTs = null;
1050
- if (bindUntyped && (ts.isArrowFunction(argNode) || ts.isFunctionExpression(argNode))) {
1139
+ if (ts.isArrowFunction(argNode) || ts.isFunctionExpression(argNode)) {
1051
1140
  argNode.parameters.forEach((param, i) => {
1052
1141
  const expected = full[i];
1053
1142
  if (expected === undefined || expected.kind === "dyn" || expected.kind === "jsval" ||
@@ -1055,7 +1144,10 @@ function hofCallbackArg(lowerer, argNode, lead, arrT, bindUntyped = false) {
1055
1144
  return;
1056
1145
  }
1057
1146
  const checkerType = lowerer.checker.getTypeAtLocation(param.name);
1058
- if ((checkerType.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) === 0)
1147
+ const untyped = (checkerType.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0;
1148
+ const raw = untyped ? null : lowerer.mapTypeOf(checkerType);
1149
+ const mapped = raw ? lowerer.runtimeOptionalBindingType(param.name, raw) : null;
1150
+ if (untyped ? !bindUntyped : mapped === null || lowerer.coercibleValue(expected, mapped))
1059
1151
  return;
1060
1152
  const symbol = lowerer.checker.getSymbolAtLocation(param.name);
1061
1153
  if (!symbol)
@@ -1076,6 +1168,10 @@ function hofCallbackArg(lowerer, argNode, lead, arrT, bindUntyped = false) {
1076
1168
  }
1077
1169
  if (contextualTs !== null)
1078
1170
  lowerer.implicitParamTypes = contextualTs;
1171
+ const previousReturn = lowerer.contextualFunctionReturns.get(argNode);
1172
+ if (expectedReturn && (ts.isArrowFunction(argNode) || ts.isFunctionExpression(argNode))) {
1173
+ lowerer.contextualFunctionReturns.set(argNode, expectedReturn);
1174
+ }
1079
1175
  let fnArg;
1080
1176
  try {
1081
1177
  fnArg = lowerer.lowerExpr(argNode);
@@ -1090,6 +1186,27 @@ function hofCallbackArg(lowerer, argNode, lead, arrT, bindUntyped = false) {
1090
1186
  lowerer.runtimeOptionalBindingTypes.set(symbol, previous);
1091
1187
  }
1092
1188
  lowerer.implicitParamTypes = previousImplicit;
1189
+ if (previousReturn === undefined)
1190
+ lowerer.contextualFunctionReturns.delete(argNode);
1191
+ else
1192
+ lowerer.contextualFunctionReturns.set(argNode, previousReturn);
1193
+ }
1194
+ // A callback can accept a wider parameter type than the array supplies
1195
+ // (a reusable predicate over a union is common). Its closure still has
1196
+ // that wider ABI: adapt each actual argument before invoking it, just
1197
+ // as assignment to a narrower function slot does. Require a conversion
1198
+ // plan so this path never manufactures a stranded callback.
1199
+ if (fnArg.type.kind === "dyn") {
1200
+ const signatures = lowerer.checker.getCallSignatures(lowerer.typeOf(argNode));
1201
+ const ret = expectedReturn ?? (signatures[0] ? lowerer.mapTypeOf(lowerer.checker.getReturnTypeOfSignature(signatures[0])) : null);
1202
+ if (ret && ret.kind !== "void")
1203
+ fnArg = lowerer.coerceToExpected(fnArg, funcOf(full, ret));
1204
+ }
1205
+ if (fnArg.type.kind === "func" && fnArg.type.params.length <= full.length &&
1206
+ fnArg.type.params.every((param, i) => lowerer.coercibleValue(full[i], param))) {
1207
+ const callbackType = funcOf(full.slice(0, fnArg.type.params.length), fnArg.type.ret);
1208
+ if (!typeEquals(fnArg.type, callbackType))
1209
+ fnArg = lowerer.coerceToExpected(fnArg, callbackType);
1093
1210
  }
1094
1211
  // Array storage widens indexed reads with undefined so holes remain
1095
1212
  // observable. The HOF helper guards every callback behind arrayHas,
@@ -1193,12 +1310,10 @@ function filterResultElem(lowerer, call, argNode, elem, valueT, booleanFilter) {
1193
1310
  const checkerReceiver = access
1194
1311
  ? lowerer.mapTypeOf(lowerer.typeOf(access.expression))
1195
1312
  : null;
1196
- // Evolving-any arrays of island handles retain their jsval element ABI,
1197
- // while the checker later describes both the receiver and unchanged
1198
- // filter result by the evolved callable type. Equal checker elements mean
1199
- // no predicate narrowing occurred; preserve the runtime element home.
1200
- if (elem.kind === "jsval" && valueT.kind === "jsval" &&
1201
- result?.kind === "array" && checkerReceiver?.kind === "array" &&
1313
+ // Equal checker elements mean the filter introduces no new refinement.
1314
+ // Preserve the stored element layout even if an earlier predicate or
1315
+ // evolving-any analysis changed the receiver's flow type.
1316
+ if (result?.kind === "array" && checkerReceiver?.kind === "array" &&
1202
1317
  typeEquals(result.elem, checkerReceiver.elem)) {
1203
1318
  return elem;
1204
1319
  }
@@ -1451,29 +1566,22 @@ function arrayUnionHofHelper(lowerer, method, receiverT, arrays, callbackT, arit
1451
1566
  });
1452
1567
  return name;
1453
1568
  }
1454
- /** READ-ONLY array methods on TUPLE receivers — `t.slice(...)` and
1455
- * `t.map(f)`: a tuple is a fixed-shape record, but these methods never
1456
- * write, so the positions snapshot into a fresh array (the for-of-over-
1457
- * tuples stance — pure receivers only, since the reads re-emit per
1458
- * position) and the ordinary array machinery runs over it. The element
1459
- * type is the one position type, or the positions' interned union with
1460
- * each read wrapped into its arm (exactly the checker's callback
1461
- * parameter type). Null when this isn't a tuple slice/map — writers and
1462
- * the rest of the surface keep their fences. */
1463
- export function lowerTupleReadMethodCall(lowerer, call, access) {
1569
+ /** Tuple methods keep the original receiver alive through argument evaluation.
1570
+ * Callback methods read each position only when it is visited, so writes to
1571
+ * later positions through a captured alias are visible. A tuple cannot be
1572
+ * passed as the callback's array parameter without changing its identity;
1573
+ * that parameter retains an explicit representation boundary. */
1574
+ export function lowerTupleReadMethodCall(lowerer, call, access, tupleReceiver) {
1464
1575
  if (lowerer.chainBlocked(access, call))
1465
1576
  return null;
1466
- const name = access.name.text;
1467
- if (name !== "slice" && name !== "map")
1577
+ const method = access.name.text;
1578
+ const search = method === "includes" || method === "indexOf" || method === "lastIndexOf";
1579
+ if (method !== "slice" && method !== "map" && method !== "flatMap" && method !== "join" && !search)
1468
1580
  return null;
1469
1581
  if (!lowerer.isStdlibMember(access))
1470
1582
  return null;
1471
- let receiverIr = lowerer.mapTypeOf(lowerer.typeOf(access.expression));
1472
- let receiver = null;
1473
- // A readonly tuple union under Array.isArray is checker-typed as an
1474
- // unmappable intersection with any[], while maybeNarrow still extracts
1475
- // its one tuple arm. Dispatch the supported tuple read methods from
1476
- // that lowered representation, like tuple indexing and `.length`.
1583
+ let receiverIr = tupleReceiver?.type ?? lowerer.mapTypeOf(lowerer.typeOf(access.expression));
1584
+ let receiver = tupleReceiver ?? null;
1477
1585
  const checkerArray = lowerer.checkerArrayValue(access.expression);
1478
1586
  if (checkerArray?.type.kind === "record") {
1479
1587
  receiverIr = checkerArray.type;
@@ -1485,75 +1593,188 @@ export function lowerTupleReadMethodCall(lowerer, call, access) {
1485
1593
  if (!shape?.tuple)
1486
1594
  return null;
1487
1595
  receiver ??= lowerer.lowerExpr(access.expression);
1596
+ if (method === "join") {
1597
+ // Object.entries can retain its dynamic array representation behind a
1598
+ // checker tuple. Native tuples box as live references, so separator
1599
+ // evaluation can still mutate their elements before join reads them.
1600
+ // An unchecked outer array read must validate its optional payload
1601
+ // before passing the tuple to the runtime.
1602
+ if (receiver.type.kind === "union") {
1603
+ receiver = lowerer.coerceInto(access.expression, receiver, receiverIr);
1604
+ }
1605
+ const converted = lowerer.coerceInto(access.expression, receiver, DYN);
1606
+ const boxed = converted.kind === "dynFrom" && converted.value.type.kind === "record"
1607
+ ? { ...converted, liveRef: true } : converted;
1608
+ const joined = lowerDynDispatchMethodCall(lowerer, call, access, boxed, true);
1609
+ return joined ? lowerer.coerceInto(call, joined, STRING) : null;
1610
+ }
1488
1611
  if (receiver.type.kind !== "record")
1489
1612
  return null;
1490
- if (!isSafeToRepeat(receiver)) {
1491
- lowerer.noLowering(`${lowerer.checker.typeToString(lowerer.typeOf(access.expression))}.${name}`, call, "tuple receivers snapshot per position, so only effect-free receivers lower — bind the tuple to a const first");
1492
- }
1613
+ const fields = [...shape.fields].sort((a, b) => Number(a.name) - Number(b.name));
1614
+ const arms = [];
1615
+ for (const field of fields) {
1616
+ const types = field.type.kind === "union" ? lowerer.unions.get(field.type.unionId).arms : [field.type];
1617
+ for (const type of types)
1618
+ if (!arms.some(arm => typeEquals(arm, type)))
1619
+ arms.push(type);
1620
+ }
1621
+ if (arms.length === 0)
1622
+ return null;
1623
+ const elem = arms.length === 1 ? arms[0] : { kind: "union", unionId: lowerer.unions.intern(arms) };
1493
1624
  const loc = locOf(call);
1494
- const byIndex = [...shape.fields].sort((a, b) => Number(a.name) - Number(b.name));
1495
- let elemT = null;
1496
- {
1497
- const arms = [];
1498
- for (const f of byIndex) {
1499
- if (f.type.kind === "union") {
1500
- elemT = null;
1501
- break;
1502
- }
1503
- if (!arms.some((a) => typeEquals(a, f.type)))
1504
- arms.push(f.type);
1505
- elemT = arms.length === 1 ? arms[0] : { kind: "union", unionId: lowerer.unions.intern(arms) };
1625
+ const tuple = varRef("a.0", receiver.type, loc);
1626
+ const read = (field) => lowerer.coerceInto(access.expression, {
1627
+ kind: "recordGet", obj: tuple, shapeId: receiverIr.shapeId, field: field.name, type: field.type, loc,
1628
+ }, elem);
1629
+ if (search) {
1630
+ if (call.arguments.length > 2 || call.arguments.some(ts.isSpreadElement)) {
1631
+ return lowerer.noLowering(`tuple .${method} with spread or extra arguments`, call);
1632
+ }
1633
+ const arg = call.arguments[0];
1634
+ const undefinedArg = arg ? lowerStaticallyUndefinedArgument(lowerer, arg) : null;
1635
+ let needle = arg ? undefinedArg ?? lowerer.lowerExpr(arg) : null;
1636
+ if (!needle || isUnitType(needle.type) || needle.type.kind === "void") {
1637
+ const optional = arrayValueType(lowerer, elem);
1638
+ const wrapped = needle?.type.kind === "nullT"
1639
+ ? lowerer.coerceInto(arg ?? call, needle, optional) : lowerer.wrappedUndefined(optional, loc);
1640
+ if (!wrapped)
1641
+ return lowerer.noLowering(`tuple .${method} missing search value`, call);
1642
+ needle = needle ? defaultAfterUndefined(needle, wrapped) : wrapped;
1506
1643
  }
1644
+ const from = call.arguments[1]
1645
+ ? lowerPositionArgument(lowerer, call.arguments[1], numLit(0, loc))
1646
+ : numLit(method === "lastIndexOf" ? Infinity : 0, loc);
1647
+ const key = `tuple.${method}:${typeKey(receiver.type)}:${typeKey(needle.type)}:${typeKey(from.type)}:${call.arguments.length}`;
1648
+ let helper = lowerer.arrHofHelpers.get(key);
1649
+ const resultType = method === "includes" ? BOOL : F64;
1650
+ if (!helper) {
1651
+ helper = `%tuple.${method}.${lowerer.arrHofHelpers.size}`;
1652
+ lowerer.arrHofHelpers.set(key, helper);
1653
+ const params = [
1654
+ { localId: "a.0", name: "a", type: receiver.type },
1655
+ { localId: "needle.0", name: "needle", type: needle.type },
1656
+ { localId: "from.0", name: "from", type: from.type },
1657
+ ];
1658
+ const result = lowerArraySearchValues(lowerer, call, method, elem, { kind: "arrayLit", elems: fields.map(read), type: arrayOf(elem), loc }, varRef("needle.0", needle.type, loc), varRef("position.0", F64, loc));
1659
+ lowerer.liftedFns.push({
1660
+ name: helper, params, returnType: resultType,
1661
+ locals: [
1662
+ ...params.map(param => ({ id: param.localId, name: param.name, type: param.type, mutable: false })),
1663
+ { id: "position.0", name: "position", type: F64, mutable: false },
1664
+ ],
1665
+ body: [
1666
+ { kind: "varDecl", localId: "position.0", init: positionNumber(lowerer, varRef("from.0", from.type, loc), numLit(0, loc), call.arguments[1] ?? call, "tuple search position"), loc },
1667
+ { kind: "return", value: result, loc },
1668
+ ], loc,
1669
+ });
1670
+ }
1671
+ return { kind: "call", callee: helper, args: [receiver, needle, from], type: resultType, loc };
1507
1672
  }
1508
- if (elemT === null || byIndex.length === 0)
1509
- return null; // empty/union-position tuples keep the fence
1510
- const snapshotElem = elemT;
1511
- const snapshot = {
1512
- kind: "arrayLit",
1513
- elems: byIndex.map((f) => {
1514
- const read = {
1515
- kind: "recordGet",
1516
- obj: receiver,
1517
- shapeId: receiverIr.shapeId,
1518
- field: f.name,
1519
- type: f.type,
1520
- loc,
1521
- };
1522
- return typeEquals(f.type, snapshotElem) ? read : lowerer.coerceInto(access.expression, read, snapshotElem);
1523
- }),
1524
- type: arrayOf(snapshotElem),
1525
- loc,
1526
- };
1527
- if (name === "slice") {
1528
- if (call.arguments.length > 2) {
1673
+ if (method === "slice") {
1674
+ if (call.arguments.length > 2 || call.arguments.some(ts.isSpreadElement)) {
1529
1675
  lowerer.noLowering(`.slice with ${call.arguments.length} arguments`, call);
1530
1676
  }
1531
- const args = call.arguments.map((a) => lowerer.lowerExpr(a));
1532
- for (let i = 0; i < args.length; i++) {
1533
- if (args[i].type.kind !== "f64")
1534
- lowerer.badType(call.arguments[i], lowerer.typeOf(call.arguments[i]));
1677
+ const args = call.arguments.map(arg => lowerer.lowerExpr(arg));
1678
+ args.forEach((arg, i) => { if (arg.type.kind !== "f64")
1679
+ lowerer.badType(call.arguments[i], lowerer.typeOf(call.arguments[i])); });
1680
+ const resultType = arrayOf(elem);
1681
+ const key = `tuple.slice:${typeKey(receiver.type)}:${args.length}`;
1682
+ let helper = lowerer.arrHofHelpers.get(key);
1683
+ if (!helper) {
1684
+ helper = `%tuple.slice.${lowerer.arrHofHelpers.size}`;
1685
+ lowerer.arrHofHelpers.set(key, helper);
1686
+ const params = [receiver, ...args].map((arg, i) => ({ localId: i === 0 ? "a.0" : `arg.${i}`, name: `arg${i}`, type: arg.type }));
1687
+ lowerer.liftedFns.push({
1688
+ name: helper, params, returnType: resultType,
1689
+ locals: params.map(param => ({ id: param.localId, name: param.name, type: param.type, mutable: false })),
1690
+ body: [{ kind: "return", value: {
1691
+ kind: "arrIntrinsic", method: "slice",
1692
+ receiver: { kind: "arrayLit", elems: fields.map(read), type: resultType, loc },
1693
+ args: args.map((arg, i) => varRef(`arg.${i + 1}`, arg.type, loc)), type: resultType, loc,
1694
+ }, loc }], loc,
1695
+ });
1535
1696
  }
1536
- return { kind: "arrIntrinsic", method: "slice", receiver: snapshot, args, type: arrayOf(snapshotElem), loc };
1697
+ return { kind: "call", callee: helper, args: [receiver, ...args], type: resultType, loc };
1537
1698
  }
1538
- // map
1539
- if (call.arguments.length !== 1) {
1540
- lowerer.noLowering(`.map with ${call.arguments.length} arguments`, call, "the thisArg parameter has no lowering — use an arrow function");
1699
+ if (call.arguments.length !== 1 || call.arguments.some(ts.isSpreadElement)) {
1700
+ lowerer.noLowering(`.${method} with ${call.arguments.length} arguments`, call, "the thisArg parameter has no lowering — use an arrow function");
1541
1701
  }
1542
- const argNode = call.arguments[0];
1543
- const { fnArg, arity } = hofCallbackArg(lowerer, argNode, [arrayValueType(lowerer, snapshotElem)], arrayOf(snapshotElem));
1544
- const fnRet = fnArg.type.ret;
1545
- if (fnRet.kind === "void" || fnRet.kind === "func")
1702
+ const callback = call.arguments[0];
1703
+ // Check before the array HOF adapter can create a tuple-to-array copy.
1704
+ const signatures = lowerer.checker.getCallSignatures(lowerer.typeOf(callback));
1705
+ if (signatures.some(signature => signature.getParameters().length > 2)) {
1706
+ lowerer.noLowering(`tuple .${method} callback array parameter`, callback, "capture the original tuple explicitly to preserve its identity");
1707
+ }
1708
+ const { fnArg, arity } = hofCallbackArg(lowerer, callback, [elem], receiver.type);
1709
+ const ret = fnArg.type.ret;
1710
+ if (ret.kind === "void" || ret.kind === "func")
1546
1711
  lowerer.badType(call, lowerer.typeOf(call));
1547
- fenceProducedArrayElem(lowerer, call, "'.map()'", fnRet);
1548
- const outElem = callbackArrayElem(lowerer, call, fnRet);
1549
- const helper = arrayHofHelper(lowerer, "map", snapshotElem, fnRet, arity, loc, outElem);
1550
- return { kind: "call", callee: helper, args: [snapshot, fnArg], type: arrayOf(outElem), loc };
1712
+ if (method === "flatMap" && (ret.kind === "dyn" || ret.kind === "jsval" || (ret.kind === "record" && lowerer.shapes.get(ret.shapeId)?.tuple))) {
1713
+ return { kind: "dynInvoke", recv: { kind: "dynFrom", value: receiver, type: DYN, loc }, method: "flatMap", calleeName: access.getText(), args: [{ kind: "dynFrom", value: fnArg, type: DYN, loc }], type: DYN, loc };
1714
+ }
1715
+ if (method === "flatMap" && ret.kind === "union" && lowerer.unions.get(ret.unionId).arms.some(arm => arm.kind === "array")) {
1716
+ lowerer.noLowering("tuple .flatMap callback mixing array and scalar results", callback, "return an array from every path");
1717
+ }
1718
+ const flatten = method === "flatMap" && ret.kind === "array";
1719
+ const outElem = flatten ? ret.elem : callbackArrayElem(lowerer, call, ret);
1720
+ fenceProducedArrayElem(lowerer, call, `'.${method}()'`, outElem);
1721
+ const outType = arrayOf(outElem);
1722
+ const key = `tuple.${method}:${typeKey(receiver.type)}:${typeKey(fnArg.type)}:${typeKey(outElem)}`;
1723
+ let helper = lowerer.arrHofHelpers.get(key);
1724
+ if (!helper) {
1725
+ helper = `%tuple.${method}.${lowerer.arrHofHelpers.size}`;
1726
+ lowerer.arrHofHelpers.set(key, helper);
1727
+ const out = varRef("out.0", outType, loc);
1728
+ const result = varRef("r.0", ret, loc);
1729
+ const outputLength = { kind: "arrIntrinsic", method: "length", receiver: out, args: [], type: F64, loc };
1730
+ const body = [{ kind: "varDecl", localId: "out.0", init: { kind: "arrayLit", elems: [], type: outType, loc }, loc }];
1731
+ for (const field of fields) {
1732
+ const invocation = {
1733
+ kind: "callValue", callee: varRef("f.0", fnArg.type, loc),
1734
+ args: [read(field), numLit(Number(field.name), loc)].slice(0, arity), type: ret, loc,
1735
+ };
1736
+ body.push(field === fields[0]
1737
+ ? { kind: "varDecl", localId: "r.0", init: invocation, loc }
1738
+ : { kind: "assign", localId: "r.0", value: invocation, loc });
1739
+ if (flatten) {
1740
+ const index = varRef("i.0", F64, loc);
1741
+ body.push(countedFor(loc, { kind: "arrIntrinsic", method: "length", receiver: result, args: [], type: F64, loc }, () => [{
1742
+ kind: "if", cond: arrayIndexPresent(result, index, loc), then: [
1743
+ { kind: "varDecl", localId: "inner.0", init: arrayValueRead(lowerer, result, index, outElem, loc), loc },
1744
+ arrayValueStore(lowerer, out, outputLength, varRef("inner.0", arrayValueType(lowerer, outElem), loc), outElem, loc),
1745
+ ], else_: null, loc,
1746
+ }]));
1747
+ }
1748
+ else {
1749
+ body.push(arrayValueStore(lowerer, out, outputLength, result, outElem, loc));
1750
+ }
1751
+ }
1752
+ body.push({ kind: "return", value: out, loc });
1753
+ lowerer.liftedFns.push({
1754
+ name: helper,
1755
+ params: [{ localId: "a.0", name: "a", type: receiver.type }, { localId: "f.0", name: "f", type: fnArg.type }],
1756
+ returnType: outType,
1757
+ locals: [
1758
+ { id: "a.0", name: "a", type: receiver.type, mutable: false },
1759
+ { id: "f.0", name: "f", type: fnArg.type, mutable: false },
1760
+ { id: "out.0", name: "out", type: outType, mutable: false },
1761
+ { id: "r.0", name: "r", type: ret, mutable: true },
1762
+ ...(flatten ? [
1763
+ { id: "i.0", name: "i", type: F64, mutable: true },
1764
+ { id: "inner.0", name: "inner", type: arrayValueType(lowerer, outElem), mutable: false },
1765
+ ] : []),
1766
+ ], body, loc,
1767
+ });
1768
+ }
1769
+ return { kind: "call", callee: helper, args: [receiver, fnArg], type: outType, loc };
1551
1770
  }
1552
1771
  /** An ordinary indexed read: values retain their element type, while
1553
1772
  * holes, missing properties, and present undefined yield undefined. */
1554
1773
  export function lowerSafeIndexRead(lowerer, arr, index, loc) {
1774
+ if (arr.type.kind !== "array")
1775
+ throw new InternalCompilerError("indexed read requires an array");
1555
1776
  const elem = arr.type.elem;
1556
- if (elem.kind === "void" || elem.kind === "dyn")
1777
+ if (elem.kind === "void")
1557
1778
  return null;
1558
1779
  const resultT = arrayValueType(lowerer, elem);
1559
1780
  const key = `idxOr:${typeKey(elem)}`;
@@ -1780,8 +2001,7 @@ function buildArrayHofFn(lowerer, name, method, elem, fnRet, arity, loc, outElem
1780
2001
  * undefined unit arm (for REF elements that arm is the unit instance, the
1781
2002
  * standard union machinery). The Last pair is the SAME loop walked
1782
2003
  * backwards (`i = n - 1; i >= 0; i--`), exactly the es2023 spec's
1783
- * descending index walk. All require a bool-returning callback
1784
- * (JS's ToBoolean of arbitrary predicate results has no lowering). */
2004
+ * descending index walk. Predicate results use JavaScript ToBoolean. */
1785
2005
  function lowerArrayFindLikeCall(lowerer, call, access, method, elem, bindUntyped = false) {
1786
2006
  const loc = locOf(call);
1787
2007
  const receiver = lowerer.lowerExpr(access.expression);
@@ -1796,7 +2016,7 @@ function lowerArrayFindLikeCall(lowerer, call, access, method, elem, bindUntyped
1796
2016
  // `packages.some((p) => p.scripts[name])` idiom, whose callback
1797
2017
  // returns the index read's `string | undefined`).
1798
2018
  const fnRet = fnArg.type.ret;
1799
- const truthyRet = fnRet.kind === "bool" || fnRet.kind === "f64" || fnRet.kind === "string" ||
2019
+ const truthyRet = fnRet.kind === "bool" || fnRet.kind === "f64" || fnRet.kind === "string" || fnRet.kind === "dyn" ||
1800
2020
  (fnRet.kind === "union" &&
1801
2021
  (lowerer.unions.get(fnRet.unionId)?.arms ?? []).every((a) => a.kind !== "dyn" && a.kind !== "caught" && a.kind !== "jsval"));
1802
2022
  if (!truthyRet)
@@ -1814,26 +2034,48 @@ function lowerArrayFindLikeCall(lowerer, call, access, method, elem, bindUntyped
1814
2034
  loc,
1815
2035
  };
1816
2036
  }
1817
- // find: the result is the checker's `T | undefined` union. When the
1818
- // element type IS that union already (it carries an undefined arm), the
1819
- // found element passes through untouched; otherwise it wraps into its
1820
- // arm. A union element whose result union differs would need the
1821
- // union-into-union re-tag that doesn't exist — fenced.
1822
- const resultT = bindUntyped ? arrayValueType(lowerer, elem) : lowerer.irTypeOf(call);
2037
+ // find visits holes as undefined and can infer a predicate that selects
2038
+ // a subset of the element union. A result matching the receiver's flow
2039
+ // element inherits that earlier refinement. Otherwise only an inline,
2040
+ // inferred predicate proves a new narrowing; explicit assertions keep
2041
+ // the same refusal boundary as filter.
2042
+ const valueT = arrayValueType(lowerer, elem);
2043
+ const checkerReceiver = lowerer.mapTypeOf(lowerer.typeOf(access.expression));
2044
+ const checkerResult = lowerer.irTypeOf(call);
2045
+ const unchangedElement = checkerReceiver?.kind === "array" &&
2046
+ typeEquals(checkerResult, arrayValueType(lowerer, checkerReceiver.elem));
2047
+ const resultT = bindUntyped ? valueT : checkerResult;
1823
2048
  if (resultT.kind !== "union")
1824
2049
  lowerer.badType(call, lowerer.typeOf(call)); // defensive: T | undefined always maps to a union
1825
2050
  const undefTag = lowerer.armTag(resultT.unionId, UNDEFINED_T);
1826
2051
  if (undefTag < 0)
1827
2052
  lowerer.badType(call, lowerer.typeOf(call));
1828
- const helper = findHelper(lowerer, elem, resultT, undefTag, fnRet, arity, last, loc);
2053
+ let retag = null;
2054
+ if (!lowerer.coercibleValue(valueT, resultT)) {
2055
+ const inline = ts.isArrowFunction(argNode) || ts.isFunctionExpression(argNode);
2056
+ if (!unchangedElement && (!inline || argNode.type !== undefined)) {
2057
+ lowerer.unsupported("SC1090", argNode, `narrowing '.${method}' requires an inline callback with an inferred predicate (annotate the return ': boolean' to keep the receiver's element type)`);
2058
+ }
2059
+ const signature = inline ? lowerer.checker.getSignatureFromDeclaration(argNode) : undefined;
2060
+ const predicate = signature ? lowerer.checker.getTypePredicateOfSignature(signature) : undefined;
2061
+ if ((!unchangedElement && (!predicate || predicate.parameterIndex !== 0)) || valueT.kind !== "union") {
2062
+ lowerer.unsupported("SC1090", call, `'.${method}' result narrowing without a predicate over its element`);
2063
+ }
2064
+ retag = lowerer.narrowedRetagHelper(call, valueT.unionId, resultT.unionId, loc);
2065
+ if (retag === null)
2066
+ lowerer.unsupported("SC1090", call, `'.${method}' narrowing to an incompatible result layout`);
2067
+ }
2068
+ const helper = findHelper(lowerer, elem, resultT, undefTag, fnRet, arity, last, loc, retag);
1829
2069
  return { kind: "call", callee: helper, args: [receiver, fnArg], type: resultT, loc };
1830
2070
  }
1831
2071
  /** ToBoolean of a predicate result inside a synthesized HOF helper — the
1832
- * ensureBool subset the find-like path admits (bool through; f64/string/
1833
- * truthy-answerable unions via toBool). */
2072
+ * ensureBool subset the find-like path admits (bool through; checked
2073
+ * values via dynTest; f64/string/truthy-answerable unions via toBool). */
1834
2074
  function predToBool(e) {
1835
2075
  if (e.type.kind === "bool")
1836
2076
  return e;
2077
+ if (e.type.kind === "dyn")
2078
+ return { kind: "dynTest", test: "truthy", value: e, type: BOOL, loc: e.loc };
1837
2079
  return { kind: "toBool", operand: e, type: BOOL, loc: e.loc };
1838
2080
  }
1839
2081
  /** The find loop, from existing IR nodes:
@@ -1842,7 +2084,7 @@ function predToBool(e) {
1842
2084
  * for (i = 0; i < n; i++) { v = a[i]; if (f(v)) return <v as result arm>; }
1843
2085
  * return <undefined arm>;
1844
2086
  */
1845
- function findHelper(lowerer, elem, resultT, undefTag, fnRet, arity, last, loc) {
2087
+ function findHelper(lowerer, elem, resultT, undefTag, fnRet, arity, last, loc, retag) {
1846
2088
  const method = last ? "findLast" : "find";
1847
2089
  const key = `${method}:${typeKey(elem)}:${typeKey(resultT)}:${typeKey(fnRet)}:${arity}`;
1848
2090
  const existing = lowerer.arrHofHelpers.get(key);
@@ -1854,7 +2096,8 @@ function findHelper(lowerer, elem, resultT, undefTag, fnRet, arity, last, loc) {
1854
2096
  const fnT = funcOf([arrayValueType(lowerer, elem), F64, arrT].slice(0, arity), fnRet);
1855
2097
  const valueT = arrayValueType(lowerer, elem);
1856
2098
  const v = varRef("v.0", valueT, loc);
1857
- const found = lowerer.coerceToExpected(v, resultT);
2099
+ const found = retag === null ? lowerer.coerceToExpected(v, resultT) :
2100
+ { kind: "call", callee: retag, args: [v], type: resultT, loc };
1858
2101
  const miss = {
1859
2102
  kind: "unionWrap",
1860
2103
  unionId: resultT.unionId,
@@ -2034,6 +2277,9 @@ function lowerArrayFlatMapCall(lowerer, call, access, elem) {
2034
2277
  lowerer.unsupported("SC1090", call, "this call form"); // tsc-guarded
2035
2278
  const { fnArg, arity } = hofCallbackArg(lowerer, argNode, [arrayValueType(lowerer, elem)], arrT);
2036
2279
  const fnRet = fnArg.type.ret;
2280
+ if (fnRet.kind === "dyn" || fnRet.kind === "jsval" || (fnRet.kind === "record" && lowerer.shapes.get(fnRet.shapeId)?.tuple)) {
2281
+ return { kind: "dynInvoke", recv: { kind: "dynFrom", value: receiver, liveRef: true, type: DYN, loc }, method: "flatMap", calleeName: access.getText(), args: [{ kind: "dynFrom", value: fnArg, type: DYN, loc }], type: DYN, loc };
2282
+ }
2037
2283
  if (fnRet.kind === "union") {
2038
2284
  const def = lowerer.unions.get(fnRet.unionId);
2039
2285
  if (def?.arms.some((a) => a.kind === "array")) {
@@ -2170,7 +2416,7 @@ function lowerArrayReduceCall(lowerer, call, access, method, elem) {
2170
2416
  (hasInit ? lowerer.irTypeOf(call) : arrayValueType(lowerer, elem));
2171
2417
  if (accT.kind === "void" || accT.kind === "func")
2172
2418
  lowerer.badType(call, lowerer.typeOf(call));
2173
- const { fnArg, arity } = hofCallbackArg(lowerer, argNode, [accT, arrayValueType(lowerer, elem)], arrT);
2419
+ const { fnArg, arity } = hofCallbackArg(lowerer, argNode, [accT, arrayValueType(lowerer, elem)], arrT, false, accT);
2174
2420
  const helper = reduceHelper(lowerer, method, elem, accT, fnArg.type.ret, arity, hasInit, loc);
2175
2421
  const args = [receiver, fnArg];
2176
2422
  if (hasInit)
@@ -2311,7 +2557,18 @@ function lowerArraySortCall(lowerer, call, access, elem, arrT) {
2311
2557
  }
2312
2558
  const receiver = lowerer.lowerExpr(access.expression);
2313
2559
  const argNode = call.arguments[0];
2314
- const fnArg = lowerer.lowerExpr(argNode);
2560
+ let fnArg = lowerer.lowerExpr(argNode);
2561
+ // Reusable JS comparators often accept checked values. Adapt the array's
2562
+ // element ABI just as other array callbacks do before sorting.
2563
+ if (fnArg.type.kind === "func" && fnArg.type.params.length <= 2 &&
2564
+ fnArg.type.params.every((param) => lowerer.coercibleValue(elem, param))) {
2565
+ // Arithmetic on inferred JS values retains a checked result because
2566
+ // it can produce BigInt. The sort callback still requires a number.
2567
+ const result = fnArg.type.ret.kind === "dyn" && isJsSourceFile(argNode.getSourceFile()) ? F64 : fnArg.type.ret;
2568
+ const expected = funcOf(fnArg.type.params.map(() => elem), result);
2569
+ if (!typeEquals(fnArg.type, expected))
2570
+ fnArg = lowerer.coerceToExpected(fnArg, expected);
2571
+ }
2315
2572
  // The comparator receives exactly (a, b); declaring a prefix is
2316
2573
  // ordinary TS. Its result must be number (the spec coerces arbitrary
2317
2574
  // results — no lowering for that).
@@ -2556,10 +2813,25 @@ export function lowerArrayConstructor(lowerer, expr, args) {
2556
2813
  if (contextual)
2557
2814
  result = lowerer.mapTypeOf(contextual);
2558
2815
  }
2816
+ if (isJsSourceFile(expr.getSourceFile()) && (result === null || result.kind === "dyn"))
2817
+ result = arrayOf(DYN);
2559
2818
  if (result?.kind !== "array" || !isSupportedArrayElem(result.elem)) {
2560
2819
  lowerer.badType(expr, lowerer.typeOf(expr));
2561
2820
  }
2562
2821
  const argType = args.length === 1 ? lowerer.mapTypeOf(lowerer.typeOf(args[0])) : null;
2822
+ if (args.length === 1 && result.elem.kind === "dyn" && (argType === null || argType.kind === "dyn")) {
2823
+ const input = lowerer.declareHiddenLocal("%arrayCtorValue", DYN);
2824
+ const value = varRef(input.id, DYN, loc);
2825
+ const local = lowerer.declareHiddenLocal("%arrayCtor", result);
2826
+ const array = varRef(local.id, result, loc);
2827
+ return { kind: "seqExpr", stmts: [
2828
+ { kind: "varDecl", localId: input.id, init: lowerer.lowerExprExpecting(args[0], DYN), loc },
2829
+ { kind: "varDecl", localId: local.id, init: { kind: "arrayLit", elems: [], type: result, loc }, loc },
2830
+ { kind: "if", cond: { kind: "dynTest", test: "number", value, type: BOOL, loc },
2831
+ then: [{ kind: "arraySetLength", arr: array, length: { kind: "dynCheck", value, type: F64, loc }, loc }],
2832
+ else_: [arrayValueStore(lowerer, array, numLit(0, loc), value, DYN, loc)], loc },
2833
+ ], result: array, type: result, loc };
2834
+ }
2563
2835
  if (argType?.kind === "dyn" || argType?.kind === "jsval") {
2564
2836
  lowerer.noLowering("Array constructor with a dynamically typed sole argument", args[0]);
2565
2837
  }
@@ -2622,6 +2894,84 @@ export function lowerArrayOfCall(lowerer, call, access) {
2622
2894
  loc: locOf(call),
2623
2895
  };
2624
2896
  }
2897
+ /** Mapper-less checked Array.from: acquire once, then step through emitted
2898
+ * property and call dispatch so native class iterators retain their methods. */
2899
+ export function lowerCheckedArrayFrom(lowerer, source, loc, mapper, receiver, numeric = false) {
2900
+ const iterator = lowerer.declareHiddenLocal("%fromIterator", DYN);
2901
+ const next = lowerer.declareHiddenLocal("%fromNext", DYN);
2902
+ const step = lowerer.declareHiddenLocal("%fromStep", DYN);
2903
+ const out = lowerer.declareHiddenLocal("%fromArray", DYN);
2904
+ const done = lowerer.declareHiddenLocal("%fromDone", BOOL);
2905
+ done.mutable = true;
2906
+ const index = mapper ? lowerer.declareHiddenLocal("%fromIndex", F64) : null;
2907
+ if (index)
2908
+ index.mutable = true;
2909
+ const get = (value, key) => ({ kind: "dynKeyGet", value, key: strLit(key, loc), type: DYN, loc });
2910
+ const item = get(varRef(step.id, DYN, loc), "value");
2911
+ const mapped = mapper && index ? { kind: "ternary", cond: { kind: "dynTest", test: "undefined", value: mapper, type: BOOL, loc },
2912
+ then: item, else_: { kind: "dynCall", callee: mapper, ...(receiver ? { receiver } : {}), calleeName: "Array.from mapper", args: [item, lowerer.coerceToExpected(varRef(index.id, F64, loc), DYN)], type: DYN, loc }, type: DYN, loc } : item;
2913
+ const element = numeric ? lowerer.coerceToExpected({ kind: "libCall", fn: "dyn.toNumberCoerce", args: [mapped], type: F64, loc }, DYN) : mapped;
2914
+ let append = { kind: "exprStmt", expr: { kind: "dynInvoke", recv: varRef(out.id, DYN, loc), method: "push", calleeName: "Array.from", args: [element], type: DYN, loc }, loc };
2915
+ if (mapper) {
2916
+ const error = lowerer.declareHiddenLocal("%fromError", CAUGHT);
2917
+ const close = lowerer.declareHiddenLocal("%fromReturn", DYN);
2918
+ append = { kind: "tryCatch", tryBody: [append], catchLocalId: error.id, finallyBody: null, loc, catchBody: [
2919
+ { kind: "tryCatch", catchLocalId: null, catchBody: [], finallyBody: null, loc, tryBody: [
2920
+ { kind: "varDecl", localId: close.id, init: get(varRef(iterator.id, DYN, loc), "return"), loc },
2921
+ { kind: "if", cond: { kind: "dynTest", test: "function", value: varRef(close.id, DYN, loc), type: BOOL, loc }, then: [
2922
+ { kind: "exprStmt", expr: { kind: "dynCall", callee: varRef(close.id, DYN, loc), receiver: varRef(iterator.id, DYN, loc), calleeName: "iterator.return", args: [], type: DYN, loc }, loc },
2923
+ ], else_: null, loc },
2924
+ ] },
2925
+ { kind: "rethrow", localId: error.id, loc },
2926
+ ] };
2927
+ }
2928
+ const stmts = [
2929
+ ...(mapper ? [{ kind: "if", cond: { kind: "dynTest", test: "undefined", value: mapper, type: BOOL, loc }, then: [], else_: [
2930
+ { kind: "if", cond: { kind: "dynTest", test: "function", value: mapper, type: BOOL, loc }, then: [], else_: [
2931
+ { kind: "exprStmt", expr: nodeThrowExpr(1, "", "Array.from mapper is not a function", DYN, loc), loc },
2932
+ ], loc },
2933
+ ], loc }] : []),
2934
+ { kind: "varDecl", localId: iterator.id, init: { kind: "libCall", fn: "dyn.iteratorResult", args: [{ kind: "libCall", fn: "dyn.arrayFromIterator", args: [source], type: DYN, loc }], type: DYN, loc }, loc },
2935
+ { kind: "varDecl", localId: next.id, init: get(varRef(iterator.id, DYN, loc), "next"), loc },
2936
+ { kind: "varDecl", localId: out.id, init: { kind: "dynArrLit", elems: [], type: DYN, loc }, loc },
2937
+ { kind: "varDecl", localId: done.id, init: boolLit(false, loc), loc },
2938
+ ...(index ? [{ kind: "varDecl", localId: index.id, init: numLit(0, loc), loc }] : []),
2939
+ { kind: "while", cond: { kind: "unary", op: "!", operand: varRef(done.id, BOOL, loc), type: BOOL, loc }, body: [
2940
+ { kind: "varDecl", localId: step.id, init: { kind: "libCall", fn: "dyn.iteratorResult", args: [{
2941
+ kind: "dynCall", callee: varRef(next.id, DYN, loc), receiver: varRef(iterator.id, DYN, loc), calleeName: "iterator.next", args: [], type: DYN, loc,
2942
+ }], type: DYN, loc }, loc },
2943
+ { kind: "assign", localId: done.id, value: { kind: "dynTest", test: "truthy", value: get(varRef(step.id, DYN, loc), "done"), type: BOOL, loc }, loc },
2944
+ { kind: "if", cond: { kind: "unary", op: "!", operand: varRef(done.id, BOOL, loc), type: BOOL, loc }, then: [
2945
+ append,
2946
+ ...(index ? [{ kind: "assign", localId: index.id, value: { kind: "bin", op: "+", left: varRef(index.id, F64, loc), right: numLit(1, loc), type: F64, loc }, loc }] : []),
2947
+ ], else_: null, loc },
2948
+ ], loc },
2949
+ ];
2950
+ return { kind: "seqExpr", stmts, result: varRef(out.id, DYN, loc), type: DYN, loc };
2951
+ }
2952
+ export function lowerArrayFromValue(lowerer, loc) {
2953
+ const name = "%builtin.Array.from";
2954
+ if (!lowerer.liftedFns.some((fn) => fn.name === name)) {
2955
+ const context = newFnCtx(false, null, null, DYN);
2956
+ lowerer.fnStack.push(context);
2957
+ try {
2958
+ const params = ["source", "options"].map((name) => {
2959
+ const local = lowerer.declareHiddenLocal(name, DYN);
2960
+ return { localId: local.id, name, type: DYN };
2961
+ });
2962
+ const [source, options] = params.map((p) => varRef(p.localId, DYN, loc));
2963
+ const argument = (index) => ({ kind: "dynKeyGet", value: options, key: strLit(index, loc), type: DYN, loc });
2964
+ const value = lowerCheckedArrayFrom(lowerer, source, loc, argument("0"), argument("1"));
2965
+ const constructorCheck = { kind: "if", cond: { kind: "dynTest", test: "function", value: { kind: "libCall", fn: "dyn.this", args: [], type: DYN, loc }, type: BOOL, loc },
2966
+ then: [{ kind: "runtimeFence", code: "SC2020", message: "Array.from with a custom constructor receiver is not supported", loc }], else_: null, loc };
2967
+ lowerer.liftedFns.push({ name, params, returnType: DYN, locals: context.locals, body: [constructorCheck, ...value.stmts, { kind: "return", value: value.result, loc }], loc });
2968
+ }
2969
+ finally {
2970
+ lowerer.fnStack.pop();
2971
+ }
2972
+ }
2973
+ return { kind: "dynFrom", value: { kind: "closure", fnName: name, captures: [], type: { kind: "func", params: [DYN], ret: DYN, rest: true }, loc }, fnName: "from", type: DYN, loc };
2974
+ }
2625
2975
  /** `Array.from({ length: n }, mapfn)` — the counted-generation idiom — on
2626
2976
  * THE stdlib Array global. The source must be an OBJECT LITERAL whose
2627
2977
  * single property is `length` (the shape the idiom always spells; the
@@ -2645,6 +2995,28 @@ export function lowerArrayFromCall(lowerer, call, access) {
2645
2995
  return null;
2646
2996
  const loc = locOf(call);
2647
2997
  const args = call.arguments;
2998
+ if (isJsSourceFile(call.getSourceFile()) && args.length >= 1 && args.length <= 3 && !args.some(ts.isSpreadElement)) {
2999
+ const name = "%builtin.Array.fromDirect";
3000
+ if (!lowerer.liftedFns.some((fn) => fn.name === name)) {
3001
+ const context = newFnCtx(false, null, null, DYN);
3002
+ lowerer.fnStack.push(context);
3003
+ try {
3004
+ const params = ["source", "mapper", "receiver"].map((name) => {
3005
+ const local = lowerer.declareHiddenLocal(name, DYN);
3006
+ return { localId: local.id, name, type: DYN };
3007
+ });
3008
+ const refs = params.map((param) => varRef(param.localId, DYN, loc));
3009
+ const value = lowerCheckedArrayFrom(lowerer, refs[0], loc, refs[1], refs[2]);
3010
+ lowerer.liftedFns.push({ name, params, returnType: DYN, locals: context.locals,
3011
+ body: [...value.stmts, { kind: "return", value: value.result, loc }], loc });
3012
+ }
3013
+ finally {
3014
+ lowerer.fnStack.pop();
3015
+ }
3016
+ }
3017
+ return { kind: "call", callee: name, args: [0, 1, 2].map((i) => args[i]
3018
+ ? lowerer.lowerExprExpecting(args[i], DYN) : dynUndefinedExpr(loc)), type: DYN, loc };
3019
+ }
2648
3020
  // MAPPER-LESS `Array.from({ length: n })` (usually with an explicit
2649
3021
  // type argument — the pMap results-array idiom): a length-n array of
2650
3022
  // ABSENT slots, filled by index before any read. Union elements with
@@ -2719,6 +3091,9 @@ export function lowerArrayFromCall(lowerer, call, access) {
2719
3091
  }
2720
3092
  return { kind: "call", callee: helper, args: [src, fnArg], type: arrayOf(outElem), loc };
2721
3093
  }
3094
+ if (src.type.kind === "bytes" && args.length === 1) {
3095
+ return { kind: "bytesIntrinsic", method: "toArray", receiver: src, args: [], type: arrayOf(F64), loc };
3096
+ }
2722
3097
  if (src.type.kind === "set" && args.length === 1) {
2723
3098
  return { kind: "setIntrinsic", method: "toArray", receiver: src, args: [], type: arrayOf(src.type.elem), loc };
2724
3099
  }
@@ -2726,6 +3101,9 @@ export function lowerArrayFromCall(lowerer, call, access) {
2726
3101
  // `[...s]` and both Array.from(s) forms.
2727
3102
  if (src.type.kind === "string" && args.length === 1)
2728
3103
  return strCharsCall(lowerer, src, loc);
3104
+ if (src.type.kind === "dyn" && args.length === 1) {
3105
+ return lowerCheckedArrayFrom(lowerer, src, loc);
3106
+ }
2729
3107
  lowerer.noLowering("Array.from with this argument shape", call, "Array.from(array), Array.from(array, mapper), Array.from(aString), Array.from(aString, mapper), and Array.from({ length: n }, mapper) are the lowered forms");
2730
3108
  }
2731
3109
  const n = args.length === 2 && ts.isObjectLiteralExpression(args[0]) && args[0].properties.length === 1
@@ -2949,13 +3327,12 @@ export function lowerMapMethodCall(lowerer, call, access) {
2949
3327
  }
2950
3328
  if (receiverIr?.kind !== "map")
2951
3329
  return null;
2952
- if (!lowerer.isStdlibMember(access))
3330
+ // Collection views can refine has() while retaining its native ABI.
3331
+ if (!probedUntyped && !lowerer.isStdlibMember(access) && name !== "has")
2953
3332
  return null;
2954
3333
  const loc = locOf(call);
2955
- const receiver = lowerer.lowerExpr(access.expression);
2956
- // The lib's `set` returns the Map (chaining typechecks); the lowered
2957
- // set is a void statement, so a chained receiver has no value — fence
2958
- // it instead of emitting a void receiver.
3334
+ const value = lowerer.lowerExpr(access.expression);
3335
+ const receiver = lowerer.runtimeOptionalPropertyReceiver(access.expression, value, receiverIr, name) ?? value;
2959
3336
  if (receiver.type.kind !== "map") {
2960
3337
  lowerer.noLowering("chained Map method calls", access.expression, "the lowered set() produces no value — call each set(k, v) as its own statement");
2961
3338
  }
@@ -2964,23 +3341,30 @@ export function lowerMapMethodCall(lowerer, call, access) {
2964
3341
  lowerer.noLowering(`.forEach with ${call.arguments.length} arguments`, call, "the thisArg parameter has no lowering — use an arrow function");
2965
3342
  }
2966
3343
  if (name === "get") {
2967
- const k = lowerer.lowerExprExpecting(call.arguments[0], receiverIr.key);
3344
+ const k = lowerer.lowerCollectionKey(call.arguments[0], receiverIr.key);
2968
3345
  // The checker types the call `V | undefined`, which interns the
2969
3346
  // result union. `undefined` sorts LAST among all possible arm
2970
3347
  // typeKeys, so when V is itself a union its arms keep their tags in
2971
3348
  // the result union — the backend leans on that (docs/ir.md).
2972
- const type = lowerer.irTypeOf(call);
2973
- if (type.kind !== "union")
3349
+ const type = receiverIr.value.kind === "dyn" ? DYN : lowerer.irTypeOf(call);
3350
+ if (type.kind !== "union" && type.kind !== "dyn")
2974
3351
  lowerer.badType(call, lowerer.typeOf(call));
2975
3352
  return { kind: "mapIntrinsic", method: "get", receiver, args: [k], type, loc };
2976
3353
  }
2977
3354
  if (name === "set") {
2978
- const k = lowerer.lowerExprExpecting(call.arguments[0], receiverIr.key);
2979
- const v = lowerer.lowerExprExpecting(call.arguments[1], receiverIr.value);
2980
- return { kind: "mapIntrinsic", method: "set", receiver, args: [k, v], type: VOID, loc };
3355
+ const k = lowerer.lowerCollectionKey(call.arguments[0], receiverIr.key);
3356
+ const v = receiverIr.value.kind === "dyn"
3357
+ ? lowerer.lowerCollectionKey(call.arguments[1], receiverIr.value)
3358
+ : lowerer.lowerExprExpecting(call.arguments[1], receiverIr.value);
3359
+ const slot = lowerer.declareHiddenLocal("%mapSetReceiver", receiver.type);
3360
+ const ref = varRef(slot.id, receiver.type, loc);
3361
+ return { kind: "seqExpr", stmts: [
3362
+ { kind: "varDecl", localId: slot.id, init: receiver, loc },
3363
+ { kind: "exprStmt", expr: { kind: "mapIntrinsic", method: "set", receiver: ref, args: [k, v], type: VOID, loc }, loc },
3364
+ ], result: ref, type: receiver.type, loc };
2981
3365
  }
2982
3366
  if (name === "has" || name === "delete") {
2983
- const k = lowerer.lowerExprExpecting(call.arguments[0], receiverIr.key);
3367
+ const k = lowerer.lowerCollectionKey(call.arguments[0], receiverIr.key);
2984
3368
  return { kind: "mapIntrinsic", method: name, receiver, args: [k], type: BOOL, loc };
2985
3369
  }
2986
3370
  if (name === "clear") {
@@ -3100,6 +3484,65 @@ function buildMapIterDrainFn(name, mapT, method, elemT, tupleT, loc) {
3100
3484
  loc,
3101
3485
  };
3102
3486
  }
3487
+ /** An immediate Map spread observes the same entry order as entries().
3488
+ * Each pair is new; its key and value retain their original identities. */
3489
+ export function mapEntriesArray(lowerer, receiver) {
3490
+ const mapT = receiver.type;
3491
+ if (mapT.kind !== "map")
3492
+ throw new InternalCompilerError("Map entries require a map");
3493
+ const tupleT = {
3494
+ kind: "record", shapeId: lowerer.shapes.intern([
3495
+ { name: "0", type: mapT.key }, { name: "1", type: mapT.value },
3496
+ ], true),
3497
+ };
3498
+ const key = `entries:${typeKey(mapT.key)}:${typeKey(mapT.value)}`;
3499
+ let helper = lowerer.mapHofHelpers.get(key);
3500
+ if (!helper) {
3501
+ helper = `%map.entries.${lowerer.mapHofHelpers.size}`;
3502
+ lowerer.mapHofHelpers.set(key, helper);
3503
+ lowerer.liftedFns.push(buildMapIterDrainFn(helper, mapT, "entries", tupleT, tupleT, receiver.loc));
3504
+ }
3505
+ return { kind: "call", callee: helper, args: [receiver], type: arrayOf(tupleT), loc: receiver.loc };
3506
+ }
3507
+ /** Snapshot a collection for immediate iteration. Array reads and callback
3508
+ * parameters may retain an undefined arm even when the checker spells a
3509
+ * bare collection. Observe that arm before touching native storage. */
3510
+ export function lowerCollectionSpread(lowerer, source, node) {
3511
+ if (source.type.kind === "map")
3512
+ return mapEntriesArray(lowerer, source);
3513
+ if (source.type.kind === "set")
3514
+ return {
3515
+ kind: "setIntrinsic", method: "toArray", receiver: source, args: [], type: arrayOf(source.type.elem), loc: source.loc,
3516
+ };
3517
+ if (source.type.kind !== "union")
3518
+ return null;
3519
+ const arms = lowerer.unions.get(source.type.unionId)?.arms;
3520
+ const tag = arms?.findIndex((arm) => arm.kind === "map" || arm.kind === "set") ?? -1;
3521
+ const collection = arms?.[tag];
3522
+ if ((collection?.kind !== "map" && collection?.kind !== "set") ||
3523
+ !arms?.every((arm, index) => index === tag || isUnitType(arm)))
3524
+ return null;
3525
+ const loc = locOf(node);
3526
+ const slot = lowerer.declareHiddenLocal("%collectionSpread", source.type);
3527
+ const value = varRef(slot.id, source.type, loc);
3528
+ const narrowed = {
3529
+ kind: "unionNarrow", unionId: source.type.unionId, tag, value, type: collection, loc,
3530
+ };
3531
+ const entries = collection.kind === "map"
3532
+ ? mapEntriesArray(lowerer, narrowed)
3533
+ : { kind: "setIntrinsic", method: "toArray", receiver: narrowed, args: [], type: arrayOf(collection.elem), loc };
3534
+ return {
3535
+ kind: "seqExpr", stmts: [{ kind: "varDecl", localId: slot.id, init: source, loc }],
3536
+ result: {
3537
+ kind: "ternary",
3538
+ cond: { kind: "unionIsTag", unionId: source.type.unionId, tag, value, negated: false, type: BOOL, loc },
3539
+ then: entries,
3540
+ else_: nodeThrowExpr(1, "", `${node.getText()} is not iterable`, entries.type, loc),
3541
+ type: entries.type, loc,
3542
+ },
3543
+ type: entries.type, loc,
3544
+ };
3545
+ }
3103
3546
  /** `m.forEach(fn)` desugars to a direct call of a synthetic module
3104
3547
  * function — one per key/value type + callback arity, interned — whose
3105
3548
  * body is an index loop over the map's ITERATION PRIMITIVES: read
@@ -3274,21 +3717,28 @@ export function lowerSetMethodCall(lowerer, call, access) {
3274
3717
  if (!SET_METHODS.has(name) && !SET_COMBINE_METHODS.has(name))
3275
3718
  return null;
3276
3719
  let receiverIr = lowerer.mapTypeOf(lowerer.typeOf(access.expression));
3720
+ let probedUntyped = false;
3277
3721
  // The identity-Set idiom (JS): the CHECKER type is an unmappable
3278
3722
  // Set<union-of-signatures>, but the VALUE lowered as a real Set of
3279
3723
  // identity tokens (the new-Set probe) — the lowered receiver's type
3280
3724
  // is the honest dispatch key.
3281
3725
  if (receiverIr?.kind !== "set" && isJsSourceFile(access.getSourceFile())) {
3282
3726
  const probed = tryLowerExpression(lowerer, access.expression);
3283
- if (probed?.type.kind === "set")
3727
+ if (probed?.type.kind === "set") {
3284
3728
  receiverIr = probed.type;
3729
+ probedUntyped = true;
3730
+ }
3285
3731
  }
3286
3732
  if (receiverIr?.kind !== "set")
3287
3733
  return null;
3288
- if (!lowerer.isStdlibMember(access))
3734
+ // A collection interface may refine has() into a type predicate.
3735
+ // Type mapping checked that view's native ABI; the value check below
3736
+ // still rejects structural mocks and assertions over other objects.
3737
+ if (!probedUntyped && !lowerer.isStdlibMember(access) && name !== "has")
3289
3738
  return null;
3290
3739
  const loc = locOf(call);
3291
- const receiver = lowerer.lowerExpr(access.expression);
3740
+ const value = lowerer.lowerExpr(access.expression);
3741
+ const receiver = lowerer.runtimeOptionalPropertyReceiver(access.expression, value, receiverIr, name) ?? value;
3292
3742
  // The lib's `add` returns the Set (chaining typechecks); the lowered
3293
3743
  // add is a void statement — fence chained receivers like Map's set.
3294
3744
  if (receiver.type.kind !== "set") {
@@ -3301,11 +3751,11 @@ export function lowerSetMethodCall(lowerer, call, access) {
3301
3751
  return lowerSetCombineCall(lowerer, call, name, receiver, receiverIr);
3302
3752
  }
3303
3753
  if (name === "add") {
3304
- const v = lowerer.lowerExprExpecting(call.arguments[0], receiverIr.elem);
3754
+ const v = lowerer.lowerCollectionKey(call.arguments[0], receiverIr.elem);
3305
3755
  return { kind: "setIntrinsic", method: "add", receiver, args: [v], type: VOID, loc };
3306
3756
  }
3307
3757
  if (name === "has" || name === "delete") {
3308
- const v = lowerer.lowerExprExpecting(call.arguments[0], receiverIr.elem);
3758
+ const v = lowerer.lowerCollectionKey(call.arguments[0], receiverIr.elem);
3309
3759
  return { kind: "setIntrinsic", method: name, receiver, args: [v], type: BOOL, loc };
3310
3760
  }
3311
3761
  if (name === "clear") {
@@ -3771,7 +4221,11 @@ export function lowerIteratorHelperCall(lowerer, call, access) {
3771
4221
  if (terminal !== "forEach" && (checkerT === null || !typeEquals(checkerT, resultT))) {
3772
4222
  lowerer.noLowering(`.${terminal} at this result type`, call, "the chain's element and result types must be representable — annotate the callbacks' types");
3773
4223
  }
3774
- const stageKeys = stageIrs.map((s) => (s.kind === "take" || s.kind === "drop" ? s.kind : `${s.kind}:${typeKey(s.fn.type)}`));
4224
+ const stageKeys = stageIrs.map((s) => {
4225
+ if (!s)
4226
+ throw new InternalCompilerError("missing iterator stage");
4227
+ return "budget" in s ? s.kind : `${s.kind}:${typeKey(s.fn.type)}`;
4228
+ });
3775
4229
  const key = `iter:${srcProj}:${typeKey(items.type)}:${stageKeys.join(",")}:${terminal}:${termArgs.map((a) => typeKey(a.type)).join(",")}`;
3776
4230
  let helper = lowerer.arrHofHelpers.get(key);
3777
4231
  if (!helper) {
@@ -3779,7 +4233,11 @@ export function lowerIteratorHelperCall(lowerer, call, access) {
3779
4233
  lowerer.arrHofHelpers.set(key, helper);
3780
4234
  lowerer.liftedFns.push(buildIterChainFn(lowerer, helper, items.type, srcProj, stageIrs, terminal, termArgs.map((a) => a.type), resultT, loc));
3781
4235
  }
3782
- const budgetOrFn = stageIrs.map((s) => (s.kind === "take" || s.kind === "drop" ? s.budget : s.fn));
4236
+ const budgetOrFn = stageIrs.map((s) => {
4237
+ if (!s)
4238
+ throw new InternalCompilerError("missing iterator stage");
4239
+ return "budget" in s ? s.budget : s.fn;
4240
+ });
3783
4241
  return { kind: "call", callee: helper, args: [items, ...budgetOrFn, ...termArgs], type: resultT, loc };
3784
4242
  }
3785
4243
  const ITER_STAGES = new Set(["map", "filter", "take", "drop", "flatMap"]);
@@ -4457,6 +4915,8 @@ export function lowerForOfSearchParams(lowerer, stmt, iterable, proj) {
4457
4915
  export function lowerForOfArrayIter(lowerer, stmt, iterable, proj) {
4458
4916
  const loc = locOf(stmt);
4459
4917
  const arrT = iterable.type;
4918
+ if (arrT.kind !== "array" && arrT.kind !== "bytes")
4919
+ throw new InternalCompilerError("array iterator requires indexed storage");
4460
4920
  const elemT = arrT.kind === "array" ? arrayValueType(lowerer, arrT.elem) : F64;
4461
4921
  const yieldsPair = proj === "entries";
4462
4922
  if (!ts.isVariableDeclarationList(stmt.initializer)) {
@@ -4715,22 +5175,12 @@ function lowerForOfMapOrSet(lowerer, stmt, iterable, contT, proj) {
4715
5175
  }
4716
5176
  }
4717
5177
  else {
4718
- // Identifier heads and the remaining patterns bind through the
4719
- // checker's own element type — the [K, V] tuple for pair yields,
4720
- // T otherwise — built/read once into a hidden per-iteration
4721
- // local, the array for-of's exact desugar.
4722
- const elemT = lowerer.mapTypeOf(lowerer.checker.getTypeAtLocation(decl.name));
4723
- if (yieldsPair) {
4724
- const shape = elemT?.kind === "record" ? lowerer.shapes.get(elemT.shapeId) : null;
4725
- if (elemT?.kind !== "record" || !shape?.tuple || shape.fields.length !== 2 ||
4726
- !typeEquals(shape.fields.find((f) => f.name === "0").type, keyT) ||
4727
- !typeEquals(shape.fields.find((f) => f.name === "1").type, secondT)) {
4728
- lowerer.badType(decl.name, lowerer.checker.getTypeAtLocation(decl.name)); // defensive: the lib declares [K, V]
4729
- }
4730
- }
4731
- else if (!elemT || !typeEquals(elemT, singleT)) {
4732
- lowerer.badType(decl.name, lowerer.checker.getTypeAtLocation(decl.name)); // defensive: the lib declares T
4733
- }
5178
+ // Derive the yielded layout from the represented container. JS
5179
+ // inference can leave the pattern at any even when the Map's
5180
+ // native key/value types are known after specialization.
5181
+ const elemT = yieldsPair
5182
+ ? { kind: "record", shapeId: lowerer.shapes.intern([{ name: "0", type: keyT }, { name: "1", type: secondT }], true) }
5183
+ : singleT;
4734
5184
  const elemInit = yieldsPair
4735
5185
  ? {
4736
5186
  kind: "recordLit",
@@ -4835,7 +5285,11 @@ function exitBeforeReturns(stmts, make) {
4835
5285
  case "block":
4836
5286
  return [{ ...s, body: walk(s.body) }];
4837
5287
  case "switch":
4838
- return [{ ...s, cases: s.cases.map((c) => ({ ...c, body: walk(c.body) })) }];
5288
+ return [{ ...s, cases: s.cases.map((c) => {
5289
+ if (!c)
5290
+ throw new InternalCompilerError("missing switch clause");
5291
+ return { ...c, body: walk(c.body) };
5292
+ }) }];
4839
5293
  case "tryCatch":
4840
5294
  return [
4841
5295
  {
@@ -4851,18 +5305,291 @@ function exitBeforeReturns(stmts, make) {
4851
5305
  });
4852
5306
  return walk(stmts);
4853
5307
  }
4854
- /** `new Map(entries)` from a tuple-array VALUE — any `[K, V][]`-typed
4855
- * expression (a variable, a .map() result, a sorted entries spread), not
4856
- * just the pair-literal form lower-classes handles inline. Desugars to a
4857
- * direct call of a synthetic function that constructs the empty map and
4858
- * set()s each pair in array order — JS-exact: pairs are visited in
4859
- * insertion order and a later duplicate key overwrites while keeping the
4860
- * first occurrence's position (set()'s own contract). Null when the
4861
- * argument isn't a matching tuple array (the caller keeps its fence). */
4862
- export function lowerMapSeedArrayNew(lowerer, argNode, mapT) {
5308
+ /** Consume a Set seed immediately, including optional inherited sets used
5309
+ * by compiler tables. Nullish seeds construct empty sets; a lazy fallback
5310
+ * consumes its evaluated branch even when it reassigns the source binding. */
5311
+ export function lowerSetSeedNew(lowerer, node, setT) {
5312
+ if (ts.isSpreadElement(node))
5313
+ return null;
5314
+ while (ts.isParenthesizedExpression(node))
5315
+ node = node.expression;
5316
+ const loc = locOf(node);
5317
+ const undefinedSeed = lowerStaticallyUndefinedArgument(lowerer, node);
5318
+ if (undefinedSeed)
5319
+ return defaultAfterUndefined(undefinedSeed, { kind: "setNew", type: setT, loc });
5320
+ if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken) {
5321
+ const undefinedLeft = lowerStaticallyUndefinedArgument(lowerer, node.left);
5322
+ const fallback = node.right;
5323
+ if (undefinedLeft) {
5324
+ const selected = lowerSetSeedNew(lowerer, fallback, setT);
5325
+ return selected ? defaultAfterUndefined(undefinedLeft, selected) : null;
5326
+ }
5327
+ const source = lowerer.lowerExpr(node.left);
5328
+ if (isUnitType(source.type)) {
5329
+ const selected = lowerSetSeedNew(lowerer, fallback, setT);
5330
+ return selected ? defaultAfterUndefined(source, selected) : null;
5331
+ }
5332
+ return setFromSeedValue(lowerer, source, setT, () => lowerSetSeedNew(lowerer, fallback, setT));
5333
+ }
5334
+ if (ts.isConditionalExpression(node)) {
5335
+ const yes = lowerSetSeedNew(lowerer, node.whenTrue, setT);
5336
+ const no = lowerSetSeedNew(lowerer, node.whenFalse, setT);
5337
+ return yes && no ? { kind: "ternary", cond: lowerer.lowerCondition(node.condition), then: yes, else_: no, type: setT, loc } : null;
5338
+ }
5339
+ // Constructor contextual types include Iterable<T>, which has no value
5340
+ // representation. Build a literal at the actual Set element ABI instead.
5341
+ if (ts.isArrayLiteralExpression(node) && !node.elements.some(ts.isSpreadElement)) {
5342
+ const elems = node.elements.map((element) => lowerer.lowerCollectionKey(element, setT.elem));
5343
+ return { kind: "setNew", seed: { kind: "arrayLit", elems, type: arrayOf(setT.elem), loc }, type: setT, loc };
5344
+ }
5345
+ const declared = lowerer.mapTypeOf(lowerer.typeOf(node));
5346
+ const scalar = setT.elem.kind === "f64" || setT.elem.kind === "string";
5347
+ let source = !scalar && (declared?.kind === "array" || declared?.kind === "record")
5348
+ ? lowerer.lowerCollectionKey(node, declared)
5349
+ : lowerer.lowerExpr(node);
5350
+ if (declared?.kind === "string" && setT.elem.kind === "string" &&
5351
+ (source.type.kind === "dyn" || source.type.kind === "jsval")) {
5352
+ source = lowerer.coerceInto(node, source, STRING);
5353
+ }
5354
+ if (source.type.kind === "dyn" && setT.elem.kind === "dyn") {
5355
+ return { kind: "dynCheck", value: { kind: "libCall", fn: "dyn.nativeSetNew", args: [source], type: DYN, loc }, type: setT, loc };
5356
+ }
5357
+ if (declared?.kind === "array" && typeEquals(declared.elem, setT.elem)) {
5358
+ // Preserve the existing checked scalar-iterable bridge. Reference
5359
+ // elements must retain identity and cannot enter via a copying exit.
5360
+ if (source.type.kind === "jsval" && lowerer.boundaryExitSafe(arrayOf(setT.elem))) {
5361
+ source = { kind: "jsExit", value: source, type: arrayOf(setT.elem), loc };
5362
+ }
5363
+ if (source.type.kind === "dyn" && scalar) {
5364
+ source = lowerer.coerceInto(node, {
5365
+ kind: "libCall", fn: "dyn.iterPack", args: [source, strLit(node.getText(), loc)], type: DYN, loc,
5366
+ }, arrayOf(setT.elem));
5367
+ }
5368
+ }
5369
+ return setFromSeedValue(lowerer, source, setT, () => ({ kind: "setNew", type: setT, loc }));
5370
+ }
5371
+ function setFromSeedValue(lowerer, source, setT, missing) {
5372
+ const loc = source.loc;
5373
+ if (isUnitType(source.type)) {
5374
+ const empty = missing();
5375
+ return empty ? defaultAfterUndefined(source, empty) : null;
5376
+ }
5377
+ if (source.type.kind === "union") {
5378
+ const unionId = source.type.unionId;
5379
+ const arms = lowerer.unions.get(unionId)?.arms;
5380
+ if (!arms)
5381
+ return null;
5382
+ const slot = lowerer.declareHiddenLocal("%setSeed", source.type);
5383
+ const ref = varRef(slot.id, source.type, loc);
5384
+ let result = null;
5385
+ for (let tag = arms.length - 1; tag >= 0; tag--) {
5386
+ const arm = arms[tag];
5387
+ const branch = isUnitType(arm) ? missing() : setFromSeedValue(lowerer, {
5388
+ kind: "unionNarrow", unionId, tag, value: ref, type: arm, loc,
5389
+ }, setT, missing);
5390
+ if (!branch)
5391
+ return null;
5392
+ result = result === null ? branch : {
5393
+ kind: "ternary", cond: { kind: "unionIsTag", unionId, tag, value: ref, negated: false, type: BOOL, loc },
5394
+ then: branch, else_: result, type: setT, loc,
5395
+ };
5396
+ }
5397
+ return result ? {
5398
+ kind: "seqExpr", stmts: [{ kind: "varDecl", localId: slot.id, init: source, loc }], result, type: setT, loc,
5399
+ } : null;
5400
+ }
5401
+ let seed;
5402
+ if (source.type.kind === "set" && typeEquals(source.type, setT)) {
5403
+ seed = { kind: "setIntrinsic", method: "toArray", receiver: source, args: [], type: arrayOf(setT.elem), loc };
5404
+ }
5405
+ else if (source.type.kind === "string" && setT.elem.kind === "string") {
5406
+ seed = strCharsCall(lowerer, source, loc);
5407
+ }
5408
+ else if (source.type.kind === "array" && typeEquals(source.type.elem, setT.elem)) {
5409
+ seed = source;
5410
+ }
5411
+ else if (source.type.kind === "record") {
5412
+ const shape = lowerer.shapes.get(source.type.shapeId);
5413
+ if (!shape?.tuple || !shape.fields.every((field) => typeEquals(field.type, setT.elem)))
5414
+ return null;
5415
+ const arrayT = { kind: "array", elem: setT.elem };
5416
+ const helper = lowerer.tupleArrayWidthHelper(source.type.shapeId, arrayT, loc);
5417
+ if (!helper)
5418
+ return null;
5419
+ seed = { kind: "call", callee: helper, args: [source], type: arrayT, loc };
5420
+ }
5421
+ else
5422
+ return null;
5423
+ return { kind: "setNew", seed, type: setT, loc };
5424
+ }
5425
+ /** Consume supported Map seeds: matching Maps and tuple arrays, plus
5426
+ * nullish values that construct an empty Map. Conditional/nullish seeds
5427
+ * select one lazy branch without representing a first-class iterable.
5428
+ * Copy loops preserve entry order and stored reference identities. */
5429
+ export function lowerMapSeedNew(lowerer, argNode, mapT) {
4863
5430
  if (ts.isSpreadElement(argNode))
4864
5431
  return null;
5432
+ const empty = lowerer.emptyCollectionFor(argNode, mapT);
5433
+ if (empty)
5434
+ return empty;
5435
+ while (ts.isParenthesizedExpression(argNode))
5436
+ argNode = argNode.expression;
5437
+ // A constructor consumes either iterable branch immediately. It does
5438
+ // not need a first-class Map|array representation for `cached ?? []`.
5439
+ // Snapshot the left before the lazy fallback can mutate its binding.
5440
+ if (ts.isBinaryExpression(argNode) && argNode.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken) {
5441
+ const source = lowerer.lowerExpr(argNode.left);
5442
+ if (isUnitType(source.type)) {
5443
+ const fallback = lowerMapSeedNew(lowerer, argNode.right, mapT);
5444
+ return fallback ? defaultAfterUndefined(source, fallback) : null;
5445
+ }
5446
+ if (source.type.kind !== "union")
5447
+ return mapFromSeedValue(lowerer, source, mapT);
5448
+ const arms = lowerer.unions.get(source.type.unionId)?.arms;
5449
+ if (!arms)
5450
+ return null;
5451
+ const loc = locOf(argNode);
5452
+ const saved = lowerer.declareHiddenLocal("%mapSeed", source.type);
5453
+ const ref = varRef(saved.id, source.type, loc);
5454
+ let result = null;
5455
+ for (let tag = arms.length - 1; tag >= 0; tag--) {
5456
+ const arm = arms[tag];
5457
+ const branch = isUnitType(arm)
5458
+ ? lowerMapSeedNew(lowerer, argNode.right, mapT)
5459
+ : mapFromSeedValue(lowerer, { kind: "unionNarrow", unionId: source.type.unionId, tag, value: ref, type: arm, loc }, mapT);
5460
+ if (!branch)
5461
+ return null;
5462
+ result = result === null ? branch : {
5463
+ kind: "ternary",
5464
+ cond: { kind: "unionIsTag", unionId: source.type.unionId, tag, value: ref, negated: false, type: BOOL, loc },
5465
+ then: branch, else_: result, type: mapT, loc,
5466
+ };
5467
+ }
5468
+ return result ? { kind: "seqExpr", stmts: [{ kind: "varDecl", localId: saved.id, init: source, loc }], result, type: mapT, loc } : null;
5469
+ }
5470
+ if (ts.isConditionalExpression(argNode)) {
5471
+ const yes = lowerMapSeedNew(lowerer, argNode.whenTrue, mapT);
5472
+ const no = lowerMapSeedNew(lowerer, argNode.whenFalse, mapT);
5473
+ return yes && no ? { kind: "ternary", cond: lowerer.lowerCondition(argNode.condition), then: yes, else_: no, type: mapT, loc: locOf(argNode) } : null;
5474
+ }
5475
+ if (ts.isArrayLiteralExpression(argNode)) {
5476
+ if (isJsSourceFile(argNode.getSourceFile()) && argNode.elements.some((entry) => !ts.isArrayLiteralExpression(entry))) {
5477
+ return mapFromSeedValue(lowerer, lowerer.lowerExprExpecting(argNode, DYN), mapT);
5478
+ }
5479
+ const tuple = { kind: "record", shapeId: lowerer.shapes.intern([
5480
+ { name: "0", type: mapT.key }, { name: "1", type: mapT.value },
5481
+ ], true) };
5482
+ return mapFromSeedValue(lowerer, lowerer.lowerArrayLiteral(argNode, { kind: "array", elem: tuple }), mapT);
5483
+ }
4865
5484
  const seed = lowerer.lowerExpr(argNode);
5485
+ return mapFromSeedValue(lowerer, seed, mapT);
5486
+ }
5487
+ function mapFromSeedValue(lowerer, seed, mapT) {
5488
+ const loc = seed.loc;
5489
+ if (isUnitType(seed.type)) {
5490
+ return defaultAfterUndefined(seed, { kind: "mapNew", type: mapT, loc });
5491
+ }
5492
+ if (seed.type.kind === "union") {
5493
+ const arms = lowerer.unions.get(seed.type.unionId)?.arms;
5494
+ if (!arms)
5495
+ return null;
5496
+ const saved = lowerer.declareHiddenLocal("%mapSeed", seed.type);
5497
+ const ref = varRef(saved.id, seed.type, loc);
5498
+ let result = null;
5499
+ for (let tag = arms.length - 1; tag >= 0; tag--) {
5500
+ const arm = arms[tag];
5501
+ const branch = isUnitType(arm) ? { kind: "mapNew", type: mapT, loc }
5502
+ : mapFromSeedValue(lowerer, { kind: "unionNarrow", unionId: seed.type.unionId, tag, value: ref, type: arm, loc }, mapT);
5503
+ if (!branch)
5504
+ return null;
5505
+ result = result === null ? branch : {
5506
+ kind: "ternary",
5507
+ cond: { kind: "unionIsTag", unionId: seed.type.unionId, tag, value: ref, negated: false, type: BOOL, loc },
5508
+ then: branch, else_: result, type: mapT, loc,
5509
+ };
5510
+ }
5511
+ return result ? { kind: "seqExpr", stmts: [{ kind: "varDecl", localId: saved.id, init: seed, loc }], result, type: mapT, loc } : null;
5512
+ }
5513
+ if (seed.type.kind === "map") {
5514
+ if (!typeEquals(seed.type, mapT))
5515
+ return null;
5516
+ const key = `copy:${typeKey(mapT)}`;
5517
+ let name = lowerer.mapHofHelpers.get(key);
5518
+ if (!name) {
5519
+ name = `%map.copy.${lowerer.mapHofHelpers.size}`;
5520
+ lowerer.mapHofHelpers.set(key, name);
5521
+ const source = varRef("source.0", mapT, loc);
5522
+ const target = varRef("target.0", mapT, loc);
5523
+ const index = varRef("i.0", F64, loc);
5524
+ const read = (method, type) => ({
5525
+ kind: "mapIntrinsic", method, receiver: source, args: method === "iterCount" ? [] : [index], type, loc,
5526
+ });
5527
+ lowerer.liftedFns.push({
5528
+ name, params: [{ localId: "source.0", name: "source", type: mapT }], returnType: mapT,
5529
+ locals: [
5530
+ { id: "source.0", name: "source", type: mapT, mutable: false },
5531
+ { id: "target.0", name: "target", type: mapT, mutable: false },
5532
+ { id: "i.0", name: "i", type: F64, mutable: true },
5533
+ ],
5534
+ body: [
5535
+ { kind: "varDecl", localId: "target.0", init: { kind: "mapNew", type: mapT, loc }, loc },
5536
+ countedFor(loc, read("iterCount", F64), () => [{
5537
+ kind: "if", cond: read("iterLive", BOOL), then: [{ kind: "exprStmt", expr: {
5538
+ kind: "mapIntrinsic", method: "set", receiver: target,
5539
+ args: [read("iterKey", mapT.key), read("iterValue", mapT.value)], type: VOID, loc,
5540
+ }, loc }], else_: null, loc,
5541
+ }]),
5542
+ { kind: "return", value: target, loc },
5543
+ ], loc,
5544
+ });
5545
+ }
5546
+ return { kind: "call", callee: name, args: [seed], type: mapT, loc };
5547
+ }
5548
+ if (seed.type.kind === "dyn" || seed.type.kind === "array" &&
5549
+ (seed.type.elem.kind === "dyn" || seed.type.elem.kind === "array")) {
5550
+ const key = `checked-seed:${typeKey(mapT)}`;
5551
+ let name = lowerer.mapHofHelpers.get(key);
5552
+ if (!name) {
5553
+ name = `%map.checkedSeed.${lowerer.mapHofHelpers.size}`;
5554
+ lowerer.mapHofHelpers.set(key, name);
5555
+ const source = varRef("source.0", DYN, loc);
5556
+ const entries = varRef("entries.0", DYN, loc);
5557
+ const entry = varRef("entry.0", DYN, loc);
5558
+ const target = varRef("target.0", mapT, loc);
5559
+ const keyValue = varRef("key.0", DYN, loc);
5560
+ const itemValue = varRef("value.0", DYN, loc);
5561
+ const checked = (value, type) => type.kind === "dyn" ? value
5562
+ : { kind: "dynCheck", value, type, loc };
5563
+ lowerer.liftedFns.push({
5564
+ name, params: [{ localId: "source.0", name: "source", type: DYN }], returnType: mapT,
5565
+ locals: [
5566
+ { id: "source.0", name: "source", type: DYN, mutable: false },
5567
+ { id: "entries.0", name: "entries", type: DYN, mutable: false },
5568
+ { id: "entry.0", name: "entry", type: DYN, mutable: false },
5569
+ { id: "key.0", name: "key", type: DYN, mutable: false },
5570
+ { id: "value.0", name: "value", type: DYN, mutable: false },
5571
+ { id: "target.0", name: "target", type: mapT, mutable: false },
5572
+ { id: "i.0", name: "i", type: F64, mutable: true },
5573
+ ],
5574
+ body: [
5575
+ { kind: "varDecl", localId: "target.0", init: { kind: "mapNew", type: mapT, loc }, loc },
5576
+ { kind: "varDecl", localId: "entries.0", init: { kind: "libCall", fn: "dyn.mapSeedEntries", args: [source], type: DYN, loc }, loc },
5577
+ countedFor(loc, { kind: "libCall", fn: "dyn.arrLen", args: [entries], type: F64, loc }, () => [
5578
+ { kind: "varDecl", localId: "entry.0", init: { kind: "libCall", fn: "dyn.mapSeedEntry", args: [
5579
+ { kind: "libCall", fn: "dyn.arrAt", args: [entries, varRef("i.0", F64, loc)], type: DYN, loc },
5580
+ ], type: DYN, loc }, loc },
5581
+ { kind: "varDecl", localId: "key.0", init: { kind: "dynKeyGet", value: entry, key: strLit("0", loc), type: DYN, loc }, loc },
5582
+ { kind: "varDecl", localId: "value.0", init: { kind: "dynKeyGet", value: entry, key: strLit("1", loc), type: DYN, loc }, loc },
5583
+ { kind: "exprStmt", expr: { kind: "mapIntrinsic", method: "set", receiver: target,
5584
+ args: [checked(keyValue, mapT.key), checked(itemValue, mapT.value)], type: VOID, loc }, loc },
5585
+ ]),
5586
+ { kind: "return", value: target, loc },
5587
+ ], loc,
5588
+ });
5589
+ }
5590
+ const source = seed.type.kind === "dyn" ? seed : { kind: "dynFrom", value: seed, type: DYN, loc };
5591
+ return { kind: "call", callee: name, args: [source], type: mapT, loc };
5592
+ }
4866
5593
  if (seed.type.kind !== "array" || seed.type.elem.kind !== "record")
4867
5594
  return null;
4868
5595
  const elem = seed.type.elem;
@@ -4873,7 +5600,6 @@ export function lowerMapSeedArrayNew(lowerer, argNode, mapT) {
4873
5600
  const vT = shape.fields.find((f) => f.name === "1").type;
4874
5601
  if (!typeEquals(kT, mapT.key) || !typeEquals(vT, mapT.value))
4875
5602
  return null;
4876
- const loc = locOf(argNode);
4877
5603
  const key = `seed:${typeKey(mapT.key)}:${typeKey(mapT.value)}:${elem.shapeId}`;
4878
5604
  let helper = lowerer.mapHofHelpers.get(key);
4879
5605
  if (!helper) {
@@ -4946,7 +5672,7 @@ export function lowerObjectIterOverIndexShape(lowerer, call, member, argIr, shap
4946
5672
  const resultT = lowerer.irTypeOf(call);
4947
5673
  if (resultT.kind !== "array")
4948
5674
  lowerer.badType(call, lowerer.typeOf(call)); // defensive
4949
- return objectIterOverIndexShape(lowerer, call, member, argIr, shape, lowerer.lowerExpr(call.arguments[0]), resultT, locOf(call));
5675
+ return objectIterOverIndexShape(lowerer, call, member, argIr, shape, objectEnumerationReceiver(lowerer, lowerer.lowerExpr(call.arguments[0]), argIr, locOf(call)), resultT, locOf(call));
4950
5676
  }
4951
5677
  /** The construction core, receiver/result pre-resolved — `node` anchors
4952
5678
  * the fences. for-in reuses the "keys" arm directly (it iterates exactly
@@ -5146,6 +5872,21 @@ export function objectIterOverIndexShape(lowerer, node, member, argIr, shape, re
5146
5872
  * (lowerRecordOvfCaptureHelper). Null when the argument or result shape
5147
5873
  * is outside this (Maps, richer iterables → the SC2020 fence). */
5148
5874
  export function lowerObjectFromEntriesCall(lowerer, call, callee) {
5875
+ const typed = lowerTypedObjectFromEntriesCall(lowerer, call, callee);
5876
+ if (typed)
5877
+ return typed;
5878
+ if (!ts.isPropertyAccessExpression(callee) || call.questionDotToken || callee.questionDotToken ||
5879
+ !lowerer.isStdlibGlobal(callee.expression, "Object") || callee.name.text !== "fromEntries" ||
5880
+ call.arguments.length !== 1 || ts.isSpreadElement(call.arguments[0]))
5881
+ return null;
5882
+ if (lowerer.dynamic)
5883
+ return null;
5884
+ return {
5885
+ kind: "libCall", fn: "dyn.fromEntries", type: DYN, loc: locOf(call),
5886
+ args: [lowerer.lowerExprExpecting(call.arguments[0], DYN)],
5887
+ };
5888
+ }
5889
+ function lowerTypedObjectFromEntriesCall(lowerer, call, callee) {
5149
5890
  if (!ts.isPropertyAccessExpression(callee))
5150
5891
  return null;
5151
5892
  if (call.questionDotToken || callee.questionDotToken)
@@ -5202,7 +5943,10 @@ export function lowerObjectFromEntriesCall(lowerer, call, callee) {
5202
5943
  if (!convertible) {
5203
5944
  lowerer.unsupported("SC1090", call, `Object.fromEntries over '${lowerer.fmt(argIr)}' (the tuple's '${lowerer.fmt(valT)}' value cannot flow into the '${lowerer.fmt(iv)}' signature slot)`);
5204
5945
  }
5205
- const receiver = lowerer.lowerExpr(argNode);
5946
+ // Enumeration/filtering may keep the array in checked-dynamic storage.
5947
+ // Validate its tuple layout before calling a helper with a native-array
5948
+ // ABI; opaque tuple values themselves retain their original references.
5949
+ const receiver = lowerer.lowerExprExpecting(argNode, argIr);
5206
5950
  const key = `obj.fromEntries:${argIr.elem.shapeId}:${resultT.shapeId}`;
5207
5951
  let helper = lowerer.arrHofHelpers.get(key);
5208
5952
  if (!helper) {