@scriptc/compiler 0.4.8 → 0.4.9

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 (536) hide show
  1. package/ambient/node-fallback/buffer.d.ts +2 -0
  2. package/ambient/node-fallback/child_process.d.ts +9 -3
  3. package/ambient/node-fallback/dns-promises.d.ts +25 -0
  4. package/ambient/node-fallback/dns.d.ts +29 -0
  5. package/ambient/node-fallback/test.d.ts +7 -0
  6. package/ambient/scriptc-node-fallback.d.ts +145 -2
  7. package/ambient/scriptc-overrides.d.ts +22 -13
  8. package/dist/backend/build-cache.d.ts +1 -1
  9. package/dist/backend/build-cache.js +1 -1
  10. package/dist/backend/build-cache.js.map +1 -1
  11. package/dist/backend/cache-root.d.ts +7 -0
  12. package/dist/backend/cache-root.js +27 -0
  13. package/dist/backend/cache-root.js.map +1 -1
  14. package/dist/backend/executable-features.js +5 -1
  15. package/dist/backend/executable-features.js.map +1 -1
  16. package/dist/backend/link-plan.js +7 -1
  17. package/dist/backend/link-plan.js.map +1 -1
  18. package/dist/backend/llvm/bytes-loop-versions.d.ts +12 -1
  19. package/dist/backend/llvm/bytes-loop-versions.js +107 -30
  20. package/dist/backend/llvm/bytes-loop-versions.js.map +1 -1
  21. package/dist/backend/llvm/bytes-loop-versions.test.js +96 -0
  22. package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -1
  23. package/dist/backend/llvm/checked-value-lifetimes.js +1 -0
  24. package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
  25. package/dist/backend/llvm/classes.d.ts +16 -5
  26. package/dist/backend/llvm/classes.js +34 -6
  27. package/dist/backend/llvm/classes.js.map +1 -1
  28. package/dist/backend/llvm/classes.test.js +21 -2
  29. package/dist/backend/llvm/classes.test.js.map +1 -1
  30. package/dist/backend/llvm/common.d.ts +9 -0
  31. package/dist/backend/llvm/common.js +9 -0
  32. package/dist/backend/llvm/common.js.map +1 -1
  33. package/dist/backend/llvm/cpu-dispatch.d.ts +36 -2
  34. package/dist/backend/llvm/cpu-dispatch.js +96 -2
  35. package/dist/backend/llvm/cpu-dispatch.js.map +1 -1
  36. package/dist/backend/llvm/dense-array-access.d.ts +5 -2
  37. package/dist/backend/llvm/dense-array-access.js +16 -12
  38. package/dist/backend/llvm/dense-array-access.js.map +1 -1
  39. package/dist/backend/llvm/dense-array-access.test.js +3 -1
  40. package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
  41. package/dist/backend/llvm/dyn.d.ts +24 -0
  42. package/dist/backend/llvm/dyn.js +117 -3
  43. package/dist/backend/llvm/dyn.js.map +1 -1
  44. package/dist/backend/llvm/emit-function.js +6 -0
  45. package/dist/backend/llvm/emit-function.js.map +1 -1
  46. package/dist/backend/llvm/emit-journal.d.ts +1 -0
  47. package/dist/backend/llvm/emit-journal.js.map +1 -1
  48. package/dist/backend/llvm/emit-module.js +48 -5
  49. package/dist/backend/llvm/emit-module.js.map +1 -1
  50. package/dist/backend/llvm/emit-module.test.js +41 -0
  51. package/dist/backend/llvm/emit-module.test.js.map +1 -1
  52. package/dist/backend/llvm/emit-statements.js +11 -0
  53. package/dist/backend/llvm/emit-statements.js.map +1 -1
  54. package/dist/backend/llvm/emitter.d.ts +87 -7
  55. package/dist/backend/llvm/emitter.js +136 -15
  56. package/dist/backend/llvm/emitter.js.map +1 -1
  57. package/dist/backend/llvm/expr-async.js +28 -6
  58. package/dist/backend/llvm/expr-async.js.map +1 -1
  59. package/dist/backend/llvm/expr-containers.js +19 -5
  60. package/dist/backend/llvm/expr-containers.js.map +1 -1
  61. package/dist/backend/llvm/expr-dynamic.js +29 -1
  62. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  63. package/dist/backend/llvm/expr-primitives.js +104 -6
  64. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  65. package/dist/backend/llvm/expr-records.js +15 -1
  66. package/dist/backend/llvm/expr-records.js.map +1 -1
  67. package/dist/backend/llvm/expr-stream-bridges.js +53 -5
  68. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  69. package/dist/backend/llvm/inline-arrays.js +1 -1
  70. package/dist/backend/llvm/inline-arrays.js.map +1 -1
  71. package/dist/backend/llvm/js-ic.js +126 -2
  72. package/dist/backend/llvm/js-ic.js.map +1 -1
  73. package/dist/backend/llvm/lanes.d.ts +38 -0
  74. package/dist/backend/llvm/lanes.js +778 -0
  75. package/dist/backend/llvm/lanes.js.map +1 -0
  76. package/dist/backend/llvm/lanes.test.d.ts +1 -0
  77. package/dist/backend/llvm/lanes.test.js +402 -0
  78. package/dist/backend/llvm/lanes.test.js.map +1 -0
  79. package/dist/backend/llvm/lib-dispatch.js +9 -4
  80. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  81. package/dist/backend/llvm/lib-network.js +20 -0
  82. package/dist/backend/llvm/lib-network.js.map +1 -1
  83. package/dist/backend/llvm/lib-shared.js +27 -0
  84. package/dist/backend/llvm/lib-shared.js.map +1 -1
  85. package/dist/backend/llvm/lib-test.js +11 -0
  86. package/dist/backend/llvm/lib-test.js.map +1 -1
  87. package/dist/backend/llvm/local-array-reads.js +2 -2
  88. package/dist/backend/llvm/local-array-reads.js.map +1 -1
  89. package/dist/backend/llvm/map-number-lookup.js +8 -2
  90. package/dist/backend/llvm/map-number-lookup.js.map +1 -1
  91. package/dist/backend/llvm/nullable-unions.js +5 -2
  92. package/dist/backend/llvm/nullable-unions.js.map +1 -1
  93. package/dist/backend/llvm/publish.d.ts +3 -0
  94. package/dist/backend/llvm/publish.js +2 -2
  95. package/dist/backend/llvm/publish.js.map +1 -1
  96. package/dist/backend/llvm/reference-writes.js +1 -0
  97. package/dist/backend/llvm/reference-writes.js.map +1 -1
  98. package/dist/backend/llvm/region-groups.js +43 -4
  99. package/dist/backend/llvm/region-groups.js.map +1 -1
  100. package/dist/backend/llvm/region-groups.test.js +79 -0
  101. package/dist/backend/llvm/region-groups.test.js.map +1 -1
  102. package/dist/backend/llvm/runtime-registries.test.js +32 -1
  103. package/dist/backend/llvm/runtime-registries.test.js.map +1 -1
  104. package/dist/backend/llvm/shapes.js +10 -1
  105. package/dist/backend/llvm/shapes.js.map +1 -1
  106. package/dist/backend/llvm/string-reads.d.ts +1 -1
  107. package/dist/backend/llvm/string-reads.js +1 -1
  108. package/dist/backend/llvm/string-reads.js.map +1 -1
  109. package/dist/backend/llvm/unwind-abi.js +24 -2
  110. package/dist/backend/llvm/unwind-abi.js.map +1 -1
  111. package/dist/backend/llvm/unwind-abi.test.js +38 -0
  112. package/dist/backend/llvm/unwind-abi.test.js.map +1 -1
  113. package/dist/backend/llvm/walkers.d.ts +3 -0
  114. package/dist/backend/llvm/walkers.js +20 -2
  115. package/dist/backend/llvm/walkers.js.map +1 -1
  116. package/dist/backend/native/contracts.d.ts +15 -3
  117. package/dist/backend/native/executable.js +19 -5
  118. package/dist/backend/native/executable.js.map +1 -1
  119. package/dist/backend/native-codegen-core.d.ts +20 -0
  120. package/dist/backend/native-codegen-core.js +15 -0
  121. package/dist/backend/native-codegen-core.js.map +1 -1
  122. package/dist/backend/native-codegen.d.ts +5 -0
  123. package/dist/backend/native-codegen.js +62 -8
  124. package/dist/backend/native-codegen.js.map +1 -1
  125. package/dist/backend/native-codegen.test.js +48 -8
  126. package/dist/backend/native-codegen.test.js.map +1 -1
  127. package/dist/backend/native-link-info-core.d.ts +27 -3
  128. package/dist/backend/native-link-info-core.js.map +1 -1
  129. package/dist/backend/native-link-info.test.js +17 -1
  130. package/dist/backend/native-link-info.test.js.map +1 -1
  131. package/dist/backend/native-toolchain.d.ts +1 -1
  132. package/dist/backend/native-toolchain.js +1 -1
  133. package/dist/backend/native-toolchain.js.map +1 -1
  134. package/dist/backend/native-toolchain.test.js +14 -1
  135. package/dist/backend/native-toolchain.test.js.map +1 -1
  136. package/dist/backend/runtime-pack-core.d.ts +9 -3
  137. package/dist/backend/runtime-pack-core.js +6 -1
  138. package/dist/backend/runtime-pack-core.js.map +1 -1
  139. package/dist/backend/runtime-pack.test.js +32 -1
  140. package/dist/backend/runtime-pack.test.js.map +1 -1
  141. package/dist/backend/targets.d.ts +9 -1
  142. package/dist/backend/targets.js +11 -2
  143. package/dist/backend/targets.js.map +1 -1
  144. package/dist/backend/targets.test.js +6 -0
  145. package/dist/backend/targets.test.js.map +1 -1
  146. package/dist/cli/command.js +15 -1
  147. package/dist/cli/command.js.map +1 -1
  148. package/dist/cli/host.d.ts +6 -0
  149. package/dist/cli/mcp.d.ts +72 -0
  150. package/dist/cli/mcp.js +601 -0
  151. package/dist/cli/mcp.js.map +1 -0
  152. package/dist/cli/mcp.test.d.ts +1 -0
  153. package/dist/cli/mcp.test.js +380 -0
  154. package/dist/cli/mcp.test.js.map +1 -0
  155. package/dist/cli/output-options.d.ts +1 -0
  156. package/dist/cli/output-options.js +3 -0
  157. package/dist/cli/output-options.js.map +1 -1
  158. package/dist/cli/usage.d.ts +51 -1
  159. package/dist/cli/usage.js +709 -186
  160. package/dist/cli/usage.js.map +1 -1
  161. package/dist/compat/fetch-profile.js +9 -4
  162. package/dist/compat/fetch-profile.js.map +1 -1
  163. package/dist/compile-types.d.ts +17 -0
  164. package/dist/coverage/report.d.ts +5 -9
  165. package/dist/coverage/report.js.map +1 -1
  166. package/dist/executable/executable-cache.d.ts +17 -3
  167. package/dist/executable/executable-cache.js +17 -3
  168. package/dist/executable/executable-cache.js.map +1 -1
  169. package/dist/executable/prepare.js +87 -10
  170. package/dist/executable/prepare.js.map +1 -1
  171. package/dist/frontend/analysis.js +3 -2
  172. package/dist/frontend/analysis.js.map +1 -1
  173. package/dist/frontend/canon-map.js +13 -8
  174. package/dist/frontend/canon-map.js.map +1 -1
  175. package/dist/frontend/decl-projection.d.ts +18 -0
  176. package/dist/frontend/decl-projection.js +90 -22
  177. package/dist/frontend/decl-projection.js.map +1 -1
  178. package/dist/frontend/decl-projection.test.js +47 -1
  179. package/dist/frontend/decl-projection.test.js.map +1 -1
  180. package/dist/frontend/default-library.d.ts +10 -0
  181. package/dist/frontend/default-library.js +43 -0
  182. package/dist/frontend/default-library.js.map +1 -0
  183. package/dist/frontend/fork-target.js +54 -9
  184. package/dist/frontend/fork-target.js.map +1 -1
  185. package/dist/frontend/fork-target.test.js +82 -0
  186. package/dist/frontend/fork-target.test.js.map +1 -1
  187. package/dist/frontend/inferred-js-diagnostics.test.js +73 -0
  188. package/dist/frontend/inferred-js-diagnostics.test.js.map +1 -1
  189. package/dist/frontend/lowering/abstract-equality.d.ts +2 -1
  190. package/dist/frontend/lowering/abstract-equality.js +7 -1
  191. package/dist/frontend/lowering/abstract-equality.js.map +1 -1
  192. package/dist/frontend/lowering/array-values.js +2 -2
  193. package/dist/frontend/lowering/array-values.js.map +1 -1
  194. package/dist/frontend/lowering/assertion-members.js +52 -2
  195. package/dist/frontend/lowering/assertion-members.js.map +1 -1
  196. package/dist/frontend/lowering/builtin-namespaces.d.ts +5 -0
  197. package/dist/frontend/lowering/builtin-namespaces.js +19 -12
  198. package/dist/frontend/lowering/builtin-namespaces.js.map +1 -1
  199. package/dist/frontend/lowering/builtins/callable-aliases.js +42 -6
  200. package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -1
  201. package/dist/frontend/lowering/builtins/child-process.d.ts +12 -11
  202. package/dist/frontend/lowering/builtins/child-process.js +235 -38
  203. package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
  204. package/dist/frontend/lowering/builtins/compression.d.ts +6 -1
  205. package/dist/frontend/lowering/builtins/compression.js +3 -3
  206. package/dist/frontend/lowering/builtins/compression.js.map +1 -1
  207. package/dist/frontend/lowering/builtins/constants.js +2 -2
  208. package/dist/frontend/lowering/builtins/constants.js.map +1 -1
  209. package/dist/frontend/lowering/builtins/crypto.d.ts +3 -1
  210. package/dist/frontend/lowering/builtins/crypto.js +9 -1
  211. package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
  212. package/dist/frontend/lowering/builtins/dates.js +26 -6
  213. package/dist/frontend/lowering/builtins/dates.js.map +1 -1
  214. package/dist/frontend/lowering/builtins/environment.d.ts +13 -1
  215. package/dist/frontend/lowering/builtins/environment.js +15 -4
  216. package/dist/frontend/lowering/builtins/environment.js.map +1 -1
  217. package/dist/frontend/lowering/builtins/module-bindings.d.ts +33 -0
  218. package/dist/frontend/lowering/builtins/module-bindings.js +213 -11
  219. package/dist/frontend/lowering/builtins/module-bindings.js.map +1 -1
  220. package/dist/frontend/lowering/builtins/module-resolution.d.ts +9 -2
  221. package/dist/frontend/lowering/builtins/module-resolution.js +187 -19
  222. package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
  223. package/dist/frontend/lowering/builtins/performance.js +1 -1
  224. package/dist/frontend/lowering/builtins/performance.js.map +1 -1
  225. package/dist/frontend/lowering/builtins/process.js +40 -2
  226. package/dist/frontend/lowering/builtins/process.js.map +1 -1
  227. package/dist/frontend/lowering/builtins/promises.js +33 -0
  228. package/dist/frontend/lowering/builtins/promises.js.map +1 -1
  229. package/dist/frontend/lowering/builtins/readline.d.ts +9 -5
  230. package/dist/frontend/lowering/builtins/readline.js +184 -75
  231. package/dist/frontend/lowering/builtins/readline.js.map +1 -1
  232. package/dist/frontend/lowering/builtins/url.d.ts +4 -0
  233. package/dist/frontend/lowering/builtins/url.js +6 -0
  234. package/dist/frontend/lowering/builtins/url.js.map +1 -1
  235. package/dist/frontend/lowering/call-arguments.js +15 -0
  236. package/dist/frontend/lowering/call-arguments.js.map +1 -1
  237. package/dist/frontend/lowering/callable-properties.d.ts +34 -0
  238. package/dist/frontend/lowering/callable-properties.js +210 -0
  239. package/dist/frontend/lowering/callable-properties.js.map +1 -0
  240. package/dist/frontend/lowering/cjs-inline-require.d.ts +16 -0
  241. package/dist/frontend/lowering/cjs-inline-require.js +105 -0
  242. package/dist/frontend/lowering/cjs-inline-require.js.map +1 -1
  243. package/dist/frontend/lowering/cjs-inline-require.test.d.ts +1 -0
  244. package/dist/frontend/lowering/cjs-inline-require.test.js +61 -0
  245. package/dist/frontend/lowering/cjs-inline-require.test.js.map +1 -0
  246. package/dist/frontend/lowering/class-dynamic-dispatch.js +82 -2
  247. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  248. package/dist/frontend/lowering/class-protocols.d.ts +57 -4
  249. package/dist/frontend/lowering/class-protocols.js +597 -30
  250. package/dist/frontend/lowering/class-protocols.js.map +1 -1
  251. package/dist/frontend/lowering/class-unions.js +2 -2
  252. package/dist/frontend/lowering/class-unions.js.map +1 -1
  253. package/dist/frontend/lowering/coercions/function-adapters.d.ts +12 -0
  254. package/dist/frontend/lowering/coercions/function-adapters.js +62 -0
  255. package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
  256. package/dist/frontend/lowering/coercions/structural-plans.js +56 -1
  257. package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
  258. package/dist/frontend/lowering/coercions/structural.js +9 -4
  259. package/dist/frontend/lowering/coercions/structural.js.map +1 -1
  260. package/dist/frontend/lowering/collection-ingestion.d.ts +9 -0
  261. package/dist/frontend/lowering/collection-ingestion.js +115 -41
  262. package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
  263. package/dist/frontend/lowering/containers/array-callbacks.js +16 -0
  264. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
  265. package/dist/frontend/lowering/containers/bytes.js +66 -10
  266. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  267. package/dist/frontend/lowering/containers/collection-methods.js +61 -5
  268. package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
  269. package/dist/frontend/lowering/containers/filter-predicates.js +11 -0
  270. package/dist/frontend/lowering/containers/filter-predicates.js.map +1 -1
  271. package/dist/frontend/lowering/containers/indexed-objects.d.ts +15 -0
  272. package/dist/frontend/lowering/containers/indexed-objects.js +213 -30
  273. package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
  274. package/dist/frontend/lowering/error-name-order.d.ts +16 -0
  275. package/dist/frontend/lowering/error-name-order.js +61 -0
  276. package/dist/frontend/lowering/error-name-order.js.map +1 -1
  277. package/dist/frontend/lowering/expressions/asserted-receiver.d.ts +17 -0
  278. package/dist/frontend/lowering/expressions/asserted-receiver.js +123 -1
  279. package/dist/frontend/lowering/expressions/asserted-receiver.js.map +1 -1
  280. package/dist/frontend/lowering/expressions/binary.js +147 -20
  281. package/dist/frontend/lowering/expressions/binary.js.map +1 -1
  282. package/dist/frontend/lowering/expressions/element-access.js +63 -14
  283. package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
  284. package/dist/frontend/lowering/expressions/erased-delete.d.ts +59 -0
  285. package/dist/frontend/lowering/expressions/erased-delete.js +247 -0
  286. package/dist/frontend/lowering/expressions/erased-delete.js.map +1 -0
  287. package/dist/frontend/lowering/expressions/hosted-narrowing.d.ts +10 -0
  288. package/dist/frontend/lowering/expressions/hosted-narrowing.js +48 -1
  289. package/dist/frontend/lowering/expressions/hosted-narrowing.js.map +1 -1
  290. package/dist/frontend/lowering/expressions/identifiers.js +20 -0
  291. package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
  292. package/dist/frontend/lowering/expressions/narrowing.d.ts +7 -2
  293. package/dist/frontend/lowering/expressions/narrowing.js +77 -45
  294. package/dist/frontend/lowering/expressions/narrowing.js.map +1 -1
  295. package/dist/frontend/lowering/expressions/object-literals.js +62 -19
  296. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  297. package/dist/frontend/lowering/expressions/optional-chains.js +19 -0
  298. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  299. package/dist/frontend/lowering/expressions/property-access.d.ts +7 -7
  300. package/dist/frontend/lowering/expressions/property-access.js +247 -48
  301. package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
  302. package/dist/frontend/lowering/expressions/relational.d.ts +1 -0
  303. package/dist/frontend/lowering/expressions/relational.js +18 -8
  304. package/dist/frontend/lowering/expressions/relational.js.map +1 -1
  305. package/dist/frontend/lowering/expressions/union-fields.js +11 -5
  306. package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
  307. package/dist/frontend/lowering/expressions/updates.js +121 -11
  308. package/dist/frontend/lowering/expressions/updates.js.map +1 -1
  309. package/dist/frontend/lowering/function-context.d.ts +10 -0
  310. package/dist/frontend/lowering/function-context.js +36 -0
  311. package/dist/frontend/lowering/function-context.js.map +1 -1
  312. package/dist/frontend/lowering/function-returns.js +8 -8
  313. package/dist/frontend/lowering/function-returns.js.map +1 -1
  314. package/dist/frontend/lowering/handle-properties.d.ts +62 -3
  315. package/dist/frontend/lowering/handle-properties.js +674 -26
  316. package/dist/frontend/lowering/handle-properties.js.map +1 -1
  317. package/dist/frontend/lowering/handle-properties.test.js +95 -2
  318. package/dist/frontend/lowering/handle-properties.test.js.map +1 -1
  319. package/dist/frontend/lowering/lower-builtin-values.d.ts +12 -0
  320. package/dist/frontend/lowering/lower-builtin-values.js +44 -0
  321. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
  322. package/dist/frontend/lowering/lower-calls.js +328 -136
  323. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  324. package/dist/frontend/lowering/lower-classes.js +82 -17
  325. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  326. package/dist/frontend/lowering/lower-event-emitter.js +113 -9
  327. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  328. package/dist/frontend/lowering/lower-expando.d.ts +13 -21
  329. package/dist/frontend/lowering/lower-expando.js +90 -126
  330. package/dist/frontend/lowering/lower-expando.js.map +1 -1
  331. package/dist/frontend/lowering/lower-exprs.js +2 -2
  332. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  333. package/dist/frontend/lowering/lower-functions.js +65 -0
  334. package/dist/frontend/lowering/lower-functions.js.map +1 -1
  335. package/dist/frontend/lowering/lower-inspect.js +471 -0
  336. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  337. package/dist/frontend/lowering/lower-modules.js +36 -10
  338. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  339. package/dist/frontend/lowering/lower-node-island.js +28 -0
  340. package/dist/frontend/lowering/lower-node-island.js.map +1 -1
  341. package/dist/frontend/lowering/lower-server.d.ts +53 -7
  342. package/dist/frontend/lowering/lower-server.js +213 -42
  343. package/dist/frontend/lowering/lower-server.js.map +1 -1
  344. package/dist/frontend/lowering/lower-stdlib.js +50 -7
  345. package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
  346. package/dist/frontend/lowering/lower-stmts.d.ts +24 -0
  347. package/dist/frontend/lowering/lower-stmts.js +463 -220
  348. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  349. package/dist/frontend/lowering/lower-stream.js +2 -2
  350. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  351. package/dist/frontend/lowering/lower-test.js +71 -2
  352. package/dist/frontend/lowering/lower-test.js.map +1 -1
  353. package/dist/frontend/lowering/lowerer.d.ts +81 -10
  354. package/dist/frontend/lowering/lowerer.js +319 -72
  355. package/dist/frontend/lowering/lowerer.js.map +1 -1
  356. package/dist/frontend/lowering/new-target.js +10 -2
  357. package/dist/frontend/lowering/new-target.js.map +1 -1
  358. package/dist/frontend/lowering/nullish-empty-pattern.js +3 -3
  359. package/dist/frontend/lowering/nullish-empty-pattern.js.map +1 -1
  360. package/dist/frontend/lowering/partial-assertions.js +30 -5
  361. package/dist/frontend/lowering/partial-assertions.js.map +1 -1
  362. package/dist/frontend/lowering/primitive-throws.js +91 -1
  363. package/dist/frontend/lowering/primitive-throws.js.map +1 -1
  364. package/dist/frontend/lowering/primitive-wrappers.d.ts +9 -0
  365. package/dist/frontend/lowering/primitive-wrappers.js +2 -2
  366. package/dist/frontend/lowering/primitive-wrappers.js.map +1 -1
  367. package/dist/frontend/lowering/promise-executor-adapter.js +5 -2
  368. package/dist/frontend/lowering/promise-executor-adapter.js.map +1 -1
  369. package/dist/frontend/lowering/record-links.js +7 -2
  370. package/dist/frontend/lowering/record-links.js.map +1 -1
  371. package/dist/frontend/lowering/surfaces.d.ts +4 -0
  372. package/dist/frontend/lowering/surfaces.js +118 -2
  373. package/dist/frontend/lowering/surfaces.js.map +1 -1
  374. package/dist/frontend/lowering/surfaces.test.d.ts +1 -0
  375. package/dist/frontend/lowering/surfaces.test.js +31 -0
  376. package/dist/frontend/lowering/surfaces.test.js.map +1 -0
  377. package/dist/frontend/mock-shapes.js +3 -3
  378. package/dist/frontend/mock-shapes.js.map +1 -1
  379. package/dist/frontend/npm-static-ladder.d.ts +21 -0
  380. package/dist/frontend/npm-static-ladder.js +2 -0
  381. package/dist/frontend/npm-static-ladder.js.map +1 -0
  382. package/dist/frontend/npm-static-ladder.test.d.ts +1 -0
  383. package/dist/frontend/npm-static-ladder.test.js +138 -0
  384. package/dist/frontend/npm-static-ladder.test.js.map +1 -0
  385. package/dist/frontend/npm-static-status.d.ts +15 -0
  386. package/dist/frontend/npm-static-status.js +2 -0
  387. package/dist/frontend/npm-static-status.js.map +1 -0
  388. package/dist/frontend/package-shims.js +1 -1
  389. package/dist/frontend/package-shims.js.map +1 -1
  390. package/dist/frontend/pipeline.d.ts +1 -1
  391. package/dist/frontend/pipeline.js +222 -25
  392. package/dist/frontend/pipeline.js.map +1 -1
  393. package/dist/frontend/program-analysis.d.ts +4 -0
  394. package/dist/frontend/program-analysis.js +6 -0
  395. package/dist/frontend/program-analysis.js.map +1 -1
  396. package/dist/frontend/program.js +258 -32
  397. package/dist/frontend/program.js.map +1 -1
  398. package/dist/frontend/program.test.js +30 -0
  399. package/dist/frontend/program.test.js.map +1 -1
  400. package/dist/frontend/resolve.js +29 -5
  401. package/dist/frontend/resolve.js.map +1 -1
  402. package/dist/frontend/resolve.test.js +40 -0
  403. package/dist/frontend/resolve.test.js.map +1 -1
  404. package/dist/frontend/services.d.ts +8 -0
  405. package/dist/frontend/services.js +7 -0
  406. package/dist/frontend/services.js.map +1 -1
  407. package/dist/frontend/ts7/checker.d.ts +7 -0
  408. package/dist/frontend/ts7/checker.js +12 -0
  409. package/dist/frontend/ts7/checker.js.map +1 -1
  410. package/dist/frontend/ts7/checker.test.js +1 -0
  411. package/dist/frontend/ts7/checker.test.js.map +1 -1
  412. package/dist/frontend/ts7/program-host.d.ts +39 -2
  413. package/dist/frontend/ts7/program-host.js +62 -8
  414. package/dist/frontend/ts7/program-host.js.map +1 -1
  415. package/dist/frontend/ts7/program-host.test.js +33 -0
  416. package/dist/frontend/ts7/program-host.test.js.map +1 -1
  417. package/dist/frontend/ts7/session-cache.d.ts +5 -1
  418. package/dist/frontend/ts7/session-cache.js +7 -1
  419. package/dist/frontend/ts7/session-cache.js.map +1 -1
  420. package/dist/frontend/ts7/session-cache.test.js +37 -0
  421. package/dist/frontend/ts7/session-cache.test.js.map +1 -1
  422. package/dist/frontend/ts7/session.js +19 -1
  423. package/dist/frontend/ts7/session.js.map +1 -1
  424. package/dist/frontend/ts7/source-parser.d.ts +17 -2
  425. package/dist/frontend/ts7/source-parser.js +61 -2
  426. package/dist/frontend/ts7/source-parser.js.map +1 -1
  427. package/dist/frontend/ts7/source-parser.test.js +55 -2
  428. package/dist/frontend/ts7/source-parser.test.js.map +1 -1
  429. package/dist/frontend/tsc-codes.d.ts +3 -2
  430. package/dist/frontend/tsc-codes.js +129 -22
  431. package/dist/frontend/tsc-codes.js.map +1 -1
  432. package/dist/frontend/type-mapper.d.ts +5 -11
  433. package/dist/frontend/type-mapper.js +380 -70
  434. package/dist/frontend/type-mapper.js.map +1 -1
  435. package/dist/index.d.ts +1 -1
  436. package/dist/index.js +67 -7
  437. package/dist/index.js.map +1 -1
  438. package/dist/ir/builtin-effects.js +29 -0
  439. package/dist/ir/builtin-effects.js.map +1 -1
  440. package/dist/ir/builtin-signatures.d.ts +1 -1
  441. package/dist/ir/builtin-signatures.js +72 -6
  442. package/dist/ir/builtin-signatures.js.map +1 -1
  443. package/dist/ir/codec.generated.d.ts +1 -1
  444. package/dist/ir/codec.generated.js +321 -263
  445. package/dist/ir/codec.generated.js.map +1 -1
  446. package/dist/ir/constant-length-clones.d.ts +26 -0
  447. package/dist/ir/constant-length-clones.js +589 -0
  448. package/dist/ir/constant-length-clones.js.map +1 -0
  449. package/dist/ir/constant-length-clones.test.d.ts +1 -0
  450. package/dist/ir/constant-length-clones.test.js +292 -0
  451. package/dist/ir/constant-length-clones.test.js.map +1 -0
  452. package/dist/ir/constant-tables.d.ts +10 -5
  453. package/dist/ir/constant-tables.js +83 -17
  454. package/dist/ir/constant-tables.js.map +1 -1
  455. package/dist/ir/constant-tables.test.js +58 -1
  456. package/dist/ir/constant-tables.test.js.map +1 -1
  457. package/dist/ir/fields.generated.js +5 -2
  458. package/dist/ir/fields.generated.js.map +1 -1
  459. package/dist/ir/function-references.js +2 -0
  460. package/dist/ir/function-references.js.map +1 -1
  461. package/dist/ir/function-references.test.js +13 -0
  462. package/dist/ir/function-references.test.js.map +1 -1
  463. package/dist/ir/integer-loops.js +1 -0
  464. package/dist/ir/integer-loops.js.map +1 -1
  465. package/dist/ir/integer-loops.test.js +16 -0
  466. package/dist/ir/integer-loops.test.js.map +1 -1
  467. package/dist/ir/ir.d.ts +50 -6
  468. package/dist/ir/ir.js +44 -2
  469. package/dist/ir/ir.js.map +1 -1
  470. package/dist/ir/ir.test.js +83 -1
  471. package/dist/ir/ir.test.js.map +1 -1
  472. package/dist/ir/js-groups.js +5 -1
  473. package/dist/ir/js-groups.js.map +1 -1
  474. package/dist/ir/js-ic.d.ts +20 -0
  475. package/dist/ir/js-ic.js +81 -4
  476. package/dist/ir/js-ic.js.map +1 -1
  477. package/dist/ir/js-ic.test.js +8 -1
  478. package/dist/ir/js-ic.test.js.map +1 -1
  479. package/dist/ir/lane-plans.d.ts +86 -0
  480. package/dist/ir/lane-plans.js +589 -0
  481. package/dist/ir/lane-plans.js.map +1 -0
  482. package/dist/ir/lane-plans.test.d.ts +1 -0
  483. package/dist/ir/lane-plans.test.js +549 -0
  484. package/dist/ir/lane-plans.test.js.map +1 -0
  485. package/dist/ir/runtime-features.d.ts +68 -10
  486. package/dist/ir/runtime-features.js +285 -17
  487. package/dist/ir/runtime-features.js.map +1 -1
  488. package/dist/ir/runtime-features.test.js +190 -1
  489. package/dist/ir/runtime-features.test.js.map +1 -1
  490. package/dist/ir/validate.js +61 -24
  491. package/dist/ir/validate.js.map +1 -1
  492. package/dist/native/cache.d.ts +5 -0
  493. package/dist/native/cache.js +23 -1
  494. package/dist/native/cache.js.map +1 -1
  495. package/dist/native/cache.test.js +29 -1
  496. package/dist/native/cache.test.js.map +1 -1
  497. package/dist/native/cli.js +4 -2
  498. package/dist/native/cli.js.map +1 -1
  499. package/dist/native/compiler.d.ts +11 -3
  500. package/dist/native/compiler.js +102 -16
  501. package/dist/native/compiler.js.map +1 -1
  502. package/dist/native/compiler.test.js +244 -2
  503. package/dist/native/compiler.test.js.map +1 -1
  504. package/dist/native/prepare.d.ts +14 -1
  505. package/dist/native/prepare.js +79 -29
  506. package/dist/native/prepare.js.map +1 -1
  507. package/dist/native/sanitizer.test.js +3 -0
  508. package/dist/native/sanitizer.test.js.map +1 -1
  509. package/dist/native/unchanged.d.ts +80 -0
  510. package/dist/native/unchanged.js +301 -0
  511. package/dist/native/unchanged.js.map +1 -0
  512. package/dist/native/unchanged.test.d.ts +1 -0
  513. package/dist/native/unchanged.test.js +249 -0
  514. package/dist/native/unchanged.test.js.map +1 -0
  515. package/dist/node-islands/boundary.d.ts +16 -0
  516. package/dist/node-islands/boundary.js +70 -7
  517. package/dist/node-islands/boundary.js.map +1 -1
  518. package/dist/node-islands/boundary.test.js +59 -14
  519. package/dist/node-islands/boundary.test.js.map +1 -1
  520. package/dist/node-islands/detect.js +203 -47
  521. package/dist/node-islands/detect.js.map +1 -1
  522. package/dist/node-islands/detect.test.js +45 -0
  523. package/dist/node-islands/detect.test.js.map +1 -1
  524. package/dist/node-islands/growth.js +4 -16
  525. package/dist/node-islands/growth.js.map +1 -1
  526. package/dist/node-islands/modules.d.ts +3 -0
  527. package/dist/node-islands/modules.js +143 -12
  528. package/dist/node-islands/modules.js.map +1 -1
  529. package/dist/node-islands/modules.test.js +125 -0
  530. package/dist/node-islands/modules.test.js.map +1 -1
  531. package/dist/node-islands/report.d.ts +1 -1
  532. package/dist/node-islands/report.js +2 -1
  533. package/dist/node-islands/report.js.map +1 -1
  534. package/package.json +20 -20
  535. package/shims/undici/core/request.ts +7 -1
  536. package/surface-manifest.json +380 -2
