@scriptc/compiler 0.2.6 → 0.2.7

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 (368) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +5 -18
  2. package/dist/backend/cycle-analysis.d.ts +21 -9
  3. package/dist/backend/cycle-analysis.js +139 -67
  4. package/dist/backend/cycle-analysis.js.map +1 -1
  5. package/dist/backend/cycle-analysis.test.js +283 -3
  6. package/dist/backend/cycle-analysis.test.js.map +1 -1
  7. package/dist/backend/cycle-mutability.d.ts +39 -0
  8. package/dist/backend/cycle-mutability.js +205 -0
  9. package/dist/backend/cycle-mutability.js.map +1 -0
  10. package/dist/backend/link-plan-core.d.ts +2 -1
  11. package/dist/backend/link-plan-core.js +15 -3
  12. package/dist/backend/link-plan-core.js.map +1 -1
  13. package/dist/backend/link-plan.d.ts +2 -1
  14. package/dist/backend/link-plan.js.map +1 -1
  15. package/dist/backend/llvm/alloc.d.ts +40 -0
  16. package/dist/backend/llvm/alloc.js +205 -0
  17. package/dist/backend/llvm/alloc.js.map +1 -0
  18. package/dist/backend/llvm/alloc.test.d.ts +1 -0
  19. package/dist/backend/llvm/alloc.test.js +102 -0
  20. package/dist/backend/llvm/alloc.test.js.map +1 -0
  21. package/dist/backend/llvm/call-lifetimes.d.ts +15 -3
  22. package/dist/backend/llvm/call-lifetimes.js +42 -18
  23. package/dist/backend/llvm/call-lifetimes.js.map +1 -1
  24. package/dist/backend/llvm/call-lifetimes.test.js +170 -0
  25. package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
  26. package/dist/backend/llvm/classes.d.ts +4 -1
  27. package/dist/backend/llvm/classes.js +35 -32
  28. package/dist/backend/llvm/classes.js.map +1 -1
  29. package/dist/backend/llvm/classes.test.js +36 -3
  30. package/dist/backend/llvm/classes.test.js.map +1 -1
  31. package/dist/backend/llvm/common.d.ts +13 -0
  32. package/dist/backend/llvm/common.js +30 -0
  33. package/dist/backend/llvm/common.js.map +1 -1
  34. package/dist/backend/llvm/constant-callbacks.d.ts +19 -3
  35. package/dist/backend/llvm/constant-callbacks.js +289 -52
  36. package/dist/backend/llvm/constant-callbacks.js.map +1 -1
  37. package/dist/backend/llvm/constant-callbacks.test.js +140 -3
  38. package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
  39. package/dist/backend/llvm/dense-array-access.d.ts +29 -0
  40. package/dist/backend/llvm/dense-array-access.js +335 -0
  41. package/dist/backend/llvm/dense-array-access.js.map +1 -0
  42. package/dist/backend/llvm/dense-array-access.test.d.ts +1 -0
  43. package/dist/backend/llvm/dense-array-access.test.js +149 -0
  44. package/dist/backend/llvm/dense-array-access.test.js.map +1 -0
  45. package/dist/backend/llvm/dyn.d.ts +34 -0
  46. package/dist/backend/llvm/dyn.js +189 -1
  47. package/dist/backend/llvm/dyn.js.map +1 -1
  48. package/dist/backend/llvm/emitter.d.ts +124 -4
  49. package/dist/backend/llvm/emitter.js +623 -105
  50. package/dist/backend/llvm/emitter.js.map +1 -1
  51. package/dist/backend/llvm/emitter.test.js +68 -6
  52. package/dist/backend/llvm/emitter.test.js.map +1 -1
  53. package/dist/backend/llvm/expr-async.js +58 -4
  54. package/dist/backend/llvm/expr-async.js.map +1 -1
  55. package/dist/backend/llvm/expr-async.test.d.ts +1 -0
  56. package/dist/backend/llvm/expr-async.test.js +62 -0
  57. package/dist/backend/llvm/expr-async.test.js.map +1 -0
  58. package/dist/backend/llvm/expr-calls.js +64 -6
  59. package/dist/backend/llvm/expr-calls.js.map +1 -1
  60. package/dist/backend/llvm/expr-containers.js +16 -5
  61. package/dist/backend/llvm/expr-containers.js.map +1 -1
  62. package/dist/backend/llvm/expr-control.js +92 -2
  63. package/dist/backend/llvm/expr-control.js.map +1 -1
  64. package/dist/backend/llvm/expr-dispatch.js +2 -0
  65. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  66. package/dist/backend/llvm/expr-dynamic.js +174 -25
  67. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  68. package/dist/backend/llvm/expr-primitives.d.ts +1 -1
  69. package/dist/backend/llvm/expr-primitives.js +52 -24
  70. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  71. package/dist/backend/llvm/expr-primitives.test.js +1 -1
  72. package/dist/backend/llvm/expr-records.js +3 -3
  73. package/dist/backend/llvm/expr-records.js.map +1 -1
  74. package/dist/backend/llvm/expr-stream-bridges.js +59 -2
  75. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  76. package/dist/backend/llvm/expr-stream-bridges.test.js +1 -1
  77. package/dist/backend/llvm/integer-remainder.d.ts +11 -0
  78. package/dist/backend/llvm/integer-remainder.js +91 -0
  79. package/dist/backend/llvm/integer-remainder.js.map +1 -1
  80. package/dist/backend/llvm/layouts.d.ts +2 -1
  81. package/dist/backend/llvm/layouts.js +3 -2
  82. package/dist/backend/llvm/layouts.js.map +1 -1
  83. package/dist/backend/llvm/lazy-captures.d.ts +16 -0
  84. package/dist/backend/llvm/lazy-captures.js +96 -0
  85. package/dist/backend/llvm/lazy-captures.js.map +1 -0
  86. package/dist/backend/llvm/lazy-captures.test.d.ts +1 -0
  87. package/dist/backend/llvm/lazy-captures.test.js +78 -0
  88. package/dist/backend/llvm/lazy-captures.test.js.map +1 -0
  89. package/dist/backend/llvm/lib-filesystem.js +3 -4
  90. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  91. package/dist/backend/llvm/local-array-reads.d.ts +5 -1
  92. package/dist/backend/llvm/local-array-reads.js +78 -17
  93. package/dist/backend/llvm/local-array-reads.js.map +1 -1
  94. package/dist/backend/llvm/local-array-reads.test.js +78 -1
  95. package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
  96. package/dist/backend/llvm/local-union-storage.d.ts +5 -1
  97. package/dist/backend/llvm/local-union-storage.js +48 -6
  98. package/dist/backend/llvm/local-union-storage.js.map +1 -1
  99. package/dist/backend/llvm/local-union-storage.test.js +91 -4
  100. package/dist/backend/llvm/local-union-storage.test.js.map +1 -1
  101. package/dist/backend/llvm/map-read-lifetimes.test.js +1 -1
  102. package/dist/backend/llvm/nullable-fields.d.ts +28 -0
  103. package/dist/backend/llvm/nullable-fields.js +45 -0
  104. package/dist/backend/llvm/nullable-fields.js.map +1 -0
  105. package/dist/backend/llvm/nullable-fields.test.d.ts +1 -0
  106. package/dist/backend/llvm/nullable-fields.test.js +48 -0
  107. package/dist/backend/llvm/nullable-fields.test.js.map +1 -0
  108. package/dist/backend/llvm/serialized-ir-emission.test.d.ts +1 -0
  109. package/dist/backend/llvm/serialized-ir-emission.test.js +52 -0
  110. package/dist/backend/llvm/serialized-ir-emission.test.js.map +1 -0
  111. package/dist/backend/llvm/shapes.d.ts +69 -2
  112. package/dist/backend/llvm/shapes.js +259 -27
  113. package/dist/backend/llvm/shapes.js.map +1 -1
  114. package/dist/backend/llvm/shapes.test.js +114 -5
  115. package/dist/backend/llvm/shapes.test.js.map +1 -1
  116. package/dist/backend/llvm/stack-callbacks.js +2 -3
  117. package/dist/backend/llvm/stack-callbacks.js.map +1 -1
  118. package/dist/backend/llvm/stack-captures.d.ts +3 -1
  119. package/dist/backend/llvm/stack-captures.js +5 -3
  120. package/dist/backend/llvm/stack-captures.js.map +1 -1
  121. package/dist/backend/llvm/stack-unions.test.js +38 -1
  122. package/dist/backend/llvm/stack-unions.test.js.map +1 -1
  123. package/dist/backend/llvm/string-construction.test.js +1 -1
  124. package/dist/backend/llvm/string-key-hash.d.ts +8 -0
  125. package/dist/backend/llvm/string-key-hash.js +59 -0
  126. package/dist/backend/llvm/string-key-hash.js.map +1 -0
  127. package/dist/backend/llvm/string-key-hash.test.d.ts +1 -0
  128. package/dist/backend/llvm/string-key-hash.test.js +34 -0
  129. package/dist/backend/llvm/string-key-hash.test.js.map +1 -0
  130. package/dist/backend/llvm/string-lifetimes.test.js +41 -4
  131. package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
  132. package/dist/backend/llvm/switch-dispatch.js +1 -1
  133. package/dist/backend/llvm/switch-dispatch.js.map +1 -1
  134. package/dist/backend/llvm/switch-dispatch.test.js +2 -2
  135. package/dist/backend/llvm/switch-dispatch.test.js.map +1 -1
  136. package/dist/backend/may-throw.js +3 -0
  137. package/dist/backend/may-throw.js.map +1 -1
  138. package/dist/backend/may-throw.test.js +1 -1
  139. package/dist/backend/native/cache-warm.d.ts +2 -1
  140. package/dist/backend/native/cache-warm.js.map +1 -1
  141. package/dist/backend/native/contracts.d.ts +3 -2
  142. package/dist/backend/native/contracts.js.map +1 -1
  143. package/dist/backend/native/runtime-inputs.d.ts +1 -1
  144. package/dist/backend/native/runtime-inputs.js +1 -0
  145. package/dist/backend/native/runtime-inputs.js.map +1 -1
  146. package/dist/backend/native-codegen-core.d.ts +2 -1
  147. package/dist/backend/native-codegen-core.js.map +1 -1
  148. package/dist/backend/native-codegen.d.ts +5 -0
  149. package/dist/backend/native-codegen.js +4 -0
  150. package/dist/backend/native-codegen.js.map +1 -1
  151. package/dist/backend/native-codegen.test.js +23 -0
  152. package/dist/backend/native-codegen.test.js.map +1 -1
  153. package/dist/backend/native-link-info-core.d.ts +3 -2
  154. package/dist/backend/native-link-info-core.js.map +1 -1
  155. package/dist/backend/native-link-info.d.ts +2 -1
  156. package/dist/backend/native-link-info.js.map +1 -1
  157. package/dist/backend/native-link-info.test.js +2 -2
  158. package/dist/backend/native-link-info.test.js.map +1 -1
  159. package/dist/backend/native-tools.d.ts +3 -1
  160. package/dist/backend/native-tools.js +0 -1
  161. package/dist/backend/native-tools.js.map +1 -1
  162. package/dist/backend/optimization.d.ts +25 -0
  163. package/dist/backend/optimization.js +21 -0
  164. package/dist/backend/optimization.js.map +1 -0
  165. package/dist/backend/optimization.test.d.ts +1 -0
  166. package/dist/backend/optimization.test.js +24 -0
  167. package/dist/backend/optimization.test.js.map +1 -0
  168. package/dist/backend/runtime-abi.d.ts +2 -2
  169. package/dist/backend/runtime-abi.js +2 -2
  170. package/dist/backend/runtime-pack-core.d.ts +15 -4
  171. package/dist/backend/runtime-pack-core.js +23 -12
  172. package/dist/backend/runtime-pack-core.js.map +1 -1
  173. package/dist/backend/runtime-pack-native.d.ts +7 -3
  174. package/dist/backend/runtime-pack-native.js +0 -3
  175. package/dist/backend/runtime-pack-native.js.map +1 -1
  176. package/dist/backend/runtime-pack-targets.test.js +1 -1
  177. package/dist/backend/runtime-pack.d.ts +20 -2
  178. package/dist/backend/runtime-pack.js +23 -0
  179. package/dist/backend/runtime-pack.js.map +1 -1
  180. package/dist/backend/runtime-pack.test.js +115 -2
  181. package/dist/backend/runtime-pack.test.js.map +1 -1
  182. package/dist/backend/target-diagnostics.test.js +1 -1
  183. package/dist/backend/targets.d.ts +2 -1
  184. package/dist/backend/targets.js +1 -1
  185. package/dist/backend/targets.js.map +1 -1
  186. package/dist/cli/command.js +5 -4
  187. package/dist/cli/command.js.map +1 -1
  188. package/dist/cli/host.d.ts +2 -1
  189. package/dist/cli/usage.d.ts +1 -1
  190. package/dist/cli/usage.js +5 -2
  191. package/dist/cli/usage.js.map +1 -1
  192. package/dist/compile-types.d.ts +5 -2
  193. package/dist/diagnostics/diagnostic.js +10 -8
  194. package/dist/diagnostics/diagnostic.js.map +1 -1
  195. package/dist/executable/executable-cache.d.ts +2 -2
  196. package/dist/executable/executable-cache.js +7 -4
  197. package/dist/executable/executable-cache.js.map +1 -1
  198. package/dist/executable/executable-cache.test.js +20 -0
  199. package/dist/executable/executable-cache.test.js.map +1 -1
  200. package/dist/frontend/lowering/abstract-equality.js +5 -49
  201. package/dist/frontend/lowering/abstract-equality.js.map +1 -1
  202. package/dist/frontend/lowering/array-values.d.ts +23 -0
  203. package/dist/frontend/lowering/array-values.js +129 -0
  204. package/dist/frontend/lowering/array-values.js.map +1 -1
  205. package/dist/frontend/lowering/builtins/errors.js +17 -2
  206. package/dist/frontend/lowering/builtins/errors.js.map +1 -1
  207. package/dist/frontend/lowering/builtins/process.d.ts +6 -17
  208. package/dist/frontend/lowering/builtins/process.js +56 -29
  209. package/dist/frontend/lowering/builtins/process.js.map +1 -1
  210. package/dist/frontend/lowering/caught-value-dispatch.d.ts +11 -0
  211. package/dist/frontend/lowering/caught-value-dispatch.js +87 -0
  212. package/dist/frontend/lowering/caught-value-dispatch.js.map +1 -0
  213. package/dist/frontend/lowering/class-assertions.d.ts +4 -0
  214. package/dist/frontend/lowering/class-assertions.js +12 -4
  215. package/dist/frontend/lowering/class-assertions.js.map +1 -1
  216. package/dist/frontend/lowering/class-callbacks.d.ts +3 -3
  217. package/dist/frontend/lowering/class-callbacks.js +18 -5
  218. package/dist/frontend/lowering/class-callbacks.js.map +1 -1
  219. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +1 -0
  220. package/dist/frontend/lowering/class-dynamic-dispatch.js +4 -1
  221. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  222. package/dist/frontend/lowering/class-method-mutations.d.ts +5 -0
  223. package/dist/frontend/lowering/class-method-mutations.js +472 -0
  224. package/dist/frontend/lowering/class-method-mutations.js.map +1 -0
  225. package/dist/frontend/lowering/class-method-values.js +25 -5
  226. package/dist/frontend/lowering/class-method-values.js.map +1 -1
  227. package/dist/frontend/lowering/class-prototypes.js +8 -2
  228. package/dist/frontend/lowering/class-prototypes.js.map +1 -1
  229. package/dist/frontend/lowering/class-unions.d.ts +16 -0
  230. package/dist/frontend/lowering/class-unions.js +127 -0
  231. package/dist/frontend/lowering/class-unions.js.map +1 -0
  232. package/dist/frontend/lowering/coercions/builders.js +8 -1
  233. package/dist/frontend/lowering/coercions/builders.js.map +1 -1
  234. package/dist/frontend/lowering/coercions/function-adapters.js +2 -0
  235. package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
  236. package/dist/frontend/lowering/coercions/identity.d.ts +7 -0
  237. package/dist/frontend/lowering/coercions/identity.js +26 -0
  238. package/dist/frontend/lowering/coercions/identity.js.map +1 -0
  239. package/dist/frontend/lowering/coercions/structural.js +9 -6
  240. package/dist/frontend/lowering/coercions/structural.js.map +1 -1
  241. package/dist/frontend/lowering/collection-narrowing.d.ts +6 -0
  242. package/dist/frontend/lowering/collection-narrowing.js +31 -0
  243. package/dist/frontend/lowering/collection-narrowing.js.map +1 -0
  244. package/dist/frontend/lowering/containers/array-callback-call.d.ts +7 -0
  245. package/dist/frontend/lowering/containers/array-callback-call.js +52 -0
  246. package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -0
  247. package/dist/frontend/lowering/containers/array-callbacks.d.ts +1 -1
  248. package/dist/frontend/lowering/containers/array-callbacks.js +363 -49
  249. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
  250. package/dist/frontend/lowering/containers/array-concat.d.ts +7 -0
  251. package/dist/frontend/lowering/containers/array-concat.js +130 -0
  252. package/dist/frontend/lowering/containers/array-concat.js.map +1 -0
  253. package/dist/frontend/lowering/containers/array-construction.d.ts +2 -0
  254. package/dist/frontend/lowering/containers/array-construction.js +95 -3
  255. package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
  256. package/dist/frontend/lowering/containers/array-methods.d.ts +1 -11
  257. package/dist/frontend/lowering/containers/array-methods.js +43 -132
  258. package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
  259. package/dist/frontend/lowering/containers/collection-methods.js +10 -1
  260. package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
  261. package/dist/frontend/lowering/containers/indexed-objects.js +56 -70
  262. package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
  263. package/dist/frontend/lowering/cycle-initialization.d.ts +41 -0
  264. package/dist/frontend/lowering/cycle-initialization.js +277 -0
  265. package/dist/frontend/lowering/cycle-initialization.js.map +1 -0
  266. package/dist/frontend/lowering/expressions/evaluation-safety.js +4 -0
  267. package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
  268. package/dist/frontend/lowering/expressions/object-literals.js +138 -32
  269. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  270. package/dist/frontend/lowering/expressions/union-field-write.d.ts +4 -4
  271. package/dist/frontend/lowering/expressions/union-field-write.js +54 -44
  272. package/dist/frontend/lowering/expressions/union-field-write.js.map +1 -1
  273. package/dist/frontend/lowering/iterator-adapters.d.ts +20 -0
  274. package/dist/frontend/lowering/iterator-adapters.js +605 -0
  275. package/dist/frontend/lowering/iterator-adapters.js.map +1 -0
  276. package/dist/frontend/lowering/lower-array-sort.d.ts +1 -1
  277. package/dist/frontend/lowering/lower-array-sort.js +44 -5
  278. package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
  279. package/dist/frontend/lowering/lower-array-sort.test.d.ts +1 -0
  280. package/dist/frontend/lowering/lower-array-sort.test.js +31 -0
  281. package/dist/frontend/lowering/lower-array-sort.test.js.map +1 -0
  282. package/dist/frontend/lowering/lower-assert.js +7 -0
  283. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  284. package/dist/frontend/lowering/lower-builtin-values.js +1 -0
  285. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
  286. package/dist/frontend/lowering/lower-calls.d.ts +3 -3
  287. package/dist/frontend/lowering/lower-calls.js +162 -121
  288. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  289. package/dist/frontend/lowering/lower-classes.d.ts +2 -0
  290. package/dist/frontend/lowering/lower-classes.js +45 -43
  291. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  292. package/dist/frontend/lowering/lower-exprs.d.ts +9 -2
  293. package/dist/frontend/lowering/lower-exprs.js +390 -157
  294. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  295. package/dist/frontend/lowering/lower-functions.js +32 -19
  296. package/dist/frontend/lowering/lower-functions.js.map +1 -1
  297. package/dist/frontend/lowering/lower-inspect.js +26 -2
  298. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  299. package/dist/frontend/lowering/lower-modules.js +10 -2
  300. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  301. package/dist/frontend/lowering/lower-stmts.js +46 -58
  302. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  303. package/dist/frontend/lowering/lowerer.d.ts +37 -0
  304. package/dist/frontend/lowering/lowerer.js +283 -18
  305. package/dist/frontend/lowering/lowerer.js.map +1 -1
  306. package/dist/frontend/lowering/native-ffi.js +3 -1
  307. package/dist/frontend/lowering/native-ffi.js.map +1 -1
  308. package/dist/frontend/lowering/runtime-optional-provenance.d.ts +15 -0
  309. package/dist/frontend/lowering/runtime-optional-provenance.js +40 -0
  310. package/dist/frontend/lowering/runtime-optional-provenance.js.map +1 -0
  311. package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
  312. package/dist/frontend/lowering/strict-equality.d.ts +9 -0
  313. package/dist/frontend/lowering/strict-equality.js +116 -0
  314. package/dist/frontend/lowering/strict-equality.js.map +1 -0
  315. package/dist/frontend/lowering/surfaces.js +3 -0
  316. package/dist/frontend/lowering/surfaces.js.map +1 -1
  317. package/dist/frontend/lowering/union-comparison.d.ts +5 -0
  318. package/dist/frontend/lowering/union-comparison.js +47 -0
  319. package/dist/frontend/lowering/union-comparison.js.map +1 -0
  320. package/dist/frontend/program.d.ts +38 -2
  321. package/dist/frontend/program.js +440 -59
  322. package/dist/frontend/program.js.map +1 -1
  323. package/dist/frontend/program.test.js +59 -6
  324. package/dist/frontend/program.test.js.map +1 -1
  325. package/dist/frontend/type-mapper.d.ts +1 -1
  326. package/dist/frontend/type-mapper.js +89 -14
  327. package/dist/frontend/type-mapper.js.map +1 -1
  328. package/dist/frontend/type-mapper.test.js +15 -3
  329. package/dist/frontend/type-mapper.test.js.map +1 -1
  330. package/dist/index.js +25 -9
  331. package/dist/index.js.map +1 -1
  332. package/dist/ir/analysis.d.ts +3 -1
  333. package/dist/ir/analysis.js +4 -0
  334. package/dist/ir/analysis.js.map +1 -1
  335. package/dist/ir/builtin-signatures.js +2 -3
  336. package/dist/ir/builtin-signatures.js.map +1 -1
  337. package/dist/ir/constant-tables.test.js +1 -1
  338. package/dist/ir/initializer-bindings.test.js +1 -1
  339. package/dist/ir/ir.d.ts +78 -15
  340. package/dist/ir/ir.js +20 -6
  341. package/dist/ir/ir.js.map +1 -1
  342. package/dist/ir/scalar-records.test.js +1 -1
  343. package/dist/ir/serialize.d.ts +1 -1
  344. package/dist/ir/serialize.js +3 -3
  345. package/dist/ir/serialize.js.map +1 -1
  346. package/dist/ir/traverse.js +8 -0
  347. package/dist/ir/traverse.js.map +1 -1
  348. package/dist/ir/validate.js +118 -20
  349. package/dist/ir/validate.js.map +1 -1
  350. package/dist/ir/validate.test.js +269 -8
  351. package/dist/ir/validate.test.js.map +1 -1
  352. package/dist/library/fence-eval.test.js +1 -1
  353. package/dist/library/int-infer.test.js +4 -4
  354. package/dist/library/library-cache.test.js +5 -5
  355. package/dist/library/library-profile.d.ts +2 -1
  356. package/dist/library/library-profile.js +4 -3
  357. package/dist/library/library-profile.js.map +1 -1
  358. package/dist/native/compiler.js.map +1 -1
  359. package/dist/native/compiler.test.js +2 -2
  360. package/dist/native/library.d.ts +2 -1
  361. package/dist/native/library.js.map +1 -1
  362. package/dist/native/prepare.js +27 -3
  363. package/dist/native/prepare.js.map +1 -1
  364. package/dist/native/sanitizer.d.ts +3 -2
  365. package/dist/native/sanitizer.js +3 -13
  366. package/dist/native/sanitizer.js.map +1 -1
  367. package/package.json +20 -20
  368. package/surface-manifest.json +8 -2