@@ -1,21 +1,27 @@
1
1
  import { lowerStaticPrivateAssignment } from "./private-statics.js";
2
2
  import { keepsCheckedDynamicValue, keepsInitializerLayout, notePreservedLayout, } from "./structural-instances.js";
3
3
  import { partialFieldRead } from "./partial-assertions.js";
4
+ import { answerLinkedCopies, registerLinkedHelper } from "./record-links.js";
5
+ import { recordSourceTest } from "./record-sources.js";
6
+ import { keyedHelperName } from "./stable-names.js";
7
+ import { OBJECT_PROTOTYPE_KEYS } from "./expressions/relational.js";
4
8
  import { jsGlobalValueByName } from "./global-values.js";
5
9
  import { lowerTupleAliasDecl, stripTypeWrappers } from "./typed-arguments.js";
6
10
  import { islandHandleBinding, lowerIslandExpr, isIslandRequireSpec, lowerIslandRequireAtStatement, lowerIslandSubclass, } from "./lower-node-island.js";
7
11
  import { isIslandSubclassDecl } from "../../node-islands/boundary.js";
8
12
  import { allBytesArms, indexedUnionArms, lowerIndexedUnionMember, lowerIndexedUnionNumberRead, lowerIndexedUnionRead, } from "./indexed-unions.js";
9
- import { declaredMemberOf, fenceDatePrototypeWrite, isPromisePrototypeRead, lowerUnionKeyedRead, } from "./expressions/property-access.js";
10
- import { hostedStorageView, hostsAll, recordViewHosted } from "./expressions/hosted-narrowing.js";
13
+ import { declaredMemberOf, fenceDatePrototypeWrite, isDataViewPrototypeRead, isPromisePrototypeRead, lowerUnionKeyedRead, } from "./expressions/property-access.js";
14
+ import { assertedOptionalExtension, hostedStorageView, hostsAll, recordViewHosted, } from "./expressions/hosted-narrowing.js";
15
+ import { assertedOnlyMemberWrite } from "./expressions/asserted-receiver.js";
11
16
  import { assertionViewCopy, bindingIdentityUse, bindingWrite } from "./divergences.js";
12
17
  import { requestGeneralStreamSurface } from "./general-streams.js";
13
18
  import { lowerForAwaitDynStream, nodeStreamInterfaceSide } from "./dyn-streams.js";
14
19
  import { lowerForAwaitValueStream } from "./builtins/hash-stream.js";
15
- import { lowerChildPropertyWrite } from "./handle-properties.js";
20
+ import { TYPED_HANDLE_KINDS, boxedHandleReceiver, handleMemberGranted, lowerChildPropertyWrite, lowerHandlePropertyWrite, } from "./handle-properties.js";
16
21
  import { matchAllRowsReadByElements, storedMatchAllRowsReadByElements, } from "./containers/match-row-uses.js";