@@ -1,5 +1,12 @@
1
+ import { checkCycleBindingAccesses, refuseUncheckedCycleReads, } from "./cycle-initialization.js";
2
+ import { identityPreservingWidening } from "./coercions/identity.js";
3
+ import { checkedClassAssertion } from "./class-assertions.js";
4
+ import { narrowStoredClassValue, narrowGenericClassValue } from "./class-unions.js";
5
+ import { isOptionalProcessStreamProperty } from "./builtins/process.js";
6
+ import { concreteCollectionNarrow } from "./collection-narrowing.js";
1
7
  import { lowerWorkerMetadata } from "./builtins/workers.js";
2
8
  import { dynUndefinedExpr, nodeThrowExpr, numLit, varRef } from "../../ir/build.js";
9
+ import { iteratorSlotAdapter } from "./iterator-adapters.js";
3
10
  import { lowerBuiltinCall } from "./builtin-calls.js";
4
11
  import { CoercionState } from "./coercions/state.js";
5
12
  import { widthLiftPlan, unitOnlyElem, recordWidthPlan, describeRecordWidthBlocker, objToRecordPlan, recordToClassPlan, } from "./coercions/structural-plans.js";
@@ -9,6 +16,7 @@ import { unionRetagMappable, narrowedRetagHelper, strandedUnitTrap, strandedCoer
9
16
  import { jsvalLiftable, jsvalLiftExpr, unionToJsvalHelper, recordToJsvalHelper, arrayToJsvalHelper, arrayToJsvalArrayHelper, } from "./coercions/island.js";
10
17
  import { lowerUtilTypeValue, pathModuleValue, utilTypesModuleValue, } from "./lower-builtin-values.js";
11
18
  import { everyExprChild, everyStmtChild, transformStmtList } from "../../ir/traverse.js";
19
+ import { RuntimeOptionalProvenance } from "./runtime-optional-provenance.js";
12
20
  import { RuntimeOptionalLocals } from "./runtime-optional-locals.js";
13
21
  import { sanitizeUnregisteredClassTypes } from "./sanitize-class-types.js";
14
22
  import { UnregisteredClassTypes } from "./unregistered-class-types.js";
@@ -1358,7 +1366,16 @@ export class Lowerer {
1358
1366
  runtimeOptionalWidening(actual, expected) {
1359
1367
  if (actual.kind !== "union" || this.armTag(actual.unionId, UNDEFINED_T) < 0)
1360
1368
  return null;
1361
- return typeEquals(this.stripUndefinedArm(actual), expected) ? actual : null;
1369
+ const present = this.stripUndefinedArm(actual);
1370
+ if (typeEquals(present, expected))
1371
+ return actual;
1372
+ // Only a bare expected arm gains runtime-optional storage. A slot that
1373
+ // already admits undefined keeps its own checked representation.
1374
+ if (expected.kind === "union" && this.armTag(expected.unionId, UNDEFINED_T) >= 0)
1375
+ return null;
1376
+ return identityPreservingWidening(this, present, expected)
1377
+ ? this.runtimeOptionalType(expected)
1378
+ : null;
1362
1379
  }
1363
1380
  runtimeOptionalType(t) {
1364
1381
  if (t.kind === "union")
@@ -1427,6 +1444,8 @@ export class Lowerer {
1427
1444
  /** True while re-lowering a base function's 2nd+ instance: the same source
1428
1445
  * statements were already counted for the first instance. */
1429
1446
  suppressStats = false;
1447
+ /** Comparisons interned by operand representations and equality semantics. */
1448
+ equalityHelpers = new Map();
1430
1449
  /** Synthetic array-HOF loop functions (map/filter/forEach desugar),
1431
1450
  * interned per method + element/callback-result type: key → fn name. */
1432
1451
  arrHofHelpers = new Map();
@@ -1518,6 +1537,10 @@ export class Lowerer {
1518
1537
  * node carrying the ?. token is marked handled so the receiver-typed
1519
1538
  * lowerings stop declining it (chainBlocked). */
1520
1539
  chainRecvByNode = new Map();
1540
+ /** Lowered void calls whose checked type is `never` (they throw or exit).
1541
+ * TypeScript lets such a call stand where any value is expected;
1542
+ * coerceToExpected turns them into diverging sequences. */
1543
+ neverValued = new Set();
1521
1544
  chainNarrowedType = new Map();
1522
1545
  chainHandled = new Set();
1523
1546
  /** for-of-over-matchAll bindings whose `.index` reads the companion-index
@@ -1549,6 +1572,8 @@ export class Lowerer {
1549
1572
  /** Named method slots observed before class collection need a callable
1550
1573
  * ABI and shared prototype descriptors instead of call-site specialization. */
1551
1574
  prototypeMethodAccesses = new Map();
1575
+ /** Field names whose complete source census stores only lexical arrows. */
1576
+ receiverFreeCallbackFields = new Set();
1552
1577
  /** Inferred JS methods participating in an override chain keep a vtable
1553
1578
  * ABI instead of call-site specialization. Filled before class collection. */
1554
1579
  virtualJsMethods = new Set();
@@ -1726,6 +1751,10 @@ export class Lowerer {
1726
1751
  * function called above the declaration statement reads that, never a
1727
1752
  * NULL slot. Filled by collectGlobals. */
1728
1753
  varGlobalEntryInits = new Map();
1754
+ /** Import-cycle bindings with an initialization flag, by global id, and
1755
+ * the top-level statements declaring them (cycle-initialization.ts). */
1756
+ cycleInitFlags = new Map();
1757
+ cycleInitDeclarations = new Map();
1729
1758
  get ctx() {
1730
1759
  const top = this.fnStack[this.fnStack.length - 1];
1731
1760
  if (!top)
@@ -2874,9 +2903,13 @@ export class Lowerer {
2874
2903
  * but it is not a runtime proof; promoting only the affected slots keeps
2875
2904
  * the rest of the dense ABI unchanged. */
2876
2905
  analyzeRuntimeOptionalArrayReads(parts) {
2906
+ const provenance = RuntimeOptionalProvenance.fromEnvironment();
2907
+ // The site whose value the current promotion follows (debug only).
2908
+ let provenanceSite;
2877
2909
  const optionalSymbols = new Set();
2878
2910
  const optionalReturns = new Set();
2879
2911
  const arithmeticReturns = new Map();
2912
+ const primitiveBindings = new Map();
2880
2913
  const optionalParams = new Map();
2881
2914
  const optionalFields = new Map();
2882
2915
  const dynamicObjectEntryRows = new Set();
@@ -2903,6 +2936,17 @@ export class Lowerer {
2903
2936
  (projection?.kind === "declared-function" ? projection.signature : null));
2904
2937
  };
2905
2938
  const functionDeclBySymbol = new Map();
2939
+ const staticFieldsBySymbol = new Map();
2940
+ for (const info of this.classes.values()) {
2941
+ for (const field of info.staticFields) {
2942
+ const declaration = field.initializer.parent;
2943
+ if (!ts.isPropertyDeclaration(declaration))
2944
+ continue;
2945
+ const symbol = symbolOf(declaration.name);
2946
+ if (symbol)
2947
+ staticFieldsBySymbol.set(symbol, field);
2948
+ }
2949
+ }
2906
2950
  const signatureBySymbol = new Map();
2907
2951
  const methodFamilies = new Map();
2908
2952
  const familyBySymbol = new Map();
@@ -2999,11 +3043,12 @@ export class Lowerer {
2999
3043
  }
3000
3044
  return false;
3001
3045
  };
3002
- const isArrayRead = (node) => {
3046
+ const isIndexedRead = (node) => {
3003
3047
  const e = peel(node);
3004
3048
  if (!ts.isElementAccessExpression(e))
3005
3049
  return false;
3006
- return this.mapTypeOf(this.typeOf(e.expression))?.kind === "array";
3050
+ const kind = this.mapTypeOf(this.typeOf(e.expression))?.kind;
3051
+ return kind === "array" || kind === "string";
3007
3052
  };
3008
3053
  const isDynamicObjectEntryRead = (node) => {
3009
3054
  const read = peel(node);
@@ -3038,7 +3083,9 @@ export class Lowerer {
3038
3083
  if (explicitlyNonNull(node))
3039
3084
  return false;
3040
3085
  const e = peel(node);
3041
- if (isArrayRead(e))
3086
+ if (isIndexedRead(e))
3087
+ return true;
3088
+ if (ts.isPropertyAccessExpression(e) && isOptionalProcessStreamProperty(this, e))
3042
3089
  return true;
3043
3090
  if (ts.isCallExpression(e) && this.runtimeOptionalReduceTypes.has(e))
3044
3091
  return true;
@@ -3058,6 +3105,11 @@ export class Lowerer {
3058
3105
  const symbol = symbolOf(e);
3059
3106
  return symbol !== null && optionalSymbols.has(symbol);
3060
3107
  }
3108
+ if (ts.isPropertyAccessExpression(e)) {
3109
+ const symbol = symbolOf(e.name);
3110
+ if (symbol && optionalSymbols.has(symbol))
3111
+ return true;
3112
+ }
3061
3113
  if (ts.isCallExpression(e) && ts.isIdentifier(e.expression)) {
3062
3114
  const symbol = callableSymbolOf(e.expression);
3063
3115
  return symbol !== null && optionalReturns.has(symbol);
@@ -3085,11 +3137,31 @@ export class Lowerer {
3085
3137
  }
3086
3138
  return false;
3087
3139
  };
3088
- const optionalStringArithmeticType = (node) => {
3140
+ const optionalPrimitiveResultType = (node) => {
3089
3141
  const e = peel(node);
3090
- if (!ts.isBinaryExpression(e) || e.operatorToken.kind !== ts.SyntaxKind.PlusToken)
3142
+ if (ts.isIdentifier(e)) {
3143
+ const symbol = symbolOf(e);
3144
+ return symbol ? (primitiveBindings.get(symbol) ?? null) : null;
3145
+ }
3146
+ if (ts.isCallExpression(e)) {
3147
+ const symbol = callableSymbolOf(e.expression);
3148
+ return symbol ? (arithmeticReturns.get(symbol) ?? null) : null;
3149
+ }
3150
+ if (!ts.isBinaryExpression(e))
3151
+ return null;
3152
+ if (e.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken && mayBeOptional(e.left)) {
3153
+ const left = this.mapTypeOf(this.typeOf(e.left));
3154
+ const right = this.mapTypeOf(this.typeOf(e.right));
3155
+ const primitive = (t) => t?.kind === "f64" || t?.kind === "string" || t?.kind === "bool";
3156
+ if (primitive(left) && primitive(right) && !typeEquals(left, right)) {
3157
+ const arms = [left, right].sort((a, b) => (typeKey(a) < typeKey(b) ? -1 : 1));
3158
+ return { kind: "union", unionId: this.unions.intern(arms) };
3159
+ }
3091
3160
  return null;
3092
- const stringArrayRead = (part) => {
3161
+ }
3162
+ if (e.operatorToken.kind !== ts.SyntaxKind.PlusToken)
3163
+ return null;
3164
+ const stringRead = (part) => {
3093
3165
  const p = peel(part);
3094
3166
  if (!ts.isElementAccessExpression(p))
3095
3167
  return false;
@@ -3097,16 +3169,15 @@ export class Lowerer {
3097
3169
  if (t?.kind !== "string")
3098
3170
  return false;
3099
3171
  const recv = this.mapTypeOf(this.typeOf(p.expression));
3100
- return recv?.kind === "array" && recv.elem.kind === "string";
3172
+ return recv?.kind === "string" || (recv?.kind === "array" && recv.elem.kind === "string");
3101
3173
  };
3102
3174
  const primitive = (part) => {
3103
3175
  const t = this.mapTypeOf(this.typeOf(part));
3104
3176
  return t?.kind === "f64" || t?.kind === "string";
3105
3177
  };
3106
- if (!stringArrayRead(e.left) && !stringArrayRead(e.right))
3178
+ if (!stringRead(e.left) && !stringRead(e.right))
3107
3179
  return null;
3108
- if (!(primitive(e.left) || stringArrayRead(e.left)) ||
3109
- !(primitive(e.right) || stringArrayRead(e.right)))
3180
+ if (!primitive(e.left) || !primitive(e.right))
3110
3181
  return null;
3111
3182
  return { kind: "union", unionId: this.unions.intern([F64, STRING]) };
3112
3183
  };
@@ -3139,6 +3210,7 @@ export class Lowerer {
3139
3210
  const symbol = symbolOf(el.name);
3140
3211
  if (symbol && !el.initializer && !optionalSymbols.has(symbol)) {
3141
3212
  optionalSymbols.add(symbol);
3213
+ provenance?.note("pattern-binding", el.name, init);
3142
3214
  // Indexed flow facts can survive a mutating method call in the
3143
3215
  // checker. The array's element ABI describes every value a
3144
3216
  // position may hold after that call, so bind from that type.
@@ -3282,6 +3354,7 @@ export class Lowerer {
3282
3354
  const widened = this.runtimeOptionalType(current);
3283
3355
  const previous = this.runtimeOptionalBindingTypes.get(symbol);
3284
3356
  this.runtimeOptionalBindingTypes.set(symbol, widened);
3357
+ provenance?.note("callback-parameter", parameter.name, provenanceSite);
3285
3358
  if (!previous || !typeEquals(previous, widened))
3286
3359
  changed = true;
3287
3360
  if (!optionalSymbols.has(symbol)) {
@@ -3293,6 +3366,7 @@ export class Lowerer {
3293
3366
  const fnType = this.mapTypeOf(this.typeOf(fn));
3294
3367
  if (fnType?.kind === "func" && bodyReturnsOptional(fn)) {
3295
3368
  const widenedReturn = this.runtimeOptionalType(fnType.ret);
3369
+ provenance?.note("callback-return", fn, provenanceSite);
3296
3370
  const previousReturn = this.runtimeOptionalFunctionReturnType(fn, fnType.ret);
3297
3371
  this.runtimeOptionalFunctionReturns.set(fn, widenedReturn);
3298
3372
  if (!typeEquals(previousReturn, widenedReturn))
@@ -3425,6 +3499,16 @@ export class Lowerer {
3425
3499
  const scan = (node) => {
3426
3500
  if (ts.isVariableDeclaration(node)) {
3427
3501
  if (node.initializer) {
3502
+ const result = optionalPrimitiveResultType(node.initializer);
3503
+ const symbol = ts.isIdentifier(node.name) ? symbolOf(node.name) : null;
3504
+ if (result?.kind === "union" && symbol) {
3505
+ const before = primitiveBindings.get(symbol);
3506
+ if (!before || !typeEquals(before, result)) {
3507
+ primitiveBindings.set(symbol, result);
3508
+ this.runtimeOptionalBindingTypes.set(symbol, result);
3509
+ changed = true;
3510
+ }
3511
+ }
3428
3512
  if (ts.isIdentifier(node.name) && isDynamicObjectEntryRead(node.initializer)) {
3429
3513
  const symbol = symbolOf(node.name);
3430
3514
  if (symbol && !dynamicObjectEntryRows.has(symbol)) {
@@ -3436,6 +3520,7 @@ export class Lowerer {
3436
3520
  const symbol = symbolOf(node.name);
3437
3521
  if (symbol && !optionalSymbols.has(symbol)) {
3438
3522
  optionalSymbols.add(symbol);
3523
+ provenance?.note("binding", node.name, node.initializer);
3439
3524
  changed = true;
3440
3525
  }
3441
3526
  }
@@ -3456,6 +3541,8 @@ export class Lowerer {
3456
3541
  const aliasNew = !optionalReturns.has(symbol);
3457
3542
  if (aliasNew)
3458
3543
  optionalReturns.add(symbol);
3544
+ if (aliasNew)
3545
+ provenance?.note("function-alias", node.name, node.initializer);
3459
3546
  if (aliasNew)
3460
3547
  changed = true;
3461
3548
  const valueType = this.mapTypeOf(this.typeOf(node.name));
@@ -3491,8 +3578,10 @@ export class Lowerer {
3491
3578
  const value = ts.isPropertyAssignment(prop)
3492
3579
  ? prop.initializer
3493
3580
  : prop.name;
3494
- if (mayBeOptional(value) && noteField(node, name.text))
3581
+ if (mayBeOptional(value) && noteField(node, name.text)) {
3582
+ provenance?.note("literal-field", name, value);
3495
3583
  changed = true;
3584
+ }
3496
3585
  }
3497
3586
  }
3498
3587
  }
@@ -3507,14 +3596,24 @@ export class Lowerer {
3507
3596
  const symbol = symbolOf(node.left);
3508
3597
  if (symbol && !optionalSymbols.has(symbol)) {
3509
3598
  optionalSymbols.add(symbol);
3599
+ provenance?.note("assigned-binding", node.left, node.right);
3510
3600
  changed = true;
3511
3601
  }
3512
3602
  }
3513
- else if (ts.isPropertyAccessExpression(node.left) &&
3514
- ts.isIdentifier(node.left.expression)) {
3515
- const symbol = symbolOf(node.left.expression);
3516
- if (symbol && noteFieldSymbol(symbol, node.left.name.text))
3603
+ else if (ts.isPropertyAccessExpression(node.left)) {
3604
+ const field = symbolOf(node.left.name);
3605
+ if (field && staticFieldsBySymbol.has(field) && !optionalSymbols.has(field)) {
3606
+ optionalSymbols.add(field);
3607
+ provenance?.note("static-field", node.left, node.right);
3517
3608
  changed = true;
3609
+ }
3610
+ else if (ts.isIdentifier(node.left.expression)) {
3611
+ const symbol = symbolOf(node.left.expression);
3612
+ if (symbol && noteFieldSymbol(symbol, node.left.name.text)) {
3613
+ provenance?.note("assigned-field", node.left, node.right);
3614
+ changed = true;
3615
+ }
3616
+ }
3518
3617
  }
3519
3618
  }
3520
3619
  if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {
@@ -3555,6 +3654,7 @@ export class Lowerer {
3555
3654
  }
3556
3655
  }
3557
3656
  if (nativeArrayReceiver) {
3657
+ provenanceSite = node;
3558
3658
  if (promoteHofCallback(callback, callbackIndices))
3559
3659
  changed = true;
3560
3660
  const method = node.expression.name.text;
@@ -3605,6 +3705,7 @@ export class Lowerer {
3605
3705
  continue;
3606
3706
  shape.type = widened;
3607
3707
  const parameter = functionDeclBySymbol.get(target)?.parameters[i];
3708
+ provenance?.note("parameter", parameter, node, "(omitted or undefined argument)");
3608
3709
  if (parameter) {
3609
3710
  for (const bound of boundIdentifiersOf(parameter.name)) {
3610
3711
  const boundSymbol = symbolOf(bound);
@@ -3629,6 +3730,7 @@ export class Lowerer {
3629
3730
  const callbackSlot = shape?.type;
3630
3731
  if (callbackSlot?.kind === "func" && !ts.isSpreadElement(arg)) {
3631
3732
  const optionalCallbackParams = callbackSlot.params.flatMap((type, index) => type.kind === "union" && this.armTag(type.unionId, UNDEFINED_T) >= 0 ? [index] : []);
3733
+ provenanceSite = node;
3632
3734
  if (optionalCallbackParams.length > 0 &&
3633
3735
  promoteHofCallback(arg, optionalCallbackParams)) {
3634
3736
  changed = true;
@@ -3649,6 +3751,7 @@ export class Lowerer {
3649
3751
  continue;
3650
3752
  rest.type = widened;
3651
3753
  const parameter = functionDeclBySymbol.get(target)?.parameters[i];
3754
+ provenance?.note("rest-parameter", parameter, arg);
3652
3755
  if (parameter && ts.isIdentifier(parameter.name)) {
3653
3756
  const bound = symbolOf(parameter.name);
3654
3757
  if (bound)
@@ -3677,6 +3780,7 @@ export class Lowerer {
3677
3780
  if (set.size !== before) {
3678
3781
  changed = true;
3679
3782
  const parameter = functionDeclBySymbol.get(target)?.parameters[i];
3783
+ provenance?.note("parameter", parameter, arg, target === symbol ? "" : "(override)");
3680
3784
  if (parameter) {
3681
3785
  for (const bound of boundIdentifiersOf(parameter.name)) {
3682
3786
  const boundSymbol = symbolOf(bound);
@@ -3700,9 +3804,10 @@ export class Lowerer {
3700
3804
  for (const expression of returnsOf(decl)) {
3701
3805
  if (mayBeOptional(expression) && !optionalReturns.has(symbol)) {
3702
3806
  optionalReturns.add(symbol);
3807
+ provenance?.note("return", decl.name ?? decl, expression);
3703
3808
  changed = true;
3704
3809
  }
3705
- const arithmetic = optionalStringArithmeticType(expression);
3810
+ const arithmetic = optionalPrimitiveResultType(expression);
3706
3811
  if (arithmetic && !arithmeticReturns.has(symbol)) {
3707
3812
  arithmeticReturns.set(symbol, arithmetic);
3708
3813
  changed = true;
@@ -3713,6 +3818,13 @@ export class Lowerer {
3713
3818
  let changed = true;
3714
3819
  while (changed) {
3715
3820
  changed = false;
3821
+ for (const [symbol, field] of staticFieldsBySymbol) {
3822
+ if (!optionalSymbols.has(symbol) && mayBeOptional(field.initializer)) {
3823
+ optionalSymbols.add(symbol);
3824
+ provenance?.note("static-field", field.initializer.parent, field.initializer);
3825
+ changed = true;
3826
+ }
3827
+ }
3716
3828
  for (const sf of sourceFiles)
3717
3829
  if (scanFile(sf))
3718
3830
  changed = true;
@@ -3744,11 +3856,27 @@ export class Lowerer {
3744
3856
  for (const symbol of family) {
3745
3857
  if (!optionalReturns.has(symbol)) {
3746
3858
  optionalReturns.add(symbol);
3859
+ provenance?.note("return", functionDeclBySymbol.get(symbol), undefined, "(override family)");
3747
3860
  changed = true;
3748
3861
  }
3749
3862
  }
3750
3863
  }
3751
3864
  }
3865
+ const globalsById = new Map(this.globalsList.map((global) => [global.id, global]));
3866
+ for (const [symbol, field] of staticFieldsBySymbol) {
3867
+ if (!optionalSymbols.has(symbol))
3868
+ continue;
3869
+ const promoted = addUndefined(field.type);
3870
+ // An explicit optional annotation already has the right layout, but
3871
+ // an indexed assignment still invalidates the checker's presence fact.
3872
+ field.type = promoted;
3873
+ field.runtimeOptional = true;
3874
+ const global = globalsById.get(field.globalId);
3875
+ if (global) {
3876
+ global.type = promoted;
3877
+ this.runtimeOptionalGlobals.add(global);
3878
+ }
3879
+ }
3752
3880
  for (const [symbol, sig] of signatureBySymbol) {
3753
3881
  const params = optionalParams.get(symbol);
3754
3882
  if (params) {
@@ -3880,6 +4008,7 @@ export class Lowerer {
3880
4008
  }
3881
4009
  });
3882
4010
  }
4011
+ provenance?.flush();
3883
4012
  }
3884
4013
  run() {
3885
4014
  const parts = this.splitFiles();
@@ -4123,6 +4252,7 @@ export class Lowerer {
4123
4252
  // the emitted program references, flushing deferred class diagnostics
4124
4253
  // that a reached type makes relevant.
4125
4254
  const artifacts = this.moduleArtifacts(functions);
4255
+ refuseUncheckedCycleReads(this, artifacts.classes ?? []);
4126
4256
  // Types still naming a class that never REGISTERED after retention's
4127
4257
  // flush (JS graphs whose class fences deferred to runtime — the
4128
4258
  // sentence-walker's path params, printer tables whose func-typed
@@ -4137,7 +4267,7 @@ export class Lowerer {
4137
4267
  const module = this.diags.length > 0
4138
4268
  ? null
4139
4269
  : {
4140
- irVersion: 14,
4270
+ irVersion: 15,
4141
4271
  sourceFile: this.entry.fileName,
4142
4272
  functions,
4143
4273
  classes: artifacts.classes,
@@ -4151,6 +4281,8 @@ export class Lowerer {
4151
4281
  };
4152
4282
  if (module)
4153
4283
  sanitizeUnregisteredClassTypes(module, (name) => this.classes.has(name));
4284
+ if (module)
4285
+ checkCycleBindingAccesses(this, module);
4154
4286
  return {
4155
4287
  module,
4156
4288
  diagnostics: this.diags,
@@ -5060,6 +5192,9 @@ export class Lowerer {
5060
5192
  if (arm !== undefined)
5061
5193
  return arm;
5062
5194
  }
5195
+ const collection = concreteCollectionNarrow(this, node, t);
5196
+ if (collection)
5197
+ return collection;
5063
5198
  // IMPLICIT-ANY instance bodies: an identifier reference to a BOUND
5064
5199
  // param answers the call site's concrete type wherever the checker
5065
5200
  // still says `any` (there is no `T` for mapType to substitute — the
@@ -5383,6 +5518,11 @@ export class Lowerer {
5383
5518
  this.pushDiag(recordShapeMismatchDiag(this.fmt(expected), this.fmt(actual), locOf(node), detail));
5384
5519
  throw new PoisonError();
5385
5520
  }
5521
+ // Iterator-typed slots hold generators and built-in collection
5522
+ // iterators; any other iterator object (a user class) stays fenced.
5523
+ if (expected.kind === "generator" && actual.kind !== "generator") {
5524
+ this.unsupported("SC1090", node, `'${this.fmt(actual)}' values in an iterator-typed slot (Iterator and IterableIterator slots hold generators and built-in collection iterators)`);
5525
+ }
5386
5526
  // Everything else — a plain-kind mismatch like a string flowing into a
5387
5527
  // class-instance slot — is tsc-rejected in the lowering world and only
5388
5528
  // reaches here through preflight's project-world second chance (e.g. a
@@ -5438,6 +5578,21 @@ export class Lowerer {
5438
5578
  }
5439
5579
  return literalUnionArm(def, values, (id) => this.shapes.get(id), cached.owners);
5440
5580
  }
5581
+ /** Widen only the result view; identical parameter ABIs preserve closure identity. */
5582
+ coerceCovariantFunction(expr, expected) {
5583
+ if (expr.type.kind === "func" &&
5584
+ expected.kind === "func" &&
5585
+ expr.type.rest === expected.rest &&
5586
+ expr.type.restAbi === expected.restAbi &&
5587
+ expr.type.argumentsAll === expected.argumentsAll &&
5588
+ expr.type.params.length === expected.params.length &&
5589
+ expr.type.params.every((type, i) => typeEquals(type, expected.params[i])) &&
5590
+ expr.type.ret.kind === "object" &&
5591
+ expected.ret.kind === "object" &&
5592
+ this.isSubclassOf(expr.type.ret.className, expected.ret.className))
5593
+ return { kind: "upcast", value: expr, type: expected, loc: expr.loc };
5594
+ return null;
5595
+ }
5441
5596
  /** Implicit union construction. Wherever a value flows into a typed slot
5442
5597
  * (initializer, assignment, call argument, return, field write, record
5443
5598
  * literal field, ternary arm) whose expected type is a union and the
@@ -5446,6 +5601,15 @@ export class Lowerer {
5446
5601
  * else (including a DIFFERENT union) is left for requireExactShape, which
5447
5602
  * rejects union mismatches with SC2003. */
5448
5603
  coerceToExpected(expr, expected) {
5604
+ if (expr.type.kind === "void" && expected.kind !== "void" && this.neverValued.has(expr))
5605
+ return this.divergentValue(expr, expected);
5606
+ // Iterator-typed slots: native iterators and differently typed
5607
+ // generators step through an adapter generator.
5608
+ if (expected.kind === "generator" && !typeEquals(expr.type, expected)) {
5609
+ const adapted = iteratorSlotAdapter(this, expr, expected);
5610
+ if (adapted)
5611
+ return adapted;
5612
+ }
5449
5613
  // Island boundary, both directions. IN: any static value flowing into
5450
5614
  // an any-typed slot marshals implicitly (tsc allows the assignment;
5451
5615
  // the marshal is where its semantics live). OUT: an 'any' value
@@ -5705,6 +5869,9 @@ export class Lowerer {
5705
5869
  return { kind: "call", callee: adapter, args: [expr], type: expected, loc: expr.loc };
5706
5870
  }
5707
5871
  }
5872
+ const covariant = this.coerceCovariantFunction(expr, expected);
5873
+ if (covariant)
5874
+ return covariant;
5708
5875
  // The GENERAL function-value adapter (funcCoerceAdapter): a function
5709
5876
  // whose signature differs from the slot's only by coercible pieces —
5710
5877
  // fewer parameters (JS ignores extras: `load(function () {})` into an
@@ -5728,6 +5895,31 @@ export class Lowerer {
5728
5895
  this.isSubclassOf(expr.type.className, expected.className)) {
5729
5896
  return { kind: "upcast", value: expr, type: expected, loc: expr.loc };
5730
5897
  }
5898
+ // Optional subclass storage still has the same object payload. Extract
5899
+ // it with a checked tag test, then widen the class view without copying.
5900
+ if (expected.kind === "object" && expr.type.kind === "union") {
5901
+ const arms = this.unions.get(expr.type.unionId)?.arms;
5902
+ const present = arms?.filter((arm) => !isUnitType(arm)) ?? [];
5903
+ if (present.length === 1 &&
5904
+ present[0].kind === "object" &&
5905
+ present[0].className !== expected.className &&
5906
+ this.isSubclassOf(present[0].className, expected.className)) {
5907
+ // One class arm: the ordinary checked narrow reports a missing value
5908
+ // exactly like same-class storage before the prefix view widens it.
5909
+ return {
5910
+ kind: "upcast",
5911
+ value: this.coerceToExpected(expr, present[0]),
5912
+ type: expected,
5913
+ loc: expr.loc,
5914
+ };
5915
+ }
5916
+ if (present.length > 1 &&
5917
+ present.every((arm) => identityPreservingWidening(this, arm, expected))) {
5918
+ const view = checkedClassAssertion(this, expr, expected, expr.loc);
5919
+ if (view)
5920
+ return view;
5921
+ }
5922
+ }
5731
5923
  // CLASS-VALUE widening (classval:D into a classval:C slot): the same
5732
5924
  // pointer with only the static type changing — legal exactly when D
5733
5925
  // strictly descends from C AND the two completed constructor ABIs
@@ -6110,6 +6302,17 @@ export class Lowerer {
6110
6302
  loc: expr.loc,
6111
6303
  }
6112
6304
  : this.coerceToExpected(expr, expected);
6305
+ // Keep storage intact when ordinary widening already accepts it. Only
6306
+ // a destination needing a more specific class layout uses the site's
6307
+ // refinement and checked extraction.
6308
+ if (!typeEquals(e.type, expected) &&
6309
+ (expected.kind === "object" || expected.kind === "union")) {
6310
+ const site = e.type.kind === "union" ? this.mapTypeOf(this.typeOf(node)) : null;
6311
+ const narrowed = (site && narrowStoredClassValue(this, e, site)) ??
6312
+ narrowGenericClassValue(this, e, expected);
6313
+ if (narrowed)
6314
+ e = this.coerceToExpected(narrowed, expected);
6315
+ }
6113
6316
  // Existing JavaScript arrays retain mutations and identity across checked
6114
6317
  // slots. Fresh literals have no prior identity and use checked storage
6115
6318
  // directly, so later writes can change their inferred element type.
@@ -6698,6 +6901,42 @@ export class Lowerer {
6698
6901
  wrappedUndefined(type, loc) {
6699
6902
  return wrappedUndefined(this, type, loc);
6700
6903
  }
6904
+ /** The value an OMITTED or deleted property leaves in a record field
6905
+ * slot of `type`: the ABSENT state for undefined-armed unions (the slot
6906
+ * reads as undefined but the property does not exist), the dyn
6907
+ * undefined for 'unknown' slots, and null when the slot cannot be
6908
+ * missing. Only legal as a direct field-slot write (IR fieldAbsent). */
6909
+ absentFieldValue(type, loc) {
6910
+ if (type.kind === "union" && this.armTag(type.unionId, UNDEFINED_T) >= 0) {
6911
+ return { kind: "fieldAbsent", unionId: type.unionId, type, loc };
6912
+ }
6913
+ return this.wrappedUndefined(type, loc);
6914
+ }
6915
+ /** A field copy that keeps absence: `value` (the converted read of
6916
+ * `field` from record `obj`, which must be repeatable) when the source
6917
+ * property exists, else the target slot's ABSENT state. Fields that are
6918
+ * always present, and targets that cannot be absent, copy `value`
6919
+ * as-is. Only legal as a direct field-slot write. */
6920
+ presenceKeepingCopy(obj, shapeId, field, value, loc) {
6921
+ const present = this.recordFieldPresent(obj, shapeId, field, loc);
6922
+ if (present.kind !== "recordHas")
6923
+ return value;
6924
+ const absent = this.absentFieldValue(value.type, loc);
6925
+ if (absent?.kind !== "fieldAbsent")
6926
+ return value;
6927
+ return { kind: "ternary", cond: present, then: value, else_: absent, type: value.type, loc };
6928
+ }
6929
+ /** Own-property presence of declared field `field` on record `obj`
6930
+ * (borrowed — callers pass a repeatable receiver): a runtime test for
6931
+ * undefined-armed union fields, which can be absent, and `true` for
6932
+ * every other declared field. */
6933
+ recordFieldPresent(obj, shapeId, field, loc) {
6934
+ const f = this.shapes.get(shapeId)?.fields.find((x) => x.name === field);
6935
+ if (f && f.type.kind === "union" && this.armTag(f.type.unionId, UNDEFINED_T) >= 0) {
6936
+ return { kind: "recordHas", obj, shapeId, field, type: BOOL, loc };
6937
+ }
6938
+ return { kind: "boolLit", value: true, type: BOOL, loc };
6939
+ }
6701
6940
  /** The entry value of a binding JS initializes to `undefined` (an
6702
6941
  * initializer-less declaration, a hoisted `var` before its statement):
6703
6942
  * undefined-armed unions hold the interned undefined arm, and 'any'
@@ -7102,6 +7341,32 @@ export class Lowerer {
7102
7341
  declareLocal(nameNode, name, type, mutable) {
7103
7342
  return declareContextLocal(this.ctx, name, type, mutable, this.checker.getSymbolAtLocation(nameNode), bindingSource(nameNode));
7104
7343
  }
7344
+ /** A never-returning call in a value position of type `expected`: the
7345
+ * call runs for its effects (it throws or exits), and the expression ends
7346
+ * in an unreachable trap instead of producing a value. The result reads an
7347
+ * uninitialized hidden local that control never reaches. */
7348
+ divergentValue(call, expected) {
7349
+ const loc = call.loc;
7350
+ const slot = this.declareHiddenLocal("%never", expected);
7351
+ slot.mutable = true;
7352
+ return {
7353
+ kind: "seqExpr",
7354
+ stmts: [
7355
+ { kind: "exprStmt", expr: call, loc },
7356
+ { kind: "varDecl", localId: slot.id, init: null, loc },
7357
+ {
7358
+ kind: "runtimeFence",
7359
+ code: "SC9002",
7360
+ message: "unreachable: a 'never' call returned — please report this",
7361
+ loc,
7362
+ },
7363
+ ],
7364
+ result: varRef(slot.id, expected, loc),
7365
+ diverges: true,
7366
+ type: expected,
7367
+ loc,
7368
+ };
7369
+ }
7105
7370
  /** A function-scope local bound to NO ts.Symbol — the hidden ABI slot of a
7106
7371
  * defaulted parameter (the parameter's symbol binds to the separately-
7107
7372
  * declared body local; nothing in the source can name this one). */