17
22
  import { dynUndefinedExpr, nodeThrowExpr, numLit, strLit, varRef } from "../../ir/build.js";
18
- import { literalFieldKeys, runtimeKeyPatternRead } from "./expressions/keyed-field-targets.js";
23
+ import { runtimeKeyPatternRead } from "./expressions/keyed-field-targets.js";
24
+ import { constantDeleteKey, erasedDeletePlan, lowerDeleteComputedKey, lowerDeleteKey, lowerRecordMemberDelete, } from "./expressions/erased-delete.js";
19
25
  import { declaresHoistedBinding, staticCondition } from "./static-typeof.js";
20
26
  import { lowerCollectionSpread } from "./containers/collection-methods.js";
21
27
  import { lowerEventObjectPropertyWrite } from "./lower-event-target.js";
@@ -42,27 +48,27 @@ import { isTimeValueDateDeclaration } from "./date-values.js";
42
48
  import { bindingSource } from "../binding-source.js";
43
49
  import { clearPendingPrimitiveReturn, lowerConstructorReturn } from "./constructor-returns.js";
44
50
  import { statementGroupKey } from "./type-failure.js";
45
- import { cjsExportValueByName, cjsNamespaceDestructureOf, cjsTableMethodEntry, inlineProgramRequireOf, requireNestedPatternsOf, splitRequireAssignmentOf, splitRequireBindingOf, splitRequireBindingOfIdent, splitRequireEarlyReadOf, wholeExportSymbolOfModule, } from "./cjs-inline-require.js";
51
+ import { cjsExportValueByName, cjsNamespaceDestructureOf, cjsTableExportNamesInOrder, cjsTableMethodEntry, inlineProgramRequireOf, requireNestedPatternsOf, requireRestElementsOf, splitRequireAssignmentOf, splitRequireBindingOf, splitRequireBindingOfIdent, splitRequireEarlyReadOf, wholeExportSymbolOfModule, } from "./cjs-inline-require.js";
46
52
  import { cjsExportMemberWriteGlobalOf, isCjsExportsIdentifier, isCjsModuleExports, isFreshExportsReset, } from "./cjs-exports-object.js";
47
53
  import { isDeadTscHelperDecl, tscInteropBindingOfDecl } from "./cjs-tsc-interop.js";
48
54
  import { arrayValueRead, arrayValueStore, arrayValueType, unionArrayValueRead, lowerSafeIndexRead, } from "./array-values.js";
49
55
  import { lowerForAwaitGenerator, lowerForOfGenerator, lowerYieldStarStatement, } from "./lower-generators.js";
50
56
  import { classAsyncGeneratorIterator, isNodeReadableIteratorSource, isWebReadableIteratorSource, lowerForAwaitBuiltin, } from "./lower-async-iteration.js";
51
- import { BOOL, BYTES_U8, CAUGHT, DATE_T, DYN_HANDLE_KINDS, DYN, F64, SEARCH_PARAMS_T, STRING, UNDEFINED_T, VOID, arrayOf, isDynTypedRefType, isUnitType, shapeHasAccessorSlots, typeEquals, } from "../../ir/ir.js";
57
+ import { BOOL, BYTES_U8, CAUGHT, DATE_T, DYN_HANDLE_KINDS, DYN, F64, SEARCH_PARAMS_T, STRING, UNDEFINED_T, VOID, arrayOf, isDynTypedRefType, isUnitType, shapeHasAccessorSlots, typeEquals, typeKey, } from "../../ir/ir.js";
52
58
  import { PoisonError, boundIdentifiersOf, dynFallbackType, neverTaintedJsType, staticImportNamespaceType, } from "./lowerer.js";
53
59
  import { enforceLibBoundary, lowerSurplusCalls } from "./lib-boundary.js";
54
60
  import { isBuiltinIdentityToken, isPrimitiveValueType, lowerPrimitiveBaseDelete, } from "./primitive-throws.js";
55
61
  import { cjsExportAssignmentOf, cjsExportChainOf, cjsVoidInitPreambleReals, cjsExportDiscardReason, cjsExportTargetLiteral, isCjsJsFile, isEsModuleStamp, isJsSourceFile, locOf, requireEarlyReference, requireSpecOf, } from "../program.js";
62
+ import { callableDeleteKey } from "./callable-properties.js";
56
63
  import { isStrictCode } from "./strict-mode.js";
57
- import { markSloppyRecordWrites } from "./frozen-records.js";
58
64
  import { COMPOUND_ASSIGN_OPS, STR_METHODS, NARROW_FIRST, UNSUPPORTED_STMT, isStdlibMember, sideEffectFreeOptionValue, stdlibGlobalAliasDecl, stdlibGlobalAliasNameOf, bufferNamespaceMember, stdlibGlobalNameOf, } from "./surfaces.js";
59
65
  import { isNativeBuiltinValueInitializer } from "./lower-builtin-values.js";
60
66
  import { isProvenanceSourceFile } from "../provenance-registry.js";
61
67
  import { ambientUndefVarRootOf, lowerImportEquals, nsUndefRead, nsWritableTarget, trapDeclRootOf, } from "./lower-namespaces.js";
62
- import { expandoWritableTarget, lowerExpandoAssignStmt } from "./lower-expando.js";
68
+ import { fenceReadonlyExpandoWrite } from "./lower-expando.js";
63
69
  import { lowerForOfArrayIter, lowerForOfMap, lowerForOfSearchParams, lowerForOfSet, } from "./containers/for-of.js";
64
70
  import { lowerForOfHelperChain } from "./containers/iterator-helpers.js";
65
- import { objectIterOverIndexShape } from "./containers/indexed-objects.js";
71
+ import { lowerRecordRestCaptureHelper, objectIterOverIndexShape, } from "./containers/indexed-objects.js";
66
72
  import { strCharsCall } from "./containers/array-construction.js";
67
73
  import { bindingContextualGenericFnNodeOf, bindingGenericFnAliasInfoOf, bindingGenericFnInfoOf, bindingGenericFnNodeOf, genericAliasPresenceStore, genericBindingPresenceStore, genericBindingStoredValue, implicitLocalFnInfoOf, implicitLocalFnNodeOf, implicitMethodCallInfersReturn, genericLocalClassBinding, } from "./generic-functions.js";
68
74
  import { bindingNeverReassigned, deadUnmappableBinding, fileWritesBinding, nullishExprUnitOf, nullishGenericBindingUnitOf, } from "./binding-analysis.js";
@@ -78,11 +84,11 @@ import { classForInHasKey, classPropertiesHelper } from "./class-dynamic-dispatc
78
84
  import { genericIfaceBindingKeepsClass, lowerClassStaticRead, staticReceiverClass, superConditionLead, } from "./lower-classes.js";
79
85
  import { lowerStreamUnderscoreAssign, streamClassAliasDecl, streamSidesOf, } from "./lower-stream.js";
80
86
  import { staticAssertInstanceDecl } from "./assert-instances.js";
81
- import { lowerHttpResPropertyAssignment, lowerHttpServerTimeoutAssignment, lowerNetServerMaxConnectionsAssignment, lowerServerCloseOverrideAssignment, } from "./lower-server.js";
87
+ import { lowerHttpClientFnBindingDecl, lowerHttpResPropertyAssignment, lowerHttpServerTimeoutAssignment, lowerNetServerMaxConnectionsAssignment, lowerServerCloseOverrideAssignment, } from "./lower-server.js";
82
88
  import { lowerUrlAssignment } from "./builtins/url.js";
83
89
  import { isFspGlobCall, lowerFspGlobForAwait } from "./builtins/fs-glob.js";
84
90
  import { isTimersPromisesIntervalCall } from "./builtins/timers.js";
85
- import { isNativeFfiRequire, builtinMemberRequireDecl, builtinNamespaceDestructureModuleOf, createRequireBindingDecl, createRequireCalleeFileOf, createRequireNamespaceDecl, createRequireProgramModuleDecl, createRequireProgramModuleOf, } from "./builtins/module-bindings.js";
91
+ import { isNativeFfiRequire, builtinMemberRequireDecl, builtinNamespaceDestructureModuleOf, createRequireBindingDecl, createRequireCalleeFileOf, createRequireEvaluatedBaseOf, createRequireFactoryDecl, createRequireNamespaceDecl, createRequireProgramModuleDecl, createRequireProgramModuleOf, } from "./builtins/module-bindings.js";
86
92
  import { lowerNodeModuleCall } from "./builtins/module-resolution.js";
87
93
  import { registerBuiltinCallableAlias } from "./builtins/callable-aliases.js";
88
94
  import { builtinClassAliasOwnsNoSlot, registerBuiltinClassAlias } from "./builtins/class-values.js";
@@ -1199,6 +1205,10 @@ function varBindingType(lowerer, nameNode) {
1199
1205
  !nameNode.parent.type &&
1200
1206
  isPromisePrototypeRead(lowerer, nameNode.parent.initializer))
1201
1207
  return DYN;
1208
+ if (ts.isVariableDeclaration(nameNode.parent) &&
1209
+ !nameNode.parent.type &&
1210
+ isDataViewPrototypeRead(lowerer, nameNode.parent.initializer))
1211
+ return DYN;
1202
1212
  let type = lowerer.mapTypeOf(lowerer.typeOf(nameNode));
1203
1213
  if (type?.kind === "record" && isJsSourceFile(ts.getSourceFileOfNode(nameNode))) {
1204
1214
  const shape = lowerer.shapes.get(type.shapeId);
@@ -1993,6 +2003,44 @@ function lowerVarDeclarator(lowerer, stmt, decl, isConst, isLet) {
1993
2003
  const value = lowerer.lowerExpr(key);
1994
2004
  lowerer.lowerBindingPattern(element.name, () => lowerer.lowerExpr(key), value.type, isLet, out);
1995
2005
  }
2006
+ // `const { a, ...rest } = require("./m")`: Node copies the module's
2007
+ // remaining own enumerable exports into a fresh object at the
2008
+ // require, in the exports object's own key order. The table's
2009
+ // statically known members are exactly those properties, each read
2010
+ // from its export global into a dynamic object (the binding's own
2011
+ // checker type is `any`, so this is its represented form).
2012
+ for (const element of requireRestElementsOf(decl)) {
2013
+ const dep = lowerer.cjsRequireRestTableOf(decl);
2014
+ const names = dep === null ? null : cjsTableExportNamesInOrder(lowerer, dep);
2015
+ if (dep === null || names === null) {
2016
+ lowerer.unsupported("SC1090", element, `the exports object of '${spec}' as a value (its exports do not form a static table)`);
2017
+ }
2018
+ const consumed = new Set();
2019
+ for (const sib of element.parent.elements.nodes) {
2020
+ if (sib === element || sib.dotDotDotToken !== undefined || sib.name === undefined)
2021
+ continue;
2022
+ const keyNode = sib.propertyName ?? sib.name;
2023
+ if (!(ts.isIdentifier(keyNode) || ts.isStringLiteralLike(keyNode))) {
2024
+ lowerer.unsupported("SC1090", element, "rest bindings beside computed keys (the copied set is a runtime fact)");
2025
+ }
2026
+ consumed.add(keyNode.text);
2027
+ }
2028
+ const loc = locOf(element);
2029
+ const fields = [];
2030
+ for (const name of names) {
2031
+ if (consumed.has(name))
2032
+ continue;
2033
+ const value = cjsExportValueByName(lowerer, dep, name, element);
2034
+ if (value === null) {
2035
+ lowerer.unsupported("SC1090", element, `the exports object of '${spec}' as a value (its export '${name}' has no static value)`);
2036
+ }
2037
+ fields.push({
2038
+ key: strLit(name, loc),
2039
+ value: lowerer.coerceToExpected(value, DYN),
2040
+ });
2041
+ }
2042
+ lowerer.bindPatternTarget(element.name, { kind: "dynObjLit", fields, type: DYN, loc }, isLet, out);
2043
+ }
1996
2044
  return out;
1997
2045
  }
1998
2046
  // A nested BUILTIN require (`get inFreeBSDJail() { const { execSync }
@@ -3342,6 +3390,16 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
3342
3390
  continue;
3343
3391
  }
3344
3392
  if (!fieldType) {
3393
+ // A property only an ASSERTED intersection declares
3394
+ // (`{ icons } = item as T & { icons?: unknown }`): the assertion is
3395
+ // erased to the bound layout, which does not carry it, but the value
3396
+ // Node destructures may. The read binds what the record can answer
3397
+ // for the property, the type's undefined otherwise.
3398
+ const missing = assertedOnlyFieldRead(lowerer, propName, srcType, srcRef, patternBindingType(lowerer, el.name), locOf(el));
3399
+ if (missing !== null) {
3400
+ lowerer.bindPatternTarget(el.name, el.initializer ? applyBindingDefault(lowerer, el, missing) : missing, isLet, out);
3401
+ continue;
3402
+ }
3345
3403
  // The pattern names a field the source SHAPE does not carry —
3346
3404
  // `for (let {x = 1} of [{}])` (signature 08): tsc types the binding
3347
3405
  // from the DEFAULT, and under JS the read is always undefined, so
@@ -3451,6 +3509,101 @@ function patternBindingType(lowerer, name) {
3451
3509
  return (lowerer.mapTypeOf(type) ??
3452
3510
  (isJsSourceFile(ts.getSourceFileOfNode(name)) ? dynFallbackType(lowerer, name, type) : null));
3453
3511
  }
3512
+ /** The value one element reads from a record shape for a property the
3513
+ * shape does NOT declare: an asserted intersection (`item as T & {icons?:
3514
+ * unknown}`) declares properties the assertion erases back to the bound
3515
+ * layout, so the static shape is narrower than the value Node reads from.
3516
+ *
3517
+ * The value can still answer for the property: a checked conversion keeps
3518
+ * the source's undeclared own properties beside the record
3519
+ * (record-sources.ts), and a narrowed copy links to the record it came from
3520
+ * (record-links.ts). Both are settled only at finalization, so the read is
3521
+ * one interned `%rec.qfield.<n>(r)` per (source shape, key, binding type):
3522
+ * its body starts as the type's static undefined and gains one `return` per
3523
+ * answering surface then. A site the two mechanisms cannot answer keeps the
3524
+ * static undefined, which is what Node binds for a value without the
3525
+ * property.
3526
+ *
3527
+ * Null where the site keeps its existing lowering: a hybrid source already
3528
+ * reads its overflow (`indexValue`), a name on `Object.prototype` is never
3529
+ * an own property (Node reads the inherited value, which the static form's
3530
+ * undefined does not reproduce), and a binding type that cannot hold
3531
+ * undefined is the required-asserted-field representation gap (a slot that
3532
+ * cannot hold the value Node would bind). */
3533
+ export function assertedOnlyFieldRead(lowerer, propName, srcType, srcRef, bodyT, loc) {
3534
+ if (OBJECT_PROTOTYPE_KEYS.has(propName))
3535
+ return null;
3536
+ if (bodyT === null || bodyT.kind === "void")
3537
+ return null;
3538
+ const undefinedArmed = bodyT.kind === "union" && lowerer.armTag(bodyT.unionId, UNDEFINED_T) >= 0;
3539
+ if (bodyT.kind !== "dyn" && !undefinedArmed)
3540
+ return null;
3541
+ const key = `qfield:${srcType.shapeId}:${propName}:${typeKey(bodyT)}`;
3542
+ let name = lowerer.valueHelpers.get(key);
3543
+ if (name === undefined) {
3544
+ name = keyedHelperName(lowerer, "%rec.qfield", key);
3545
+ lowerer.valueHelpers.set(key, name);
3546
+ const recT = srcType;
3547
+ const statics = bodyT.kind === "dyn"
3548
+ ? dynUndefinedExpr(loc)
3549
+ : (lowerer.wrappedUndefined(bodyT, loc) ?? dynUndefinedExpr(loc));
3550
+ const fn = {
3551
+ name,
3552
+ params: [{ localId: "r.0", name: "r", type: recT }],
3553
+ returnType: bodyT,
3554
+ locals: [{ id: "r.0", name: "r", type: recT, mutable: false }],
3555
+ body: [{ kind: "return", value: statics, loc }],
3556
+ loc,
3557
+ };
3558
+ // `r.<key>` through the record's live view: the capsule of a record
3559
+ // that kept a source starts from that view (scr_dyn.h's
3560
+ // scr_record_source_view), and a composed linked copy declares the key.
3561
+ const viewRead = (value) => {
3562
+ const got = {
3563
+ kind: "dynKeyGet",
3564
+ value: { kind: "dynFrom", value, liveRef: true, type: DYN, loc },
3565
+ key: { kind: "strLit", value: propName, type: STRING, loc },
3566
+ type: DYN,
3567
+ loc,
3568
+ };
3569
+ return bodyT.kind === "dyn" ? got : { kind: "dynCheck", value: got, type: bodyT, loc };
3570
+ };
3571
+ const receiver = varRef("r.0", recT, loc);
3572
+ lowerer.linkedHelperFinalizers.push((sourced) => {
3573
+ // Links first: answerLinkedCopies prepends, and a kept source is
3574
+ // tested on the record itself, before any composed copy.
3575
+ answerLinkedCopies(lowerer, fn, srcType.shapeId, (composed) => [
3576
+ { kind: "return", value: viewRead(composed), loc },
3577
+ ]);
3578
+ if (sourced.has(srcType.shapeId))
3579
+ fn.body = [
3580
+ {
3581
+ kind: "if",
3582
+ cond: recordSourceTest(receiver, loc),
3583
+ then: [{ kind: "return", value: viewRead(receiver), loc }],
3584
+ else_: null,
3585
+ loc,
3586
+ },
3587
+ ...fn.body,
3588
+ ];
3589
+ });
3590
+ registerLinkedHelper(lowerer, fn, srcType.shapeId, "custom");
3591
+ lowerer.liftedFns.push(fn);
3592
+ }
3593
+ return { kind: "call", callee: name, args: [srcRef()], type: bodyT, loc };
3594
+ }
3595
+ const INTEGER_LIKE_KEY = /^(0|[1-9][0-9]{0,9})$/;
3596
+ /** A declared integer-like field name in a rest copy's own frame: JS orders
3597
+ * integer-like own keys first, ACROSS the declared and overflow stores, so a
3598
+ * reshape that walks the declared fields before the source's overflow cannot
3599
+ * reproduce Node's key order (the rule Object.keys' index-shape lowering
3600
+ * already fences on). Callers use it only where the site fenced before the
3601
+ * rest capture existed. */
3602
+ function fenceIntegerKeyRest(lowerer, blame, fields) {
3603
+ if (!fields.some((f) => INTEGER_LIKE_KEY.test(f.name) && Number(f.name) <= 4294967294))
3604
+ return;
3605
+ lowerer.unsupported("SC1031", blame, "rest bindings over index-signature sources that declare an integer-like field name (JS orders integer keys first, across the declared and overflow keys)");
3606
+ }
3454
3607
  /** `const { a, b: c } = ns` / `const { f } = await import("./m")` over
3455
3608
  * a program module's namespace: each element reads the export exactly
3456
3609
  * like `ns.a` does — the member resolves to the exporter's own binding
@@ -3593,7 +3746,7 @@ function unionObjectRestValue(lowerer, el, srcRef, srcType, arms) {
3593
3746
  fence(`rest bindings over union sources (${NARROW_FIRST})`);
3594
3747
  }
3595
3748
  const shape = lowerer.shapes.get(arm.shapeId);
3596
- if (!shape || shape.indexValue) {
3749
+ if (!shape) {
3597
3750
  fence("rest bindings over index-signature shapes (the undeclared entries would need overflow packing)");
3598
3751
  }
3599
3752
  const rem = shape.fields.filter((f) => !consumed.has(f.name));
@@ -3608,25 +3761,46 @@ function unionObjectRestValue(lowerer, el, srcRef, srcType, arms) {
3608
3761
  type: arm,
3609
3762
  loc,
3610
3763
  };
3611
- const packed = lowerer.keyOrder.copy({
3612
- kind: "recordLit",
3613
- fields: rem.map((f) => ({
3614
- name: f.name,
3615
- value: lowerer.presenceKeepingCopy(armRef, arm.shapeId, f.name, {
3616
- kind: "recordGet",
3617
- obj: armRef,
3618
- shapeId: arm.shapeId,
3619
- field: f.name,
3620
- type: f.type,
3621
- loc,
3622
- }, loc),
3623
- })),
3624
- type: {
3625
- kind: "record",
3626
- shapeId: lowerer.shapes.intern(rem.map((f) => ({ name: f.name, type: f.type }))),
3627
- },
3628
- loc,
3629
- }, arm.shapeId);
3764
+ // An INDEX-SIGNATURE arm packs through the same `%rec.rest` capture
3765
+ // reshape the single-shape path uses, into the arm's source-derived
3766
+ // hybrid (its remaining declared fields plus its own overflow slot).
3767
+ let packed;
3768
+ if (shape.indexValue !== undefined) {
3769
+ fenceIntegerKeyRest(lowerer, el, rem);
3770
+ const derivedId = lowerer.shapes.intern(rem.map((f) => ({ ...f })), false, shape.indexValue, (shape.declaredOrder ?? shape.fields.map((f) => f.name)).filter((n) => rem.some((f) => f.name === n)));
3771
+ const helper = lowerRecordRestCaptureHelper(lowerer, arm.shapeId, derivedId, [...consumed], loc);
3772
+ if (helper === null) {
3773
+ fence("rest bindings over index-signature shapes (the undeclared entries would need overflow packing)");
3774
+ }
3775
+ packed = {
3776
+ kind: "call",
3777
+ callee: helper,
3778
+ args: [armRef],
3779
+ type: { kind: "record", shapeId: derivedId },
3780
+ loc,
3781
+ };
3782
+ }
3783
+ else {
3784
+ packed = lowerer.keyOrder.copy({
3785
+ kind: "recordLit",
3786
+ fields: rem.map((f) => ({
3787
+ name: f.name,
3788
+ value: lowerer.presenceKeepingCopy(armRef, arm.shapeId, f.name, {
3789
+ kind: "recordGet",
3790
+ obj: armRef,
3791
+ shapeId: arm.shapeId,
3792
+ field: f.name,
3793
+ type: f.type,
3794
+ loc,
3795
+ }, loc, f),
3796
+ })),
3797
+ type: {
3798
+ kind: "record",
3799
+ shapeId: lowerer.shapes.intern(rem.map((f) => ({ ...f }))),
3800
+ },
3801
+ loc,
3802
+ }, arm.shapeId);
3803
+ }
3630
3804
  const coerced = lowerer.coerceInto(el, packed, restT);
3631
3805
  if (!typeEquals(coerced.type, restT)) {
3632
3806
  fence(`rest bindings over union sources (the remaining fields of an arm do not spell an arm of '${lowerer.fmt(restT)}')`);
@@ -4510,11 +4684,30 @@ function tupleTailValue(lowerer, blame, srcRef, srcType, shape, from, restT) {
4510
4684
  * copies out of the source at destructure time (JS's CopyDataProperties
4511
4685
  * is a fresh object of copied values too, so mutations through the rest
4512
4686
  * binding never reach the source — and records have no getters to make
4513
- * the copy observable). Index-signature rest types keep a named fence:
4514
- * their entries would need overflow packing, not field reads. */
4687
+ * the copy observable). An INDEX-SIGNATURE source or rest type takes the
4688
+ * interned `%rec.rest` capture reshape with the pattern's literal keys as
4689
+ * its exclusion set (lowerRecordRestCaptureHelper), which enumerates the
4690
+ * source's remaining declared fields and overflow entries exactly as the
4691
+ * source's own Object.keys does. A rest type that is CLOSED over such a
4692
+ * source keeps a named fence: the undeclared entries have no slot. */
4515
4693
  function objectRestValue(lowerer, el, srcRef, srcType, shape) {
4516
4694
  const loc = locOf(el);
4517
4695
  const restT = patternBindingType(lowerer, el.name); // callers skip nameless elisions
4696
+ // The consumed set is the pattern's literal sibling keys: a computed
4697
+ // sibling would make it a runtime fact and fences.
4698
+ const consumed = new Set();
4699
+ let computedSibling = false;
4700
+ if (ts.isObjectBindingPattern(el.parent)) {
4701
+ for (const sib of el.parent.elements.nodes) {
4702
+ if (sib === el || sib.dotDotDotToken)
4703
+ continue;
4704
+ const key = sib.propertyName ?? sib.name;
4705
+ if (key && ts.isComputedPropertyName(key))
4706
+ computedSibling = true;
4707
+ else if (key && (ts.isIdentifier(key) || ts.isStringLiteral(key) || ts.isNumericLiteral(key)))
4708
+ consumed.add(key.text);
4709
+ }
4710
+ }
4518
4711
  // A DYN rest type is the top-type spelling (`const { ...rest } = src`
4519
4712
  // where the checker's rest type is `{}` — every field consumed, or the
4520
4713
  // empty-source `const { ...empty } = {}`): CopyDataProperties still
@@ -4523,27 +4716,30 @@ function objectRestValue(lowerer, el, srcRef, srcType, shape) {
4523
4716
  // binding. Computed sibling keys would make the consumed set a runtime
4524
4717
  // fact, and reserved accessor slots are closures, not data — both fence.
4525
4718
  if (restT?.kind === "dyn") {
4526
- const pattern = el.parent;
4527
- const consumed = new Set();
4528
- let computedSibling = false;
4529
- if (ts.isObjectBindingPattern(pattern)) {
4530
- for (const sib of pattern.elements.nodes) {
4531
- if (sib === el || sib.dotDotDotToken)
4532
- continue;
4533
- const key = sib.propertyName ?? sib.name;
4534
- if (key && ts.isComputedPropertyName(key))
4535
- computedSibling = true;
4536
- else if (key &&
4537
- (ts.isIdentifier(key) || ts.isStringLiteral(key) || ts.isNumericLiteral(key)))
4538
- consumed.add(key.text);
4539
- }
4540
- }
4541
4719
  const rem = shape.fields.filter((f) => !consumed.has(f.name));
4542
- if (computedSibling || shape.indexValue || rem.some((f) => f.name.startsWith("%"))) {
4720
+ if (computedSibling || rem.some((f) => f.name.startsWith("%"))) {
4543
4721
  lowerer.unsupported("SC1031", el, computedSibling
4544
4722
  ? "rest bindings beside computed keys (the consumed set is a runtime fact)"
4545
4723
  : "rest bindings over index-signature or accessor shapes (the entries would need overflow packing)");
4546
4724
  }
4725
+ // An INDEX-SIGNATURE source packs into the source-derived hybrid (the
4726
+ // remaining declared fields plus the source's own overflow slot), so
4727
+ // the undeclared entries survive the copy.
4728
+ if (shape.indexValue !== undefined) {
4729
+ fenceIntegerKeyRest(lowerer, el, rem);
4730
+ const derivedId = lowerer.shapes.intern(rem.map((f) => ({ ...f })), false, shape.indexValue, (shape.declaredOrder ?? shape.fields.map((f) => f.name)).filter((n) => rem.some((f) => f.name === n)));
4731
+ const helper = lowerRecordRestCaptureHelper(lowerer, srcType.shapeId, derivedId, [...consumed], loc);
4732
+ if (helper !== null) {
4733
+ return lowerer.coerceInto(el, {
4734
+ kind: "call",
4735
+ callee: helper,
4736
+ args: [srcRef()],
4737
+ type: { kind: "record", shapeId: derivedId },
4738
+ loc,
4739
+ }, DYN);
4740
+ }
4741
+ lowerer.unsupported("SC1031", el, "rest bindings over index-signature or accessor shapes (the entries would need overflow packing)");
4742
+ }
4547
4743
  const packed = {
4548
4744
  kind: "recordLit",
4549
4745
  fields: rem.map((f) => ({
@@ -4555,11 +4751,11 @@ function objectRestValue(lowerer, el, srcRef, srcType, shape) {
4555
4751
  field: f.name,
4556
4752
  type: f.type,
4557
4753
  loc,
4558
- }, loc),
4754
+ }, loc, f),
4559
4755
  })),
4560
4756
  type: {
4561
4757
  kind: "record",
4562
- shapeId: lowerer.shapes.intern(rem.map((f) => ({ name: f.name, type: f.type }))),
4758
+ shapeId: lowerer.shapes.intern(rem.map((f) => ({ ...f }))),
4563
4759
  },
4564
4760
  loc,
4565
4761
  };
@@ -4573,8 +4769,27 @@ function objectRestValue(lowerer, el, srcRef, srcType, shape) {
4573
4769
  const restShape = lowerer.shapes.get(restT.shapeId);
4574
4770
  if (!restShape)
4575
4771
  throw new InternalCompilerError(`lowerer bug: rest binding over unknown shape ${restT.shapeId}`);
4576
- if (restShape.indexValue || shape.indexValue) {
4577
- lowerer.unsupported("SC1031", el, "rest bindings over index-signature shapes (the undeclared entries would need overflow packing)");
4772
+ if (restShape.indexValue !== undefined || shape.indexValue !== undefined) {
4773
+ // An INDEX-SIGNATURE source or rest type: the capture reshape with the
4774
+ // pattern's literal keys excluded. A CLOSED rest type over a source
4775
+ // with an overflow slot has nowhere to put the undeclared entries.
4776
+ if (computedSibling) {
4777
+ lowerer.unsupported("SC1031", el, "rest bindings beside computed keys (the consumed set is a runtime fact)");
4778
+ }
4779
+ fenceIntegerKeyRest(lowerer, el, restShape.fields);
4780
+ // Reserved accessor slots are closures, not data: the reshape copies
4781
+ // declared values, and JS's copy would call the getters.
4782
+ if (shape.fields.some((f) => f.name.startsWith("%"))) {
4783
+ lowerer.unsupported("SC1031", el, "rest bindings over accessor shapes (the entries are closures, not data)");
4784
+ }
4785
+ if (restShape.indexValue === undefined) {
4786
+ lowerer.unsupported("SC1031", el, `rest bindings packing an index-signature source into the closed rest type '${lowerer.fmt(restT)}' (its undeclared keys have no slot)`);
4787
+ }
4788
+ const helper = lowerRecordRestCaptureHelper(lowerer, srcType.shapeId, restT.shapeId, [...consumed], loc);
4789
+ if (helper === null) {
4790
+ lowerer.unsupported("SC1031", el, "rest bindings over index-signature shapes (the undeclared entries would need overflow packing)");
4791
+ }
4792
+ return { kind: "call", callee: helper, args: [srcRef()], type: restT, loc };
4578
4793
  }
4579
4794
  const fields = restShape.fields.map((f) => {
4580
4795
  const srcField = shape.fields.find((s) => s.name === f.name);
@@ -4591,7 +4806,7 @@ function objectRestValue(lowerer, el, srcRef, srcType, shape) {
4591
4806
  };
4592
4807
  return {
4593
4808
  name: f.name,
4594
- value: lowerer.presenceKeepingCopy(srcRef(), srcType.shapeId, srcField.name, lowerer.coerceInto(el, read, f.type), loc),
4809
+ value: lowerer.presenceKeepingCopy(srcRef(), srcType.shapeId, srcField.name, lowerer.coerceInto(el, read, f.type), loc, f),
4595
4810
  };
4596
4811
  });
4597
4812
  return lowerer.keyOrder.copy({ kind: "recordLit", fields, type: restT, loc }, srcType.shapeId);
@@ -5302,6 +5517,12 @@ export function lowerVarDecl(lowerer, decl, isLet) {
5302
5517
  ts.getModifiers(s)?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) === true))) {
5303
5518
  lowerer.unsupported("SC1090", decl.name, `initializer-less top-level declarations named '${decl.name.text}' in an import/export-free file (Node hosts the file as CommonJS, where the wrapper's own binding keeps its value — the declaration reads as the module object there, which has no lowering; rename the variable or give it an initializer)`);
5304
5519
  }
5520
+ // `const requestFn = cond ? https.request : http.request`: calls through
5521
+ // the binding lower as the runtime-secure client. A condition that is not
5522
+ // a stable identifier read is evaluated once, here, into a hidden bool.
5523
+ const clientFnDecl = lowerHttpClientFnBindingDecl(lowerer, decl);
5524
+ if (clientFnDecl !== false)
5525
+ return clientFnDecl;
5305
5526
  // `const asyncFn = promisify(supportedBuiltin)`: the binding registers
5306
5527
  // a static callable projection; calls route to the target's promise
5307
5528
  // lowering and the declaration emits no runtime slot.
@@ -5316,8 +5537,20 @@ export function lowerVarDecl(lowerer, decl, isLet) {
5316
5537
  // `const require = createRequire(import.meta.url)` — compile-time
5317
5538
  // plumbing: each call through the binding resolves per site
5318
5539
  // (lowerCreateRequireCall); no storage, no code (collectGlobals
5319
- // skipped its global by the same test).
5320
- if (createRequireBindingDecl(lowerer, decl.name, decl.initializer))
5540
+ // skipped its global by the same test). A RUN-TIME base is still
5541
+ // evaluated here, as Node evaluates it at the declaration: its side
5542
+ // effects happen and its throws unwind the module, even though the
5543
+ // loader value stays the deferred fence.
5544
+ if (createRequireBindingDecl(lowerer, decl.name, decl.initializer)) {
5545
+ const base = createRequireEvaluatedBaseOf(lowerer, decl.initializer);
5546
+ return base === null
5547
+ ? null
5548
+ : { kind: "exprStmt", expr: lowerer.lowerExpr(base), loc: locOf(base) };
5549
+ }
5550
+ // `const { createRequire: cr } = require("node:module")` — the factory
5551
+ // binding is the same compile-time plumbing (its calls take the
5552
+ // run-time-base fence; createRequireFactoryBinding).
5553
+ if (createRequireFactoryDecl(lowerer, decl.name, decl.initializer))
5321
5554
  return null;
5322
5555
  // `const fs = require("node:fs")` through that binding — a builtin
5323
5556
  // namespace import in const clothing: alias plumbing, no storage
@@ -5682,6 +5915,13 @@ export function lowerVarDecl(lowerer, decl, isLet) {
5682
5915
  // Promise.prototype is an ordinary object the checker types Promise<any>.
5683
5916
  if (!decl.type && !hasJsTypeAnnotation(decl) && isPromisePrototypeRead(lowerer, decl.initializer))
5684
5917
  type = DYN;
5918
+ // DataView.prototype (and its members) is likewise the prototype OBJECT,
5919
+ // though the checker types it DataView, whose lowering is a bytes view:
5920
+ // the binding holds the object the read lowered to.
5921
+ if (!decl.type &&
5922
+ !hasJsTypeAnnotation(decl) &&
5923
+ isDataViewPrototypeRead(lowerer, decl.initializer))
5924
+ type = DYN;
5685
5925
  // A web stream value in JavaScript keeps its checked-dynamic identity.
5686
5926
  if (init.type.kind === "dyn" &&
5687
5927
  !decl.type &&
@@ -6884,58 +7124,6 @@ export function lowerTry(lowerer, stmt) {
6884
7124
  loc: locOf(stmt),
6885
7125
  };
6886
7126
  }
6887
- /** The refusal for `delete` of an optional `unknown`/`any` field, whose
6888
- * slot is the checked-dynamic one and so has no ABSENT state to write. */
6889
- const OPTIONAL_CHECKED_DYN_DELETE = "'delete' of optional 'unknown'/'any' fields (the checked-dynamic slot has no absent state yet — an omitted such field already reads as present)";
6890
- /** TypeScript's declaration marks property `name` of `receiver` optional
6891
- * (`?:`), in every union constituent. A mapped IR type cannot tell an
6892
- * optional `unknown`/`any` field from a required one — both ride the
6893
- * checked-dynamic slot — so a refused `delete`'s real reason comes from
6894
- * the declaration. */
6895
- function declaredOptionalProperty(lowerer, receiver, name) {
6896
- const receiverType = lowerer.typeOf(receiver);
6897
- const parts = receiverType.flags & ts.TypeFlags.Union ? constituentTypes(receiverType) : [receiverType];
6898
- return parts.every((part) => {
6899
- const property = lowerer.checker.getPropertyOfType(part, name);
6900
- return property !== undefined && (property.flags & ts.SymbolFlags.Optional) !== 0;
6901
- });
6902
- }
6903
- /** `type` — a record or a union whose every arm is a non-tuple record —
6904
- * declares `name` in the checked-dynamic slot, which has no ABSENT state:
6905
- * an optional such field cannot be removed by a `delete`. */
6906
- function declaresCheckedDynField(lowerer, type, name) {
6907
- if (type.kind === "record") {
6908
- const shape = lowerer.shapes.get(type.shapeId);
6909
- if (!shape || shape.tuple)
6910
- return false;
6911
- return shape.fields.find((f) => f.name === name)?.type.kind === "dyn";
6912
- }
6913
- if (type.kind !== "union")
6914
- return false;
6915
- const arms = lowerer.unions.get(type.unionId)?.arms ?? [];
6916
- return arms.length > 0 && arms.every((arm) => declaresCheckedDynField(lowerer, arm, name));
6917
- }
6918
- /** The constant property key of a `delete` target: the name of a dot
6919
- * access, or the one key of a bracket access spelled as a literal or
6920
- * proved by a literal-typed binding (`const key = "a"`). A key of several
6921
- * literals folds to nothing — deleting it would need per-key dispatch, so
6922
- * the record branch refuses and names the keys. Consistent with keyed
6923
- * record reads/writes (literalFieldKeys), the key expression is not
6924
- * evaluated: only a literal or an identifier folds, and an identifier
6925
- * read is pure. */
6926
- function constantDeleteKey(lowerer, target) {
6927
- if (ts.isPropertyAccessExpression(target))
6928
- return target.name.text;
6929
- if (!ts.isElementAccessExpression(target))
6930
- return null;
6931
- const keyNode = target.argumentExpression;
6932
- if (ts.isStringLiteralLike(keyNode))
6933
- return keyNode.text;
6934
- if (!ts.isIdentifier(keyNode))
6935
- return null;
6936
- const keys = literalFieldKeys(lowerer, keyNode);
6937
- return keys?.length === 1 ? keys[0] : null;
6938
- }
6939
7127
  /** Statement-position `delete`: process.env keys → process.envUnset
6940
7128
  * (unsetenv), pure `Record<string, T>` keys → recordKeyDelete (the
6941
7129
  * overflow Map delete), declared OPTIONAL fields → the field's ABSENT
@@ -6977,24 +7165,13 @@ function lowerDeleteStatement(lowerer, expr) {
6977
7165
  loc,
6978
7166
  };
6979
7167
  const lowerKey = () => {
6980
- if (ts.isPropertyAccessExpression(target)) {
6981
- return { kind: "strLit", value: target.name.text, type: STRING, loc: locOf(target.name) };
6982
- }
7168
+ if (ts.isPropertyAccessExpression(target))
7169
+ return lowerDeleteKey(lowerer, target);
6983
7170
  const keyNode = target.argumentExpression;
6984
- let key = lowerer.isProcessEnv(target.expression) ||
7171
+ return lowerer.isProcessEnv(target.expression) ||
6985
7172
  heldEnvValueType(lowerer, target.expression) !== null
6986
7173
  ? lowerEnvironmentKey(lowerer, keyNode)
6987
- : lowerer.lowerExpr(keyNode);
6988
- if (key.type.kind === "dyn") {
6989
- key = { kind: "libCall", fn: "dyn.toStringCoerce", args: [key], type: STRING, loc: key.loc };
6990
- }
6991
- if (lowerer.runtimeOptionalWidening(key.type, STRING) !== null) {
6992
- key = lowerer.ensureString(key, keyNode);
6993
- }
6994
- if (key.type.kind !== "string") {
6995
- lowerer.unsupported("SC1090", keyNode, `'delete' with '${lowerer.fmt(key.type)}' keys (index-signature and env keys are strings)`);
6996
- }
6997
- return key;
7174
+ : lowerDeleteComputedKey(lowerer, keyNode);
6998
7175
  };
6999
7176
  if (lowerer.isProcessEnv(target.expression) ||
7000
7177
  heldEnvValueType(lowerer, target.expression) !== null) {
@@ -7013,7 +7190,17 @@ function lowerDeleteStatement(lowerer, expr) {
7013
7190
  if (unionDelete)
7014
7191
  return unionDelete;
7015
7192
  }
7016
- let obj = lowerer.lowerExpr(target.expression);
7193
+ // A delete through a chain of type assertions addresses the operand the
7194
+ // assertions erase to (`(o as View).k` names `o`): the asserted view's
7195
+ // conversion may build a copying width record, and the delete would land
7196
+ // on that temporary. Delete in place from the operand when its own stored
7197
+ // layout holds the member as a deletable slot; a view that names a member
7198
+ // the layout does not hold has nothing to delete, so refuse by name.
7199
+ const erased = erasedDeletePlan(lowerer, target);
7200
+ if (erased !== null && "refuse" in erased) {
7201
+ lowerer.unsupported("SC1090", target, erased.refuse);
7202
+ }
7203
+ let obj = lowerer.lowerExpr(erased !== null && "operand" in erased ? erased.operand : target.expression);
7017
7204
  // A PRIMITIVE receiver: `delete` runs ToObject on the base AFTER the key,
7018
7205
  // and the base's type decides the answer — null and undefined throw
7019
7206
  // Node's TypeError, `?.` on a nullish base short-circuits to `true`
@@ -7068,11 +7255,43 @@ function lowerDeleteStatement(lowerer, expr) {
7068
7255
  };
7069
7256
  }
7070
7257
  }
7071
- if (isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
7072
- obj.type.kind === "func" &&
7073
- lowerer.dynConvertible(obj.type)) {
7258
+ if (obj.type.kind === "func" &&
7259
+ lowerer.dynConvertible(obj.type) &&
7260
+ (isJsSourceFile(ts.getSourceFileOfNode(expr)) || callableDeleteKey(lowerer, target))) {
7074
7261
  obj = lowerer.coerceToExpected(obj, DYN);
7075
7262
  }
7263
+ // A typed handle in a program that adds properties to handles: the
7264
+ // delete removes an entry of its property table (scr_dyn_handle_props.c).
7265
+ {
7266
+ const boxed = boxedHandleReceiver(lowerer, obj);
7267
+ if (boxed) {
7268
+ const strict = { kind: "boolLit", value: isStrictCode(expr), type: BOOL, loc };
7269
+ if (ts.isElementAccessExpression(target)) {
7270
+ return {
7271
+ kind: "exprStmt",
7272
+ expr: {
7273
+ kind: "libCall",
7274
+ fn: "dyn.keyDeleteComputed",
7275
+ args: [boxed, lowerer.lowerExprExpecting(target.argumentExpression, DYN), strict],
7276
+ type: VOID,
7277
+ loc,
7278
+ },
7279
+ loc,
7280
+ };
7281
+ }
7282
+ return {
7283
+ kind: "exprStmt",
7284
+ expr: {
7285
+ kind: "libCall",
7286
+ fn: "dyn.keyDelete",
7287
+ args: [boxed, lowerKey(), strict],
7288
+ type: VOID,
7289
+ loc,
7290
+ },
7291
+ loc,
7292
+ };
7293
+ }
7294
+ }
7076
7295
  if (obj.type.kind === "dyn") {
7077
7296
  const strict = { kind: "boolLit", value: isStrictCode(expr), type: BOOL, loc };
7078
7297
  if (ts.isElementAccessExpression(target)) {
@@ -7107,59 +7326,8 @@ function lowerDeleteStatement(lowerer, expr) {
7107
7326
  // read/write takes (literalFieldKeys): identifier evaluation is pure, so
7108
7327
  // skipping it matches JavaScript.
7109
7328
  const constantKey = constantDeleteKey(lowerer, target);
7110
- // An OPTIONAL `unknown`/`any` field rides the checked-dynamic slot,
7111
- // which has no ABSENT state yet (an omitted such field already reads as
7112
- // present), so it cannot delete. Name that reason instead of calling
7113
- // the field required or blaming the receiver.
7114
- const optionalCheckedDynDelete = constantKey !== null &&
7115
- declaresCheckedDynField(lowerer, obj.type, constantKey) &&
7116
- declaredOptionalProperty(lowerer, target.expression, constantKey);
7117
7329
  if (obj.type.kind === "record") {
7118
- const shape = lowerer.shapes.get(obj.type.shapeId);
7119
- if (shape?.indexValue && shape.fields.length === 0 && !shape.tuple) {
7120
- return markSloppyRecordWrites(lowerer, { kind: "recordKeyDelete", obj, shapeId: obj.type.shapeId, key: lowerKey(), loc }, expr);
7121
- }
7122
- // `delete r.f` of a declared OPTIONAL field (undefined-armed slot)
7123
- // writes the field's ABSENT state: a monomorphic shape cannot remove
7124
- // its slot, but the slot remembers that no property exists, so `in`
7125
- // answers false, Object.keys skips it, and JSON.stringify drops it,
7126
- // while a later write makes it present again. Constant keys only
7127
- // (dot access or a literal bracket); required fields keep the honest
7128
- // fence below.
7129
- const field = constantKey !== null && !shape?.tuple
7130
- ? shape?.fields.find((f) => f.name === constantKey)
7131
- : undefined;
7132
- if (field) {
7133
- const absent = lowerer.absentFieldValue(field.type, loc);
7134
- if (absent) {
7135
- return markSloppyRecordWrites(lowerer, {
7136
- kind: "recordSet",
7137
- obj,
7138
- shapeId: obj.type.shapeId,
7139
- field: field.name,
7140
- value: absent,
7141
- loc,
7142
- }, expr, true);
7143
- }
7144
- }
7145
- if (shape?.indexValue) {
7146
- lowerer.unsupported("SC1090", expr, "'delete' of hybrid index-signature keys (declared struct slots and overflow entries answer differently — model deletable dynamic keys with a pure Record<string, T>)");
7147
- }
7148
- if (optionalCheckedDynDelete) {
7149
- lowerer.unsupported("SC1090", expr, OPTIONAL_CHECKED_DYN_DELETE);
7150
- }
7151
- // A key of SEVERAL literals names no single slot: say that instead of
7152
- // blaming a field the caller never named.
7153
- const keyNames = constantKey === null && ts.isElementAccessExpression(target)
7154
- ? literalFieldKeys(lowerer, target.argumentExpression)
7155
- : null;
7156
- if (keyNames !== null && keyNames.length > 1) {
7157
- lowerer.unsupported("SC1090", expr, `'delete' through keys of ${keyNames.length} literals (${keyNames.map((k) => `'${k}'`).join(", ")}; delete one constant key at a time, or switch over the key)`);
7158
- }
7159
- lowerer.unsupported("SC1090", expr, "'delete' of required record fields (the shape's slot cannot be removed — only an optional field (`f?: T`) has an absent state, which Object.keys, 'in', and JSON.stringify follow; make the field optional if the program must remove it)");
7160
- }
7161
- if (optionalCheckedDynDelete) {
7162
- lowerer.unsupported("SC1090", expr, OPTIONAL_CHECKED_DYN_DELETE);
7330
+ return lowerRecordMemberDelete(lowerer, expr, target, obj, lowerKey);
7163
7331
  }
7164
7332
  // A class field lives in the instance's fixed layout: there is no
7165
7333
  // per-field presence state for a delete to write, so Object.keys,
@@ -7857,14 +8025,11 @@ export function lowerExprStatement(lowerer, expr) {
7857
8025
  if (callableWrite)
7858
8026
  return { kind: "exprStmt", expr: callableWrite, loc: locOf(expr) };
7859
8027
  // Expando function members (`foo.bar = 12`, `foo[SYM] = v` on a
7860
- // module-level function/callable const): the member's module
7861
- // global (lower-expando.ts) — claimed by symbol identity before
7862
- // any receiver-shape path.
7863
- {
7864
- const ex = lowerExpandoAssignStmt(lowerer, expr);
7865
- if (ex)
7866
- return ex;
7867
- }
8028
+ // module-level function/callable const): the write is the closure's
8029
+ // own-property table store, like any other callable member; the
8030
+ // read-only function members keep their fault fence.
8031
+ if (ts.isPropertyAccessExpression(expr.left) || ts.isElementAccessExpression(expr.left))
8032
+ fenceReadonlyExpandoWrite(lowerer, expr.left);
7868
8033
  {
7869
8034
  const dereferenced = lowerDereferencedElementWrite(lowerer, expr);
7870
8035
  if (dereferenced)
@@ -8210,6 +8375,12 @@ export function lowerExprStatement(lowerer, expr) {
8210
8375
  const unionWrite = lowerUnionFieldWrite(lowerer, expr.left, expr.right);
8211
8376
  if (unionWrite)
8212
8377
  return { kind: "exprStmt", expr: unionWrite, loc: locOf(expr) };
8378
+ // A member only the asserted type declares is refused before any
8379
+ // field target: the checker's type names a slot the stored record
8380
+ // does not have, so a target built from it addresses a field the
8381
+ // receiver's shape lacks. `(view).member` and `view!.member` reach
8382
+ // the same refusal as `view.member`.
8383
+ assertedOnlyMemberWrite(lowerer, expr.left.expression, expr.left.name.text, expr.left);
8213
8384
  const target = lowerer.fieldTarget(expr.left);
8214
8385
  if (target) {
8215
8386
  const value = lowerer.lowerExprExpecting(expr.right, target.fieldType);
@@ -8250,6 +8421,18 @@ export function lowerExprStatement(lowerer, expr) {
8250
8421
  }
8251
8422
  if (recv?.type.kind === "child" && isJsSourceFile(ts.getSourceFileOfNode(expr)))
8252
8423
  return lowerChildPropertyWrite(lowerer, recv, expr.left, expr.right, locOf(expr));
8424
+ // `m.label = 1` over a typed handle in JavaScript: an undeclared
8425
+ // member name is a property table entry, and so is a member name
8426
+ // the program shadows (scr_dyn_handle_props.c). The grant query
8427
+ // (a whole-program census) waits for a handle-typed receiver.
8428
+ if (!lowerer.checker.getPropertyOfType(lowerer.typeOf(expr.left.expression), expr.left.name.text) ||
8429
+ (recv !== null &&
8430
+ TYPED_HANDLE_KINDS.has(recv.type.kind) &&
8431
+ handleMemberGranted(lowerer, expr.left.expression, expr.left.name.text))) {
8432
+ const boxed = boxedHandleReceiver(lowerer, recv);
8433
+ if (boxed)
8434
+ return lowerHandlePropertyWrite(lowerer, boxed, { kind: "strLit", value: expr.left.name.text, type: STRING, loc: locOf(expr) }, expr.right, locOf(expr));
8435
+ }
8253
8436
  // `err.code = v` on an Error value (`err as Error & { code?:
8254
8437
  // string }`): typed reads come from the runtime error's code
8255
8438
  // slot, so the write lands there. A value that is not statically
@@ -8454,12 +8637,10 @@ export function lowerExprStatement(lowerer, expr) {
8454
8637
  if (ts.isPropertyAccessExpression(expr.left)) {
8455
8638
  // `N.x += v` — the namespace-qualified spelling of a module-
8456
8639
  // global compound assign (nsWritableTarget resolves the member's
8457
- // global; everything else keeps the field path). Expando
8458
- // function members (`foo.count += 1`) are module globals too.
8640
+ // global; everything else keeps the field path). Expando function
8641
+ // members (`foo.count += 1`) are callable-member table data.
8459
8642
  if (!expr.left.questionDotToken) {
8460
- const exT = expandoWritableTarget(lowerer, expr.left);
8461
- if (exT)
8462
- return lowerCompoundToTarget(lowerer, expr, compound, exT);
8643
+ fenceReadonlyExpandoWrite(lowerer, expr.left);
8463
8644
  const nsT = nsWritableTarget(lowerer, expr.left);
8464
8645
  if (nsT)
8465
8646
  return lowerCompoundToTarget(lowerer, expr, compound, nsT);
@@ -8485,9 +8666,11 @@ export function lowerExprStatement(lowerer, expr) {
8485
8666
  if (ts.isPropertyAccessExpression(expr.operand) || ts.isElementAccessExpression(expr.operand)) {
8486
8667
  fenceDatePrototypeWrite(lowerer, expr.operand);
8487
8668
  // Statement and value positions share ToNumeric and reference order.
8488
- // Namespace/expando globals retain their direct binding path below.
8669
+ // Namespace globals retain their direct binding path below.
8670
+ if (ts.isPropertyAccessExpression(expr.operand))
8671
+ fenceReadonlyExpandoWrite(lowerer, expr.operand);
8489
8672
  const binding = ts.isPropertyAccessExpression(expr.operand)
8490
- ? (expandoWritableTarget(lowerer, expr.operand) ?? nsWritableTarget(lowerer, expr.operand))
8673
+ ? nsWritableTarget(lowerer, expr.operand)
8491
8674
  : null;
8492
8675
  if (binding)
8493
8676
  return lowerIncDecToTarget(lowerer, expr, binding);
@@ -9196,51 +9379,102 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
9196
9379
  let restTo = prop.expression;
9197
9380
  while (ts.isParenthesizedExpression(restTo))
9198
9381
  restTo = restTo.expression;
9199
- if (shape.indexValue) {
9200
- lowerer.unsupported("SC1031", prop, "rest bindings over index-signature shapes (the undeclared entries would need overflow packing)");
9201
- }
9202
9382
  const consumed = new Set();
9383
+ let computedSibling = false;
9203
9384
  for (const p of target.properties.nodes) {
9385
+ if (p === prop)
9386
+ continue;
9204
9387
  if (ts.isShorthandPropertyAssignment(p))
9205
9388
  consumed.add(p.name.text);
9206
9389
  else if (ts.isPropertyAssignment(p)) {
9207
9390
  const n = patternKeyNameOf(lowerer, p.name);
9208
9391
  if (n !== null)
9209
9392
  consumed.add(n);
9393
+ else if (ts.isComputedPropertyName(p.name))
9394
+ computedSibling = true;
9210
9395
  }
9211
9396
  }
9212
9397
  const remaining = shape.fields.filter((f) => !consumed.has(f.name));
9213
9398
  const restOrder = shape.declaredOrder?.filter((n) => !consumed.has(n));
9214
- const restShapeId = lowerer.shapes.intern(remaining.map((f) => ({ name: f.name, type: f.type })), false, undefined, restOrder);
9215
- if (restOrder !== undefined) {
9216
- lowerer.shapeOrderMetadataFinalizers.push(lowerer.shapes.declaredOrderFinalizer(restShapeId, restOrder, () => lowerer.shapes.get(srcType.shapeId)?.declaredOrder?.filter((n) => !consumed.has(n))));
9399
+ let packed;
9400
+ if (shape.indexValue !== undefined) {
9401
+ // An INDEX-SIGNATURE source: the `%rec.rest` capture reshape into
9402
+ // the source-derived hybrid (its remaining declared fields plus its
9403
+ // own overflow slot), exactly the destructuring form's copy.
9404
+ if (computedSibling) {
9405
+ lowerer.unsupported("SC1031", prop, "rest bindings beside computed keys (the consumed set is a runtime fact)");
9406
+ }
9407
+ if (remaining.some((f) => f.name.startsWith("%"))) {
9408
+ lowerer.unsupported("SC1031", prop, "rest bindings over accessor shapes (the entries are closures, not data)");
9409
+ }
9410
+ fenceIntegerKeyRest(lowerer, prop, remaining);
9411
+ const derivedId = lowerer.shapes.intern(remaining.map((f) => ({ ...f })), false, shape.indexValue, restOrder);
9412
+ if (restOrder !== undefined) {
9413
+ lowerer.shapeOrderMetadataFinalizers.push(lowerer.shapes.declaredOrderFinalizer(derivedId, restOrder, () => lowerer.shapes
9414
+ .get(srcType.shapeId)
9415
+ ?.declaredOrder?.filter((n) => !consumed.has(n) && remaining.some((f) => f.name === n))));
9416
+ }
9417
+ const helper = lowerRecordRestCaptureHelper(lowerer, srcType.shapeId, derivedId, [...consumed], locOf(prop));
9418
+ if (helper === null) {
9419
+ lowerer.unsupported("SC1031", prop, "rest bindings over index-signature shapes (the undeclared entries would need overflow packing)");
9420
+ }
9421
+ packed = {
9422
+ kind: "call",
9423
+ callee: helper,
9424
+ args: [{ kind: "varRef", localId: tmp.id, type: srcType, loc: locOf(prop) }],
9425
+ type: { kind: "record", shapeId: derivedId },
9426
+ loc: locOf(prop),
9427
+ };
9217
9428
  }
9218
- const packed = lowerer.keyOrder.copy({
9219
- kind: "recordLit",
9220
- fields: remaining.map((f) => ({
9221
- name: f.name,
9222
- value: {
9223
- kind: "recordGet",
9224
- obj: { kind: "varRef", localId: tmp.id, type: srcType, loc: locOf(prop) },
9225
- shapeId: srcType.shapeId,
9226
- field: f.name,
9227
- type: f.type,
9228
- loc: locOf(prop),
9229
- },
9230
- })),
9231
- type: { kind: "record", shapeId: restShapeId },
9232
- loc: locOf(prop),
9233
- }, srcType.shapeId);
9429
+ else {
9430
+ const restShapeId = lowerer.shapes.intern(remaining.map((f) => ({ ...f })), false, undefined, restOrder);
9431
+ if (restOrder !== undefined) {
9432
+ lowerer.shapeOrderMetadataFinalizers.push(lowerer.shapes.declaredOrderFinalizer(restShapeId, restOrder, () => lowerer.shapes.get(srcType.shapeId)?.declaredOrder?.filter((n) => !consumed.has(n))));
9433
+ }
9434
+ packed = lowerer.keyOrder.copy({
9435
+ kind: "recordLit",
9436
+ fields: remaining.map((f) => ({
9437
+ name: f.name,
9438
+ // A field the source lacks keeps the rest copy absent too.
9439
+ value: lowerer.presenceKeepingCopy({ kind: "varRef", localId: tmp.id, type: srcType, loc: locOf(prop) }, srcType.shapeId, f.name, {
9440
+ kind: "recordGet",
9441
+ obj: { kind: "varRef", localId: tmp.id, type: srcType, loc: locOf(prop) },
9442
+ shapeId: srcType.shapeId,
9443
+ field: f.name,
9444
+ type: f.type,
9445
+ loc: locOf(prop),
9446
+ }, locOf(prop), f),
9447
+ })),
9448
+ type: { kind: "record", shapeId: restShapeId },
9449
+ loc: locOf(prop),
9450
+ }, srcType.shapeId);
9451
+ }
9452
+ /** A CLOSED rest target has nowhere to put the source's undeclared
9453
+ * entries; refuse rather than let the coercion drop them. */
9454
+ const checkRestTarget = (targetT) => {
9455
+ if (shape.indexValue === undefined || targetT === null)
9456
+ return;
9457
+ if (targetT.kind === "dyn")
9458
+ return;
9459
+ if (targetT.kind === "record" &&
9460
+ lowerer.shapes.get(targetT.shapeId)?.indexValue !== undefined)
9461
+ return;
9462
+ lowerer.unsupported("SC1031", prop, `rest assignments packing an index-signature source into '${lowerer.fmt(targetT)}' (its undeclared keys have no slot)`);
9463
+ };
9234
9464
  if (!ts.isIdentifier(restTo)) {
9235
9465
  // `({ a, ...box.rest } = src)` — the rest packs identically and
9236
9466
  // lands through the property/element write machinery.
9237
- lowerAssignTargetInto(lowerer, out, restTo, prop, null, () => packed);
9467
+ lowerAssignTargetInto(lowerer, out, restTo, prop, null, (targetT) => {
9468
+ checkRestTarget(targetT);
9469
+ return packed;
9470
+ });
9238
9471
  continue;
9239
9472
  }
9240
9473
  const targetBinding = lowerer.resolveWritable(restTo);
9241
9474
  if (!targetBinding) {
9242
9475
  lowerer.rejectUnresolved(restTo, `assignment to '${restTo.text}' (not a writable local or module global)`);
9243
9476
  }
9477
+ checkRestTarget(targetBinding.type);
9244
9478
  out.push({
9245
9479
  kind: "assign",
9246
9480
  localId: targetBinding.id,
@@ -12505,6 +12739,13 @@ function assertionKeepsStorageLayout(lowerer, decl, init, settled) {
12505
12739
  return false;
12506
12740
  if (hostsAll(lowerer, init, settled))
12507
12741
  return true;
12742
+ // An assertion that only ADDS optional members (`item as Base & { icons?:
12743
+ // unknown }`) keeps the value too: Node erases it, and the added members
12744
+ // have no slot in the stored layout, so reads answer them through the
12745
+ // layout's kept source (assertedOnlyFieldRead) instead of a width copy's
12746
+ // absent slot.
12747
+ if (assertedOptionalExtension(lowerer, init, settled))
12748
+ return true;
12508
12749
  // A projection (`{ text: string }` over `TextBlock`) keeps the stored
12509
12750
  // record only when the binding's identity is observable through it
12510
12751
  // (a write, an identity comparison). A read-only view is equal either
@@ -12524,9 +12765,11 @@ function assertionKeepsStorageLayout(lowerer, decl, init, settled) {
12524
12765
  * child object in both), so only a write to the copy's own field is
12525
12766
  * refused, by name. Where the layouts agree the binding keeps the value's
12526
12767
  * storage instead (assertionKeepsStorageLayout), narrowing.ts and
12527
- * lowerVarDecl record that in layoutKeptNodes, and nothing here fires.
12528
- * Runs for file-scope and local bindings alike, after the declaration has
12529
- * been lowered (so the keep is known). */
12768
+ * lowerVarDecl record that in layoutKeptNodes, and nothing here fires: an
12769
+ * assertion that only adds optional members keeps the layout its reads
12770
+ * answer from, and a write to an added member is refused where it happens
12771
+ * (assertedOnlyMemberWrite). Runs for file-scope and local bindings alike,
12772
+ * after the declaration has been lowered (so the keep is known). */
12530
12773
  function refuseAssertionViewWrite(lowerer, decl) {
12531
12774
  if (decl.initializer === undefined || !isAssertionInitializer(decl.initializer))
12532
12775
  return;