@flighthq/tool-compiler 0.5.1-edge.1687.b63c819

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 (831) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +74 -0
  3. package/dist/packages/compiler-ambient/src/compilerAmbientSurface.d.ts +3 -0
  4. package/dist/packages/compiler-ambient/src/compilerAmbientSurface.d.ts.map +1 -0
  5. package/dist/packages/compiler-ambient/src/compilerAmbientSurface.js +564 -0
  6. package/dist/packages/compiler-ambient/src/compilerAmbientSurface.js.map +1 -0
  7. package/dist/packages/compiler-ambient/src/index.d.ts +2 -0
  8. package/dist/packages/compiler-ambient/src/index.d.ts.map +1 -0
  9. package/dist/packages/compiler-ambient/src/index.js +2 -0
  10. package/dist/packages/compiler-ambient/src/index.js.map +1 -0
  11. package/dist/packages/compiler-backend-cpp/src/cppAmbientMemberBinding.d.ts +3 -0
  12. package/dist/packages/compiler-backend-cpp/src/cppAmbientMemberBinding.d.ts.map +1 -0
  13. package/dist/packages/compiler-backend-cpp/src/cppAmbientMemberBinding.js +146 -0
  14. package/dist/packages/compiler-backend-cpp/src/cppAmbientMemberBinding.js.map +1 -0
  15. package/dist/packages/compiler-backend-cpp/src/cppBindingTypeInference.d.ts +3 -0
  16. package/dist/packages/compiler-backend-cpp/src/cppBindingTypeInference.d.ts.map +1 -0
  17. package/dist/packages/compiler-backend-cpp/src/cppBindingTypeInference.js +197 -0
  18. package/dist/packages/compiler-backend-cpp/src/cppBindingTypeInference.js.map +1 -0
  19. package/dist/packages/compiler-backend-cpp/src/cppCallableSignatureAbi.d.ts +8 -0
  20. package/dist/packages/compiler-backend-cpp/src/cppCallableSignatureAbi.d.ts.map +1 -0
  21. package/dist/packages/compiler-backend-cpp/src/cppCallableSignatureAbi.js +9 -0
  22. package/dist/packages/compiler-backend-cpp/src/cppCallableSignatureAbi.js.map +1 -0
  23. package/dist/packages/compiler-backend-cpp/src/cppClosureCapturePlan.d.ts +3 -0
  24. package/dist/packages/compiler-backend-cpp/src/cppClosureCapturePlan.d.ts.map +1 -0
  25. package/dist/packages/compiler-backend-cpp/src/cppClosureCapturePlan.js +109 -0
  26. package/dist/packages/compiler-backend-cpp/src/cppClosureCapturePlan.js.map +1 -0
  27. package/dist/packages/compiler-backend-cpp/src/cppCompilerBackend.d.ts +4 -0
  28. package/dist/packages/compiler-backend-cpp/src/cppCompilerBackend.d.ts.map +1 -0
  29. package/dist/packages/compiler-backend-cpp/src/cppCompilerBackend.js +16568 -0
  30. package/dist/packages/compiler-backend-cpp/src/cppCompilerBackend.js.map +1 -0
  31. package/dist/packages/compiler-backend-cpp/src/cppCompilerIdentity.d.ts +7 -0
  32. package/dist/packages/compiler-backend-cpp/src/cppCompilerIdentity.d.ts.map +1 -0
  33. package/dist/packages/compiler-backend-cpp/src/cppCompilerIdentity.js +176 -0
  34. package/dist/packages/compiler-backend-cpp/src/cppCompilerIdentity.js.map +1 -0
  35. package/dist/packages/compiler-backend-cpp/src/cppReferenceRepresentationPlan.d.ts +7 -0
  36. package/dist/packages/compiler-backend-cpp/src/cppReferenceRepresentationPlan.d.ts.map +1 -0
  37. package/dist/packages/compiler-backend-cpp/src/cppReferenceRepresentationPlan.js +1514 -0
  38. package/dist/packages/compiler-backend-cpp/src/cppReferenceRepresentationPlan.js.map +1 -0
  39. package/dist/packages/compiler-backend-cpp/src/cppRuntimeExternalSymbolBinding.d.ts +44 -0
  40. package/dist/packages/compiler-backend-cpp/src/cppRuntimeExternalSymbolBinding.d.ts.map +1 -0
  41. package/dist/packages/compiler-backend-cpp/src/cppRuntimeExternalSymbolBinding.js +1060 -0
  42. package/dist/packages/compiler-backend-cpp/src/cppRuntimeExternalSymbolBinding.js.map +1 -0
  43. package/dist/packages/compiler-backend-cpp/src/cppTupleRepresentation.d.ts +3 -0
  44. package/dist/packages/compiler-backend-cpp/src/cppTupleRepresentation.d.ts.map +1 -0
  45. package/dist/packages/compiler-backend-cpp/src/cppTupleRepresentation.js +13 -0
  46. package/dist/packages/compiler-backend-cpp/src/cppTupleRepresentation.js.map +1 -0
  47. package/dist/packages/compiler-backend-cpp/src/cppUnionRepresentationPlan.d.ts +66 -0
  48. package/dist/packages/compiler-backend-cpp/src/cppUnionRepresentationPlan.d.ts.map +1 -0
  49. package/dist/packages/compiler-backend-cpp/src/cppUnionRepresentationPlan.js +196 -0
  50. package/dist/packages/compiler-backend-cpp/src/cppUnionRepresentationPlan.js.map +1 -0
  51. package/dist/packages/compiler-backend-cpp/src/index.d.ts +6 -0
  52. package/dist/packages/compiler-backend-cpp/src/index.d.ts.map +1 -0
  53. package/dist/packages/compiler-backend-cpp/src/index.js +6 -0
  54. package/dist/packages/compiler-backend-cpp/src/index.js.map +1 -0
  55. package/dist/packages/compiler-backend-hx/src/haxeAmbientMemberBinding.d.ts +4 -0
  56. package/dist/packages/compiler-backend-hx/src/haxeAmbientMemberBinding.d.ts.map +1 -0
  57. package/dist/packages/compiler-backend-hx/src/haxeAmbientMemberBinding.js +160 -0
  58. package/dist/packages/compiler-backend-hx/src/haxeAmbientMemberBinding.js.map +1 -0
  59. package/dist/packages/compiler-backend-hx/src/haxeAsyncIterationLowering.d.ts +3 -0
  60. package/dist/packages/compiler-backend-hx/src/haxeAsyncIterationLowering.d.ts.map +1 -0
  61. package/dist/packages/compiler-backend-hx/src/haxeAsyncIterationLowering.js +129 -0
  62. package/dist/packages/compiler-backend-hx/src/haxeAsyncIterationLowering.js.map +1 -0
  63. package/dist/packages/compiler-backend-hx/src/haxeCompilerBackend.d.ts +5 -0
  64. package/dist/packages/compiler-backend-hx/src/haxeCompilerBackend.d.ts.map +1 -0
  65. package/dist/packages/compiler-backend-hx/src/haxeCompilerBackend.js +5172 -0
  66. package/dist/packages/compiler-backend-hx/src/haxeCompilerBackend.js.map +1 -0
  67. package/dist/packages/compiler-backend-hx/src/haxeCompilerEmittedSourceSyntax.d.ts +3 -0
  68. package/dist/packages/compiler-backend-hx/src/haxeCompilerEmittedSourceSyntax.d.ts.map +1 -0
  69. package/dist/packages/compiler-backend-hx/src/haxeCompilerEmittedSourceSyntax.js +8 -0
  70. package/dist/packages/compiler-backend-hx/src/haxeCompilerEmittedSourceSyntax.js.map +1 -0
  71. package/dist/packages/compiler-backend-hx/src/haxeCompilerIdentity.d.ts +3 -0
  72. package/dist/packages/compiler-backend-hx/src/haxeCompilerIdentity.d.ts.map +1 -0
  73. package/dist/packages/compiler-backend-hx/src/haxeCompilerIdentity.js +51 -0
  74. package/dist/packages/compiler-backend-hx/src/haxeCompilerIdentity.js.map +1 -0
  75. package/dist/packages/compiler-backend-hx/src/haxeCompilerTargetCompilationSmoke.d.ts +3 -0
  76. package/dist/packages/compiler-backend-hx/src/haxeCompilerTargetCompilationSmoke.d.ts.map +1 -0
  77. package/dist/packages/compiler-backend-hx/src/haxeCompilerTargetCompilationSmoke.js +8 -0
  78. package/dist/packages/compiler-backend-hx/src/haxeCompilerTargetCompilationSmoke.js.map +1 -0
  79. package/dist/packages/compiler-backend-hx/src/haxeExternEmission.d.ts +40 -0
  80. package/dist/packages/compiler-backend-hx/src/haxeExternEmission.d.ts.map +1 -0
  81. package/dist/packages/compiler-backend-hx/src/haxeExternEmission.js +968 -0
  82. package/dist/packages/compiler-backend-hx/src/haxeExternEmission.js.map +1 -0
  83. package/dist/packages/compiler-backend-hx/src/haxeRuntimeAbiManifest.d.ts +3 -0
  84. package/dist/packages/compiler-backend-hx/src/haxeRuntimeAbiManifest.d.ts.map +1 -0
  85. package/dist/packages/compiler-backend-hx/src/haxeRuntimeAbiManifest.js +53 -0
  86. package/dist/packages/compiler-backend-hx/src/haxeRuntimeAbiManifest.js.map +1 -0
  87. package/dist/packages/compiler-backend-hx/src/haxeRuntimeExternalConstructorAbi.d.ts +3 -0
  88. package/dist/packages/compiler-backend-hx/src/haxeRuntimeExternalConstructorAbi.d.ts.map +1 -0
  89. package/dist/packages/compiler-backend-hx/src/haxeRuntimeExternalConstructorAbi.js +64 -0
  90. package/dist/packages/compiler-backend-hx/src/haxeRuntimeExternalConstructorAbi.js.map +1 -0
  91. package/dist/packages/compiler-backend-hx/src/haxeRuntimeExternalSymbolBinding.d.ts +8 -0
  92. package/dist/packages/compiler-backend-hx/src/haxeRuntimeExternalSymbolBinding.d.ts.map +1 -0
  93. package/dist/packages/compiler-backend-hx/src/haxeRuntimeExternalSymbolBinding.js +803 -0
  94. package/dist/packages/compiler-backend-hx/src/haxeRuntimeExternalSymbolBinding.js.map +1 -0
  95. package/dist/packages/compiler-backend-hx/src/haxeRuntimeTaskCapability.d.ts +3 -0
  96. package/dist/packages/compiler-backend-hx/src/haxeRuntimeTaskCapability.d.ts.map +1 -0
  97. package/dist/packages/compiler-backend-hx/src/haxeRuntimeTaskCapability.js +66 -0
  98. package/dist/packages/compiler-backend-hx/src/haxeRuntimeTaskCapability.js.map +1 -0
  99. package/dist/packages/compiler-backend-hx/src/haxeTaskEmission.d.ts +3 -0
  100. package/dist/packages/compiler-backend-hx/src/haxeTaskEmission.d.ts.map +1 -0
  101. package/dist/packages/compiler-backend-hx/src/haxeTaskEmission.js +361 -0
  102. package/dist/packages/compiler-backend-hx/src/haxeTaskEmission.js.map +1 -0
  103. package/dist/packages/compiler-backend-hx/src/haxeTaskLowering.d.ts +4 -0
  104. package/dist/packages/compiler-backend-hx/src/haxeTaskLowering.d.ts.map +1 -0
  105. package/dist/packages/compiler-backend-hx/src/haxeTaskLowering.js +265 -0
  106. package/dist/packages/compiler-backend-hx/src/haxeTaskLowering.js.map +1 -0
  107. package/dist/packages/compiler-backend-hx/src/haxeTypeEmission.d.ts +16 -0
  108. package/dist/packages/compiler-backend-hx/src/haxeTypeEmission.d.ts.map +1 -0
  109. package/dist/packages/compiler-backend-hx/src/haxeTypeEmission.js +134 -0
  110. package/dist/packages/compiler-backend-hx/src/haxeTypeEmission.js.map +1 -0
  111. package/dist/packages/compiler-backend-hx/src/index.d.ts +13 -0
  112. package/dist/packages/compiler-backend-hx/src/index.d.ts.map +1 -0
  113. package/dist/packages/compiler-backend-hx/src/index.js +13 -0
  114. package/dist/packages/compiler-backend-hx/src/index.js.map +1 -0
  115. package/dist/packages/compiler-backend-rs/src/index.d.ts +8 -0
  116. package/dist/packages/compiler-backend-rs/src/index.d.ts.map +1 -0
  117. package/dist/packages/compiler-backend-rs/src/index.js +8 -0
  118. package/dist/packages/compiler-backend-rs/src/index.js.map +1 -0
  119. package/dist/packages/compiler-backend-rs/src/rustAmbientMemberBinding.d.ts +3 -0
  120. package/dist/packages/compiler-backend-rs/src/rustAmbientMemberBinding.d.ts.map +1 -0
  121. package/dist/packages/compiler-backend-rs/src/rustAmbientMemberBinding.js +99 -0
  122. package/dist/packages/compiler-backend-rs/src/rustAmbientMemberBinding.js.map +1 -0
  123. package/dist/packages/compiler-backend-rs/src/rustCompilerBackend.d.ts +5 -0
  124. package/dist/packages/compiler-backend-rs/src/rustCompilerBackend.d.ts.map +1 -0
  125. package/dist/packages/compiler-backend-rs/src/rustCompilerBackend.js +4555 -0
  126. package/dist/packages/compiler-backend-rs/src/rustCompilerBackend.js.map +1 -0
  127. package/dist/packages/compiler-backend-rs/src/rustCompilerEmittedSourceSyntax.d.ts +3 -0
  128. package/dist/packages/compiler-backend-rs/src/rustCompilerEmittedSourceSyntax.d.ts.map +1 -0
  129. package/dist/packages/compiler-backend-rs/src/rustCompilerEmittedSourceSyntax.js +8 -0
  130. package/dist/packages/compiler-backend-rs/src/rustCompilerEmittedSourceSyntax.js.map +1 -0
  131. package/dist/packages/compiler-backend-rs/src/rustCompilerIdentity.d.ts +4 -0
  132. package/dist/packages/compiler-backend-rs/src/rustCompilerIdentity.d.ts.map +1 -0
  133. package/dist/packages/compiler-backend-rs/src/rustCompilerIdentity.js +113 -0
  134. package/dist/packages/compiler-backend-rs/src/rustCompilerIdentity.js.map +1 -0
  135. package/dist/packages/compiler-backend-rs/src/rustCompilerTargetCompilationSmoke.d.ts +3 -0
  136. package/dist/packages/compiler-backend-rs/src/rustCompilerTargetCompilationSmoke.d.ts.map +1 -0
  137. package/dist/packages/compiler-backend-rs/src/rustCompilerTargetCompilationSmoke.js +8 -0
  138. package/dist/packages/compiler-backend-rs/src/rustCompilerTargetCompilationSmoke.js.map +1 -0
  139. package/dist/packages/compiler-backend-rs/src/rustOwnershipEvidence.d.ts +5 -0
  140. package/dist/packages/compiler-backend-rs/src/rustOwnershipEvidence.d.ts.map +1 -0
  141. package/dist/packages/compiler-backend-rs/src/rustOwnershipEvidence.js +345 -0
  142. package/dist/packages/compiler-backend-rs/src/rustOwnershipEvidence.js.map +1 -0
  143. package/dist/packages/compiler-backend-rs/src/rustRuntimeExternalConstructorAbi.d.ts +3 -0
  144. package/dist/packages/compiler-backend-rs/src/rustRuntimeExternalConstructorAbi.d.ts.map +1 -0
  145. package/dist/packages/compiler-backend-rs/src/rustRuntimeExternalConstructorAbi.js +38 -0
  146. package/dist/packages/compiler-backend-rs/src/rustRuntimeExternalConstructorAbi.js.map +1 -0
  147. package/dist/packages/compiler-backend-rs/src/rustRuntimeExternalSymbolBinding.d.ts +6 -0
  148. package/dist/packages/compiler-backend-rs/src/rustRuntimeExternalSymbolBinding.d.ts.map +1 -0
  149. package/dist/packages/compiler-backend-rs/src/rustRuntimeExternalSymbolBinding.js +301 -0
  150. package/dist/packages/compiler-backend-rs/src/rustRuntimeExternalSymbolBinding.js.map +1 -0
  151. package/dist/packages/compiler-canonical-form/src/compilerPortablePath.d.ts +2 -0
  152. package/dist/packages/compiler-canonical-form/src/compilerPortablePath.d.ts.map +1 -0
  153. package/dist/packages/compiler-canonical-form/src/compilerPortablePath.js +4 -0
  154. package/dist/packages/compiler-canonical-form/src/compilerPortablePath.js.map +1 -0
  155. package/dist/packages/compiler-canonical-form/src/compilerStructuralValue.d.ts +2 -0
  156. package/dist/packages/compiler-canonical-form/src/compilerStructuralValue.d.ts.map +1 -0
  157. package/dist/packages/compiler-canonical-form/src/compilerStructuralValue.js +63 -0
  158. package/dist/packages/compiler-canonical-form/src/compilerStructuralValue.js.map +1 -0
  159. package/dist/packages/compiler-canonical-form/src/compilerTextOrder.d.ts +2 -0
  160. package/dist/packages/compiler-canonical-form/src/compilerTextOrder.d.ts.map +1 -0
  161. package/dist/packages/compiler-canonical-form/src/compilerTextOrder.js +4 -0
  162. package/dist/packages/compiler-canonical-form/src/compilerTextOrder.js.map +1 -0
  163. package/dist/packages/compiler-canonical-form/src/index.d.ts +4 -0
  164. package/dist/packages/compiler-canonical-form/src/index.d.ts.map +1 -0
  165. package/dist/packages/compiler-canonical-form/src/index.js +4 -0
  166. package/dist/packages/compiler-canonical-form/src/index.js.map +1 -0
  167. package/dist/packages/compiler-check/src/compilerPackageCheck.d.ts +9 -0
  168. package/dist/packages/compiler-check/src/compilerPackageCheck.d.ts.map +1 -0
  169. package/dist/packages/compiler-check/src/compilerPackageCheck.js +417 -0
  170. package/dist/packages/compiler-check/src/compilerPackageCheck.js.map +1 -0
  171. package/dist/packages/compiler-check/src/index.d.ts +2 -0
  172. package/dist/packages/compiler-check/src/index.d.ts.map +1 -0
  173. package/dist/packages/compiler-check/src/index.js +2 -0
  174. package/dist/packages/compiler-check/src/index.js.map +1 -0
  175. package/dist/packages/compiler-closure/src/compilerClosureEvidence.d.ts +3 -0
  176. package/dist/packages/compiler-closure/src/compilerClosureEvidence.d.ts.map +1 -0
  177. package/dist/packages/compiler-closure/src/compilerClosureEvidence.js +469 -0
  178. package/dist/packages/compiler-closure/src/compilerClosureEvidence.js.map +1 -0
  179. package/dist/packages/compiler-closure/src/index.d.ts +2 -0
  180. package/dist/packages/compiler-closure/src/index.d.ts.map +1 -0
  181. package/dist/packages/compiler-closure/src/index.js +2 -0
  182. package/dist/packages/compiler-closure/src/index.js.map +1 -0
  183. package/dist/packages/compiler-command-line/src/compilerCommandLine.d.ts +12 -0
  184. package/dist/packages/compiler-command-line/src/compilerCommandLine.d.ts.map +1 -0
  185. package/dist/packages/compiler-command-line/src/compilerCommandLine.js +549 -0
  186. package/dist/packages/compiler-command-line/src/compilerCommandLine.js.map +1 -0
  187. package/dist/packages/compiler-command-line/src/compilerCommandLineEntryPoint.d.ts +5 -0
  188. package/dist/packages/compiler-command-line/src/compilerCommandLineEntryPoint.d.ts.map +1 -0
  189. package/dist/packages/compiler-command-line/src/compilerCommandLineEntryPoint.js +134 -0
  190. package/dist/packages/compiler-command-line/src/compilerCommandLineEntryPoint.js.map +1 -0
  191. package/dist/packages/compiler-command-line/src/index.d.ts +3 -0
  192. package/dist/packages/compiler-command-line/src/index.d.ts.map +1 -0
  193. package/dist/packages/compiler-command-line/src/index.js +3 -0
  194. package/dist/packages/compiler-command-line/src/index.js.map +1 -0
  195. package/dist/packages/compiler-completion/src/compilerAsyncTaskCompletion.d.ts +6 -0
  196. package/dist/packages/compiler-completion/src/compilerAsyncTaskCompletion.d.ts.map +1 -0
  197. package/dist/packages/compiler-completion/src/compilerAsyncTaskCompletion.js +89 -0
  198. package/dist/packages/compiler-completion/src/compilerAsyncTaskCompletion.js.map +1 -0
  199. package/dist/packages/compiler-completion/src/compilerCatchCompletion.d.ts +6 -0
  200. package/dist/packages/compiler-completion/src/compilerCatchCompletion.d.ts.map +1 -0
  201. package/dist/packages/compiler-completion/src/compilerCatchCompletion.js +77 -0
  202. package/dist/packages/compiler-completion/src/compilerCatchCompletion.js.map +1 -0
  203. package/dist/packages/compiler-completion/src/compilerCompletionSet.d.ts +6 -0
  204. package/dist/packages/compiler-completion/src/compilerCompletionSet.d.ts.map +1 -0
  205. package/dist/packages/compiler-completion/src/compilerCompletionSet.js +110 -0
  206. package/dist/packages/compiler-completion/src/compilerCompletionSet.js.map +1 -0
  207. package/dist/packages/compiler-completion/src/compilerFinallyCompletion.d.ts +3 -0
  208. package/dist/packages/compiler-completion/src/compilerFinallyCompletion.d.ts.map +1 -0
  209. package/dist/packages/compiler-completion/src/compilerFinallyCompletion.js +13 -0
  210. package/dist/packages/compiler-completion/src/compilerFinallyCompletion.js.map +1 -0
  211. package/dist/packages/compiler-completion/src/compilerStatementCompletion.d.ts +4 -0
  212. package/dist/packages/compiler-completion/src/compilerStatementCompletion.d.ts.map +1 -0
  213. package/dist/packages/compiler-completion/src/compilerStatementCompletion.js +181 -0
  214. package/dist/packages/compiler-completion/src/compilerStatementCompletion.js.map +1 -0
  215. package/dist/packages/compiler-completion/src/compilerStatementValueCompletion.d.ts +5 -0
  216. package/dist/packages/compiler-completion/src/compilerStatementValueCompletion.d.ts.map +1 -0
  217. package/dist/packages/compiler-completion/src/compilerStatementValueCompletion.js +41 -0
  218. package/dist/packages/compiler-completion/src/compilerStatementValueCompletion.js.map +1 -0
  219. package/dist/packages/compiler-completion/src/compilerValueCompletion.d.ts +8 -0
  220. package/dist/packages/compiler-completion/src/compilerValueCompletion.d.ts.map +1 -0
  221. package/dist/packages/compiler-completion/src/compilerValueCompletion.js +208 -0
  222. package/dist/packages/compiler-completion/src/compilerValueCompletion.js.map +1 -0
  223. package/dist/packages/compiler-completion/src/index.d.ts +8 -0
  224. package/dist/packages/compiler-completion/src/index.d.ts.map +1 -0
  225. package/dist/packages/compiler-completion/src/index.js +8 -0
  226. package/dist/packages/compiler-completion/src/index.js.map +1 -0
  227. package/dist/packages/compiler-emission/src/compilerEmittedSourceSyntax.d.ts +4 -0
  228. package/dist/packages/compiler-emission/src/compilerEmittedSourceSyntax.d.ts.map +1 -0
  229. package/dist/packages/compiler-emission/src/compilerEmittedSourceSyntax.js +122 -0
  230. package/dist/packages/compiler-emission/src/compilerEmittedSourceSyntax.js.map +1 -0
  231. package/dist/packages/compiler-emission/src/compilerGeneratedFileProvenance.d.ts +3 -0
  232. package/dist/packages/compiler-emission/src/compilerGeneratedFileProvenance.d.ts.map +1 -0
  233. package/dist/packages/compiler-emission/src/compilerGeneratedFileProvenance.js +17 -0
  234. package/dist/packages/compiler-emission/src/compilerGeneratedFileProvenance.js.map +1 -0
  235. package/dist/packages/compiler-emission/src/compilerLiteralUnion.d.ts +3 -0
  236. package/dist/packages/compiler-emission/src/compilerLiteralUnion.d.ts.map +1 -0
  237. package/dist/packages/compiler-emission/src/compilerLiteralUnion.js +20 -0
  238. package/dist/packages/compiler-emission/src/compilerLiteralUnion.js.map +1 -0
  239. package/dist/packages/compiler-emission/src/compilerNullableFlowGuard.d.ts +4 -0
  240. package/dist/packages/compiler-emission/src/compilerNullableFlowGuard.d.ts.map +1 -0
  241. package/dist/packages/compiler-emission/src/compilerNullableFlowGuard.js +32 -0
  242. package/dist/packages/compiler-emission/src/compilerNullableFlowGuard.js.map +1 -0
  243. package/dist/packages/compiler-emission/src/compilerSourceEmission.d.ts +16 -0
  244. package/dist/packages/compiler-emission/src/compilerSourceEmission.d.ts.map +1 -0
  245. package/dist/packages/compiler-emission/src/compilerSourceEmission.js +176 -0
  246. package/dist/packages/compiler-emission/src/compilerSourceEmission.js.map +1 -0
  247. package/dist/packages/compiler-emission/src/compilerTargetCompilationSmoke.d.ts +4 -0
  248. package/dist/packages/compiler-emission/src/compilerTargetCompilationSmoke.d.ts.map +1 -0
  249. package/dist/packages/compiler-emission/src/compilerTargetCompilationSmoke.js +114 -0
  250. package/dist/packages/compiler-emission/src/compilerTargetCompilationSmoke.js.map +1 -0
  251. package/dist/packages/compiler-emission/src/compilerTargetNameAllocation.d.ts +5 -0
  252. package/dist/packages/compiler-emission/src/compilerTargetNameAllocation.d.ts.map +1 -0
  253. package/dist/packages/compiler-emission/src/compilerTargetNameAllocation.js +449 -0
  254. package/dist/packages/compiler-emission/src/compilerTargetNameAllocation.js.map +1 -0
  255. package/dist/packages/compiler-emission/src/index.d.ts +8 -0
  256. package/dist/packages/compiler-emission/src/index.d.ts.map +1 -0
  257. package/dist/packages/compiler-emission/src/index.js +8 -0
  258. package/dist/packages/compiler-emission/src/index.js.map +1 -0
  259. package/dist/packages/compiler-inventory/src/compilerInventoryFailure.d.ts +4 -0
  260. package/dist/packages/compiler-inventory/src/compilerInventoryFailure.d.ts.map +1 -0
  261. package/dist/packages/compiler-inventory/src/compilerInventoryFailure.js +42 -0
  262. package/dist/packages/compiler-inventory/src/compilerInventoryFailure.js.map +1 -0
  263. package/dist/packages/compiler-inventory/src/compilerModuleResolution.d.ts +4 -0
  264. package/dist/packages/compiler-inventory/src/compilerModuleResolution.d.ts.map +1 -0
  265. package/dist/packages/compiler-inventory/src/compilerModuleResolution.js +74 -0
  266. package/dist/packages/compiler-inventory/src/compilerModuleResolution.js.map +1 -0
  267. package/dist/packages/compiler-inventory/src/fileSystemWorkspaceSource.d.ts +3 -0
  268. package/dist/packages/compiler-inventory/src/fileSystemWorkspaceSource.d.ts.map +1 -0
  269. package/dist/packages/compiler-inventory/src/fileSystemWorkspaceSource.js +20 -0
  270. package/dist/packages/compiler-inventory/src/fileSystemWorkspaceSource.js.map +1 -0
  271. package/dist/packages/compiler-inventory/src/flightPackageEligibility.d.ts +5 -0
  272. package/dist/packages/compiler-inventory/src/flightPackageEligibility.d.ts.map +1 -0
  273. package/dist/packages/compiler-inventory/src/flightPackageEligibility.js +174 -0
  274. package/dist/packages/compiler-inventory/src/flightPackageEligibility.js.map +1 -0
  275. package/dist/packages/compiler-inventory/src/flightPackageExclusion.d.ts +3 -0
  276. package/dist/packages/compiler-inventory/src/flightPackageExclusion.d.ts.map +1 -0
  277. package/dist/packages/compiler-inventory/src/flightPackageExclusion.js +79 -0
  278. package/dist/packages/compiler-inventory/src/flightPackageExclusion.js.map +1 -0
  279. package/dist/packages/compiler-inventory/src/flightPackageExportLane.d.ts +4 -0
  280. package/dist/packages/compiler-inventory/src/flightPackageExportLane.d.ts.map +1 -0
  281. package/dist/packages/compiler-inventory/src/flightPackageExportLane.js +30 -0
  282. package/dist/packages/compiler-inventory/src/flightPackageExportLane.js.map +1 -0
  283. package/dist/packages/compiler-inventory/src/flightPackageExportManifest.d.ts +3 -0
  284. package/dist/packages/compiler-inventory/src/flightPackageExportManifest.d.ts.map +1 -0
  285. package/dist/packages/compiler-inventory/src/flightPackageExportManifest.js +90 -0
  286. package/dist/packages/compiler-inventory/src/flightPackageExportManifest.js.map +1 -0
  287. package/dist/packages/compiler-inventory/src/flightPackageHostFacts.d.ts +3 -0
  288. package/dist/packages/compiler-inventory/src/flightPackageHostFacts.d.ts.map +1 -0
  289. package/dist/packages/compiler-inventory/src/flightPackageHostFacts.js +33 -0
  290. package/dist/packages/compiler-inventory/src/flightPackageHostFacts.js.map +1 -0
  291. package/dist/packages/compiler-inventory/src/flightPackageImport.d.ts +3 -0
  292. package/dist/packages/compiler-inventory/src/flightPackageImport.d.ts.map +1 -0
  293. package/dist/packages/compiler-inventory/src/flightPackageImport.js +82 -0
  294. package/dist/packages/compiler-inventory/src/flightPackageImport.js.map +1 -0
  295. package/dist/packages/compiler-inventory/src/flightPackageManifest.d.ts +3 -0
  296. package/dist/packages/compiler-inventory/src/flightPackageManifest.d.ts.map +1 -0
  297. package/dist/packages/compiler-inventory/src/flightPackageManifest.js +116 -0
  298. package/dist/packages/compiler-inventory/src/flightPackageManifest.js.map +1 -0
  299. package/dist/packages/compiler-inventory/src/flightWorkspaceCompilationInput.d.ts +4 -0
  300. package/dist/packages/compiler-inventory/src/flightWorkspaceCompilationInput.d.ts.map +1 -0
  301. package/dist/packages/compiler-inventory/src/flightWorkspaceCompilationInput.js +315 -0
  302. package/dist/packages/compiler-inventory/src/flightWorkspaceCompilationInput.js.map +1 -0
  303. package/dist/packages/compiler-inventory/src/flightWorkspaceInventory.d.ts +3 -0
  304. package/dist/packages/compiler-inventory/src/flightWorkspaceInventory.d.ts.map +1 -0
  305. package/dist/packages/compiler-inventory/src/flightWorkspaceInventory.js +591 -0
  306. package/dist/packages/compiler-inventory/src/flightWorkspaceInventory.js.map +1 -0
  307. package/dist/packages/compiler-inventory/src/gitCheckoutRevision.d.ts +2 -0
  308. package/dist/packages/compiler-inventory/src/gitCheckoutRevision.d.ts.map +1 -0
  309. package/dist/packages/compiler-inventory/src/gitCheckoutRevision.js +20 -0
  310. package/dist/packages/compiler-inventory/src/gitCheckoutRevision.js.map +1 -0
  311. package/dist/packages/compiler-inventory/src/index.d.ts +17 -0
  312. package/dist/packages/compiler-inventory/src/index.d.ts.map +1 -0
  313. package/dist/packages/compiler-inventory/src/index.js +17 -0
  314. package/dist/packages/compiler-inventory/src/index.js.map +1 -0
  315. package/dist/packages/compiler-inventory/src/memoryWorkspaceSource.d.ts +3 -0
  316. package/dist/packages/compiler-inventory/src/memoryWorkspaceSource.d.ts.map +1 -0
  317. package/dist/packages/compiler-inventory/src/memoryWorkspaceSource.js +61 -0
  318. package/dist/packages/compiler-inventory/src/memoryWorkspaceSource.js.map +1 -0
  319. package/dist/packages/compiler-inventory/src/typeScriptHostEndpointInventory.d.ts +3 -0
  320. package/dist/packages/compiler-inventory/src/typeScriptHostEndpointInventory.d.ts.map +1 -0
  321. package/dist/packages/compiler-inventory/src/typeScriptHostEndpointInventory.js +138 -0
  322. package/dist/packages/compiler-inventory/src/typeScriptHostEndpointInventory.js.map +1 -0
  323. package/dist/packages/compiler-inventory/src/typeScriptProject.d.ts +3 -0
  324. package/dist/packages/compiler-inventory/src/typeScriptProject.d.ts.map +1 -0
  325. package/dist/packages/compiler-inventory/src/typeScriptProject.js +28 -0
  326. package/dist/packages/compiler-inventory/src/typeScriptProject.js.map +1 -0
  327. package/dist/packages/compiler-inventory/src/typeScriptRuntimeBinding.d.ts +7 -0
  328. package/dist/packages/compiler-inventory/src/typeScriptRuntimeBinding.d.ts.map +1 -0
  329. package/dist/packages/compiler-inventory/src/typeScriptRuntimeBinding.js +67 -0
  330. package/dist/packages/compiler-inventory/src/typeScriptRuntimeBinding.js.map +1 -0
  331. package/dist/packages/compiler-ir-traversal/src/compilerIntermediateRepresentationTraversal.d.ts +5 -0
  332. package/dist/packages/compiler-ir-traversal/src/compilerIntermediateRepresentationTraversal.d.ts.map +1 -0
  333. package/dist/packages/compiler-ir-traversal/src/compilerIntermediateRepresentationTraversal.js +469 -0
  334. package/dist/packages/compiler-ir-traversal/src/compilerIntermediateRepresentationTraversal.js.map +1 -0
  335. package/dist/packages/compiler-ir-traversal/src/compilerIntermediateRepresentationTraversalPath.d.ts +3 -0
  336. package/dist/packages/compiler-ir-traversal/src/compilerIntermediateRepresentationTraversalPath.d.ts.map +1 -0
  337. package/dist/packages/compiler-ir-traversal/src/compilerIntermediateRepresentationTraversalPath.js +14 -0
  338. package/dist/packages/compiler-ir-traversal/src/compilerIntermediateRepresentationTraversalPath.js.map +1 -0
  339. package/dist/packages/compiler-ir-traversal/src/index.d.ts +3 -0
  340. package/dist/packages/compiler-ir-traversal/src/index.d.ts.map +1 -0
  341. package/dist/packages/compiler-ir-traversal/src/index.js +3 -0
  342. package/dist/packages/compiler-ir-traversal/src/index.js.map +1 -0
  343. package/dist/packages/compiler-ir-validation/src/compilerIrModuleStructure.d.ts +3 -0
  344. package/dist/packages/compiler-ir-validation/src/compilerIrModuleStructure.d.ts.map +1 -0
  345. package/dist/packages/compiler-ir-validation/src/compilerIrModuleStructure.js +1258 -0
  346. package/dist/packages/compiler-ir-validation/src/compilerIrModuleStructure.js.map +1 -0
  347. package/dist/packages/compiler-ir-validation/src/index.d.ts +2 -0
  348. package/dist/packages/compiler-ir-validation/src/index.d.ts.map +1 -0
  349. package/dist/packages/compiler-ir-validation/src/index.js +2 -0
  350. package/dist/packages/compiler-ir-validation/src/index.js.map +1 -0
  351. package/dist/packages/compiler-lowering/src/compilerArrayBindingPatternLowering.d.ts +3 -0
  352. package/dist/packages/compiler-lowering/src/compilerArrayBindingPatternLowering.d.ts.map +1 -0
  353. package/dist/packages/compiler-lowering/src/compilerArrayBindingPatternLowering.js +717 -0
  354. package/dist/packages/compiler-lowering/src/compilerArrayBindingPatternLowering.js.map +1 -0
  355. package/dist/packages/compiler-lowering/src/compilerArrayBindingPatternPresence.d.ts +3 -0
  356. package/dist/packages/compiler-lowering/src/compilerArrayBindingPatternPresence.d.ts.map +1 -0
  357. package/dist/packages/compiler-lowering/src/compilerArrayBindingPatternPresence.js +162 -0
  358. package/dist/packages/compiler-lowering/src/compilerArrayBindingPatternPresence.js.map +1 -0
  359. package/dist/packages/compiler-lowering/src/compilerAwaitConditionHoistingLowering.d.ts +3 -0
  360. package/dist/packages/compiler-lowering/src/compilerAwaitConditionHoistingLowering.d.ts.map +1 -0
  361. package/dist/packages/compiler-lowering/src/compilerAwaitConditionHoistingLowering.js +721 -0
  362. package/dist/packages/compiler-lowering/src/compilerAwaitConditionHoistingLowering.js.map +1 -0
  363. package/dist/packages/compiler-lowering/src/compilerBindingPatternLowering.d.ts +4 -0
  364. package/dist/packages/compiler-lowering/src/compilerBindingPatternLowering.d.ts.map +1 -0
  365. package/dist/packages/compiler-lowering/src/compilerBindingPatternLowering.js +43 -0
  366. package/dist/packages/compiler-lowering/src/compilerBindingPatternLowering.js.map +1 -0
  367. package/dist/packages/compiler-lowering/src/compilerCStyleForLowering.d.ts +3 -0
  368. package/dist/packages/compiler-lowering/src/compilerCStyleForLowering.d.ts.map +1 -0
  369. package/dist/packages/compiler-lowering/src/compilerCStyleForLowering.js +591 -0
  370. package/dist/packages/compiler-lowering/src/compilerCStyleForLowering.js.map +1 -0
  371. package/dist/packages/compiler-lowering/src/compilerCatchAwaitHoistingLowering.d.ts +3 -0
  372. package/dist/packages/compiler-lowering/src/compilerCatchAwaitHoistingLowering.d.ts.map +1 -0
  373. package/dist/packages/compiler-lowering/src/compilerCatchAwaitHoistingLowering.js +244 -0
  374. package/dist/packages/compiler-lowering/src/compilerCatchAwaitHoistingLowering.js.map +1 -0
  375. package/dist/packages/compiler-lowering/src/compilerClassInitialization.d.ts +4 -0
  376. package/dist/packages/compiler-lowering/src/compilerClassInitialization.d.ts.map +1 -0
  377. package/dist/packages/compiler-lowering/src/compilerClassInitialization.js +102 -0
  378. package/dist/packages/compiler-lowering/src/compilerClassInitialization.js.map +1 -0
  379. package/dist/packages/compiler-lowering/src/compilerExtraArgumentErasureLowering.d.ts +3 -0
  380. package/dist/packages/compiler-lowering/src/compilerExtraArgumentErasureLowering.d.ts.map +1 -0
  381. package/dist/packages/compiler-lowering/src/compilerExtraArgumentErasureLowering.js +156 -0
  382. package/dist/packages/compiler-lowering/src/compilerExtraArgumentErasureLowering.js.map +1 -0
  383. package/dist/packages/compiler-lowering/src/compilerFinallyAwaitHoistingLowering.d.ts +3 -0
  384. package/dist/packages/compiler-lowering/src/compilerFinallyAwaitHoistingLowering.d.ts.map +1 -0
  385. package/dist/packages/compiler-lowering/src/compilerFinallyAwaitHoistingLowering.js +255 -0
  386. package/dist/packages/compiler-lowering/src/compilerFinallyAwaitHoistingLowering.js.map +1 -0
  387. package/dist/packages/compiler-lowering/src/compilerInterfaceInheritanceLowering.d.ts +3 -0
  388. package/dist/packages/compiler-lowering/src/compilerInterfaceInheritanceLowering.d.ts.map +1 -0
  389. package/dist/packages/compiler-lowering/src/compilerInterfaceInheritanceLowering.js +1062 -0
  390. package/dist/packages/compiler-lowering/src/compilerInterfaceInheritanceLowering.js.map +1 -0
  391. package/dist/packages/compiler-lowering/src/compilerLoweringPass.d.ts +5 -0
  392. package/dist/packages/compiler-lowering/src/compilerLoweringPass.d.ts.map +1 -0
  393. package/dist/packages/compiler-lowering/src/compilerLoweringPass.js +133 -0
  394. package/dist/packages/compiler-lowering/src/compilerLoweringPass.js.map +1 -0
  395. package/dist/packages/compiler-lowering/src/compilerObjectBindingPatternLowering.d.ts +3 -0
  396. package/dist/packages/compiler-lowering/src/compilerObjectBindingPatternLowering.d.ts.map +1 -0
  397. package/dist/packages/compiler-lowering/src/compilerObjectBindingPatternLowering.js +589 -0
  398. package/dist/packages/compiler-lowering/src/compilerObjectBindingPatternLowering.js.map +1 -0
  399. package/dist/packages/compiler-lowering/src/compilerSwitchClauseCompletion.d.ts +3 -0
  400. package/dist/packages/compiler-lowering/src/compilerSwitchClauseCompletion.d.ts.map +1 -0
  401. package/dist/packages/compiler-lowering/src/compilerSwitchClauseCompletion.js +71 -0
  402. package/dist/packages/compiler-lowering/src/compilerSwitchClauseCompletion.js.map +1 -0
  403. package/dist/packages/compiler-lowering/src/compilerSwitchFallthroughLowering.d.ts +3 -0
  404. package/dist/packages/compiler-lowering/src/compilerSwitchFallthroughLowering.d.ts.map +1 -0
  405. package/dist/packages/compiler-lowering/src/compilerSwitchFallthroughLowering.js +810 -0
  406. package/dist/packages/compiler-lowering/src/compilerSwitchFallthroughLowering.js.map +1 -0
  407. package/dist/packages/compiler-lowering/src/compilerSwitchSuspensionLowering.d.ts +3 -0
  408. package/dist/packages/compiler-lowering/src/compilerSwitchSuspensionLowering.d.ts.map +1 -0
  409. package/dist/packages/compiler-lowering/src/compilerSwitchSuspensionLowering.js +226 -0
  410. package/dist/packages/compiler-lowering/src/compilerSwitchSuspensionLowering.js.map +1 -0
  411. package/dist/packages/compiler-lowering/src/compilerVariableHoistingInitialization.d.ts +3 -0
  412. package/dist/packages/compiler-lowering/src/compilerVariableHoistingInitialization.d.ts.map +1 -0
  413. package/dist/packages/compiler-lowering/src/compilerVariableHoistingInitialization.js +724 -0
  414. package/dist/packages/compiler-lowering/src/compilerVariableHoistingInitialization.js.map +1 -0
  415. package/dist/packages/compiler-lowering/src/compilerVariableHoistingLowering.d.ts +3 -0
  416. package/dist/packages/compiler-lowering/src/compilerVariableHoistingLowering.d.ts.map +1 -0
  417. package/dist/packages/compiler-lowering/src/compilerVariableHoistingLowering.js +797 -0
  418. package/dist/packages/compiler-lowering/src/compilerVariableHoistingLowering.js.map +1 -0
  419. package/dist/packages/compiler-lowering/src/compilerVariableInitializationCompletion.d.ts +9 -0
  420. package/dist/packages/compiler-lowering/src/compilerVariableInitializationCompletion.d.ts.map +1 -0
  421. package/dist/packages/compiler-lowering/src/compilerVariableInitializationCompletion.js +42 -0
  422. package/dist/packages/compiler-lowering/src/compilerVariableInitializationCompletion.js.map +1 -0
  423. package/dist/packages/compiler-lowering/src/index.d.ts +17 -0
  424. package/dist/packages/compiler-lowering/src/index.d.ts.map +1 -0
  425. package/dist/packages/compiler-lowering/src/index.js +17 -0
  426. package/dist/packages/compiler-lowering/src/index.js.map +1 -0
  427. package/dist/packages/compiler-module/src/compilerModuleEvaluation.d.ts +4 -0
  428. package/dist/packages/compiler-module/src/compilerModuleEvaluation.d.ts.map +1 -0
  429. package/dist/packages/compiler-module/src/compilerModuleEvaluation.js +506 -0
  430. package/dist/packages/compiler-module/src/compilerModuleEvaluation.js.map +1 -0
  431. package/dist/packages/compiler-module/src/compilerModuleFacadeIdentity.d.ts +4 -0
  432. package/dist/packages/compiler-module/src/compilerModuleFacadeIdentity.d.ts.map +1 -0
  433. package/dist/packages/compiler-module/src/compilerModuleFacadeIdentity.js +182 -0
  434. package/dist/packages/compiler-module/src/compilerModuleFacadeIdentity.js.map +1 -0
  435. package/dist/packages/compiler-module/src/compilerModuleFacadeLowering.d.ts +4 -0
  436. package/dist/packages/compiler-module/src/compilerModuleFacadeLowering.d.ts.map +1 -0
  437. package/dist/packages/compiler-module/src/compilerModuleFacadeLowering.js +466 -0
  438. package/dist/packages/compiler-module/src/compilerModuleFacadeLowering.js.map +1 -0
  439. package/dist/packages/compiler-module/src/compilerModuleFacadeRequirement.d.ts +3 -0
  440. package/dist/packages/compiler-module/src/compilerModuleFacadeRequirement.d.ts.map +1 -0
  441. package/dist/packages/compiler-module/src/compilerModuleFacadeRequirement.js +28 -0
  442. package/dist/packages/compiler-module/src/compilerModuleFacadeRequirement.js.map +1 -0
  443. package/dist/packages/compiler-module/src/index.d.ts +5 -0
  444. package/dist/packages/compiler-module/src/index.d.ts.map +1 -0
  445. package/dist/packages/compiler-module/src/index.js +5 -0
  446. package/dist/packages/compiler-module/src/index.js.map +1 -0
  447. package/dist/packages/compiler-orchestration/src/compilerOrchestration.d.ts +8 -0
  448. package/dist/packages/compiler-orchestration/src/compilerOrchestration.d.ts.map +1 -0
  449. package/dist/packages/compiler-orchestration/src/compilerOrchestration.js +161 -0
  450. package/dist/packages/compiler-orchestration/src/compilerOrchestration.js.map +1 -0
  451. package/dist/packages/compiler-orchestration/src/compilerPackageCompilation.d.ts +4 -0
  452. package/dist/packages/compiler-orchestration/src/compilerPackageCompilation.d.ts.map +1 -0
  453. package/dist/packages/compiler-orchestration/src/compilerPackageCompilation.js +745 -0
  454. package/dist/packages/compiler-orchestration/src/compilerPackageCompilation.js.map +1 -0
  455. package/dist/packages/compiler-orchestration/src/flightWorkspaceCompilation.d.ts +3 -0
  456. package/dist/packages/compiler-orchestration/src/flightWorkspaceCompilation.d.ts.map +1 -0
  457. package/dist/packages/compiler-orchestration/src/flightWorkspaceCompilation.js +14 -0
  458. package/dist/packages/compiler-orchestration/src/flightWorkspaceCompilation.js.map +1 -0
  459. package/dist/packages/compiler-orchestration/src/index.d.ts +4 -0
  460. package/dist/packages/compiler-orchestration/src/index.d.ts.map +1 -0
  461. package/dist/packages/compiler-orchestration/src/index.js +4 -0
  462. package/dist/packages/compiler-orchestration/src/index.js.map +1 -0
  463. package/dist/packages/compiler-patch/src/compilerSemanticPatch.d.ts +6 -0
  464. package/dist/packages/compiler-patch/src/compilerSemanticPatch.d.ts.map +1 -0
  465. package/dist/packages/compiler-patch/src/compilerSemanticPatch.js +316 -0
  466. package/dist/packages/compiler-patch/src/compilerSemanticPatch.js.map +1 -0
  467. package/dist/packages/compiler-patch/src/index.d.ts +2 -0
  468. package/dist/packages/compiler-patch/src/index.d.ts.map +1 -0
  469. package/dist/packages/compiler-patch/src/index.js +2 -0
  470. package/dist/packages/compiler-patch/src/index.js.map +1 -0
  471. package/dist/packages/compiler-provenance/src/index.d.ts +2 -0
  472. package/dist/packages/compiler-provenance/src/index.d.ts.map +1 -0
  473. package/dist/packages/compiler-provenance/src/index.js +2 -0
  474. package/dist/packages/compiler-provenance/src/index.js.map +1 -0
  475. package/dist/packages/compiler-provenance/src/sourceFingerprint.d.ts +7 -0
  476. package/dist/packages/compiler-provenance/src/sourceFingerprint.d.ts.map +1 -0
  477. package/dist/packages/compiler-provenance/src/sourceFingerprint.js +58 -0
  478. package/dist/packages/compiler-provenance/src/sourceFingerprint.js.map +1 -0
  479. package/dist/packages/compiler-runtime-contract/src/compilerRuntimeExternalConstructorAbiCompleteness.d.ts +4 -0
  480. package/dist/packages/compiler-runtime-contract/src/compilerRuntimeExternalConstructorAbiCompleteness.d.ts.map +1 -0
  481. package/dist/packages/compiler-runtime-contract/src/compilerRuntimeExternalConstructorAbiCompleteness.js +110 -0
  482. package/dist/packages/compiler-runtime-contract/src/compilerRuntimeExternalConstructorAbiCompleteness.js.map +1 -0
  483. package/dist/packages/compiler-runtime-contract/src/compilerRuntimeExternalConstructorReachability.d.ts +3 -0
  484. package/dist/packages/compiler-runtime-contract/src/compilerRuntimeExternalConstructorReachability.d.ts.map +1 -0
  485. package/dist/packages/compiler-runtime-contract/src/compilerRuntimeExternalConstructorReachability.js +42 -0
  486. package/dist/packages/compiler-runtime-contract/src/compilerRuntimeExternalConstructorReachability.js.map +1 -0
  487. package/dist/packages/compiler-runtime-contract/src/compilerRuntimeExternalSymbolCompleteness.d.ts +4 -0
  488. package/dist/packages/compiler-runtime-contract/src/compilerRuntimeExternalSymbolCompleteness.d.ts.map +1 -0
  489. package/dist/packages/compiler-runtime-contract/src/compilerRuntimeExternalSymbolCompleteness.js +64 -0
  490. package/dist/packages/compiler-runtime-contract/src/compilerRuntimeExternalSymbolCompleteness.js.map +1 -0
  491. package/dist/packages/compiler-runtime-contract/src/compilerRuntimeExternalSymbolReachability.d.ts +3 -0
  492. package/dist/packages/compiler-runtime-contract/src/compilerRuntimeExternalSymbolReachability.d.ts.map +1 -0
  493. package/dist/packages/compiler-runtime-contract/src/compilerRuntimeExternalSymbolReachability.js +89 -0
  494. package/dist/packages/compiler-runtime-contract/src/compilerRuntimeExternalSymbolReachability.js.map +1 -0
  495. package/dist/packages/compiler-runtime-contract/src/compilerRuntimeTaskCapability.d.ts +6 -0
  496. package/dist/packages/compiler-runtime-contract/src/compilerRuntimeTaskCapability.d.ts.map +1 -0
  497. package/dist/packages/compiler-runtime-contract/src/compilerRuntimeTaskCapability.js +247 -0
  498. package/dist/packages/compiler-runtime-contract/src/compilerRuntimeTaskCapability.js.map +1 -0
  499. package/dist/packages/compiler-runtime-contract/src/index.d.ts +6 -0
  500. package/dist/packages/compiler-runtime-contract/src/index.d.ts.map +1 -0
  501. package/dist/packages/compiler-runtime-contract/src/index.js +6 -0
  502. package/dist/packages/compiler-runtime-contract/src/index.js.map +1 -0
  503. package/dist/packages/compiler-semantic/src/compilerIrStaticFacts.d.ts +4 -0
  504. package/dist/packages/compiler-semantic/src/compilerIrStaticFacts.d.ts.map +1 -0
  505. package/dist/packages/compiler-semantic/src/compilerIrStaticFacts.js +396 -0
  506. package/dist/packages/compiler-semantic/src/compilerIrStaticFacts.js.map +1 -0
  507. package/dist/packages/compiler-semantic/src/compilerIrTypeMemberEvidence.d.ts +4 -0
  508. package/dist/packages/compiler-semantic/src/compilerIrTypeMemberEvidence.d.ts.map +1 -0
  509. package/dist/packages/compiler-semantic/src/compilerIrTypeMemberEvidence.js +63 -0
  510. package/dist/packages/compiler-semantic/src/compilerIrTypeMemberEvidence.js.map +1 -0
  511. package/dist/packages/compiler-semantic/src/compilerOperatorDomainEvidence.d.ts +4 -0
  512. package/dist/packages/compiler-semantic/src/compilerOperatorDomainEvidence.d.ts.map +1 -0
  513. package/dist/packages/compiler-semantic/src/compilerOperatorDomainEvidence.js +76 -0
  514. package/dist/packages/compiler-semantic/src/compilerOperatorDomainEvidence.js.map +1 -0
  515. package/dist/packages/compiler-semantic/src/compilerStaticNumericArithmetic.d.ts +7 -0
  516. package/dist/packages/compiler-semantic/src/compilerStaticNumericArithmetic.d.ts.map +1 -0
  517. package/dist/packages/compiler-semantic/src/compilerStaticNumericArithmetic.js +107 -0
  518. package/dist/packages/compiler-semantic/src/compilerStaticNumericArithmetic.js.map +1 -0
  519. package/dist/packages/compiler-semantic/src/compilerTypeScriptForInKeyEvidence.d.ts +4 -0
  520. package/dist/packages/compiler-semantic/src/compilerTypeScriptForInKeyEvidence.d.ts.map +1 -0
  521. package/dist/packages/compiler-semantic/src/compilerTypeScriptForInKeyEvidence.js +159 -0
  522. package/dist/packages/compiler-semantic/src/compilerTypeScriptForInKeyEvidence.js.map +1 -0
  523. package/dist/packages/compiler-semantic/src/compilerTypeScriptInvocationSemantics.d.ts +4 -0
  524. package/dist/packages/compiler-semantic/src/compilerTypeScriptInvocationSemantics.d.ts.map +1 -0
  525. package/dist/packages/compiler-semantic/src/compilerTypeScriptInvocationSemantics.js +31 -0
  526. package/dist/packages/compiler-semantic/src/compilerTypeScriptInvocationSemantics.js.map +1 -0
  527. package/dist/packages/compiler-semantic/src/compilerTypeScriptSyntacticTypeEvidence.d.ts +8 -0
  528. package/dist/packages/compiler-semantic/src/compilerTypeScriptSyntacticTypeEvidence.d.ts.map +1 -0
  529. package/dist/packages/compiler-semantic/src/compilerTypeScriptSyntacticTypeEvidence.js +83 -0
  530. package/dist/packages/compiler-semantic/src/compilerTypeScriptSyntacticTypeEvidence.js.map +1 -0
  531. package/dist/packages/compiler-semantic/src/index.d.ts +4 -0
  532. package/dist/packages/compiler-semantic/src/index.d.ts.map +1 -0
  533. package/dist/packages/compiler-semantic/src/index.js +4 -0
  534. package/dist/packages/compiler-semantic/src/index.js.map +1 -0
  535. package/dist/packages/compiler-semantic/src/typeScriptSemanticLowering.d.ts +6 -0
  536. package/dist/packages/compiler-semantic/src/typeScriptSemanticLowering.d.ts.map +1 -0
  537. package/dist/packages/compiler-semantic/src/typeScriptSemanticLowering.js +8158 -0
  538. package/dist/packages/compiler-semantic/src/typeScriptSemanticLowering.js.map +1 -0
  539. package/dist/packages/compiler-structural/src/compilerStructuralObjectCompatibility.d.ts +5 -0
  540. package/dist/packages/compiler-structural/src/compilerStructuralObjectCompatibility.d.ts.map +1 -0
  541. package/dist/packages/compiler-structural/src/compilerStructuralObjectCompatibility.js +500 -0
  542. package/dist/packages/compiler-structural/src/compilerStructuralObjectCompatibility.js.map +1 -0
  543. package/dist/packages/compiler-structural/src/compilerStructuralObjectCopySemantics.d.ts +3 -0
  544. package/dist/packages/compiler-structural/src/compilerStructuralObjectCopySemantics.d.ts.map +1 -0
  545. package/dist/packages/compiler-structural/src/compilerStructuralObjectCopySemantics.js +11 -0
  546. package/dist/packages/compiler-structural/src/compilerStructuralObjectCopySemantics.js.map +1 -0
  547. package/dist/packages/compiler-structural/src/compilerStructuralTypeAssignability.d.ts +4 -0
  548. package/dist/packages/compiler-structural/src/compilerStructuralTypeAssignability.d.ts.map +1 -0
  549. package/dist/packages/compiler-structural/src/compilerStructuralTypeAssignability.js +261 -0
  550. package/dist/packages/compiler-structural/src/compilerStructuralTypeAssignability.js.map +1 -0
  551. package/dist/packages/compiler-structural/src/compilerStructuralTypeShapeIdentity.d.ts +4 -0
  552. package/dist/packages/compiler-structural/src/compilerStructuralTypeShapeIdentity.d.ts.map +1 -0
  553. package/dist/packages/compiler-structural/src/compilerStructuralTypeShapeIdentity.js +168 -0
  554. package/dist/packages/compiler-structural/src/compilerStructuralTypeShapeIdentity.js.map +1 -0
  555. package/dist/packages/compiler-structural/src/compilerStructuralTypeShapeInventory.d.ts +3 -0
  556. package/dist/packages/compiler-structural/src/compilerStructuralTypeShapeInventory.d.ts.map +1 -0
  557. package/dist/packages/compiler-structural/src/compilerStructuralTypeShapeInventory.js +50 -0
  558. package/dist/packages/compiler-structural/src/compilerStructuralTypeShapeInventory.js.map +1 -0
  559. package/dist/packages/compiler-structural/src/compilerStructuralTypeSubstitution.d.ts +5 -0
  560. package/dist/packages/compiler-structural/src/compilerStructuralTypeSubstitution.d.ts.map +1 -0
  561. package/dist/packages/compiler-structural/src/compilerStructuralTypeSubstitution.js +224 -0
  562. package/dist/packages/compiler-structural/src/compilerStructuralTypeSubstitution.js.map +1 -0
  563. package/dist/packages/compiler-structural/src/compilerTypeValueIdentityAnalysis.d.ts +4 -0
  564. package/dist/packages/compiler-structural/src/compilerTypeValueIdentityAnalysis.d.ts.map +1 -0
  565. package/dist/packages/compiler-structural/src/compilerTypeValueIdentityAnalysis.js +592 -0
  566. package/dist/packages/compiler-structural/src/compilerTypeValueIdentityAnalysis.js.map +1 -0
  567. package/dist/packages/compiler-structural/src/index.d.ts +8 -0
  568. package/dist/packages/compiler-structural/src/index.d.ts.map +1 -0
  569. package/dist/packages/compiler-structural/src/index.js +8 -0
  570. package/dist/packages/compiler-structural/src/index.js.map +1 -0
  571. package/dist/packages/compiler-task/src/compilerAsyncStateMachine.d.ts +3 -0
  572. package/dist/packages/compiler-task/src/compilerAsyncStateMachine.d.ts.map +1 -0
  573. package/dist/packages/compiler-task/src/compilerAsyncStateMachine.js +785 -0
  574. package/dist/packages/compiler-task/src/compilerAsyncStateMachine.js.map +1 -0
  575. package/dist/packages/compiler-task/src/compilerAsyncTaskInventory.d.ts +3 -0
  576. package/dist/packages/compiler-task/src/compilerAsyncTaskInventory.d.ts.map +1 -0
  577. package/dist/packages/compiler-task/src/compilerAsyncTaskInventory.js +182 -0
  578. package/dist/packages/compiler-task/src/compilerAsyncTaskInventory.js.map +1 -0
  579. package/dist/packages/compiler-task/src/compilerTaskOperationSemantics.d.ts +4 -0
  580. package/dist/packages/compiler-task/src/compilerTaskOperationSemantics.d.ts.map +1 -0
  581. package/dist/packages/compiler-task/src/compilerTaskOperationSemantics.js +101 -0
  582. package/dist/packages/compiler-task/src/compilerTaskOperationSemantics.js.map +1 -0
  583. package/dist/packages/compiler-task/src/index.d.ts +4 -0
  584. package/dist/packages/compiler-task/src/index.d.ts.map +1 -0
  585. package/dist/packages/compiler-task/src/index.js +4 -0
  586. package/dist/packages/compiler-task/src/index.js.map +1 -0
  587. package/dist/packages/compiler-types/src/compilerAccessSemanticIntermediateRepresentation.d.ts +79 -0
  588. package/dist/packages/compiler-types/src/compilerAccessSemanticIntermediateRepresentation.d.ts.map +1 -0
  589. package/dist/packages/compiler-types/src/compilerAccessSemanticIntermediateRepresentation.js +2 -0
  590. package/dist/packages/compiler-types/src/compilerAccessSemanticIntermediateRepresentation.js.map +1 -0
  591. package/dist/packages/compiler-types/src/compilerAmbientMemberBindingContract.d.ts +87 -0
  592. package/dist/packages/compiler-types/src/compilerAmbientMemberBindingContract.d.ts.map +1 -0
  593. package/dist/packages/compiler-types/src/compilerAmbientMemberBindingContract.js +2 -0
  594. package/dist/packages/compiler-types/src/compilerAmbientMemberBindingContract.js.map +1 -0
  595. package/dist/packages/compiler-types/src/compilerAsyncStateMachineContract.d.ts +126 -0
  596. package/dist/packages/compiler-types/src/compilerAsyncStateMachineContract.d.ts.map +1 -0
  597. package/dist/packages/compiler-types/src/compilerAsyncStateMachineContract.js +2 -0
  598. package/dist/packages/compiler-types/src/compilerAsyncStateMachineContract.js.map +1 -0
  599. package/dist/packages/compiler-types/src/compilerAsyncTaskCompletionContract.d.ts +32 -0
  600. package/dist/packages/compiler-types/src/compilerAsyncTaskCompletionContract.d.ts.map +1 -0
  601. package/dist/packages/compiler-types/src/compilerAsyncTaskCompletionContract.js +2 -0
  602. package/dist/packages/compiler-types/src/compilerAsyncTaskCompletionContract.js.map +1 -0
  603. package/dist/packages/compiler-types/src/compilerAsyncTaskInventoryContract.d.ts +63 -0
  604. package/dist/packages/compiler-types/src/compilerAsyncTaskInventoryContract.d.ts.map +1 -0
  605. package/dist/packages/compiler-types/src/compilerAsyncTaskInventoryContract.js +2 -0
  606. package/dist/packages/compiler-types/src/compilerAsyncTaskInventoryContract.js.map +1 -0
  607. package/dist/packages/compiler-types/src/compilerBackendContract.d.ts +183 -0
  608. package/dist/packages/compiler-types/src/compilerBackendContract.d.ts.map +1 -0
  609. package/dist/packages/compiler-types/src/compilerBackendContract.js +2 -0
  610. package/dist/packages/compiler-types/src/compilerBackendContract.js.map +1 -0
  611. package/dist/packages/compiler-types/src/compilerBindingIntermediateRepresentation.d.ts +46 -0
  612. package/dist/packages/compiler-types/src/compilerBindingIntermediateRepresentation.d.ts.map +1 -0
  613. package/dist/packages/compiler-types/src/compilerBindingIntermediateRepresentation.js +2 -0
  614. package/dist/packages/compiler-types/src/compilerBindingIntermediateRepresentation.js.map +1 -0
  615. package/dist/packages/compiler-types/src/compilerBindingPatternIntermediateRepresentation.d.ts +43 -0
  616. package/dist/packages/compiler-types/src/compilerBindingPatternIntermediateRepresentation.d.ts.map +1 -0
  617. package/dist/packages/compiler-types/src/compilerBindingPatternIntermediateRepresentation.js +2 -0
  618. package/dist/packages/compiler-types/src/compilerBindingPatternIntermediateRepresentation.js.map +1 -0
  619. package/dist/packages/compiler-types/src/compilerCatchCompletionContract.d.ts +23 -0
  620. package/dist/packages/compiler-types/src/compilerCatchCompletionContract.d.ts.map +1 -0
  621. package/dist/packages/compiler-types/src/compilerCatchCompletionContract.js +2 -0
  622. package/dist/packages/compiler-types/src/compilerCatchCompletionContract.js.map +1 -0
  623. package/dist/packages/compiler-types/src/compilerClassInitializationContract.d.ts +30 -0
  624. package/dist/packages/compiler-types/src/compilerClassInitializationContract.d.ts.map +1 -0
  625. package/dist/packages/compiler-types/src/compilerClassInitializationContract.js +2 -0
  626. package/dist/packages/compiler-types/src/compilerClassInitializationContract.js.map +1 -0
  627. package/dist/packages/compiler-types/src/compilerClosureEvidenceContract.d.ts +60 -0
  628. package/dist/packages/compiler-types/src/compilerClosureEvidenceContract.d.ts.map +1 -0
  629. package/dist/packages/compiler-types/src/compilerClosureEvidenceContract.js +2 -0
  630. package/dist/packages/compiler-types/src/compilerClosureEvidenceContract.js.map +1 -0
  631. package/dist/packages/compiler-types/src/compilerCommandLineContract.d.ts +79 -0
  632. package/dist/packages/compiler-types/src/compilerCommandLineContract.d.ts.map +1 -0
  633. package/dist/packages/compiler-types/src/compilerCommandLineContract.js +2 -0
  634. package/dist/packages/compiler-types/src/compilerCommandLineContract.js.map +1 -0
  635. package/dist/packages/compiler-types/src/compilerCompletionContract.d.ts +25 -0
  636. package/dist/packages/compiler-types/src/compilerCompletionContract.d.ts.map +1 -0
  637. package/dist/packages/compiler-types/src/compilerCompletionContract.js +2 -0
  638. package/dist/packages/compiler-types/src/compilerCompletionContract.js.map +1 -0
  639. package/dist/packages/compiler-types/src/compilerCppClosureCaptureContract.d.ts +21 -0
  640. package/dist/packages/compiler-types/src/compilerCppClosureCaptureContract.d.ts.map +1 -0
  641. package/dist/packages/compiler-types/src/compilerCppClosureCaptureContract.js +2 -0
  642. package/dist/packages/compiler-types/src/compilerCppClosureCaptureContract.js.map +1 -0
  643. package/dist/packages/compiler-types/src/compilerCppReferenceRepresentationContract.d.ts +74 -0
  644. package/dist/packages/compiler-types/src/compilerCppReferenceRepresentationContract.d.ts.map +1 -0
  645. package/dist/packages/compiler-types/src/compilerCppReferenceRepresentationContract.js +2 -0
  646. package/dist/packages/compiler-types/src/compilerCppReferenceRepresentationContract.js.map +1 -0
  647. package/dist/packages/compiler-types/src/compilerDeclarationIntermediateRepresentation.d.ts +113 -0
  648. package/dist/packages/compiler-types/src/compilerDeclarationIntermediateRepresentation.d.ts.map +1 -0
  649. package/dist/packages/compiler-types/src/compilerDeclarationIntermediateRepresentation.js +2 -0
  650. package/dist/packages/compiler-types/src/compilerDeclarationIntermediateRepresentation.js.map +1 -0
  651. package/dist/packages/compiler-types/src/compilerDependentCallablePackContract.d.ts +11 -0
  652. package/dist/packages/compiler-types/src/compilerDependentCallablePackContract.d.ts.map +1 -0
  653. package/dist/packages/compiler-types/src/compilerDependentCallablePackContract.js +2 -0
  654. package/dist/packages/compiler-types/src/compilerDependentCallablePackContract.js.map +1 -0
  655. package/dist/packages/compiler-types/src/compilerDiagnosticContract.d.ts +11 -0
  656. package/dist/packages/compiler-types/src/compilerDiagnosticContract.d.ts.map +1 -0
  657. package/dist/packages/compiler-types/src/compilerDiagnosticContract.js +2 -0
  658. package/dist/packages/compiler-types/src/compilerDiagnosticContract.js.map +1 -0
  659. package/dist/packages/compiler-types/src/compilerEmittedSourceSyntaxContract.d.ts +28 -0
  660. package/dist/packages/compiler-types/src/compilerEmittedSourceSyntaxContract.d.ts.map +1 -0
  661. package/dist/packages/compiler-types/src/compilerEmittedSourceSyntaxContract.js +2 -0
  662. package/dist/packages/compiler-types/src/compilerEmittedSourceSyntaxContract.js.map +1 -0
  663. package/dist/packages/compiler-types/src/compilerExecutableIntermediateRepresentation.d.ts +343 -0
  664. package/dist/packages/compiler-types/src/compilerExecutableIntermediateRepresentation.d.ts.map +1 -0
  665. package/dist/packages/compiler-types/src/compilerExecutableIntermediateRepresentation.js +2 -0
  666. package/dist/packages/compiler-types/src/compilerExecutableIntermediateRepresentation.js.map +1 -0
  667. package/dist/packages/compiler-types/src/compilerFlightWorkspaceContract.d.ts +26 -0
  668. package/dist/packages/compiler-types/src/compilerFlightWorkspaceContract.d.ts.map +1 -0
  669. package/dist/packages/compiler-types/src/compilerFlightWorkspaceContract.js +2 -0
  670. package/dist/packages/compiler-types/src/compilerFlightWorkspaceContract.js.map +1 -0
  671. package/dist/packages/compiler-types/src/compilerHaxeTaskEmissionContract.d.ts +12 -0
  672. package/dist/packages/compiler-types/src/compilerHaxeTaskEmissionContract.d.ts.map +1 -0
  673. package/dist/packages/compiler-types/src/compilerHaxeTaskEmissionContract.js +2 -0
  674. package/dist/packages/compiler-types/src/compilerHaxeTaskEmissionContract.js.map +1 -0
  675. package/dist/packages/compiler-types/src/compilerHaxeTaskLoweringContract.d.ts +119 -0
  676. package/dist/packages/compiler-types/src/compilerHaxeTaskLoweringContract.d.ts.map +1 -0
  677. package/dist/packages/compiler-types/src/compilerHaxeTaskLoweringContract.js +2 -0
  678. package/dist/packages/compiler-types/src/compilerHaxeTaskLoweringContract.js.map +1 -0
  679. package/dist/packages/compiler-types/src/compilerHostEndpointContract.d.ts +27 -0
  680. package/dist/packages/compiler-types/src/compilerHostEndpointContract.d.ts.map +1 -0
  681. package/dist/packages/compiler-types/src/compilerHostEndpointContract.js +2 -0
  682. package/dist/packages/compiler-types/src/compilerHostEndpointContract.js.map +1 -0
  683. package/dist/packages/compiler-types/src/compilerInvariantContract.d.ts +7 -0
  684. package/dist/packages/compiler-types/src/compilerInvariantContract.d.ts.map +1 -0
  685. package/dist/packages/compiler-types/src/compilerInvariantContract.js +2 -0
  686. package/dist/packages/compiler-types/src/compilerInvariantContract.js.map +1 -0
  687. package/dist/packages/compiler-types/src/compilerInventoryContract.d.ts +186 -0
  688. package/dist/packages/compiler-types/src/compilerInventoryContract.d.ts.map +1 -0
  689. package/dist/packages/compiler-types/src/compilerInventoryContract.js +2 -0
  690. package/dist/packages/compiler-types/src/compilerInventoryContract.js.map +1 -0
  691. package/dist/packages/compiler-types/src/compilerIrValidationContract.d.ts +13 -0
  692. package/dist/packages/compiler-types/src/compilerIrValidationContract.d.ts.map +1 -0
  693. package/dist/packages/compiler-types/src/compilerIrValidationContract.js +2 -0
  694. package/dist/packages/compiler-types/src/compilerIrValidationContract.js.map +1 -0
  695. package/dist/packages/compiler-types/src/compilerLoweringContract.d.ts +32 -0
  696. package/dist/packages/compiler-types/src/compilerLoweringContract.d.ts.map +1 -0
  697. package/dist/packages/compiler-types/src/compilerLoweringContract.js +2 -0
  698. package/dist/packages/compiler-types/src/compilerLoweringContract.js.map +1 -0
  699. package/dist/packages/compiler-types/src/compilerModuleEvaluationContract.d.ts +84 -0
  700. package/dist/packages/compiler-types/src/compilerModuleEvaluationContract.d.ts.map +1 -0
  701. package/dist/packages/compiler-types/src/compilerModuleEvaluationContract.js +2 -0
  702. package/dist/packages/compiler-types/src/compilerModuleEvaluationContract.js.map +1 -0
  703. package/dist/packages/compiler-types/src/compilerModuleFacadeContract.d.ts +78 -0
  704. package/dist/packages/compiler-types/src/compilerModuleFacadeContract.d.ts.map +1 -0
  705. package/dist/packages/compiler-types/src/compilerModuleFacadeContract.js +2 -0
  706. package/dist/packages/compiler-types/src/compilerModuleFacadeContract.js.map +1 -0
  707. package/dist/packages/compiler-types/src/compilerModuleIntermediateRepresentation.d.ts +53 -0
  708. package/dist/packages/compiler-types/src/compilerModuleIntermediateRepresentation.d.ts.map +1 -0
  709. package/dist/packages/compiler-types/src/compilerModuleIntermediateRepresentation.js +2 -0
  710. package/dist/packages/compiler-types/src/compilerModuleIntermediateRepresentation.js.map +1 -0
  711. package/dist/packages/compiler-types/src/compilerModuleResolutionContract.d.ts +20 -0
  712. package/dist/packages/compiler-types/src/compilerModuleResolutionContract.d.ts.map +1 -0
  713. package/dist/packages/compiler-types/src/compilerModuleResolutionContract.js +2 -0
  714. package/dist/packages/compiler-types/src/compilerModuleResolutionContract.js.map +1 -0
  715. package/dist/packages/compiler-types/src/compilerOperatorIntermediateRepresentation.d.ts +5 -0
  716. package/dist/packages/compiler-types/src/compilerOperatorIntermediateRepresentation.d.ts.map +1 -0
  717. package/dist/packages/compiler-types/src/compilerOperatorIntermediateRepresentation.js +2 -0
  718. package/dist/packages/compiler-types/src/compilerOperatorIntermediateRepresentation.js.map +1 -0
  719. package/dist/packages/compiler-types/src/compilerOperatorSemanticIntermediateRepresentation.d.ts +34 -0
  720. package/dist/packages/compiler-types/src/compilerOperatorSemanticIntermediateRepresentation.d.ts.map +1 -0
  721. package/dist/packages/compiler-types/src/compilerOperatorSemanticIntermediateRepresentation.js +2 -0
  722. package/dist/packages/compiler-types/src/compilerOperatorSemanticIntermediateRepresentation.js.map +1 -0
  723. package/dist/packages/compiler-types/src/compilerOrchestrationContract.d.ts +43 -0
  724. package/dist/packages/compiler-types/src/compilerOrchestrationContract.d.ts.map +1 -0
  725. package/dist/packages/compiler-types/src/compilerOrchestrationContract.js +2 -0
  726. package/dist/packages/compiler-types/src/compilerOrchestrationContract.js.map +1 -0
  727. package/dist/packages/compiler-types/src/compilerPackageCheckContract.d.ts +96 -0
  728. package/dist/packages/compiler-types/src/compilerPackageCheckContract.d.ts.map +1 -0
  729. package/dist/packages/compiler-types/src/compilerPackageCheckContract.js +2 -0
  730. package/dist/packages/compiler-types/src/compilerPackageCheckContract.js.map +1 -0
  731. package/dist/packages/compiler-types/src/compilerPackageCompilationContract.d.ts +108 -0
  732. package/dist/packages/compiler-types/src/compilerPackageCompilationContract.d.ts.map +1 -0
  733. package/dist/packages/compiler-types/src/compilerPackageCompilationContract.js +2 -0
  734. package/dist/packages/compiler-types/src/compilerPackageCompilationContract.js.map +1 -0
  735. package/dist/packages/compiler-types/src/compilerRefusalClassificationContract.d.ts +3 -0
  736. package/dist/packages/compiler-types/src/compilerRefusalClassificationContract.d.ts.map +1 -0
  737. package/dist/packages/compiler-types/src/compilerRefusalClassificationContract.js +2 -0
  738. package/dist/packages/compiler-types/src/compilerRefusalClassificationContract.js.map +1 -0
  739. package/dist/packages/compiler-types/src/compilerRuntimeContract.d.ts +122 -0
  740. package/dist/packages/compiler-types/src/compilerRuntimeContract.d.ts.map +1 -0
  741. package/dist/packages/compiler-types/src/compilerRuntimeContract.js +2 -0
  742. package/dist/packages/compiler-types/src/compilerRuntimeContract.js.map +1 -0
  743. package/dist/packages/compiler-types/src/compilerRuntimeTaskCapabilityContract.d.ts +96 -0
  744. package/dist/packages/compiler-types/src/compilerRuntimeTaskCapabilityContract.d.ts.map +1 -0
  745. package/dist/packages/compiler-types/src/compilerRuntimeTaskCapabilityContract.js +2 -0
  746. package/dist/packages/compiler-types/src/compilerRuntimeTaskCapabilityContract.js.map +1 -0
  747. package/dist/packages/compiler-types/src/compilerRustOwnershipContract.d.ts +25 -0
  748. package/dist/packages/compiler-types/src/compilerRustOwnershipContract.d.ts.map +1 -0
  749. package/dist/packages/compiler-types/src/compilerRustOwnershipContract.js +2 -0
  750. package/dist/packages/compiler-types/src/compilerRustOwnershipContract.js.map +1 -0
  751. package/dist/packages/compiler-types/src/compilerSemanticPatchContract.d.ts +80 -0
  752. package/dist/packages/compiler-types/src/compilerSemanticPatchContract.d.ts.map +1 -0
  753. package/dist/packages/compiler-types/src/compilerSemanticPatchContract.js +2 -0
  754. package/dist/packages/compiler-types/src/compilerSemanticPatchContract.js.map +1 -0
  755. package/dist/packages/compiler-types/src/compilerSourceFingerprint.d.ts +2 -0
  756. package/dist/packages/compiler-types/src/compilerSourceFingerprint.d.ts.map +1 -0
  757. package/dist/packages/compiler-types/src/compilerSourceFingerprint.js +2 -0
  758. package/dist/packages/compiler-types/src/compilerSourceFingerprint.js.map +1 -0
  759. package/dist/packages/compiler-types/src/compilerSourceIdentity.d.ts +21 -0
  760. package/dist/packages/compiler-types/src/compilerSourceIdentity.d.ts.map +1 -0
  761. package/dist/packages/compiler-types/src/compilerSourceIdentity.js +2 -0
  762. package/dist/packages/compiler-types/src/compilerSourceIdentity.js.map +1 -0
  763. package/dist/packages/compiler-types/src/compilerStatementCompletionContract.d.ts +7 -0
  764. package/dist/packages/compiler-types/src/compilerStatementCompletionContract.d.ts.map +1 -0
  765. package/dist/packages/compiler-types/src/compilerStatementCompletionContract.js +2 -0
  766. package/dist/packages/compiler-types/src/compilerStatementCompletionContract.js.map +1 -0
  767. package/dist/packages/compiler-types/src/compilerStaticFactContract.d.ts +71 -0
  768. package/dist/packages/compiler-types/src/compilerStaticFactContract.d.ts.map +1 -0
  769. package/dist/packages/compiler-types/src/compilerStaticFactContract.js +2 -0
  770. package/dist/packages/compiler-types/src/compilerStaticFactContract.js.map +1 -0
  771. package/dist/packages/compiler-types/src/compilerStructuralObjectCompatibilityContract.d.ts +18 -0
  772. package/dist/packages/compiler-types/src/compilerStructuralObjectCompatibilityContract.d.ts.map +1 -0
  773. package/dist/packages/compiler-types/src/compilerStructuralObjectCompatibilityContract.js +2 -0
  774. package/dist/packages/compiler-types/src/compilerStructuralObjectCompatibilityContract.js.map +1 -0
  775. package/dist/packages/compiler-types/src/compilerStructuralTypeAssignabilityContract.d.ts +20 -0
  776. package/dist/packages/compiler-types/src/compilerStructuralTypeAssignabilityContract.d.ts.map +1 -0
  777. package/dist/packages/compiler-types/src/compilerStructuralTypeAssignabilityContract.js +2 -0
  778. package/dist/packages/compiler-types/src/compilerStructuralTypeAssignabilityContract.js.map +1 -0
  779. package/dist/packages/compiler-types/src/compilerStructuralTypeShapeContract.d.ts +22 -0
  780. package/dist/packages/compiler-types/src/compilerStructuralTypeShapeContract.d.ts.map +1 -0
  781. package/dist/packages/compiler-types/src/compilerStructuralTypeShapeContract.js +2 -0
  782. package/dist/packages/compiler-types/src/compilerStructuralTypeShapeContract.js.map +1 -0
  783. package/dist/packages/compiler-types/src/compilerStructuralTypeSubstitutionContract.d.ts +17 -0
  784. package/dist/packages/compiler-types/src/compilerStructuralTypeSubstitutionContract.d.ts.map +1 -0
  785. package/dist/packages/compiler-types/src/compilerStructuralTypeSubstitutionContract.js +2 -0
  786. package/dist/packages/compiler-types/src/compilerStructuralTypeSubstitutionContract.js.map +1 -0
  787. package/dist/packages/compiler-types/src/compilerTargetCompilationSmokeContract.d.ts +26 -0
  788. package/dist/packages/compiler-types/src/compilerTargetCompilationSmokeContract.d.ts.map +1 -0
  789. package/dist/packages/compiler-types/src/compilerTargetCompilationSmokeContract.js +2 -0
  790. package/dist/packages/compiler-types/src/compilerTargetCompilationSmokeContract.js.map +1 -0
  791. package/dist/packages/compiler-types/src/compilerTargetNamingContract.d.ts +27 -0
  792. package/dist/packages/compiler-types/src/compilerTargetNamingContract.d.ts.map +1 -0
  793. package/dist/packages/compiler-types/src/compilerTargetNamingContract.js +2 -0
  794. package/dist/packages/compiler-types/src/compilerTargetNamingContract.js.map +1 -0
  795. package/dist/packages/compiler-types/src/compilerTaskOperationSemanticsContract.d.ts +65 -0
  796. package/dist/packages/compiler-types/src/compilerTaskOperationSemanticsContract.d.ts.map +1 -0
  797. package/dist/packages/compiler-types/src/compilerTaskOperationSemanticsContract.js +2 -0
  798. package/dist/packages/compiler-types/src/compilerTaskOperationSemanticsContract.js.map +1 -0
  799. package/dist/packages/compiler-types/src/compilerTraversalObserverContract.d.ts +29 -0
  800. package/dist/packages/compiler-types/src/compilerTraversalObserverContract.d.ts.map +1 -0
  801. package/dist/packages/compiler-types/src/compilerTraversalObserverContract.js +2 -0
  802. package/dist/packages/compiler-types/src/compilerTraversalObserverContract.js.map +1 -0
  803. package/dist/packages/compiler-types/src/compilerTypeIntermediateRepresentation.d.ts +99 -0
  804. package/dist/packages/compiler-types/src/compilerTypeIntermediateRepresentation.d.ts.map +1 -0
  805. package/dist/packages/compiler-types/src/compilerTypeIntermediateRepresentation.js +2 -0
  806. package/dist/packages/compiler-types/src/compilerTypeIntermediateRepresentation.js.map +1 -0
  807. package/dist/packages/compiler-types/src/compilerTypeScriptContract.d.ts +39 -0
  808. package/dist/packages/compiler-types/src/compilerTypeScriptContract.d.ts.map +1 -0
  809. package/dist/packages/compiler-types/src/compilerTypeScriptContract.js +2 -0
  810. package/dist/packages/compiler-types/src/compilerTypeScriptContract.js.map +1 -0
  811. package/dist/packages/compiler-types/src/compilerTypeValueIdentityContract.d.ts +14 -0
  812. package/dist/packages/compiler-types/src/compilerTypeValueIdentityContract.d.ts.map +1 -0
  813. package/dist/packages/compiler-types/src/compilerTypeValueIdentityContract.js +2 -0
  814. package/dist/packages/compiler-types/src/compilerTypeValueIdentityContract.js.map +1 -0
  815. package/dist/packages/compiler-types/src/compilerValueCompletionContract.d.ts +46 -0
  816. package/dist/packages/compiler-types/src/compilerValueCompletionContract.d.ts.map +1 -0
  817. package/dist/packages/compiler-types/src/compilerValueCompletionContract.js +2 -0
  818. package/dist/packages/compiler-types/src/compilerValueCompletionContract.js.map +1 -0
  819. package/dist/packages/compiler-types/src/compilerWorkspaceSourceContract.d.ts +11 -0
  820. package/dist/packages/compiler-types/src/compilerWorkspaceSourceContract.d.ts.map +1 -0
  821. package/dist/packages/compiler-types/src/compilerWorkspaceSourceContract.js +12 -0
  822. package/dist/packages/compiler-types/src/compilerWorkspaceSourceContract.js.map +1 -0
  823. package/dist/packages/compiler-types/src/index.d.ts +60 -0
  824. package/dist/packages/compiler-types/src/index.d.ts.map +1 -0
  825. package/dist/packages/compiler-types/src/index.js +2 -0
  826. package/dist/packages/compiler-types/src/index.js.map +1 -0
  827. package/dist/packages/tool-compiler/src/index.d.ts +24 -0
  828. package/dist/packages/tool-compiler/src/index.d.ts.map +1 -0
  829. package/dist/packages/tool-compiler/src/index.js +23 -0
  830. package/dist/packages/tool-compiler/src/index.js.map +1 -0
  831. package/package.json +45 -0
@@ -0,0 +1,4555 @@
1
+ import path from 'node:path';
2
+ import { analyzeIrModuleClosureEvidence } from '../../compiler-closure/src/index.js';
3
+ import { collectIrModuleNullableBindingIds, createBackendEmissionFailure, createCompilerGeneratedFileHeader, createIrModuleTargetNameAllocation, getIrUnionTypeStringLiteralValues, hasIrTypeAbsentMember, indentSourceLines, normalizeSourceTextGrouping, isCompilerTargetNameAllocationFailure, } from '../../compiler-emission/src/index.js';
4
+ import { analyzeIrModuleTraversal, analyzeIrStatementSubtreeTraversal, getIrModuleTraversalPathValue, } from '../../compiler-ir-traversal/src/index.js';
5
+ import { createIrClassInitializationPlan, createCompilerLoweringPassAwaitConditionHoisting, createCompilerLoweringPassBindingPattern, createCompilerLoweringPassCStyleFor, createCompilerLoweringPassExtraArgumentErasure, createCompilerLoweringPassInterfaceInheritance, createCompilerLoweringPassSwitchFallthrough, createCompilerLoweringPassSwitchSuspension, createCompilerLoweringPassVariableHoisting, lowerIrModuleWithCompilerPasses, } from '../../compiler-lowering/src/index.js';
6
+ import { analyzeCompilerRuntimeExternalConstructorAbiCompleteness, analyzeCompilerRuntimeExternalSymbolCompleteness, collectIrModulesRuntimeExternalConstructorInvocations, collectIrModulesRuntimeExternalSymbolIdentities, } from '../../compiler-runtime-contract/src/index.js';
7
+ import { analyzeIrModuleStructuralObjectCompatibilityAcrossModules, analyzeIrTypeStructuralAssignability, createIrObjectTypeShapeIdentity, createIrTypeParameterSubstitutionPlan, isCompilerStructuralTypeSubstitutionFailure, resolveIrTypeStructuralSubstitution, } from '../../compiler-structural/src/index.js';
8
+ import { analyzeIrModuleAsyncStateMachines } from '../../compiler-task/src/index.js';
9
+ import { getCompilerRustAmbientMemberBinding } from './rustAmbientMemberBinding.js';
10
+ import { convertPackageNameToRustCrateName, convertSourcePathToRustModuleName, isRustCompilerKeyword, } from './rustCompilerIdentity.js';
11
+ import { analyzeIrModuleOwnershipEvidenceRust, collectIrModuleMovedBindingIdsRust, collectIrModuleReferentMutatedParameterIdsRust, } from './rustOwnershipEvidence.js';
12
+ import { createCompilerRuntimeExternalConstructorAbiPlanRust } from './rustRuntimeExternalConstructorAbi.js';
13
+ import { createCompilerRuntimeExternalSymbolBindingPlanRust, getCompilerRuntimeExternalMemberTargetRust, getCompilerRuntimeExternalSymbolTargetRust, isCompilerRuntimeExternalSymbolProvidedRust, } from './rustRuntimeExternalSymbolBinding.js';
14
+ export function createRustCompilerBackend() {
15
+ return {
16
+ emitModule(module, { moduleResolution, modules, options }) {
17
+ return [emitIrModuleRustWithContext(module, modules, moduleResolution, options)];
18
+ },
19
+ name: 'rust',
20
+ };
21
+ }
22
+ export function emitIrModuleRust(sourceModule, options = {}) {
23
+ return emitIrModuleRustWithContext(sourceModule, [sourceModule], undefined, options);
24
+ }
25
+ function createCompilerLoweringPassInterfaceInheritanceRust(modules, moduleResolution) {
26
+ return createCompilerLoweringPassInterfaceInheritance(modules, moduleResolution, {
27
+ // TypeScript has already materialized every selected ambient member on the interface. The
28
+ // shared pass verifies that evidence before it erases the otherwise nonlocal DOM heritage.
29
+ eraseAmbientUtilityHeritage: (reference) => reference.reference.kind === 'ambient' && reference.reference.name === 'Pick',
30
+ });
31
+ }
32
+ function emitIrModuleRustWithContext(sourceModule, sourceModules, moduleResolution, options) {
33
+ const module = lowerIrModuleWithCompilerPasses(sourceModule, [
34
+ createCompilerLoweringPassExtraArgumentErasure(),
35
+ createCompilerLoweringPassAwaitConditionHoisting(),
36
+ createCompilerLoweringPassBindingPattern(),
37
+ createCompilerLoweringPassVariableHoisting(),
38
+ createCompilerLoweringPassCStyleFor(),
39
+ createCompilerLoweringPassInterfaceInheritanceRust(sourceModules, moduleResolution),
40
+ createCompilerLoweringPassSwitchFallthrough(),
41
+ createCompilerLoweringPassSwitchSuspension(),
42
+ ]);
43
+ assertStructuralObjectCompatibilityRust(module, replaceIrModuleBackendContext(sourceModules, module), moduleResolution);
44
+ assertRuntimeExternalSymbolBindingsRust(module, options);
45
+ assertRuntimeExternalConstructorAbiRust(module);
46
+ const asyncAnalysis = analyzeIrModuleAsyncStateMachines(module);
47
+ const asyncTryStatements = collectAsyncTryStatementsRust(module, asyncAnalysis);
48
+ const constantIdentities = new Set(module.declarations.flatMap((declaration) => declaration.kind === 'variable' && !declaration.mutable && !('pattern' in declaration)
49
+ ? [declaration.binding.id]
50
+ : []));
51
+ let targetNames;
52
+ try {
53
+ targetNames = new Map(createIrModuleTargetNameAllocation(module, (binding) => ({
54
+ namespace: 'identifier',
55
+ preferredName: getPreferredBindingNameRust(binding, constantIdentities),
56
+ })).map((allocation) => [allocation.identity, allocation.name]));
57
+ }
58
+ catch (error) {
59
+ if (isCompilerTargetNameAllocationFailure(error)) {
60
+ throw createBackendEmissionFailure('rust', module, `public declarations share fixed Rust target name ${error.targetName}`);
61
+ }
62
+ throw error;
63
+ }
64
+ const closureEvidence = analyzeIrModuleClosureEvidence(module);
65
+ const bindingTypes = collectIrModuleBindingTypesRust(module);
66
+ const allCellWrappedIds = closureEvidence.closures
67
+ .filter((closure) => closure.origin.kind === 'functionExpression' &&
68
+ !closure.valueUses.every((use) => use.kind === 'directInvocation'))
69
+ .flatMap((closure) => closure.captures.filter((capture) => capture.mutation !== 'none').map((capture) => capture.binding.id));
70
+ const cellWrappedBindingIds = new Set(allCellWrappedIds.filter((id) => {
71
+ const type = bindingTypes.get(id);
72
+ return !type || isIrTypeCopyRust(type);
73
+ }));
74
+ const refCellWrappedBindingIds = new Set(allCellWrappedIds.filter((id) => {
75
+ const type = bindingTypes.get(id);
76
+ return type !== undefined && !isIrTypeCopyRust(type);
77
+ }));
78
+ const accessorClassNames = new Map();
79
+ const classBindingNames = new Map();
80
+ const borrowedParameterPositions = new Map();
81
+ const primitiveUnionEnums = new Map();
82
+ const primitiveUnionBindingIds = new Map();
83
+ const taggedUnionBindingNames = new Map();
84
+ const numericEnumNamespaceNames = new Map(module.declarations.flatMap((declaration) => declaration.kind === 'enum' && getIrEnumNamespaceFunctionsRust(declaration, module).length > 0
85
+ ? [
86
+ [
87
+ declaration.binding.id,
88
+ targetNames.get(declaration.binding.id) ?? safeRustTypeName(declaration.binding.name),
89
+ ],
90
+ ]
91
+ : []));
92
+ const context = {
93
+ abstractFieldNames: new Set(),
94
+ activeTypeParameters: [],
95
+ assertedUnknownBindingTypes: collectAssertedUnknownBindingTypesRust(module, bindingTypes),
96
+ accessorClassNames,
97
+ anonymousObjectRecords: new Map(),
98
+ anonymousUnionEnums: new Map(),
99
+ apiReferencedBindingIds: collectIrModuleApiReferencedBindingIdsRust(module),
100
+ arrayElementBindingIds: collectIrModuleArrayElementBindingIdsRust(module),
101
+ asyncTryStatements,
102
+ cellWrappedBindingIds,
103
+ refCellWrappedBindingIds,
104
+ classBindingNames,
105
+ borrowedParameterPositions,
106
+ callableObjectRecords: new Map(),
107
+ deferredBindingIds: new Set(analyzeIrModuleOwnershipEvidenceRust(module).bindings.flatMap((evidence) => evidence.uses.filter((use) => use.kind === 'rebind').length === 1 ? [evidence.binding.id] : [])),
108
+ primitiveUnionEnums,
109
+ primitiveUnionBindingIds,
110
+ runtimeTypeNames: new Set(),
111
+ reboundBindingIds: new Set(analyzeIrModuleOwnershipEvidenceRust(module).bindings.flatMap((evidence) => evidence.mutation !== 'none' ? [evidence.binding.id] : [])),
112
+ generatedNames: new Set(targetNames.values()),
113
+ movedBindingIds: collectIrModuleMovedBindingIdsRust(module),
114
+ referentMutatedBindingIds: new Set(analyzeIrModuleOwnershipEvidenceRust(module).bindings.flatMap((evidence) => evidence.mutation === 'referentMutated' || evidence.mutation === 'bindingAndReferent'
115
+ ? [evidence.binding.id]
116
+ : [])),
117
+ referentMutatedParameterIds: collectIrModuleReferentMutatedParameterIdsRust(module),
118
+ taggedUnionBindingNames,
119
+ bindingTypes,
120
+ module,
121
+ moduleResolution,
122
+ sourceModules: replaceIrModuleBackendContext(sourceModules, module),
123
+ needsCellImport: new Set(),
124
+ needsRcImport: new Set(),
125
+ needsRefCellImport: new Set(),
126
+ nullableBindingIds: collectIrModuleNullableBindingIds(module),
127
+ numericEnumNamespaceNames,
128
+ objectRestRecords: new Map(),
129
+ options,
130
+ returnsAbsent: false,
131
+ targetNames,
132
+ };
133
+ // Which bindings hold a union this module lowered to an enum. The type is on the binding, not on
134
+ // the member access, so the access site can only tell that its object is an enum by asking here.
135
+ for (const evidence of analyzeIrModuleOwnershipEvidenceRust(module).bindings) {
136
+ if (evidence.type.kind !== 'named' || evidence.type.reference.kind !== 'binding')
137
+ continue;
138
+ const reference = evidence.type.reference;
139
+ const alias = module.declarations.find((candidate) => candidate.kind === 'typeAlias' && candidate.binding.name === reference.binding.name);
140
+ if (alias?.kind === 'typeAlias' &&
141
+ alias.type.kind === 'union' &&
142
+ getIrUnionTypeMemberRecordsRust(alias.type, context)) {
143
+ taggedUnionBindingNames.set(evidence.binding.id, getBindingTargetNameRust(alias.binding, context));
144
+ continue;
145
+ }
146
+ // Which bindings hold a class with accessors. Rust has no properties, so a source-level field
147
+ // read of one is a call, and the access site can only tell by asking what the binding holds.
148
+ const classDeclaration = module.declarations.find((candidate) => candidate.kind === 'class' && candidate.binding.name === reference.binding.name);
149
+ if (classDeclaration?.kind !== 'class')
150
+ continue;
151
+ classBindingNames.set(evidence.binding.id, classDeclaration.binding.name);
152
+ if (classDeclaration.methods.some((method) => method.accessor)) {
153
+ accessorClassNames.set(evidence.binding.id, classDeclaration.binding.name);
154
+ }
155
+ }
156
+ // Which positions each module-local function borrows. Rust does not take a reference for an
157
+ // argument the way it does for a method receiver, so the call site has to lend explicitly, and only
158
+ // the callee's own declaration knows which positions those are.
159
+ for (const declaration of module.declarations) {
160
+ if (declaration.kind !== 'function')
161
+ continue;
162
+ const borrowed = new Set(declaration.parameters.flatMap((parameter, index) => context.referentMutatedParameterIds.has(parameter.binding.id) ? [index] : []));
163
+ if (borrowed.size > 0)
164
+ borrowedParameterPositions.set(declaration.binding.id, borrowed);
165
+ }
166
+ collectPrimitiveUnionBindingsRust(module, context);
167
+ const lines = [createCompilerGeneratedFileHeader(module, '//', options.upstreamCommit), '#![forbid(unsafe_code)]'];
168
+ const imports = [...emitImports(module.imports, context), ...emitReexportsRust(module.exports, context)];
169
+ const declarations = module.declarations
170
+ .filter((declaration) => declaration.kind !== 'function' || !declaration.namespaceMember)
171
+ .map((declaration) => emitDeclaration(declaration, context));
172
+ // The runtime contract's types are named bare in emitted source, so the module has to bring them
173
+ // into scope. Which ones it needs is only known once everything is emitted, which is why the use
174
+ // line is assembled here rather than beside the source's own imports.
175
+ const runtimeImports = context.runtimeTypeNames.size > 0
176
+ ? [`use ${options.runtimeCrate ?? 'flight_runtime'}::${emitUseTreeRust([...context.runtimeTypeNames].sort())};`]
177
+ : [];
178
+ const stdImports = [];
179
+ if (context.needsCellImport.size > 0)
180
+ stdImports.push('use std::cell::Cell;');
181
+ if (context.needsRefCellImport.size > 0)
182
+ stdImports.push('use std::cell::RefCell;');
183
+ if (context.needsRcImport.size > 0)
184
+ stdImports.push('use std::rc::Rc;');
185
+ if (runtimeImports.length > 0 || imports.length > 0 || stdImports.length > 0)
186
+ lines.push('', ...stdImports, ...runtimeImports, ...imports);
187
+ context.anonymousObjectRecords.forEach((record) => {
188
+ lines.push('', ...emitRecord(record.name, record.properties, [], false, context));
189
+ });
190
+ context.objectRestRecords.forEach((record) => {
191
+ lines.push('', ...emitRecord(record.name, record.properties, [], false, context));
192
+ });
193
+ context.primitiveUnionEnums.forEach((union) => {
194
+ lines.push('', ...emitPrimitiveUnionEnumRust(union));
195
+ });
196
+ context.anonymousUnionEnums.forEach((union) => {
197
+ lines.push('', ...emitGeneralUnionRust(union.name, union.variants, union.typeParameters, true, context));
198
+ });
199
+ context.callableObjectRecords.forEach((record) => {
200
+ lines.push('', ...emitCallableObjectRecordRust(record, context));
201
+ });
202
+ declarations.forEach((declaration) => lines.push('', ...declaration));
203
+ return {
204
+ contents: lines.join('\n'),
205
+ path: getRustModuleFilePath(module, context.sourceModules),
206
+ };
207
+ }
208
+ function emitClass(declaration, context) {
209
+ // Rust has no inheritance of state, so a base that carries fields has nothing to inherit into. A
210
+ // stateless abstract base is a different thing: it is a set of methods, which is a trait, and the
211
+ // subclass implements it.
212
+ const abstractBase = getIrClassStatelessAbstractBaseRust(declaration, context);
213
+ const concreteBase = !abstractBase ? getIrClassConcreteBaseRust(declaration, context) : undefined;
214
+ if (declaration.extends && !abstractBase && !concreteBase) {
215
+ emissionError(context, `class ${declaration.binding.name} inheritance requires Rust ownership lowering`);
216
+ }
217
+ // An abstract class declares behaviour and holds no state, which is what a Rust trait is. A method
218
+ // it implements becomes the trait's default body, so a subclass inherits it by implementing nothing.
219
+ if (declaration.abstract)
220
+ return emitAbstractClassTraitRust(declaration, context);
221
+ const inheritedTraits = abstractBase ? [getBindingTargetNameRust(abstractBase.binding, context)] : [];
222
+ const implementedTraits = declaration.implements.map((reference) => {
223
+ if (reference.kind !== 'named' || reference.reference.kind !== 'binding') {
224
+ return emissionError(context, `class ${declaration.binding.name} implements a type with no Rust trait`);
225
+ }
226
+ const target = context.module.declarations.find((candidate) => candidate.kind === 'interface' &&
227
+ reference.reference.kind === 'binding' &&
228
+ candidate.binding.id === reference.reference.binding.id);
229
+ if (!target) {
230
+ return emissionError(context, `class ${declaration.binding.name} implements an interface declared outside this module`);
231
+ }
232
+ return emitType(reference, context);
233
+ });
234
+ const compositionInit = concreteBase && declaration.classConstructor
235
+ ? getIrClassCompositionConstructorRust(declaration, concreteBase)
236
+ : undefined;
237
+ const constructorFields = !concreteBase && declaration.classConstructor
238
+ ? getIrClassConstructorFieldAssignmentsRust(declaration, abstractBase !== undefined)
239
+ : undefined;
240
+ if (declaration.classConstructor &&
241
+ !constructorFields &&
242
+ !compositionInit &&
243
+ (declaration.classConstructor.parameters.length > 0 || declaration.classConstructor.body.length > 0)) {
244
+ emissionError(context, `class ${declaration.binding.name} constructor requires Rust initialization lowering`);
245
+ }
246
+ // A static field is one value shared by the type, which Rust spells as an associated constant —
247
+ // but only where the source's initializer is a constant. Anything computed needs a place to run,
248
+ // and an associated constant has none.
249
+ const staticFields = declaration.fields.filter((field) => field.static);
250
+ if (staticFields.some((field) => field.initializer?.kind !== 'literal')) {
251
+ emissionError(context, `class ${declaration.binding.name} static fields require a constant initializer`);
252
+ }
253
+ const constructed = !declaration.classConstructor ||
254
+ (declaration.classConstructor.parameters.length === 0 && declaration.classConstructor.body.length === 0);
255
+ const instanceFields = declaration.fields.filter((field) => !field.static);
256
+ if (instanceFields.some((field) => field.initializer) && !constructed && !constructorFields && !compositionInit) {
257
+ emissionError(context, `class ${declaration.binding.name} field initializers require constructor lowering`);
258
+ }
259
+ if (instanceFields.some((field) => field.initializer) &&
260
+ instanceFields.some((field) => !field.initializer && !field.declare)) {
261
+ emissionError(context, `class ${declaration.binding.name} partially initializes its fields`);
262
+ }
263
+ const structVisibility = declaration.exported || context.apiReferencedBindingIds.has(declaration.binding.id) ? 'pub ' : '';
264
+ const lines = [
265
+ emitRustRecordDerive([...instanceFields.map((field) => field.type), ...(declaration.extends ? [declaration.extends] : [])], context),
266
+ `${structVisibility}struct ${getBindingTargetNameRust(declaration.binding, context)}${emitTypeParameters(declaration.typeParameters, context)} {`,
267
+ ];
268
+ if (concreteBase) {
269
+ lines.push(` ${safeRustValueName('base')}: ${getBindingTargetNameRust(concreteBase.binding, context)},`);
270
+ }
271
+ for (const field of instanceFields) {
272
+ lines.push(` ${field.visibility === 'public' ? 'pub ' : ''}${safeRustValueName(field.name)}: ${emitType(field.type, context)},`);
273
+ }
274
+ lines.push('}');
275
+ // A field initializer is a constructor obligation, and the neutral plan already decides when each
276
+ // field is initialized. Rust has no implicit constructor, so the plan becomes an associated `new`.
277
+ const initialization = instanceFields.every((field) => field.initializer || field.declare) && instanceFields.length > 0 && constructed
278
+ ? createIrClassInitializationPlan(declaration)
279
+ : undefined;
280
+ const associated = staticFields.map((field) => ` ${field.visibility === 'public' ? 'pub ' : ''}const ${constantRustName(field.name)}: ${emitType(field.type, context)} = ${emitExpression(field.initializer, context)};`);
281
+ if (constructorFields && declaration.classConstructor) {
282
+ associated.push(` ${structVisibility}fn new(${declaration.classConstructor.parameters.map((parameter) => emitParameter(parameter, context)).join(', ')}) -> Self {`, ' Self {', ...constructorFields.map((field) => ` ${safeRustValueName(field.name)}: ${emitOwnedOperandRust(field.value, context)},`), ' }', ' }');
283
+ }
284
+ if (compositionInit && concreteBase && declaration.classConstructor) {
285
+ associated.push(` ${structVisibility}fn new(${declaration.classConstructor.parameters.map((parameter) => emitParameter(parameter, context)).join(', ')}) -> Self {`, ' Self {', ` ${safeRustValueName('base')}: ${getBindingTargetNameRust(concreteBase.binding, context)}::new(${compositionInit.superArguments.map((argument) => emitOwnedOperandRust(argument, context)).join(', ')}),`, ...compositionInit.childFields.map((field) => ` ${safeRustValueName(field.name)}: ${emitOwnedOperandRust(field.value, context)},`), ' }', ' }');
286
+ }
287
+ if (initialization) {
288
+ const instanceOrder = initialization.fields.filter((field) => declaration.fields[field.fieldIndex] && !declaration.fields[field.fieldIndex].static);
289
+ associated.push(` ${structVisibility}fn new() -> Self {`, ' Self {', ...instanceOrder.map((field) => {
290
+ const source = declaration.fields[field.fieldIndex];
291
+ if (source.declare)
292
+ return ` ${safeRustValueName(source.name)}: Default::default(),`;
293
+ return ` ${safeRustValueName(source.name)}: ${emitExpression(source.initializer, context)},`;
294
+ }), ' }', ' }');
295
+ }
296
+ const mutatingMethodNames = getIrClassMutatingMethodNamesRust(declaration);
297
+ // A trait's methods belong in its `impl` block, not in the inherent one, so the two are split by
298
+ // which trait declares each method name.
299
+ const traitMethodNames = new Map();
300
+ for (const reference of declaration.implements) {
301
+ if (reference.kind !== 'named' || reference.reference.kind !== 'binding')
302
+ continue;
303
+ const target = context.module.declarations.find((candidate) => candidate.kind === 'interface' &&
304
+ reference.reference.kind === 'binding' &&
305
+ candidate.binding.id === reference.reference.binding.id);
306
+ if (target?.kind !== 'interface')
307
+ continue;
308
+ for (const property of target.properties)
309
+ traitMethodNames.set(property.name, emitType(reference, context));
310
+ }
311
+ const traitAbstractFields = new Map();
312
+ if (abstractBase) {
313
+ const traitName = getBindingTargetNameRust(abstractBase.binding, context);
314
+ for (const method of abstractBase.methods)
315
+ traitMethodNames.set(method.name, traitName);
316
+ const abstractFields = abstractBase.fields.filter((field) => field.abstract);
317
+ if (abstractFields.length > 0)
318
+ traitAbstractFields.set(traitName, abstractFields);
319
+ }
320
+ const traitDataProperties = new Map();
321
+ for (const reference of declaration.implements) {
322
+ if (reference.kind !== 'named' || reference.reference.kind !== 'binding')
323
+ continue;
324
+ const target = context.module.declarations.find((candidate) => candidate.kind === 'interface' &&
325
+ reference.reference.kind === 'binding' &&
326
+ candidate.binding.id === reference.reference.binding.id);
327
+ if (target?.kind !== 'interface')
328
+ continue;
329
+ traitDataProperties.set(emitType(reference, context), target.properties.filter((property) => property.type.kind !== 'function'));
330
+ }
331
+ if (concreteBase) {
332
+ context.compositionBase = {
333
+ baseDeclaration: concreteBase,
334
+ fieldName: 'base',
335
+ };
336
+ }
337
+ const inherentMethods = declaration.methods.filter((method) => !traitMethodNames.has(method.name));
338
+ const emitMethodLines = (method) => {
339
+ // Rust has no properties, so an accessor is a method. A setter takes the receiver mutably and is
340
+ // named apart from the getter, because Rust has one namespace for both and the source had two.
341
+ const target = getIrClassMethodTargetNameRust(method);
342
+ const receiver = method.accessor === 'set' || mutatingMethodNames.has(target) ? '&mut self' : '&self';
343
+ const parameters = [
344
+ ...(method.static ? [] : [receiver]),
345
+ ...method.parameters.map((parameter) => emitParameter(parameter, context)),
346
+ ].join(', ');
347
+ // A setter yields nothing. The source wrote no return type and the neutral model kept that
348
+ // unknown, but the accessor contract already decides it.
349
+ const returns = method.accessor === 'set' ? '()' : emitType(method.returns, context);
350
+ return [
351
+ ` ${method.visibility === 'public' && !traitMethodNames.has(method.name) ? 'pub ' : ''}fn ${target}${emitTypeParameters(method.typeParameters, context)}(${parameters}) -> ${returns} {`,
352
+ ...indentSourceLines(emitStatements(method.body, context), 2),
353
+ ' }',
354
+ ];
355
+ };
356
+ for (const trait of [...inheritedTraits, ...implementedTraits]) {
357
+ const traitMethods = declaration.methods.filter((method) => traitMethodNames.get(method.name) === trait);
358
+ lines.push('', `impl${emitTypeParameters(declaration.typeParameters, context)} ${trait} for ${getBindingTargetNameRust(declaration.binding, context)}${emitTypeArguments(declaration.typeParameters, context)} {`);
359
+ const traitAccessors = traitDataProperties.get(trait) ?? [];
360
+ const abstractFields = traitAbstractFields.get(trait) ?? [];
361
+ let emittedCount = 0;
362
+ abstractFields.forEach((field) => {
363
+ if (emittedCount > 0)
364
+ lines.push('');
365
+ const owned = isIrTypeCopyValueRust(field.type) ? '' : '.clone()';
366
+ lines.push(` fn ${safeRustValueName(field.name)}(&self) -> ${emitType(field.type, context)} {`, ` self.${safeRustValueName(field.name)}${owned}`, ' }');
367
+ emittedCount++;
368
+ });
369
+ traitMethods.forEach((method) => {
370
+ if (emittedCount > 0)
371
+ lines.push('');
372
+ lines.push(...emitMethodLines(method));
373
+ emittedCount++;
374
+ });
375
+ traitAccessors.forEach((property) => {
376
+ if (emittedCount > 0)
377
+ lines.push('');
378
+ lines.push(` fn ${safeRustValueName(property.name)}(&self) -> ${emitType(property.type, context)} {`, ` self.${safeRustValueName(property.name)}.clone()`, ' }');
379
+ emittedCount++;
380
+ });
381
+ lines.push('}');
382
+ }
383
+ if (inherentMethods.length > 0 || associated.length > 0) {
384
+ lines.push('', `impl${emitTypeParameters(declaration.typeParameters, context)} ${getBindingTargetNameRust(declaration.binding, context)}${emitTypeArguments(declaration.typeParameters, context)} {`, ...associated);
385
+ inherentMethods.forEach((method, index) => {
386
+ if (index > 0 || associated.length > 0)
387
+ lines.push('');
388
+ lines.push(...emitMethodLines(method));
389
+ });
390
+ lines.push('}');
391
+ }
392
+ if (concreteBase) {
393
+ context.compositionBase = undefined;
394
+ }
395
+ return lines;
396
+ }
397
+ function emitDeclaration(declaration, context) {
398
+ switch (declaration.kind) {
399
+ case 'class':
400
+ return emitClass(declaration, context);
401
+ case 'enum':
402
+ return emitEnum(declaration, context);
403
+ case 'function':
404
+ return emitFunction(declaration, context);
405
+ case 'interface':
406
+ return emitInterface(declaration, context);
407
+ case 'typeAlias':
408
+ return emitTypeAlias(declaration, context);
409
+ case 'variable':
410
+ return emitVariableDeclaration(declaration, context);
411
+ }
412
+ }
413
+ function emitEnum(declaration, context) {
414
+ const values = declaration.members.map((member) => member.value);
415
+ const namespaceFunctions = getIrEnumNamespaceFunctionsRust(declaration, context.module);
416
+ if (namespaceFunctions.length > 0) {
417
+ if (values.some((value) => typeof value !== 'number' || !Number.isInteger(value))) {
418
+ emissionError(context, `enum ${declaration.binding.name} value namespace requires integer discriminants`);
419
+ }
420
+ if (values.some((value) => Number(value) < -2_147_483_648 || Number(value) > 2_147_483_647)) {
421
+ emissionError(context, `enum ${declaration.binding.name} has a discriminant outside the Rust i32 range`);
422
+ }
423
+ return emitNumericEnumNamespaceWrapperRust(declaration, namespaceFunctions, context);
424
+ }
425
+ if (values.every((value) => typeof value === 'string'))
426
+ return emitStringEnumRust(declaration, context);
427
+ if (values.some((value) => typeof value !== 'number' || !Number.isInteger(value))) {
428
+ emissionError(context, `enum ${declaration.binding.name} requires one discriminant domain for Rust`);
429
+ }
430
+ if (values.some((value) => Number(value) < -2_147_483_648 || Number(value) > 2_147_483_647)) {
431
+ emissionError(context, `enum ${declaration.binding.name} has a discriminant outside the Rust i32 range`);
432
+ }
433
+ const visibility = declaration.exported || context.apiReferencedBindingIds.has(declaration.binding.id) ? 'pub ' : '';
434
+ const lines = [
435
+ '#[derive(Clone, Copy, Debug, PartialEq, Eq)]',
436
+ '#[repr(i32)]',
437
+ `${visibility}enum ${getBindingTargetNameRust(declaration.binding, context)} {`,
438
+ ];
439
+ declaration.members.forEach((member) => {
440
+ lines.push(` ${safeRustTypeName(member.name)} = ${String(member.value)},`);
441
+ });
442
+ lines.push('}');
443
+ return lines;
444
+ }
445
+ function getIrEnumNamespaceFunctionsRust(declaration, module) {
446
+ return module.declarations.filter((candidate) => candidate.kind === 'function' &&
447
+ candidate.namespaceMember?.kind === 'binding' &&
448
+ candidate.namespaceMember.binding.id === declaration.binding.id &&
449
+ candidate.namespaceMember.path.length === 1);
450
+ }
451
+ function emitNumericEnumNamespaceWrapperRust(declaration, namespaceFunctions, context) {
452
+ const name = getBindingTargetNameRust(declaration.binding, context);
453
+ const visibility = declaration.exported || context.apiReferencedBindingIds.has(declaration.binding.id) ? 'pub ' : '';
454
+ const lines = [
455
+ '#[derive(Clone, Copy, Debug, PartialEq, Eq)]',
456
+ `${visibility}struct ${name}(i32);`,
457
+ '',
458
+ `impl ${name} {`,
459
+ ...declaration.members.map((member) => ` ${visibility}const ${safeRustTypeName(member.name)}: Self = Self(${String(member.value)});`),
460
+ ];
461
+ for (const namespaceFunction of namespaceFunctions) {
462
+ lines.push('', ...indentSourceLines(emitEnumNamespaceFunctionRust(namespaceFunction, context)));
463
+ }
464
+ lines.push('}');
465
+ return lines;
466
+ }
467
+ function emitEnumNamespaceFunctionRust(declaration, outer) {
468
+ const context = {
469
+ ...outer,
470
+ activeTypeParameters: declaration.typeParameters,
471
+ enclosingReturnType: declaration.returns,
472
+ returnsAbsent: hasIrTypeAbsentMember(declaration.returns),
473
+ };
474
+ if (declaration.async)
475
+ emissionError(context, 'async enum namespace functions require Rust task lowering');
476
+ return [
477
+ `pub fn ${safeRustValueName(declaration.binding.name)}${emitTypeParameters(declaration.typeParameters, context)}(${declaration.parameters.map((parameter) => emitParameter(parameter, context)).join(', ')}) -> ${emitType(declaration.returns, context)} {`,
478
+ ...indentSourceLines(emitStatements(declaration.body, context)),
479
+ '}',
480
+ ];
481
+ }
482
+ // Rust discriminants are integers, so a string enum keeps unit variants and carries its source
483
+ // values as an explicit mapping. Both directions are emitted because the source language treats the
484
+ // value as the enum: code compares against it and constructs from it.
485
+ function emitStringEnumRust(declaration, context) {
486
+ const name = getBindingTargetNameRust(declaration.binding, context);
487
+ const visibility = declaration.exported || context.apiReferencedBindingIds.has(declaration.binding.id) ? 'pub ' : '';
488
+ return [
489
+ '#[derive(Clone, Copy, Debug, PartialEq, Eq)]',
490
+ `${visibility}enum ${name} {`,
491
+ ...declaration.members.map((member) => ` ${safeRustTypeName(member.name)},`),
492
+ '}',
493
+ '',
494
+ `impl ${name} {`,
495
+ ` ${visibility}fn as_str(&self) -> &'static str {`,
496
+ ' match self {',
497
+ ...declaration.members.map((member) => ` ${name}::${safeRustTypeName(member.name)} => ${JSON.stringify(String(member.value))},`),
498
+ ' }',
499
+ ' }',
500
+ '',
501
+ ` ${visibility}fn from_str(value: &str) -> Option<Self> {`,
502
+ ' match value {',
503
+ ...declaration.members.map((member) => ` ${JSON.stringify(String(member.value))} => Some(${name}::${safeRustTypeName(member.name)}),`),
504
+ ' _ => None,',
505
+ ' }',
506
+ ' }',
507
+ '}',
508
+ ];
509
+ }
510
+ function emitExpression(expression, context) {
511
+ switch (expression.kind) {
512
+ case 'array':
513
+ return `vec![${expression.elements.map((element) => (element ? emitOwnedOperandRust(element, context) : 'Default::default()')).join(', ')}]`;
514
+ case 'assignment': {
515
+ const typedArrayAssignment = emitTypedArrayElementAssignmentRust(expression, context);
516
+ if (typedArrayAssignment)
517
+ return typedArrayAssignment;
518
+ if (expression.left.kind === 'identifier' &&
519
+ expression.left.reference.kind === 'binding' &&
520
+ context.cellWrappedBindingIds.has(expression.left.reference.binding.id)) {
521
+ const name = emitIdentifierReferenceRust(expression.left.reference, context);
522
+ const right = emitExpression(expression.right, context);
523
+ if (expression.operator === '=')
524
+ return `${name}.set(${right})`;
525
+ if (expression.operator === '**=' &&
526
+ expression.semantics.left.flow === 'number' &&
527
+ expression.semantics.right.flow === 'number') {
528
+ return `${name}.set(f64::powf(${name}.get(), ${right}))`;
529
+ }
530
+ if (expression.operator === '>>>=' &&
531
+ expression.semantics.left.flow === 'number' &&
532
+ expression.semantics.right.flow === 'number') {
533
+ return `${name}.set(((((${name}.get() as i32) as u32) >> (${right} as u32)) as f64))`;
534
+ }
535
+ if ((expression.operator === '&=' ||
536
+ expression.operator === '|=' ||
537
+ expression.operator === '^=' ||
538
+ expression.operator === '<<=' ||
539
+ expression.operator === '>>=') &&
540
+ expression.semantics.left.flow === 'number' &&
541
+ expression.semantics.right.flow === 'number') {
542
+ const binaryOp = expression.operator.slice(0, -1);
543
+ return `${name}.set((((${name}.get() as i32) ${binaryOp} (${right} as i32)) as f64))`;
544
+ }
545
+ if (expression.operator === '||=' || expression.operator === '&&=') {
546
+ if (expression.semantics.left.flow === 'boolean') {
547
+ const condition = expression.operator === '||=' ? `!${name}.get()` : `${name}.get()`;
548
+ return `{ if ${condition} { ${name}.set(${right}); } ${name}.get() }`;
549
+ }
550
+ if (expression.semantics.left.flow === 'number') {
551
+ const condition = expression.operator === '||='
552
+ ? `${name}.get() == 0.0 || ${name}.get().is_nan()`
553
+ : `${name}.get() != 0.0 && !${name}.get().is_nan()`;
554
+ return `{ if ${condition} { ${name}.set(${right}); } ${name}.get() }`;
555
+ }
556
+ }
557
+ if (expression.operator === '??=') {
558
+ if (context.nullableBindingIds.has(expression.left.reference.binding.id) &&
559
+ (expression.semantics.right.flow === 'number' || expression.semantics.right.flow === 'boolean')) {
560
+ return `{ if ${name}.get().is_none() { ${name}.set(Some(${right})); } ${name}.get().clone().unwrap() }`;
561
+ }
562
+ emissionError(context, `operator ${expression.operator} on ${expression.semantics.left.flow} and ${expression.semantics.right.flow} requires Rust type-directed lowering`);
563
+ }
564
+ if (!isAssignmentOperatorDirectRust(expression.operator, expression.semantics)) {
565
+ emissionError(context, `operator ${expression.operator} on ${expression.semantics.left.flow} and ${expression.semantics.right.flow} requires Rust type-directed lowering`);
566
+ }
567
+ const op = expression.operator.slice(0, -1);
568
+ return `${name}.set(${name}.get() ${op} ${normalizeSourceTextGrouping(right)})`;
569
+ }
570
+ if (expression.left.kind === 'identifier' &&
571
+ expression.left.reference.kind === 'binding' &&
572
+ context.refCellWrappedBindingIds.has(expression.left.reference.binding.id)) {
573
+ const name = emitIdentifierReferenceRust(expression.left.reference, context);
574
+ const right = emitExpression(expression.right, context);
575
+ if (expression.operator === '=')
576
+ return `${name}.replace(${right})`;
577
+ if (expression.operator === '??=') {
578
+ if (context.nullableBindingIds.has(expression.left.reference.binding.id)) {
579
+ return `{ if ${name}.borrow().is_none() { *${name}.borrow_mut() = Some(${right}); } ${name}.borrow().clone().unwrap() }`;
580
+ }
581
+ emissionError(context, 'operator ??= on ref-cell-wrapped binding requires a nullable Rust target');
582
+ }
583
+ emissionError(context, `operator ${expression.operator} on non-Copy ref-cell-wrapped binding requires Rust type-directed lowering`);
584
+ }
585
+ if (expression.operator === '=' &&
586
+ expression.left.kind === 'property' &&
587
+ getIrExpressionClassAccessorRust(expression.left.object, expression.left.name, 'set', context)) {
588
+ return `${emitExpression(expression.left.object, context)}.set_${safeRustValueName(expression.left.name)}(${emitOwnedOperandRust(expression.right, context)})`;
589
+ }
590
+ if (expression.operator === '+=' &&
591
+ expression.semantics.left.flow === 'string' &&
592
+ expression.semantics.right.flow === 'string') {
593
+ const left = emitExpression(expression.left, context);
594
+ const right = emitExpression(expression.right, context);
595
+ return `${left}.push_str(&${normalizeSourceTextGrouping(right)})`;
596
+ }
597
+ if ((expression.operator === '&=' ||
598
+ expression.operator === '|=' ||
599
+ expression.operator === '^=' ||
600
+ expression.operator === '<<=' ||
601
+ expression.operator === '>>=') &&
602
+ expression.semantics.left.flow === 'number' &&
603
+ expression.semantics.right.flow === 'number') {
604
+ const left = emitExpression(expression.left, context);
605
+ const right = emitExpression(expression.right, context);
606
+ const binaryOp = expression.operator.slice(0, -1);
607
+ return `${left} = (((${left} as i32) ${binaryOp} (${right} as i32)) as f64)`;
608
+ }
609
+ if (expression.operator === '**=' &&
610
+ expression.semantics.left.flow === 'number' &&
611
+ expression.semantics.right.flow === 'number') {
612
+ const left = emitExpression(expression.left, context);
613
+ const right = emitExpression(expression.right, context);
614
+ return `${left} = f64::powf(${left}, ${right})`;
615
+ }
616
+ if (expression.operator === '>>>=' &&
617
+ expression.semantics.left.flow === 'number' &&
618
+ expression.semantics.right.flow === 'number') {
619
+ const left = emitExpression(expression.left, context);
620
+ const right = emitExpression(expression.right, context);
621
+ return `${left} = ((((${left} as i32) as u32) >> (${right} as u32)) as f64)`;
622
+ }
623
+ if (expression.operator === '||=' || expression.operator === '&&=') {
624
+ const left = emitExpression(expression.left, context);
625
+ const right = emitExpression(expression.right, context);
626
+ if (expression.semantics.left.flow === 'boolean') {
627
+ const condition = expression.operator === '||=' ? `!${left}` : left;
628
+ return `{ if ${condition} { ${left} = ${right}; } ${left} }`;
629
+ }
630
+ if (expression.semantics.left.flow === 'number') {
631
+ const condition = expression.operator === '||='
632
+ ? `${left} == 0.0 || ${left}.is_nan()`
633
+ : `${left} != 0.0 && !${left}.is_nan()`;
634
+ return `{ if ${condition} { ${left} = ${right}; } ${left} }`;
635
+ }
636
+ if (expression.semantics.left.flow === 'string') {
637
+ const condition = expression.operator === '||=' ? `${left}.is_empty()` : `!${left}.is_empty()`;
638
+ return `{ if ${condition} { ${left} = ${right}; } ${left} }`;
639
+ }
640
+ emissionError(context, `operator ${expression.operator} on ${expression.semantics.left.flow} requires Rust semantic lowering`);
641
+ }
642
+ if (expression.operator === '??=') {
643
+ const left = emitExpression(expression.left, context);
644
+ const right = emitExpression(expression.right, context);
645
+ if (expression.left.kind === 'identifier' &&
646
+ expression.left.reference.kind === 'binding' &&
647
+ context.nullableBindingIds.has(expression.left.reference.binding.id)) {
648
+ return `{ if ${left}.is_none() { ${left} = Some(${right}); } ${left}.clone().unwrap() }`;
649
+ }
650
+ emissionError(context, 'operator ??= requires a nullable Rust target');
651
+ }
652
+ if (expression.operator === '=' &&
653
+ expression.left.kind === 'identifier' &&
654
+ expression.left.reference.kind === 'binding') {
655
+ const targetType = context.bindingTypes.get(expression.left.reference.binding.id);
656
+ const dualSentinelUnion = targetType ? resolveDualSentinelUnionEnumRust(targetType, context) : undefined;
657
+ if (dualSentinelUnion) {
658
+ const wrapped = emitDualSentinelUnionConstructionRust(expression.right, dualSentinelUnion, context);
659
+ if (wrapped)
660
+ return `${emitExpression(expression.left, context)} = ${wrapped}`;
661
+ }
662
+ const enumName = context.primitiveUnionBindingIds.get(expression.left.reference.binding.id);
663
+ if (enumName) {
664
+ const targetEnum = [...context.primitiveUnionEnums.values()].find((e) => e.name === enumName);
665
+ if (targetEnum) {
666
+ const wrapped = emitPrimitiveUnionConstructionRust(expression.right, targetEnum, context);
667
+ if (wrapped) {
668
+ return `${emitExpression(expression.left, context)} = ${wrapped}`;
669
+ }
670
+ }
671
+ }
672
+ }
673
+ const left = emitExpression(expression.left, context);
674
+ const right = emitOptionalTargetOperandRust(expression.left, expression.right, context);
675
+ return `${left} ${emitAssignmentOperatorRust(expression.operator, expression.semantics, context)} ${normalizeSourceTextGrouping(right)}`;
676
+ }
677
+ case 'await':
678
+ // `.await` consumes the future it is given, while the source language's await does not consume
679
+ // the promise: a promise settles once and every await sees that settlement. A task reached more
680
+ // than once is therefore cloned, which the runtime contract's first-call-wins settlement is
681
+ // what makes equivalent.
682
+ return `${emitOwnedOperandRust(expression.expression, context)}.await`;
683
+ case 'binary': {
684
+ if (expression.semantics.nullishComparison) {
685
+ const evidence = expression.semantics.nullishComparison;
686
+ // A single absent member uses `Option`. When both source sentinels are possible the binding
687
+ // instead carries a generated enum, so strict comparison selects one unit variant while
688
+ // loose comparison deliberately accepts either.
689
+ if (evidence.admitsNull && evidence.admitsUndefined) {
690
+ const operand = expression.left.kind === 'identifier' && expression.left.reference.kind === 'ambient'
691
+ ? expression.right
692
+ : expression.left;
693
+ const union = getIrExpressionDualSentinelUnionRust(operand, context);
694
+ if (!union) {
695
+ emissionError(context, 'dual-sentinel nullish comparison requires Rust union representation evidence');
696
+ }
697
+ const strict = expression.operator === '===' || expression.operator === '!==';
698
+ const patterns = strict
699
+ ? [`${union.name}::${evidence.literal === 'null' ? 'Null' : 'Undefined'}`]
700
+ : [`${union.name}::Null`, `${union.name}::Undefined`];
701
+ const test = `matches!(&${emitExpression(operand, context)}, ${patterns.join(' | ')})`;
702
+ return expression.operator === '!=' || expression.operator === '!==' ? `!${test}` : test;
703
+ }
704
+ const operand = expression.left.kind === 'identifier' && expression.left.reference.kind === 'ambient'
705
+ ? expression.right
706
+ : expression.left;
707
+ const negated = expression.operator === '!=' || expression.operator === '!==';
708
+ return `${emitExpression(operand, context)}.${negated ? 'is_some' : 'is_none'}()`;
709
+ }
710
+ if (expression.operator === '??') {
711
+ // Rust has no `??`. The shape is `Option::unwrap_or_else`, which needs the left operand to
712
+ // already be an Option — an optional chain produces one, an ordinary value does not.
713
+ // A coalesce whose left cannot be absent is its left: the default is unreachable, and the
714
+ // source's own types are what say so.
715
+ if (expression.left.kind === 'property' && expression.left.optionalChain?.receiverNullish === 'excluded') {
716
+ return emitExpression(expression.left, context);
717
+ }
718
+ if (!isIrExpressionOptionShapedRust(expression.left, context)) {
719
+ emissionError(context, 'operator ?? requires an Option-shaped left operand for Rust');
720
+ }
721
+ return `${emitOptionShapedOperandRust(expression.left, context)}.unwrap_or_else(|| ${emitExpression(expression.right, context)})`;
722
+ }
723
+ if (expression.operator === '+' &&
724
+ expression.semantics.left.flow === 'string' &&
725
+ expression.semantics.right.flow === 'string') {
726
+ return emitStringConcatenationRust(expression, context);
727
+ }
728
+ if ((expression.operator === '==' ||
729
+ expression.operator === '===' ||
730
+ expression.operator === '!=' ||
731
+ expression.operator === '!==') &&
732
+ ((isIrExpressionTypedArrayRust(expression.left, context) &&
733
+ isIrExpressionTypedArrayRust(expression.right, context)) ||
734
+ (isIrExpressionDataViewRust(expression.left, context) &&
735
+ isIrExpressionDataViewRust(expression.right, context)) ||
736
+ (isIrExpressionArrayBufferRust(expression.left, context) &&
737
+ isIrExpressionArrayBufferRust(expression.right, context)))) {
738
+ const operator = expression.operator === '!=' || expression.operator === '!==' ? '!=' : '==';
739
+ return `(${emitExpression(expression.left, context)} ${operator} ${emitExpression(expression.right, context)})`;
740
+ }
741
+ const typeofTest = getTypeofTypeTestRust(expression, context);
742
+ if (typeofTest) {
743
+ const operand = emitExpression(typeofTest.operand, context);
744
+ const test = `matches!(${operand}, ${typeofTest.enumName}::${typeofTest.variantName}(_))`;
745
+ return typeofTest.negated ? `!${test}` : test;
746
+ }
747
+ if (expression.operator === '**' &&
748
+ expression.semantics.left.flow === 'number' &&
749
+ expression.semantics.right.flow === 'number') {
750
+ const left = emitExpression(expression.left, context);
751
+ const right = emitExpression(expression.right, context);
752
+ return `f64::powf(${left}, ${right})`;
753
+ }
754
+ if (expression.operator === '>>>' &&
755
+ expression.semantics.left.flow === 'number' &&
756
+ expression.semantics.right.flow === 'number') {
757
+ const left = emitExpression(expression.left, context);
758
+ const right = emitExpression(expression.right, context);
759
+ return `((((${left} as i32) as u32) >> (${right} as u32)) as f64)`;
760
+ }
761
+ const op = emitBinaryOperatorRust(expression.operator, expression.semantics, context);
762
+ const bitwise = expression.operator === '&' ||
763
+ expression.operator === '|' ||
764
+ expression.operator === '^' ||
765
+ expression.operator === '<<' ||
766
+ expression.operator === '>>';
767
+ const left = emitNumericEnumOperandRust(expression.left, context);
768
+ const right = emitNumericEnumOperandRust(expression.right, context);
769
+ if (bitwise)
770
+ return `(((${left} as i32) ${op} (${right} as i32)) as f64)`;
771
+ return `(${left} ${op} ${right})`;
772
+ }
773
+ case 'call':
774
+ if (expression.semantics.statementValue)
775
+ return emitStatementValueExpressionRust(expression, context);
776
+ if (expression.optional)
777
+ return emitOptionalCallExpressionRust(expression, context);
778
+ // Rust joins a slice of strings with a borrowed separator, while the source hands it an owned
779
+ // one. The separator is the only argument, so the borrow is decided here rather than by a
780
+ // general rule about where an owned string may stand.
781
+ if (expression.callee.kind === 'property' &&
782
+ expression.callee.member?.receiver === 'array' &&
783
+ expression.callee.member.name === 'join') {
784
+ const separator = expression.arguments[0];
785
+ if (expression.arguments.length !== 1 || !separator) {
786
+ emissionError(context, 'joining a collection requires exactly one separator argument');
787
+ }
788
+ return `${emitExpression(expression.callee.object, context)}.join(${emitBorrowedTextRust(separator, context)})`;
789
+ }
790
+ // Typed arrays use runtime views rather than Vec: slice copies storage, while subarray creates
791
+ // a distinct view sharing storage. Their bounds stay numeric until the runtime applies source
792
+ // relative-index rules (including negative and infinite bounds).
793
+ if (expression.callee.kind === 'property' &&
794
+ expression.callee.member?.receiver === 'typedArray' &&
795
+ (expression.callee.member.name === 'slice' || expression.callee.member.name === 'subarray')) {
796
+ if (expression.arguments.length > 2) {
797
+ emissionError(context, `${expression.callee.member.name} on a typed array takes at most a start and an end`);
798
+ }
799
+ const receiver = emitExpression(expression.callee.object, context);
800
+ const method = expression.callee.member.name;
801
+ if (expression.arguments.length === 0)
802
+ return `${receiver}.${method}(0.0)`;
803
+ const start = emitExpression(expression.arguments[0], context);
804
+ if (expression.arguments.length === 1)
805
+ return `${receiver}.${method}(${start})`;
806
+ return `${receiver}.${method}_range(${start}, ${emitExpression(expression.arguments[1], context)})`;
807
+ }
808
+ if (expression.semantics.typedArraySet) {
809
+ assertOneIrTypedArrayReceiverRust(expression.semantics.typedArraySet.receivers, context);
810
+ if (expression.callee.kind !== 'property' ||
811
+ expression.arguments.length < 1 ||
812
+ expression.arguments.length > 2) {
813
+ emissionError(context, 'setting a typed array requires a source and an optional offset');
814
+ }
815
+ const receiver = emitExpression(expression.callee.object, context);
816
+ const source = emitOwnedOperandRust(expression.arguments[0], context);
817
+ const offset = expression.arguments[1] ? emitExpression(expression.arguments[1], context) : '0.0';
818
+ return `${receiver}.copy_from(${source}, ${offset})`;
819
+ }
820
+ // An ordinary array slice is a Rust range copied back into an owned Vec.
821
+ if (expression.callee.kind === 'property' &&
822
+ expression.callee.member?.receiver === 'array' &&
823
+ expression.callee.member.name === 'slice') {
824
+ const receiver = emitExpression(expression.callee.object, context);
825
+ if (expression.arguments.length === 0)
826
+ return `${receiver}.clone()`;
827
+ if (expression.arguments.length > 2) {
828
+ emissionError(context, 'slicing a collection takes at most a start and an end');
829
+ }
830
+ const bounds = expression.arguments
831
+ .map((argument) => `${emitExpression(argument, context)} as usize`)
832
+ .join('..');
833
+ return `${receiver}[${expression.arguments.length === 1 ? `${bounds}..` : bounds}].to_vec()`;
834
+ }
835
+ if (expression.callee.kind === 'property' &&
836
+ expression.callee.member?.receiver === 'array' &&
837
+ expression.callee.member.name === 'concat' &&
838
+ expression.arguments.length === 1) {
839
+ const receiver = emitExpression(expression.callee.object, context);
840
+ const other = emitExpression(expression.arguments[0], context);
841
+ return `{ let mut __concat = ${receiver}; __concat.extend(${other}); __concat }`;
842
+ }
843
+ if (expression.callee.kind === 'property' &&
844
+ expression.callee.member?.receiver === 'string' &&
845
+ expression.callee.member.name === 'charAt' &&
846
+ expression.arguments.length === 1) {
847
+ const receiver = emitExpression(expression.callee.object, context);
848
+ const index = emitExpression(expression.arguments[0], context);
849
+ return `${receiver}.chars().nth(${index} as usize).map(|c| c.to_string()).unwrap_or_default()`;
850
+ }
851
+ if (expression.callee.kind === 'property' &&
852
+ expression.callee.member?.receiver === 'string' &&
853
+ expression.callee.member.name === 'charCodeAt' &&
854
+ expression.arguments.length === 1) {
855
+ const receiver = emitExpression(expression.callee.object, context);
856
+ const index = emitExpression(expression.arguments[0], context);
857
+ return `${receiver}.chars().nth(${index} as usize).map(|c| c as u32 as f64).unwrap_or(f64::NAN)`;
858
+ }
859
+ if (expression.callee.kind === 'property' &&
860
+ expression.callee.member?.receiver === 'string' &&
861
+ expression.callee.member.name === 'substring') {
862
+ const receiver = emitExpression(expression.callee.object, context);
863
+ if (expression.arguments.length === 0 || expression.arguments.length > 2) {
864
+ emissionError(context, 'string substring takes a start index and an optional end index');
865
+ }
866
+ const bounds = expression.arguments
867
+ .map((argument) => `${emitExpression(argument, context)} as usize`)
868
+ .join('..');
869
+ return `${receiver}[${expression.arguments.length === 1 ? `${bounds}..` : bounds}].to_string()`;
870
+ }
871
+ if (expression.callee.kind === 'property' && expression.callee.member) {
872
+ const binding = getCompilerRustAmbientMemberBinding(expression.callee.member);
873
+ if (binding && binding.kind !== 'countingMethod' && binding.kind !== 'propertyMethod') {
874
+ const receiver = emitPrimitiveUnionNarrowedReceiverRust(expression.callee.object, context) ??
875
+ emitExpression(expression.callee.object, context);
876
+ const borrows = binding.kind === 'borrowedMethod' || binding.kind === 'sentinelSearch' || binding.kind === 'splitCollect';
877
+ const values = expression.callee.member.receiver === 'dataView'
878
+ ? emitCallArgumentsRust(expression, context)
879
+ : expression.arguments.map((argument) => borrows ? emitBorrowedTextRust(argument, context) : emitExpression(argument, context));
880
+ if (binding.kind === 'runtimeMethod') {
881
+ const target = recordRuntimeTypeRust(binding.targetName, context);
882
+ return `${target}(&${receiver}${values.length > 0 ? `, ${values.join(', ')}` : ''})`;
883
+ }
884
+ if (binding.kind === 'predicatePosition') {
885
+ return emitArrayPredicatePositionRust(receiver, expression.arguments[0], values[0], binding.targetName, context);
886
+ }
887
+ if (binding.kind === 'iterator') {
888
+ const firstArg = expression.arguments[0];
889
+ const closure = binding.borrowsElement
890
+ ? emitBorrowedElementClosureRust(firstArg, context)
891
+ : firstArg && firstArg.kind !== 'function'
892
+ ? emitIteratorCallbackWrapperRust(firstArg, values[0], context)
893
+ : values[0];
894
+ const ordered = binding.argumentOrder
895
+ ? binding.argumentOrder.map((position) => values[position] ?? '')
896
+ : [closure ?? ''];
897
+ return `${receiver}.into_iter().${binding.targetName}(${ordered.join(', ')})${binding.collect ? '.collect::<Vec<_>>()' : ''}`;
898
+ }
899
+ if (binding.kind === 'positionSearch') {
900
+ const borrowed = expression.arguments.map((argument) => emitBorrowedTextRust(argument, context));
901
+ return `${receiver}.iter().${binding.targetName}(|x| x == ${borrowed.join(', ')}).map(|i| i as f64).unwrap_or(-1.0)`;
902
+ }
903
+ if (binding.kind === 'sentinelSearch') {
904
+ return `${receiver}.${binding.targetName}(${values.join(', ')}).map(|i| i as f64).unwrap_or(-1.0)`;
905
+ }
906
+ if (binding.kind === 'splitCollect') {
907
+ return `${receiver}.${binding.targetName}(${values.join(', ')}).map(|s| s.to_string()).collect::<Vec<String>>()`;
908
+ }
909
+ if (binding.kind === 'optionalLookup') {
910
+ const borrowed = expression.arguments.map((argument) => emitBorrowedTextRust(argument, context));
911
+ return `${receiver}.${binding.targetName}(${borrowed.join(', ')}).cloned()`;
912
+ }
913
+ const leading = binding.kind === 'method' ? (binding.leadingArguments ?? []) : [];
914
+ const trailing = binding.kind === 'borrowedMethod' ? (binding.trailingArguments ?? []) : [];
915
+ return `${receiver}.${binding.targetName}(${[...leading, ...values, ...trailing].join(', ')})${binding.owns ? '.to_owned()' : ''}`;
916
+ }
917
+ }
918
+ if (expression.arguments.length === 1 &&
919
+ expression.arguments[0].kind === 'spread' &&
920
+ expression.callee.kind === 'property' &&
921
+ expression.callee.object.kind === 'identifier' &&
922
+ expression.callee.object.reference.kind === 'ambient' &&
923
+ expression.callee.object.reference.name === 'Math') {
924
+ const foldTarget = rustMathSpreadFoldTargets[expression.callee.name];
925
+ if (foldTarget) {
926
+ const spreadOperand = emitExpression(expression.arguments[0].expression, context);
927
+ return `${spreadOperand}.iter().cloned().fold(${foldTarget.identity}, ${foldTarget.folder})`;
928
+ }
929
+ }
930
+ if (expression.callee.kind === 'identifier' &&
931
+ expression.callee.reference.kind === 'ambient' &&
932
+ expression.callee.reference.name === 'String' &&
933
+ expression.arguments.length === 1) {
934
+ const operand = emitExpression(expression.arguments[0], context);
935
+ return operand.startsWith('*') ? `(${operand}).to_string()` : `${operand}.to_string()`;
936
+ }
937
+ return `${expression.callee.kind === 'function' ? `(${emitExpression(expression.callee, context)})` : emitExpression(expression.callee, context)}(${emitCallArgumentsRust(expression, context).join(', ')})`;
938
+ case 'cast': {
939
+ const assertedUnknownType = expression.expression.kind === 'identifier' && expression.expression.reference.kind === 'binding'
940
+ ? context.assertedUnknownBindingTypes.get(expression.expression.reference.binding.id)
941
+ : undefined;
942
+ if (assertedUnknownType &&
943
+ expression.expression.kind === 'identifier' &&
944
+ expression.expression.reference.kind === 'binding' &&
945
+ areIrAssertedUnknownRepresentationsEqualRust(assertedUnknownType, expression.type)) {
946
+ return emitOwnedOperandRust(expression.expression, context);
947
+ }
948
+ const unionCast = emitPrimitiveUnionCastRust(expression, context);
949
+ if (unionCast)
950
+ return unionCast;
951
+ if (!isIrCastTargetNumericRust(expression.type)) {
952
+ emissionError(context, `cast to ${expression.type.kind} requires Rust type-directed lowering`);
953
+ }
954
+ return `(${emitExpression(expression.expression, context)} as ${emitType(expression.type, context)})`;
955
+ }
956
+ case 'conditional':
957
+ return `if ${emitExpression(expression.condition, context)} { ${emitExpression(expression.whenTrue, context)} } else { ${emitExpression(expression.whenFalse, context)} }`;
958
+ case 'element':
959
+ if (expression.optional)
960
+ return emitOptionalElementExpressionRust(expression, context);
961
+ {
962
+ const closedSelection = emitClosedKeyElementSelectionRust(expression, context);
963
+ if (closedSelection)
964
+ return closedSelection;
965
+ }
966
+ if (expression.semantics.receivers.includes('object')) {
967
+ emissionError(context, 'computed object access requires JavaScript property-key coercion lowering');
968
+ }
969
+ if (expression.semantics.receivers.includes('tuple')) {
970
+ const index = getElementAccessTupleIndexRust(expression, context);
971
+ return `${emitExpression(expression.object, context)}.${String(index)}`;
972
+ }
973
+ if (hasOnlyIrTypedArrayReceiversRust(expression.semantics.receivers)) {
974
+ assertOneIrTypedArrayReceiverRust(expression.semantics.receivers, context);
975
+ return `${emitExpression(expression.object, context)}.get_index(${emitNumericEnumOperandRust(expression.index, context)})`;
976
+ }
977
+ // A written index is already a whole number; sending it through the neutral numeric type and
978
+ // back is noise the source never asked for.
979
+ return `${emitExpression(expression.object, context)}[${emitIndexOperandRust(expression.index, context)}]`;
980
+ case 'function':
981
+ if (expression.async)
982
+ emissionError(context, 'async closures require Flight task lowering');
983
+ if (expression.typeParameters.length > 0)
984
+ emissionError(context, 'generic closures require monomorphization');
985
+ return expression.expression
986
+ ? `|${expression.parameters.map((parameter) => getBindingTargetNameRust(parameter.binding, context)).join(', ')}| ${normalizeSourceTextGrouping(emitExpression(expression.expression, context))}`
987
+ : `|${expression.parameters.map((parameter) => getBindingTargetNameRust(parameter.binding, context)).join(', ')}| {\n${indentSourceLines(emitStatements(expression.body, context)).join('\n')}\n}`;
988
+ case 'identifier': {
989
+ if (expression.reference.kind === 'binding' && context.cellWrappedBindingIds.has(expression.reference.binding.id))
990
+ return `${emitIdentifierReferenceRust(expression.reference, context)}.get()`;
991
+ if (expression.reference.kind === 'binding' &&
992
+ context.refCellWrappedBindingIds.has(expression.reference.binding.id)) {
993
+ const target = emitIdentifierReferenceRust(expression.reference, context);
994
+ if (expression.presence === 'narrowedPresent' &&
995
+ context.nullableBindingIds.has(expression.reference.binding.id))
996
+ return `${target}.borrow().clone().unwrap()`;
997
+ return `${target}.borrow().clone()`;
998
+ }
999
+ const dualSentinelUnion = getIrExpressionDualSentinelUnionRust(expression, context);
1000
+ if (expression.presence === 'narrowedPresent' && dualSentinelUnion) {
1001
+ const payloads = dualSentinelUnion.variants.filter((variant) => variant.kind === 'tuple');
1002
+ if (payloads.length !== 1) {
1003
+ emissionError(context, 'present dual-sentinel union requires one Rust payload alternative');
1004
+ }
1005
+ const target = emitIdentifierReferenceRust(expression.reference, context);
1006
+ return `match &${target} { ${dualSentinelUnion.name}::${payloads[0].name}(value) => value.clone(), _ => unreachable!() }`;
1007
+ }
1008
+ if (expression.presence === 'narrowedPresent' &&
1009
+ expression.reference.kind === 'binding' &&
1010
+ context.nullableBindingIds.has(expression.reference.binding.id))
1011
+ return `${emitIdentifierReferenceRust(expression.reference, context)}.clone().unwrap()`;
1012
+ const narrowedReceiver = emitPrimitiveUnionNarrowedReceiverRust(expression, context);
1013
+ if (narrowedReceiver)
1014
+ return expression.narrowedMember === 'string' ? `${narrowedReceiver}.clone()` : `*${narrowedReceiver}`;
1015
+ return emitIdentifierReferenceRust(expression.reference, context);
1016
+ }
1017
+ case 'literal':
1018
+ return emitLiteral(expression.value);
1019
+ case 'new':
1020
+ if (expression.callee.kind !== 'identifier') {
1021
+ emissionError(context, 'qualified constructors require Rust type-path lowering');
1022
+ }
1023
+ assertIrConstructorInvocationAbiRust(expression, context);
1024
+ {
1025
+ const constructor = emitConstructorReferenceRust(expression.callee.reference, context);
1026
+ if (expression.callee.reference.kind === 'ambient' &&
1027
+ rustTypedArrayConstructorNames.has(expression.callee.reference.name)) {
1028
+ const oneArgument = expression.arguments[0];
1029
+ const method = expression.arguments.length === 1 && oneArgument && isIrExpressionArrayBufferRust(oneArgument, context)
1030
+ ? 'from_buffer'
1031
+ : ['empty', 'from_source', 'from_buffer_offset', 'from_buffer_range'][expression.arguments.length];
1032
+ if (!method)
1033
+ emissionError(context, 'typed-array construction supports zero through three arguments');
1034
+ return `${constructor}::${method}(${expression.arguments.map((argument) => emitOwnedOperandRust(argument, context)).join(', ')})`;
1035
+ }
1036
+ if (expression.callee.reference.kind === 'ambient' && expression.callee.reference.name === 'DataView') {
1037
+ const method = [undefined, 'from_buffer', 'from_buffer_offset', 'from_buffer_range'][expression.arguments.length];
1038
+ if (!method)
1039
+ emissionError(context, 'DataView construction supports one through three arguments');
1040
+ return `${constructor}::${method}(${expression.arguments.map((argument) => emitOwnedOperandRust(argument, context)).join(', ')})`;
1041
+ }
1042
+ return `${constructor}::new(${expression.arguments.map((argument) => emitOwnedOperandRust(argument, context)).join(', ')})`;
1043
+ }
1044
+ case 'object':
1045
+ return emitObjectExpressionRust(expression, context);
1046
+ case 'objectRest':
1047
+ return emitObjectRestExpressionRust(expression, context);
1048
+ case 'property': {
1049
+ if (expression.optional)
1050
+ return emitOptionalPropertyExpressionRust(expression, context);
1051
+ const namespaceMember = expression.namespaceMember;
1052
+ if (namespaceMember?.kind === 'binding') {
1053
+ const owner = context.numericEnumNamespaceNames.get(namespaceMember.binding.id);
1054
+ const namespaceFunction = context.module.declarations.some((declaration) => declaration.kind === 'function' &&
1055
+ declaration.binding.name === expression.name &&
1056
+ declaration.namespaceMember?.kind === 'binding' &&
1057
+ declaration.namespaceMember.binding.id === namespaceMember.binding.id);
1058
+ if (owner && namespaceFunction)
1059
+ return `${owner}::${safeRustValueName(expression.name)}`;
1060
+ }
1061
+ // Rust spells a collection's length `len()`, and it counts in `usize` while the neutral numeric
1062
+ // domain is one type. The cast is what keeps the comparison it feeds well typed.
1063
+ // A member of the ambient surface is spelled by the table, not by the source's name. Rust
1064
+ // counts in `usize`, so a counting member is cast back into the neutral numeric domain.
1065
+ if (expression.member) {
1066
+ const binding = getCompilerRustAmbientMemberBinding(expression.member);
1067
+ if (!binding) {
1068
+ emissionError(context, `${expression.member.receiver} member ${expression.member.name} has no Rust binding`);
1069
+ }
1070
+ if (binding.kind === 'countingMethod') {
1071
+ const countingReceiver = emitPrimitiveUnionNarrowedReceiverRust(expression.object, context) ??
1072
+ emitExpression(expression.object, context);
1073
+ return `(${countingReceiver}.${binding.targetName}() as f64)`;
1074
+ }
1075
+ if (binding.kind === 'propertyMethod') {
1076
+ return `${emitExpression(expression.object, context)}.${binding.targetName}()`;
1077
+ }
1078
+ }
1079
+ // A union is a closed set of alternatives in Rust, so its fields are not reachable by name.
1080
+ // A reference control flow narrowed to one alternative reads that alternative's own field; an
1081
+ // unnarrowed one can only read what every alternative agrees on, through the shared accessor.
1082
+ // A class's static members belong to the type, not to a value of it, so Rust paths into the
1083
+ // type: an associated constant for a field and an associated function for a method. Reading
1084
+ // either off a value is the source language's spelling, not Rust's.
1085
+ const classDeclaration = getIrExpressionClassDeclarationRust(expression.object, context);
1086
+ if (classDeclaration) {
1087
+ const field = classDeclaration.fields.find((candidate) => candidate.static && candidate.name === expression.name);
1088
+ const method = classDeclaration.methods.find((candidate) => candidate.static && candidate.name === expression.name);
1089
+ if (field || method) {
1090
+ return `${getBindingTargetNameRust(classDeclaration.binding, context)}::${field ? constantRustName(expression.name) : safeRustValueName(expression.name)}`;
1091
+ }
1092
+ }
1093
+ // An enum member is a variant, not a field: Rust paths into the type rather than reading off a
1094
+ // value, and the variant keeps the source's own spelling.
1095
+ const enumeration = getIrExpressionEnumDeclarationRust(expression.object, context);
1096
+ if (enumeration) {
1097
+ return `${getBindingTargetNameRust(enumeration.binding, context)}::${safeRustTypeName(expression.name)}`;
1098
+ }
1099
+ // Reading a member of a narrowed `Option` only needs to look at it, so it is borrowed open
1100
+ // rather than copied out.
1101
+ const borrowedNarrow = emitBorrowedNarrowedReceiverRust(expression.object, context);
1102
+ if (borrowedNarrow !== undefined) {
1103
+ return `${borrowedNarrow}.${safeRustValueName(expression.name)}`;
1104
+ }
1105
+ const accessor = getIrExpressionClassAccessorRust(expression.object, expression.name, 'get', context);
1106
+ if (accessor)
1107
+ return `${emitExpression(expression.object, context)}.${safeRustValueName(expression.name)}()`;
1108
+ const union = getIrExpressionTaggedUnionRust(expression.object, context);
1109
+ if (union) {
1110
+ const object = emitExpression(expression.object, context);
1111
+ return expression.object.kind === 'identifier' && expression.object.narrowedMember
1112
+ ? `${object}.as_${safeRustValueName(expression.object.narrowedMember)}().${safeRustValueName(expression.name)}`
1113
+ : `${object}.${safeRustValueName(expression.name)}()`;
1114
+ }
1115
+ // A namespace-like ambient symbol has no target name of its own, so the member decides the
1116
+ // whole spelling: `Math.max` is `f64::max`, not `Math::max`.
1117
+ if (expression.object.kind === 'identifier' && expression.object.reference.kind === 'ambient') {
1118
+ const member = getCompilerRuntimeExternalMemberTargetRust(expression.object.reference.name, expression.name, context.options.hostBindings);
1119
+ if (member)
1120
+ return member;
1121
+ }
1122
+ if (expression.object.kind === 'identifier' &&
1123
+ expression.object.reference.kind === 'this' &&
1124
+ context.abstractFieldNames.has(expression.name)) {
1125
+ return `self.${safeRustValueName(expression.name)}()`;
1126
+ }
1127
+ if (expression.object.kind === 'identifier' &&
1128
+ expression.object.reference.kind === 'this' &&
1129
+ context.compositionBase &&
1130
+ isIrCompositionBaseMemberRust(expression.name, context.compositionBase.baseDeclaration)) {
1131
+ const baseField = context.compositionBase.baseDeclaration.fields.find((candidate) => !candidate.static && candidate.name === expression.name);
1132
+ const cloneSuffix = baseField && !isIrTypeCopyValueRust(baseField.type) ? '.clone()' : '';
1133
+ return `self.${safeRustValueName(context.compositionBase.fieldName)}.${safeRustValueName(expression.name)}${cloneSuffix}`;
1134
+ }
1135
+ const needsClone = expression.object.kind === 'element' ||
1136
+ (expression.object.kind === 'identifier' &&
1137
+ expression.object.reference.kind === 'this' &&
1138
+ isIrSelfFieldNonCopyRust(expression.name, context));
1139
+ const owned = needsClone ? '.clone()' : '';
1140
+ return `${emitExpression(expression.object, context)}${isAmbientIdentifier(expression.object) ? '::' : '.'}${safeRustValueName(expression.name)}${owned}`;
1141
+ }
1142
+ case 'regexp':
1143
+ emissionError(context, 'regular expressions require a downstream standard-library mapping');
1144
+ case 'spread':
1145
+ // As in Haxe: a fixed tuple spread is already normalized away, so what reaches here spreads an
1146
+ // unbounded collection into a fixed-arity callee, and Rust has no variadic call to lower it to.
1147
+ emissionError(context, 'spreading an unbounded collection requires a fold or a variadic target');
1148
+ case 'template': {
1149
+ const format = expression.parts
1150
+ .map((part) => (typeof part === 'string' ? part.replaceAll('{', '{{').replaceAll('}', '}}') : '{}'))
1151
+ .join('');
1152
+ const values = expression.parts.flatMap((part) => typeof part === 'string' ? [] : [emitExpression(part, context)]);
1153
+ return `format!(${JSON.stringify(format)}${values.length > 0 ? `, ${values.join(', ')}` : ''})`;
1154
+ }
1155
+ case 'tuple': {
1156
+ const elements = expression.elements.map((element) => {
1157
+ if (!element.expression)
1158
+ return 'None';
1159
+ const emitted = emitExpression(element.expression, context);
1160
+ return element.optional ? `Some(${emitted})` : emitted;
1161
+ });
1162
+ return `(${elements.join(', ')}${elements.length === 1 ? ',' : ''})`;
1163
+ }
1164
+ case 'tupleSpread':
1165
+ return emitTupleSpreadExpressionRust(expression, context);
1166
+ case 'tupleRest':
1167
+ return `${emitExpression(expression.object, context)}.${String(expression.start)}`;
1168
+ case 'tupleSuffix': {
1169
+ const object = emitExpression(expression.object, context);
1170
+ const elements = Array.from({ length: expression.width }, (_, offset) => `${object}.${String(expression.start + offset)}`);
1171
+ return `(${elements.join(', ')}${elements.length === 1 ? ',' : ''})`;
1172
+ }
1173
+ case 'unary': {
1174
+ if (expression.operator === '++' || expression.operator === '--') {
1175
+ return emitNumericUpdateUnaryRust(expression, context);
1176
+ }
1177
+ if (expression.operator === 'void') {
1178
+ return `{ ${emitExpression(expression.operand, context)}; () }`;
1179
+ }
1180
+ if (expression.operator === 'typeof') {
1181
+ const sourceName = getStaticTypeofNameRust(expression.semantics.operand.flow);
1182
+ if (!sourceName) {
1183
+ emissionError(context, `typeof on ${expression.semantics.operand.flow} requires Rust runtime representation evidence`);
1184
+ }
1185
+ if (expression.semantics.operand.flow === 'undefined')
1186
+ return '"undefined".to_owned()';
1187
+ return `{ let _ = &${emitExpression(expression.operand, context)}; ${JSON.stringify(sourceName)}.to_owned() }`;
1188
+ }
1189
+ const operand = expression.semantics.operand.flow === 'number'
1190
+ ? emitNumericEnumOperandRust(expression.operand, context)
1191
+ : emitExpression(expression.operand, context);
1192
+ const operator = emitPrefixUnaryOperatorRust(expression.operator, expression.semantics, context);
1193
+ if (expression.operator === '~')
1194
+ return `(!(${operand} as i32) as f64)`;
1195
+ if (expression.operator === '+' && expression.semantics.operand.flow === 'number')
1196
+ return operand;
1197
+ return `${operator}${operand}`;
1198
+ }
1199
+ case 'undefinedValue':
1200
+ getIrTypeOptionalPayloadRust(expression.type, 'contextual undefined value', context);
1201
+ return 'None';
1202
+ case 'undefinedDefault':
1203
+ return `${emitExpression(expression.value, context)}.unwrap_or_else(|| ${emitExpression(expression.fallback, context)})`;
1204
+ }
1205
+ }
1206
+ function emitTypedArrayElementAssignmentRust(expression, context) {
1207
+ if (expression.left.kind !== 'element' || !hasOnlyIrTypedArrayReceiversRust(expression.left.semantics.receivers)) {
1208
+ return undefined;
1209
+ }
1210
+ assertOneIrTypedArrayReceiverRust(expression.left.semantics.receivers, context);
1211
+ if (expression.semantics.right.flow !== 'number' ||
1212
+ (expression.operator !== '=' && expression.semantics.left.flow !== 'number')) {
1213
+ emissionError(context, `operator ${expression.operator} on a typed-array element requires numeric Rust lowering`);
1214
+ }
1215
+ const receiverName = getGeneratedTargetNameRust('typed_array', context);
1216
+ const indexName = getGeneratedTargetNameRust('typed_index', context);
1217
+ const valueName = getGeneratedTargetNameRust('typed_value', context);
1218
+ const receiver = emitExpression(expression.left.object, context);
1219
+ const index = emitNumericEnumOperandRust(expression.left.index, context);
1220
+ if (expression.operator === '=') {
1221
+ const right = expression.semantics.right.flow === 'number'
1222
+ ? emitNumericEnumOperandRust(expression.right, context)
1223
+ : emitExpression(expression.right, context);
1224
+ return `{ let ${receiverName} = &${receiver}; let ${indexName} = ${index}; let ${valueName} = ${right}; ${receiverName}.set_index(${indexName}, ${valueName}) }`;
1225
+ }
1226
+ const currentName = getGeneratedTargetNameRust('typed_current', context);
1227
+ const rightName = getGeneratedTargetNameRust('typed_right', context);
1228
+ const right = emitNumericEnumOperandRust(expression.right, context);
1229
+ if (expression.operator === '||=' || expression.operator === '&&=') {
1230
+ const assignCondition = expression.operator === '||='
1231
+ ? `${currentName} == 0.0 || ${currentName}.is_nan()`
1232
+ : `${currentName} != 0.0 && !${currentName}.is_nan()`;
1233
+ return `{ let ${receiverName} = &${receiver}; let ${indexName} = ${index}; let ${currentName} = ${receiverName}.get_index(${indexName}); if ${assignCondition} { let ${valueName} = ${right}; ${receiverName}.set_index(${indexName}, ${valueName}) } else { ${currentName} } }`;
1234
+ }
1235
+ if (expression.operator === '??=') {
1236
+ emissionError(context, 'operator ??= on a typed-array element requires absent-index lowering');
1237
+ }
1238
+ let operation;
1239
+ if (expression.operator === '**=') {
1240
+ operation = `f64::powf(${currentName}, ${rightName})`;
1241
+ }
1242
+ else if (expression.operator === '>>>=') {
1243
+ operation = `(((((${currentName} as i32) as u32) >> (${rightName} as u32)) as f64))`;
1244
+ }
1245
+ else if (expression.operator === '&=' ||
1246
+ expression.operator === '|=' ||
1247
+ expression.operator === '^=' ||
1248
+ expression.operator === '<<=' ||
1249
+ expression.operator === '>>=') {
1250
+ operation = `(((${currentName} as i32) ${expression.operator.slice(0, -1)} (${rightName} as i32)) as f64)`;
1251
+ }
1252
+ else if (expression.operator === '+=' ||
1253
+ expression.operator === '-=' ||
1254
+ expression.operator === '*=' ||
1255
+ expression.operator === '/=' ||
1256
+ expression.operator === '%=') {
1257
+ operation = `${currentName} ${expression.operator.slice(0, -1)} ${rightName}`;
1258
+ }
1259
+ else {
1260
+ emissionError(context, `operator ${expression.operator} on a typed-array element requires Rust lowering`);
1261
+ }
1262
+ return `{ let ${receiverName} = &${receiver}; let ${indexName} = ${index}; let ${currentName} = ${receiverName}.get_index(${indexName}); let ${rightName} = ${right}; let ${valueName} = ${operation}; ${receiverName}.set_index(${indexName}, ${valueName}) }`;
1263
+ }
1264
+ function hasOnlyIrTypedArrayReceiversRust(receivers) {
1265
+ return receivers.every((receiver) => rustTypedArrayReceiverNames.has(receiver));
1266
+ }
1267
+ function assertOneIrTypedArrayReceiverRust(receivers, context) {
1268
+ if (receivers.length !== 1) {
1269
+ emissionError(context, 'mixed typed-array receivers require Rust representation-union lowering');
1270
+ }
1271
+ }
1272
+ function isIrExpressionTypedArrayRust(expression, context) {
1273
+ let type;
1274
+ if (expression.kind === 'identifier' && expression.reference.kind === 'binding') {
1275
+ type = context.bindingTypes.get(expression.reference.binding.id);
1276
+ }
1277
+ else if (expression.kind === 'call') {
1278
+ if (expression.callee.kind === 'property' &&
1279
+ expression.callee.member?.receiver === 'typedArray' &&
1280
+ (expression.callee.member.name === 'slice' || expression.callee.member.name === 'subarray')) {
1281
+ return true;
1282
+ }
1283
+ type = expression.semantics.resultType;
1284
+ }
1285
+ else if (expression.kind === 'cast') {
1286
+ type = expression.type;
1287
+ }
1288
+ else if (expression.kind === 'new' &&
1289
+ expression.callee.kind === 'identifier' &&
1290
+ expression.callee.reference.kind === 'ambient') {
1291
+ return rustTypedArrayConstructorNames.has(expression.callee.reference.name);
1292
+ }
1293
+ return isIrTypeTypedArrayRust(type);
1294
+ }
1295
+ function isIrExpressionArrayBufferRust(expression, context) {
1296
+ if (expression.kind === 'identifier' && expression.reference.kind === 'binding') {
1297
+ const type = context.bindingTypes.get(expression.reference.binding.id);
1298
+ return type?.kind === 'named' && type.reference.kind === 'ambient' && type.reference.name === 'ArrayBuffer';
1299
+ }
1300
+ if (expression.kind === 'property' &&
1301
+ expression.name === 'buffer' &&
1302
+ (expression.member?.receiver === 'dataView' || expression.member?.receiver === 'typedArray')) {
1303
+ return true;
1304
+ }
1305
+ if (expression.kind === 'cast') {
1306
+ return (expression.type.kind === 'named' &&
1307
+ expression.type.reference.kind === 'ambient' &&
1308
+ expression.type.reference.name === 'ArrayBuffer');
1309
+ }
1310
+ return (expression.kind === 'new' &&
1311
+ expression.callee.kind === 'identifier' &&
1312
+ expression.callee.reference.kind === 'ambient' &&
1313
+ expression.callee.reference.name === 'ArrayBuffer');
1314
+ }
1315
+ function isIrExpressionDataViewRust(expression, context) {
1316
+ let type;
1317
+ if (expression.kind === 'identifier' && expression.reference.kind === 'binding') {
1318
+ type = context.bindingTypes.get(expression.reference.binding.id);
1319
+ }
1320
+ else if (expression.kind === 'cast') {
1321
+ type = expression.type;
1322
+ }
1323
+ else if (expression.kind === 'new' &&
1324
+ expression.callee.kind === 'identifier' &&
1325
+ expression.callee.reference.kind === 'ambient') {
1326
+ return expression.callee.reference.name === 'DataView';
1327
+ }
1328
+ return type?.kind === 'named' && type.reference.kind === 'ambient' && type.reference.name === 'DataView';
1329
+ }
1330
+ function isIrTypeTypedArrayRust(type) {
1331
+ return (type?.kind === 'named' &&
1332
+ type.reference.kind === 'ambient' &&
1333
+ rustTypedArrayConstructorNames.has(type.reference.name));
1334
+ }
1335
+ // `Promise<T>` in the return position of an `async fn` is the future Rust already builds, so the
1336
+ // emitted signature carries `T`. Anywhere else the task type has no native spelling yet.
1337
+ function getIrTaskAwaitedTypeRust(type, context) {
1338
+ if (type.kind !== 'named' || type.reference.kind !== 'ambient' || type.reference.name !== 'Promise') {
1339
+ emissionError(context, 'an async function must return a task type');
1340
+ }
1341
+ const awaited = type.typeArguments[0];
1342
+ if (type.typeArguments.length !== 1 || !awaited) {
1343
+ emissionError(context, 'a task type requires one awaited type argument');
1344
+ }
1345
+ return awaited;
1346
+ }
1347
+ // Rust distinguishes a method that observes its receiver from one that changes it, and the two are
1348
+ // not interchangeable to a caller. Taking `&mut self` everywhere is the conservative choice that
1349
+ // makes every method exclusive, so a shared read of one value blocks a read of another. The mutation
1350
+ // evidence is already in the body: an assignment whose target reaches `this`, or a bare rebinding of
1351
+ // it, is what requires exclusivity.
1352
+ // Which methods need an exclusive receiver. Writing through `this` is the direct case; calling a
1353
+ // method that writes is the transitive one, and missing it emits a `&self` method that calls a
1354
+ // `&mut self` method — which Rust rejects. The relation is closed to a fixed point because a caller
1355
+ // of a caller needs the same receiver.
1356
+ // Keyed by the name the method is emitted under, not the name it was written under: a getter and a
1357
+ // setter share one source name and Rust gives them two, so keying by the source name would hand the
1358
+ // getter the setter's mutable receiver.
1359
+ function getIrClassMutatingMethodNamesRust(declaration) {
1360
+ const mutating = new Set(declaration.methods
1361
+ .filter((method) => hasIrFunctionSignatureThisMutationRust(method))
1362
+ .map((method) => getIrClassMethodTargetNameRust(method)));
1363
+ const calls = new Map(declaration.methods.map((method) => [getIrClassMethodTargetNameRust(method), getIrFunctionSignatureSelfCallNamesRust(method)]));
1364
+ let changed = true;
1365
+ while (changed) {
1366
+ changed = false;
1367
+ for (const method of declaration.methods) {
1368
+ const target = getIrClassMethodTargetNameRust(method);
1369
+ if (mutating.has(target))
1370
+ continue;
1371
+ if ((calls.get(target) ?? []).some((name) => mutating.has(safeRustValueName(name)))) {
1372
+ mutating.add(target);
1373
+ changed = true;
1374
+ }
1375
+ }
1376
+ }
1377
+ return mutating;
1378
+ }
1379
+ function getIrFunctionSignatureSelfCallNamesRust(method) {
1380
+ const names = [];
1381
+ const observer = {
1382
+ expression(expression) {
1383
+ if (expression.kind === 'call' &&
1384
+ expression.callee.kind === 'property' &&
1385
+ expression.callee.object.kind === 'identifier' &&
1386
+ expression.callee.object.reference.kind === 'this') {
1387
+ names.push(expression.callee.name);
1388
+ }
1389
+ return undefined;
1390
+ },
1391
+ };
1392
+ method.body.forEach((statement) => analyzeIrStatementSubtreeTraversal(statement, observer));
1393
+ return names;
1394
+ }
1395
+ function hasIrFunctionSignatureThisMutationRust(method) {
1396
+ let mutates = false;
1397
+ const reachesThis = (expression) => {
1398
+ if (expression.kind === 'identifier')
1399
+ return expression.reference.kind === 'this';
1400
+ if (expression.kind === 'property' || expression.kind === 'element')
1401
+ return reachesThis(expression.object);
1402
+ return false;
1403
+ };
1404
+ const observer = {
1405
+ expression(expression) {
1406
+ // An assignment and an update both write through their target. `this.count++` is a mutation
1407
+ // as much as `this.count = 1`, and the untyped walk this replaced missed it entirely.
1408
+ const target = expression.kind === 'assignment'
1409
+ ? expression.left
1410
+ : expression.kind === 'unary'
1411
+ ? expression.operand
1412
+ : undefined;
1413
+ if (!target || !reachesThis(target))
1414
+ return undefined;
1415
+ mutates = true;
1416
+ return false;
1417
+ },
1418
+ };
1419
+ method.body.forEach((statement) => analyzeIrStatementSubtreeTraversal(statement, observer));
1420
+ return mutates;
1421
+ }
1422
+ function emitFunction(declaration, outer) {
1423
+ if (declaration.namespaceMember) {
1424
+ emissionError(outer, `value namespace function ${declaration.binding.name} requires Rust namespace lowering`);
1425
+ }
1426
+ const context = {
1427
+ ...outer,
1428
+ activeTypeParameters: declaration.typeParameters,
1429
+ enclosingReturnType: declaration.returns,
1430
+ returnsAbsent: hasIrTypeAbsentMember(declaration.returns),
1431
+ };
1432
+ // Rust has native suspension, so it declines the neutral state-machine lowering that Haxe elects
1433
+ // and emits `async fn` instead. The awaited type of an async function is its return type: the
1434
+ // future is implied by `async`, so the task wrapper is dropped rather than named.
1435
+ return [
1436
+ `${declaration.exported ? 'pub ' : ''}${declaration.async ? 'async ' : ''}fn ${getBindingTargetNameRust(declaration.binding, context)}${emitTypeParameters(declaration.typeParameters, context)}(${declaration.parameters.map((parameter) => emitParameter(parameter, context)).join(', ')}) -> ${emitType(declaration.async ? getIrTaskAwaitedTypeRust(declaration.returns, context) : declaration.returns, context)} {`,
1437
+ ...indentSourceLines([
1438
+ ...declaration.parameters.flatMap((parameter) => parameter.initializer
1439
+ ? [
1440
+ `let ${getBindingTargetNameRust(parameter.binding, context)} = ${getBindingTargetNameRust(parameter.binding, context)}.unwrap_or_else(|| ${emitExpression(parameter.initializer, context)});`,
1441
+ ]
1442
+ : []),
1443
+ ...emitStatements(declaration.body, context),
1444
+ ]),
1445
+ '}',
1446
+ ];
1447
+ }
1448
+ function emitImports(imports, context) {
1449
+ const lines = new Set();
1450
+ for (const imported of imports) {
1451
+ if (imported.bindings.length === 0)
1452
+ continue;
1453
+ const module = rustImportModule(imported.specifier, context);
1454
+ const names = imported.bindings.map((binding) => {
1455
+ if (binding.imported === '*' || binding.imported === 'default') {
1456
+ emissionError(context, `${binding.imported} imports require explicit Rust mapping for ${imported.specifier}`);
1457
+ }
1458
+ const importedName = binding.binding.space === 'type' || /^[A-Z]/u.test(binding.imported)
1459
+ ? safeRustTypeName(binding.imported)
1460
+ : safeRustValueName(binding.imported);
1461
+ const localName = getBindingTargetNameRust(binding.binding, context);
1462
+ return importedName === localName ? importedName : `${importedName} as ${localName}`;
1463
+ });
1464
+ lines.add(`use ${module}::${emitUseTreeRust(names.sort())};`);
1465
+ }
1466
+ return [...lines].sort();
1467
+ }
1468
+ // A facade module names what it re-exports and where it came from, which is exactly what Rust's
1469
+ // `pub use` says. The name a target spells it by depends on which space it lives in, so a re-export
1470
+ // carries the same value-versus-type decision an import does.
1471
+ function emitReexportsRust(exports, context) {
1472
+ const lines = new Set();
1473
+ for (const exported of exports) {
1474
+ if (exported.kind === 'local')
1475
+ continue;
1476
+ if (exported.kind === 'all') {
1477
+ lines.add(`pub use ${rustImportModule(exported.specifier, context)}::*;`);
1478
+ continue;
1479
+ }
1480
+ if (exported.kind === 'namespace') {
1481
+ const target = safeRustValueName(exported.exported);
1482
+ lines.add(`pub use ${rustImportModule(exported.specifier, context)} as ${target};`);
1483
+ continue;
1484
+ }
1485
+ if (exported.kind !== 'reexport')
1486
+ emissionError(context, 'default exports require Rust module-facade lowering');
1487
+ const module = rustImportModule(exported.specifier, context);
1488
+ const source = exported.typeOnly || /^[A-Z]/u.test(exported.imported)
1489
+ ? safeRustTypeName(exported.imported)
1490
+ : safeRustValueName(exported.imported);
1491
+ const target = exported.typeOnly || /^[A-Z]/u.test(exported.exported)
1492
+ ? safeRustTypeName(exported.exported)
1493
+ : safeRustValueName(exported.exported);
1494
+ lines.add(`pub use ${module}::${emitUseTreeRust([source === target ? source : `${source} as ${target}`])};`);
1495
+ }
1496
+ return [...lines].sort();
1497
+ }
1498
+ function emitInterface(declaration, context) {
1499
+ if (declaration.extends.length > 0)
1500
+ emissionError(context, `interface ${declaration.binding.name} inheritance requires record flattening`);
1501
+ // A shape a class implements is a contract on behaviour, which Rust spells as a trait. A shape
1502
+ // nothing implements is data, which Rust spells as a struct — and emitting the second as the first
1503
+ // would make an ordinary object type unconstructible.
1504
+ if (hasIrModuleClassImplementingRust(declaration, context)) {
1505
+ return emitTraitRust(declaration, context);
1506
+ }
1507
+ return emitRecord(getBindingTargetNameRust(declaration.binding, context), declaration.properties, declaration.typeParameters, declaration.exported, context);
1508
+ }
1509
+ function emitTraitRust(declaration, context) {
1510
+ const visibility = declaration.exported || context.apiReferencedBindingIds.has(declaration.binding.id) ? 'pub ' : '';
1511
+ return [
1512
+ `${visibility}trait ${getBindingTargetNameRust(declaration.binding, context)}${emitTypeParameters(declaration.typeParameters, context)} {`,
1513
+ ...declaration.properties.map((property) => {
1514
+ // A Rust trait holds no data, so a data property becomes the accessor that reads it. Fields and
1515
+ // methods live in different namespaces, so the accessor keeps the property's own name.
1516
+ if (property.type.kind !== 'function') {
1517
+ if (property.optional) {
1518
+ return emissionError(context, `interface ${declaration.binding.name} property ${property.name} requires Rust optional accessor lowering`);
1519
+ }
1520
+ return ` fn ${safeRustValueName(property.name)}(&self) -> ${emitType(property.type, context)};`;
1521
+ }
1522
+ const parameters = property.type.parameters
1523
+ .map((parameter, index) => `${safeRustValueName(parameter.name ?? `argument${String(index)}`)}: ${emitType(parameter.type, context)}`)
1524
+ .join(', ');
1525
+ return ` fn ${safeRustValueName(property.name)}(&self${parameters ? `, ${parameters}` : ''}) -> ${emitType(property.type.returns, context)};`;
1526
+ }),
1527
+ '}',
1528
+ ];
1529
+ }
1530
+ function hasIrModuleClassImplementingRust(declaration, context) {
1531
+ return context.module.declarations.some((candidate) => candidate.kind === 'class' &&
1532
+ candidate.implements.some((implemented) => implemented.kind === 'named' &&
1533
+ implemented.reference.kind === 'binding' &&
1534
+ implemented.reference.binding.id === declaration.binding.id));
1535
+ }
1536
+ function emitConstructorReferenceRust(reference, context) {
1537
+ if (reference.kind === 'super')
1538
+ emissionError(context, 'super cannot be used as a Rust constructor value');
1539
+ if (reference.kind === 'this')
1540
+ emissionError(context, 'this cannot be used as a Rust constructor');
1541
+ if (reference.kind !== 'ambient')
1542
+ return getBindingTargetNameRust(reference.binding, context);
1543
+ const targetName = getCompilerRuntimeExternalSymbolTargetRust(reference.name, 'value', context.options.hostBindings);
1544
+ if (!targetName)
1545
+ emissionError(context, `external constructor ${reference.name} has no Rust binding`);
1546
+ return isCompilerRuntimeExternalSymbolProvidedRust(reference.name, 'value', context.options.hostBindings)
1547
+ ? recordRuntimeTypeRust(targetName, context)
1548
+ : targetName;
1549
+ }
1550
+ function assertIrConstructorInvocationAbiRust(expression, context) {
1551
+ if (expression.callee.kind === 'identifier' && expression.callee.reference.kind === 'ambient')
1552
+ return;
1553
+ // A class this module declares has an associated `new` whenever its constructor was lowered to one,
1554
+ // so the call is emitted; a class whose constructor was refused has nothing to call.
1555
+ if (expression.callee.kind === 'identifier' && expression.callee.reference.kind === 'binding') {
1556
+ const target = context.module.declarations.find((candidate) => candidate.kind === 'class' &&
1557
+ expression.callee.kind === 'identifier' &&
1558
+ expression.callee.reference.kind === 'binding' &&
1559
+ candidate.binding.id === expression.callee.reference.binding.id);
1560
+ if (target?.kind === 'class') {
1561
+ const abstractBase = getIrClassStatelessAbstractBaseRust(target, context);
1562
+ if (getIrClassConstructorFieldAssignmentsRust(target, abstractBase !== undefined))
1563
+ return;
1564
+ const concreteBase = !abstractBase ? getIrClassConcreteBaseRust(target, context) : undefined;
1565
+ if (concreteBase && getIrClassCompositionConstructorRust(target, concreteBase))
1566
+ return;
1567
+ }
1568
+ }
1569
+ emissionError(context, 'class constructor calls require Rust initialization lowering');
1570
+ }
1571
+ function emitIdentifierReferenceRust(reference, context) {
1572
+ if (reference.kind === 'super')
1573
+ emissionError(context, 'super requires Rust inheritance lowering');
1574
+ if (reference.kind === 'this')
1575
+ return 'self';
1576
+ if (reference.kind === 'ambient') {
1577
+ if (reference.name === 'undefined') {
1578
+ emissionError(context, 'undefined expressions require Rust Option-aware lowering');
1579
+ }
1580
+ const targetName = getCompilerRuntimeExternalSymbolTargetRust(reference.name, 'value', context.options.hostBindings);
1581
+ if (!targetName)
1582
+ emissionError(context, `external value ${reference.name} has no Rust binding`);
1583
+ return isCompilerRuntimeExternalSymbolProvidedRust(reference.name, 'value', context.options.hostBindings)
1584
+ ? recordRuntimeTypeRust(targetName, context)
1585
+ : targetName;
1586
+ }
1587
+ return getBindingTargetNameRust(reference.binding, context);
1588
+ }
1589
+ function emitLiteral(value) {
1590
+ if (typeof value === 'string')
1591
+ return `${JSON.stringify(value)}.to_owned()`;
1592
+ if (value === null)
1593
+ return 'None';
1594
+ if (typeof value === 'number' && Number.isInteger(value) && !/[eE]/u.test(String(value))) {
1595
+ return `${String(value)}.0`;
1596
+ }
1597
+ return String(value);
1598
+ }
1599
+ function emitCallArgumentsRust(expression, context) {
1600
+ const signature = expression.semantics.signature;
1601
+ if (signature &&
1602
+ signature.restParameter === undefined &&
1603
+ typeof signature.providedArgumentCount === 'number' &&
1604
+ signature.providedArgumentCount > signature.parameterCount) {
1605
+ emissionError(context, 'extra JavaScript call arguments require target-neutral erasure lowering');
1606
+ }
1607
+ const borrowed = getIrCallBorrowedPositionsRust(expression, context);
1608
+ const defaults = expression.semantics.defaultParameters;
1609
+ const optionals = expression.semantics.optionalParameters;
1610
+ if (!defaults && !optionals) {
1611
+ return expression.arguments.map((argument, index) => borrowed.has(index) ? emitLentOperandRust(argument, context) : emitOwnedOperandRust(argument, context));
1612
+ }
1613
+ const plan = defaults ?? optionals;
1614
+ if (!plan)
1615
+ return expression.arguments.map((argument) => emitOwnedOperandRust(argument, context));
1616
+ if (plan.providedArgumentCount === 'dynamic') {
1617
+ emissionError(context, 'spread calls into optional or default parameters require Rust ABI expansion lowering');
1618
+ }
1619
+ if (expression.arguments.length > plan.parameterCount) {
1620
+ emissionError(context, 'extra JavaScript call arguments require Rust ABI erasure lowering');
1621
+ }
1622
+ const wrapped = new Set([...(defaults?.defaulted ?? []), ...(optionals?.optional ?? [])]);
1623
+ const defaultProvided = new Map(defaults?.provided.map((provided) => [provided.position, provided]) ?? []);
1624
+ const optionalProvided = new Map(optionals?.provided.map((provided) => [provided.position, provided]) ?? []);
1625
+ return Array.from({ length: plan.parameterCount }, (_, index) => {
1626
+ const argument = expression.arguments[index];
1627
+ if (!argument) {
1628
+ if (!wrapped.has(index)) {
1629
+ emissionError(context, `missing required call argument at position ${String(index)}`);
1630
+ }
1631
+ return 'None';
1632
+ }
1633
+ const providedEvidence = defaultProvided.get(index) ?? optionalProvided.get(index);
1634
+ if (providedEvidence?.value === 'undefined' || argument.kind === 'undefinedValue')
1635
+ return 'None';
1636
+ const emitted = emitExpression(argument, context);
1637
+ const optionalEvidence = optionalProvided.get(index);
1638
+ if (optionalEvidence && hasIrTypeNullMemberRust(optionalEvidence.parameterType)) {
1639
+ return isNullableType(optionalEvidence.argumentType) ? `Some(${emitted})` : `Some(Some(${emitted}))`;
1640
+ }
1641
+ if (optionalEvidence &&
1642
+ isNullableType(optionalEvidence.parameterType) &&
1643
+ isNullableType(optionalEvidence.argumentType)) {
1644
+ return emitted;
1645
+ }
1646
+ return wrapped.has(index) ? `Some(${emitted})` : emitted;
1647
+ });
1648
+ }
1649
+ function emitOptionalCallExpressionRust(expression, context) {
1650
+ const semantics = expression.semantics.optionalChain;
1651
+ if (!semantics)
1652
+ emissionError(context, 'optional call lacks neutral optional-chain evidence');
1653
+ const arguments_ = emitCallArgumentsRust(expression, context).join(', ');
1654
+ const callee = emitExpression(expression.callee, context);
1655
+ if (semantics.receiverNullish === 'excluded')
1656
+ return `${callee}(${arguments_})`;
1657
+ getIrTypeOptionalPayloadRust(semantics.receiverType, 'optional call receiver', context);
1658
+ const operation = isNullableType(semantics.valueType) ? 'and_then' : 'map';
1659
+ return `${callee}.as_ref().${operation}(|optional_chain_value| optional_chain_value(${arguments_}))`;
1660
+ }
1661
+ function emitOptionalElementExpressionRust(expression, context) {
1662
+ const semantics = expression.semantics.optionalChain;
1663
+ if (!semantics)
1664
+ emissionError(context, 'optional element access lacks neutral optional-chain evidence');
1665
+ if (semantics.receiverNullish === 'excluded') {
1666
+ return emitRequiredElementExpressionRust(expression, context);
1667
+ }
1668
+ const receiver = getIrTypeOptionalPayloadRust(semantics.receiverType, 'optional element receiver', context);
1669
+ const object = emitExpression(expression.object, context);
1670
+ const value = 'optional_chain_value';
1671
+ if (receiver.kind === 'tuple') {
1672
+ const index = getElementAccessTupleIndexRust(expression, context);
1673
+ const operation = receiver.elements[index]?.optional ? 'and_then' : 'map';
1674
+ return `${object}.as_ref().${operation}(|${value}| ${value}.${String(index)}.clone())`;
1675
+ }
1676
+ if (receiver.kind === 'array') {
1677
+ return `${object}.as_ref().and_then(|${value}| ${value}.get(${emitExpression(expression.index, context)} as usize).cloned())`;
1678
+ }
1679
+ emissionError(context, 'optional element access requires array or fixed-tuple receiver evidence');
1680
+ }
1681
+ function emitOptionalPropertyExpressionRust(expression, context) {
1682
+ const semantics = expression.optionalChain;
1683
+ if (!semantics)
1684
+ emissionError(context, 'optional property access lacks neutral optional-chain evidence');
1685
+ const object = emitExpression(expression.object, context);
1686
+ const property = safeRustValueName(expression.name);
1687
+ if (semantics.receiverNullish === 'excluded') {
1688
+ // Indexing yields a place the caller does not own, so the field read out of it is a copy.
1689
+ const owned = expression.object.kind === 'element' ? '.clone()' : '';
1690
+ return `${object}${isAmbientIdentifier(expression.object) ? '::' : '.'}${property}${owned}`;
1691
+ }
1692
+ getIrTypeOptionalPayloadRust(semantics.receiverType, 'optional property receiver', context);
1693
+ const operation = isNullableType(semantics.valueType) ? 'and_then' : 'map';
1694
+ return `${object}.as_ref().${operation}(|optional_chain_value| optional_chain_value.${property}.clone())`;
1695
+ }
1696
+ function emitRequiredElementExpressionRust(expression, context) {
1697
+ const closedSelection = emitClosedKeyElementSelectionRust(expression, context);
1698
+ if (closedSelection)
1699
+ return closedSelection;
1700
+ if (expression.semantics.receivers.includes('object')) {
1701
+ emissionError(context, 'computed object access requires JavaScript property-key coercion lowering');
1702
+ }
1703
+ if (expression.semantics.receivers.includes('tuple')) {
1704
+ const index = getElementAccessTupleIndexRust(expression, context);
1705
+ return `${emitExpression(expression.object, context)}.${String(index)}`;
1706
+ }
1707
+ return `${emitExpression(expression.object, context)}[${emitExpression(expression.index, context)} as usize]`;
1708
+ }
1709
+ // A finite string-key domain identifies every field this access can reach. Rust records have no
1710
+ // string subscript, so select the represented field explicitly while evaluating the receiver and key
1711
+ // once, in source order. Borrowing the receiver keeps the selection from moving a source binding; the
1712
+ // selected field is cloned into the expression's owned result.
1713
+ function emitClosedKeyElementSelectionRust(expression, context) {
1714
+ const keys = expression.semantics.closedKeys;
1715
+ if (!keys)
1716
+ return undefined;
1717
+ let objectType = inferIrExpressionTypeRust(expression.object, context);
1718
+ if (objectType?.kind === 'union' &&
1719
+ 'presence' in expression.object &&
1720
+ expression.object.presence === 'narrowedPresent') {
1721
+ const present = objectType.types.filter((member) => member.kind !== 'null' && member.kind !== 'undefined');
1722
+ if (present.length === 1)
1723
+ objectType = present[0];
1724
+ }
1725
+ const properties = objectType ? getIrObjectTypePropertiesRust(objectType, context) : undefined;
1726
+ if (!objectType || !properties) {
1727
+ emissionError(context, 'closed-key element access requires represented Rust object storage');
1728
+ }
1729
+ const members = new Map(properties
1730
+ .filter((property) => !property.computedKey && !property.phantom)
1731
+ .map((property) => [property.name, property]));
1732
+ const selections = keys.map((key) => ({ key, property: members.get(key) }));
1733
+ const absent = selections.find((selection) => !selection.property);
1734
+ if (absent) {
1735
+ emissionError(context, `closed key ${absent.key} is not a represented Rust object member`);
1736
+ }
1737
+ const memberTypes = selections.map(({ property }) => {
1738
+ const emitted = emitType(property.type, context);
1739
+ return property.optional ? `Option<${emitted}>` : emitted;
1740
+ });
1741
+ const distinctTypes = [...new Set(memberTypes)];
1742
+ if (distinctTypes.length !== 1) {
1743
+ emissionError(context, `closed-key selection over ${String(distinctTypes.length)} member types requires one Rust representation`);
1744
+ }
1745
+ const receiver = getGeneratedTargetNameRust('selection_receiver', context);
1746
+ const selectionKey = getGeneratedTargetNameRust('selection_key', context);
1747
+ const branches = selections.map(({ key, property }) => `${JSON.stringify(key)} => ${receiver}.${safeRustValueName(property.name)}.clone(),`);
1748
+ return `{ let ${receiver} = &${emitExpression(expression.object, context)}; let ${selectionKey} = &${emitExpression(expression.index, context)}; match ${selectionKey}.as_str() { ${branches.join(' ')} _ => unreachable!("Flight finite-key selection reached no member"), } }`;
1749
+ }
1750
+ function getIrTypeOptionalPayloadRust(type, subject, context) {
1751
+ if (type.kind !== 'union')
1752
+ emissionError(context, `${subject} requires one concrete Rust Option payload`);
1753
+ const concrete = type.types.filter((member) => member.kind !== 'null' && member.kind !== 'undefined');
1754
+ if (concrete.length !== 1)
1755
+ emissionError(context, `${subject} requires one concrete Rust Option payload`);
1756
+ return concrete[0];
1757
+ }
1758
+ function emitObjectRestExpressionRust(expression, context) {
1759
+ if (expression.excluded.some((key) => key.kind === 'computed')) {
1760
+ emissionError(context, 'computed object rest requires Rust property-key and record projection lowering');
1761
+ }
1762
+ const properties = getIrObjectRestPropertiesRust(expression, context);
1763
+ if (!properties)
1764
+ emissionError(context, 'object rest requires closed residual-record type evidence');
1765
+ const shape = createIrObjectTypeShapeIdentity(properties);
1766
+ const existing = context.objectRestRecords.get(shape);
1767
+ const recordName = existing?.name ?? getGeneratedTargetNameRust('ObjectRestRecord', context);
1768
+ if (!existing)
1769
+ context.objectRestRecords.set(shape, { name: recordName, properties });
1770
+ const object = emitExpression(expression.object, context);
1771
+ const fields = properties.map((property) => {
1772
+ const name = safeRustValueName(property.name);
1773
+ return {
1774
+ initializer: `${name}: ${object}.${name}.clone(),`,
1775
+ };
1776
+ });
1777
+ return `${recordName} { ${fields.map((field) => field.initializer).join(' ')} }`;
1778
+ }
1779
+ function getIrObjectRestPropertiesRust(expression, context) {
1780
+ const explicit = getIrObjectTypePropertiesRust(expression.type, context);
1781
+ if (explicit)
1782
+ return explicit;
1783
+ if (expression.object.reference.kind !== 'binding')
1784
+ return undefined;
1785
+ const sourceType = context.bindingTypes.get(expression.object.reference.binding.id);
1786
+ if (!sourceType)
1787
+ return undefined;
1788
+ const sourceProperties = getIrObjectTypePropertiesRust(sourceType, context);
1789
+ if (!sourceProperties)
1790
+ return undefined;
1791
+ const excluded = new Set(expression.excluded.flatMap((key) => (key.kind === 'named' ? [key.name] : [])));
1792
+ return sourceProperties.filter((property) => !excluded.has(property.name));
1793
+ }
1794
+ function emitObjectExpressionRust(expression, context) {
1795
+ if (expression.members.some((member) => member.kind === 'getAccessor')) {
1796
+ emissionError(context, 'object getters require target-specific accessor lowering');
1797
+ }
1798
+ const target = emitType(expression.type, context);
1799
+ const properties = getIrObjectConstructionPropertiesRust(expression.type, context);
1800
+ const members = expression.members.filter((member) => member.kind === 'property');
1801
+ const names = new Set();
1802
+ const fields = members.map((member) => {
1803
+ names.add(member.name);
1804
+ const property = properties?.find((candidate) => candidate.name === member.name);
1805
+ const value = emitExpression(member.value, context);
1806
+ return `${safeRustValueName(member.name)}: ${property?.optional ? `Some(${value})` : value},`;
1807
+ });
1808
+ for (const property of properties ?? []) {
1809
+ if (names.has(property.name))
1810
+ continue;
1811
+ fields.push(`${safeRustValueName(property.name)}: None,`);
1812
+ }
1813
+ return `${target} { ${fields.join(' ')} }`;
1814
+ }
1815
+ function inferIrExpressionTypeRust(expression, context) {
1816
+ switch (expression.kind) {
1817
+ case 'literal':
1818
+ if (expression.value === null)
1819
+ return { kind: 'null' };
1820
+ return typeof expression.value === 'string'
1821
+ ? { kind: 'primitive', name: 'string' }
1822
+ : typeof expression.value === 'number'
1823
+ ? { kind: 'primitive', name: 'number' }
1824
+ : { kind: 'primitive', name: 'boolean' };
1825
+ case 'cast':
1826
+ return expression.type;
1827
+ case 'call':
1828
+ return expression.semantics.resultType;
1829
+ case 'identifier':
1830
+ return expression.reference.kind === 'binding'
1831
+ ? context.bindingTypes.get(expression.reference.binding.id)
1832
+ : undefined;
1833
+ case 'binary':
1834
+ case 'unary': {
1835
+ const domain = expression.semantics.result;
1836
+ return domain === 'bigint' ||
1837
+ domain === 'boolean' ||
1838
+ domain === 'number' ||
1839
+ domain === 'string' ||
1840
+ domain === 'symbol'
1841
+ ? { kind: 'primitive', name: domain }
1842
+ : domain === 'null'
1843
+ ? { kind: 'null' }
1844
+ : domain === 'undefined'
1845
+ ? { kind: 'undefined' }
1846
+ : undefined;
1847
+ }
1848
+ case 'object':
1849
+ return expression.type;
1850
+ case 'property': {
1851
+ const binding = expression.member ? getCompilerRustAmbientMemberBinding(expression.member) : undefined;
1852
+ return binding?.kind === 'countingMethod' ? { kind: 'primitive', name: 'number' } : undefined;
1853
+ }
1854
+ default:
1855
+ return undefined;
1856
+ }
1857
+ }
1858
+ function getIrObjectConstructionPropertiesRust(type, context) {
1859
+ return getIrObjectTypePropertiesRust(type, context);
1860
+ }
1861
+ function getIrObjectTypeTargetNameRust(properties, context) {
1862
+ const shape = createIrObjectTypeShapeIdentity(properties);
1863
+ const existing = context.anonymousObjectRecords.get(shape);
1864
+ if (existing)
1865
+ return existing.name;
1866
+ const name = getGeneratedTargetNameRust('AnonymousObjectRecord', context);
1867
+ context.anonymousObjectRecords.set(shape, { name, properties });
1868
+ return name;
1869
+ }
1870
+ function getOrCreateCallableObjectRecordRust(type, context) {
1871
+ const callables = type.types.filter((member) => member.kind === 'function');
1872
+ if (callables.length !== 1)
1873
+ return undefined;
1874
+ const callable = callables[0];
1875
+ if (callable.typeParameters.length > 0) {
1876
+ emissionError(context, 'generic callable-object intersections require Rust monomorphization');
1877
+ }
1878
+ const shapes = type.types
1879
+ .filter((member) => member !== callable)
1880
+ .map((member) => getIrObjectTypePropertiesRust(member, context));
1881
+ if (shapes.length === 0 || shapes.some((shape) => !shape))
1882
+ return undefined;
1883
+ const properties = mergeIrObjectTypePropertiesRust(shapes.flatMap((shape) => shape));
1884
+ if (!properties)
1885
+ return undefined;
1886
+ const key = JSON.stringify({
1887
+ callable,
1888
+ parameters: context.activeTypeParameters.map((parameter) => parameter.binding.id),
1889
+ shape: createIrObjectTypeShapeIdentity(properties),
1890
+ });
1891
+ const existing = context.callableObjectRecords.get(key);
1892
+ if (existing)
1893
+ return existing;
1894
+ context.needsRcImport.add('Rc');
1895
+ const record = {
1896
+ callable: {
1897
+ parameters: callable.parameters.map((parameter) => {
1898
+ const emitted = emitType(parameter.type, context);
1899
+ return parameter.optional ? `Option<${emitted}>` : emitted;
1900
+ }),
1901
+ returns: emitType(callable.returns, context),
1902
+ },
1903
+ fields: properties.map((property) => ({
1904
+ name: safeRustValueName(property.name),
1905
+ optional: property.optional,
1906
+ rustType: emitType(property.type, context),
1907
+ })),
1908
+ name: getGeneratedTargetNameRust('AnonymousCallableObject', context),
1909
+ typeParameters: context.activeTypeParameters,
1910
+ };
1911
+ context.callableObjectRecords.set(key, record);
1912
+ return record;
1913
+ }
1914
+ function emitCallableObjectRecordRust(record, context) {
1915
+ const parameters = record.callable.parameters.join(', ');
1916
+ const signature = `dyn Fn(${parameters}) -> ${record.callable.returns}`;
1917
+ const typeParameters = emitTypeParameters(record.typeParameters, context);
1918
+ const typeArguments = emitTypeArguments(record.typeParameters, context);
1919
+ return [
1920
+ '#[derive(Clone)]',
1921
+ `pub struct ${record.name}${typeParameters} {`,
1922
+ ` pub callback: Rc<${signature}>,`,
1923
+ ...record.fields.map((field) => ` pub ${field.name}: ${field.optional ? `Option<${field.rustType}>` : field.rustType},`),
1924
+ '}',
1925
+ '',
1926
+ `impl${typeParameters} std::ops::Deref for ${record.name}${typeArguments} {`,
1927
+ ` type Target = ${signature};`,
1928
+ '',
1929
+ ' fn deref(&self) -> &Self::Target {',
1930
+ ' self.callback.as_ref()',
1931
+ ' }',
1932
+ '}',
1933
+ ];
1934
+ }
1935
+ // A value Rust moves is invalidated at the site that consumes it, so a binding the source still
1936
+ // needs afterwards is cloned into the consuming position rather than handed over. Every emitted
1937
+ // record derives `Clone`, so this is always available. The election is per binding rather than per
1938
+ // use, so the last consumption clones as well: correct, at the cost of one copy the source did not
1939
+ // need, and a binding consumed once is left to move.
1940
+ function emitOwnedOperandRust(expression, context) {
1941
+ const source = emitExpression(expression, context);
1942
+ if (expression.kind === 'identifier' &&
1943
+ expression.reference.kind === 'binding' &&
1944
+ context.movedBindingIds.has(expression.reference.binding.id))
1945
+ return `${source}.clone()`;
1946
+ if (expression.kind === 'element' && !expression.optional && expression.semantics.receivers.includes('array'))
1947
+ return `${source}.clone()`;
1948
+ return source;
1949
+ }
1950
+ function emitReturnedExpressionRust(expression, context) {
1951
+ const source = emitExpression(expression, context);
1952
+ if (expression.kind === 'element' && !expression.optional && expression.semantics.receivers.includes('array'))
1953
+ return `${source}.clone()`;
1954
+ if (context.enclosingReturnType?.kind === 'function' && expression.kind === 'function') {
1955
+ context.needsRcImport.add('Rc');
1956
+ return emitCellCloneBlockRust(`Rc::new(move ${source})`, expression, context);
1957
+ }
1958
+ return source;
1959
+ }
1960
+ function collectIrModuleApiReferencedBindingIdsRust(module) {
1961
+ const ids = new Set();
1962
+ function collectFromType(type) {
1963
+ switch (type.kind) {
1964
+ case 'named':
1965
+ if (type.reference.kind === 'binding')
1966
+ ids.add(type.reference.binding.id);
1967
+ for (const arg of type.typeArguments)
1968
+ collectFromType(arg);
1969
+ break;
1970
+ case 'array':
1971
+ collectFromType(type.element);
1972
+ break;
1973
+ case 'conditionalFacet':
1974
+ collectFromType(type.check);
1975
+ collectFromType(type.facet);
1976
+ break;
1977
+ case 'function':
1978
+ for (const parameter of type.parameters)
1979
+ collectFromType(parameter.type);
1980
+ collectFromType(type.returns);
1981
+ break;
1982
+ case 'intersection':
1983
+ case 'union':
1984
+ for (const member of type.types)
1985
+ collectFromType(member);
1986
+ break;
1987
+ case 'object':
1988
+ for (const property of type.properties)
1989
+ collectFromType(property.type);
1990
+ break;
1991
+ case 'tuple':
1992
+ for (const element of type.elements)
1993
+ collectFromType(element.type);
1994
+ break;
1995
+ case 'indexedAccess':
1996
+ collectFromType(type.object);
1997
+ collectFromType(type.index);
1998
+ break;
1999
+ case 'keyof':
2000
+ collectFromType(type.type);
2001
+ break;
2002
+ }
2003
+ }
2004
+ for (const declaration of module.declarations) {
2005
+ if (!declaration.exported)
2006
+ continue;
2007
+ if (declaration.kind === 'function') {
2008
+ for (const parameter of declaration.parameters)
2009
+ collectFromType(parameter.type);
2010
+ collectFromType(declaration.returns);
2011
+ }
2012
+ else if (declaration.kind === 'class') {
2013
+ for (const field of declaration.fields)
2014
+ if (field.visibility === 'public')
2015
+ collectFromType(field.type);
2016
+ for (const method of declaration.methods) {
2017
+ if (method.visibility !== 'public')
2018
+ continue;
2019
+ for (const parameter of method.parameters)
2020
+ collectFromType(parameter.type);
2021
+ collectFromType(method.returns);
2022
+ }
2023
+ }
2024
+ }
2025
+ return ids;
2026
+ }
2027
+ function collectIrModuleArrayElementBindingIdsRust(module) {
2028
+ const candidates = new Set();
2029
+ const coalesceTargets = new Set();
2030
+ analyzeIrModuleTraversal(module, {
2031
+ variable(variable) {
2032
+ if ('binding' in variable &&
2033
+ variable.initializer?.kind === 'element' &&
2034
+ !variable.initializer.optional &&
2035
+ variable.initializer.semantics.receivers.includes('array')) {
2036
+ candidates.add(variable.binding.id);
2037
+ }
2038
+ return undefined;
2039
+ },
2040
+ expression(expression) {
2041
+ if (expression.kind === 'binary' &&
2042
+ expression.operator === '??' &&
2043
+ expression.left.kind === 'identifier' &&
2044
+ expression.left.reference.kind === 'binding') {
2045
+ coalesceTargets.add(expression.left.reference.binding.id);
2046
+ }
2047
+ return undefined;
2048
+ },
2049
+ });
2050
+ const ids = new Set();
2051
+ for (const id of candidates) {
2052
+ if (coalesceTargets.has(id))
2053
+ ids.add(id);
2054
+ }
2055
+ return ids;
2056
+ }
2057
+ function collectIrModuleBindingTypesRust(module) {
2058
+ const result = new Map();
2059
+ analyzeIrModuleTraversal(module, {
2060
+ parameter(parameter) {
2061
+ result.set(parameter.binding.id, parameter.type);
2062
+ },
2063
+ variable(variable) {
2064
+ if ('binding' in variable && variable.type) {
2065
+ result.set(variable.binding.id, variable.type);
2066
+ }
2067
+ },
2068
+ });
2069
+ return result;
2070
+ }
2071
+ // `unknown` has no single native Rust representation. A binding used exclusively through one
2072
+ // explicit source assertion does, however: the Rust API can expose that asserted type directly and
2073
+ // erase the assertion. Any unasserted use or disagreement leaves the binding opaque, so this never
2074
+ // guesses a dynamic conversion that the source did not perform.
2075
+ function collectAssertedUnknownBindingTypesRust(module, bindingTypes) {
2076
+ const candidates = new Map();
2077
+ const disqualified = new Set();
2078
+ const parameters = new Set();
2079
+ analyzeIrModuleTraversal(module, {
2080
+ parameter(parameter) {
2081
+ if (parameter.type.kind === 'unknown')
2082
+ parameters.add(parameter.binding.id);
2083
+ },
2084
+ });
2085
+ analyzeIrModuleTraversal(module, {
2086
+ expression(expression, path) {
2087
+ if (expression.kind !== 'identifier' || expression.reference.kind !== 'binding')
2088
+ return;
2089
+ const id = expression.reference.binding.id;
2090
+ if (!parameters.has(id) || bindingTypes.get(id)?.kind !== 'unknown')
2091
+ return;
2092
+ const parent = path.length > 0 ? getIrModuleTraversalPathValue(module, path.slice(0, -1)) : undefined;
2093
+ const asserted = parent &&
2094
+ typeof parent === 'object' &&
2095
+ 'kind' in parent &&
2096
+ parent.kind === 'cast' &&
2097
+ 'expression' in parent &&
2098
+ parent.expression === expression &&
2099
+ 'type' in parent &&
2100
+ isIrTypeAssertedUnknownRepresentationRust(parent.type)
2101
+ ? parent.type
2102
+ : undefined;
2103
+ if (!asserted) {
2104
+ disqualified.add(id);
2105
+ return;
2106
+ }
2107
+ const existing = candidates.get(id);
2108
+ if (existing && !areIrAssertedUnknownRepresentationsEqualRust(existing, asserted)) {
2109
+ disqualified.add(id);
2110
+ return;
2111
+ }
2112
+ candidates.set(id, asserted);
2113
+ },
2114
+ });
2115
+ for (const id of disqualified)
2116
+ candidates.delete(id);
2117
+ return candidates;
2118
+ }
2119
+ function isIrTypeAssertedUnknownRepresentationRust(type) {
2120
+ if (!type || typeof type !== 'object' || !('kind' in type) || type.kind !== 'primitive')
2121
+ return false;
2122
+ return 'name' in type && (type.name === 'boolean' || type.name === 'number' || type.name === 'string');
2123
+ }
2124
+ function areIrAssertedUnknownRepresentationsEqualRust(left, right) {
2125
+ return left.kind === 'primitive' && right.kind === 'primitive' && left.name === right.name;
2126
+ }
2127
+ function resolvePrimitiveUnionEnumRust(type, context) {
2128
+ if (type.kind !== 'union')
2129
+ return undefined;
2130
+ const concrete = type.types.filter((t) => t.kind !== 'null' && t.kind !== 'undefined');
2131
+ if (concrete.length < 2)
2132
+ return undefined;
2133
+ return getOrCreatePrimitiveUnionEnumRust(concrete, context);
2134
+ }
2135
+ function resolveDualSentinelUnionEnumRust(type, context) {
2136
+ return type.kind === 'union' && hasIrTypeNullMemberRust(type) && hasIrTypeUndefinedMemberRust(type)
2137
+ ? getOrCreateAnonymousUnionEnumRust(type.types, context)
2138
+ : undefined;
2139
+ }
2140
+ function getIrExpressionDualSentinelUnionRust(expression, context) {
2141
+ if (expression.kind !== 'identifier' || expression.reference.kind !== 'binding')
2142
+ return undefined;
2143
+ const type = context.bindingTypes.get(expression.reference.binding.id);
2144
+ return type ? resolveDualSentinelUnionEnumRust(type, context) : undefined;
2145
+ }
2146
+ function emitDualSentinelUnionConstructionRust(expression, targetEnum, context) {
2147
+ if (expression.kind === 'conditional') {
2148
+ const condition = emitExpression(expression.condition, context);
2149
+ const whenTrue = emitDualSentinelUnionConstructionRust(expression.whenTrue, targetEnum, context);
2150
+ const whenFalse = emitDualSentinelUnionConstructionRust(expression.whenFalse, targetEnum, context);
2151
+ return whenTrue && whenFalse ? `if ${condition} { ${whenTrue} } else { ${whenFalse} }` : undefined;
2152
+ }
2153
+ if (expression.kind === 'literal' && expression.value === null)
2154
+ return `${targetEnum.name}::Null`;
2155
+ if (expression.kind === 'undefinedValue' ||
2156
+ (expression.kind === 'identifier' &&
2157
+ expression.reference.kind === 'ambient' &&
2158
+ expression.reference.name === 'undefined')) {
2159
+ return `${targetEnum.name}::Undefined`;
2160
+ }
2161
+ const sourceUnion = getIrExpressionDualSentinelUnionRust(expression, context);
2162
+ if (sourceUnion?.name === targetEnum.name)
2163
+ return emitOwnedOperandRust(expression, context);
2164
+ const payloads = targetEnum.variants.filter((variant) => variant.kind === 'tuple');
2165
+ if (payloads.length === 1) {
2166
+ return `${targetEnum.name}::${payloads[0].name}(${emitOwnedOperandRust(expression, context)})`;
2167
+ }
2168
+ const primitiveKind = inferIrExpressionPrimitiveKindRust(expression, context);
2169
+ const preferred = primitiveKind
2170
+ ? getGeneralUnionVariantNameRust({ kind: 'primitive', name: primitiveKind }, context)
2171
+ : undefined;
2172
+ const payload = preferred ? payloads.find((variant) => variant.name === preferred) : undefined;
2173
+ return payload ? `${targetEnum.name}::${payload.name}(${emitOwnedOperandRust(expression, context)})` : undefined;
2174
+ }
2175
+ function inferIrExpressionPrimitiveKindRust(expression, context) {
2176
+ switch (expression.kind) {
2177
+ case 'literal':
2178
+ return typeof expression.value === 'string'
2179
+ ? 'string'
2180
+ : typeof expression.value === 'number'
2181
+ ? 'number'
2182
+ : typeof expression.value === 'boolean'
2183
+ ? 'boolean'
2184
+ : undefined;
2185
+ case 'template':
2186
+ return 'string';
2187
+ case 'binary': {
2188
+ const result = expression.semantics.result;
2189
+ return result === 'string' || result === 'number' || result === 'boolean' ? result : undefined;
2190
+ }
2191
+ case 'unary': {
2192
+ const result = expression.semantics.result;
2193
+ return result === 'string' || result === 'number' || result === 'boolean' ? result : undefined;
2194
+ }
2195
+ case 'call': {
2196
+ const resultType = expression.semantics.resultType;
2197
+ return resultType.kind === 'primitive' &&
2198
+ (resultType.name === 'string' || resultType.name === 'number' || resultType.name === 'boolean')
2199
+ ? resultType.name
2200
+ : undefined;
2201
+ }
2202
+ case 'cast':
2203
+ return expression.type.kind === 'primitive' &&
2204
+ (expression.type.name === 'string' || expression.type.name === 'number' || expression.type.name === 'boolean')
2205
+ ? expression.type.name
2206
+ : undefined;
2207
+ case 'identifier': {
2208
+ if (expression.reference.kind !== 'binding')
2209
+ return undefined;
2210
+ const bindingType = context.bindingTypes.get(expression.reference.binding.id);
2211
+ if (!bindingType || bindingType.kind !== 'primitive')
2212
+ return undefined;
2213
+ return bindingType.name === 'string' || bindingType.name === 'number' || bindingType.name === 'boolean'
2214
+ ? bindingType.name
2215
+ : undefined;
2216
+ }
2217
+ default:
2218
+ return undefined;
2219
+ }
2220
+ }
2221
+ function emitPrimitiveUnionConstructionRust(expression, targetEnum, context) {
2222
+ if (expression.kind === 'conditional') {
2223
+ const condition = emitExpression(expression.condition, context);
2224
+ const whenTrue = emitPrimitiveUnionConstructionRust(expression.whenTrue, targetEnum, context);
2225
+ const whenFalse = emitPrimitiveUnionConstructionRust(expression.whenFalse, targetEnum, context);
2226
+ if (whenTrue === undefined || whenFalse === undefined)
2227
+ return undefined;
2228
+ return `if ${condition} { ${whenTrue} } else { ${whenFalse} }`;
2229
+ }
2230
+ const emitted = normalizeSourceTextGrouping(emitOwnedOperandRust(expression, context));
2231
+ const primitiveKind = inferIrExpressionPrimitiveKindRust(expression, context);
2232
+ if (!primitiveKind)
2233
+ return undefined;
2234
+ const variant = targetEnum.variants.find((v) => v.primitiveKind === primitiveKind);
2235
+ if (!variant)
2236
+ return undefined;
2237
+ return `${targetEnum.name}::${variant.variantName}(${emitted})`;
2238
+ }
2239
+ function collectCellCapturedBindingIdsRust(expression, context) {
2240
+ if (expression.kind !== 'function' ||
2241
+ (context.cellWrappedBindingIds.size === 0 && context.refCellWrappedBindingIds.size === 0))
2242
+ return [];
2243
+ const found = new Set();
2244
+ const observer = {
2245
+ expression(expr) {
2246
+ if (expr.kind === 'identifier' &&
2247
+ expr.reference.kind === 'binding' &&
2248
+ (context.cellWrappedBindingIds.has(expr.reference.binding.id) ||
2249
+ context.refCellWrappedBindingIds.has(expr.reference.binding.id))) {
2250
+ found.add(expr.reference.binding.id);
2251
+ }
2252
+ if (expr.kind === 'function')
2253
+ return false;
2254
+ return undefined;
2255
+ },
2256
+ };
2257
+ expression.body.forEach((stmt) => analyzeIrStatementSubtreeTraversal(stmt, observer));
2258
+ return [...found];
2259
+ }
2260
+ function emitCellCloneBlockRust(rcExpression, closureExpression, context) {
2261
+ const capturedCellIds = collectCellCapturedBindingIdsRust(closureExpression, context);
2262
+ if (capturedCellIds.length === 0)
2263
+ return rcExpression;
2264
+ const clones = capturedCellIds.map((id) => {
2265
+ const name = context.targetNames.get(id) ?? id;
2266
+ return ` let ${name} = Rc::clone(&${name});`;
2267
+ });
2268
+ return `{\n${clones.join('\n')}\n ${rcExpression}\n}`;
2269
+ }
2270
+ function emitClosureWithCellClonesRust(expression, context) {
2271
+ const source = emitExpression(expression, context);
2272
+ return emitCellCloneBlockRust(`Rc::new(move ${source})`, expression, context);
2273
+ }
2274
+ // A value lent to a callee that mutates through it. An argument that is already a mutable borrow is
2275
+ // passed as it stands, because Rust reborrows it: taking a reference to it again would hand the
2276
+ // callee a reference to the reference.
2277
+ function emitLentOperandRust(expression, context) {
2278
+ const source = emitExpression(expression, context);
2279
+ return expression.kind === 'identifier' &&
2280
+ expression.reference.kind === 'binding' &&
2281
+ context.referentMutatedParameterIds.has(expression.reference.binding.id)
2282
+ ? source
2283
+ : `&mut ${source}`;
2284
+ }
2285
+ // A closure an iterator adaptor hands a reference to. The source wrote it for the element, so the
2286
+ // reference is destructured away at the binding — which Rust allows for a value it can copy, and
2287
+ // which is why an element it cannot copy is refused rather than silently borrowed.
2288
+ function emitBorrowedElementClosureRust(expression, context) {
2289
+ if (expression?.kind !== 'function') {
2290
+ return emissionError(context, 'filtering requires a closure written where the predicate is passed');
2291
+ }
2292
+ const parameters = expression.parameters.map((parameter, index) => {
2293
+ if (index > 0)
2294
+ return getBindingTargetNameRust(parameter.binding, context);
2295
+ if (!isIrTypeCopyValueRust(parameter.type)) {
2296
+ emissionError(context, 'filtering an element Rust cannot copy requires a borrowed predicate lowering');
2297
+ }
2298
+ return `&${getBindingTargetNameRust(parameter.binding, context)}`;
2299
+ });
2300
+ const body = expression.expression
2301
+ ? normalizeSourceTextGrouping(emitExpression(expression.expression, context))
2302
+ : `{\n${indentSourceLines(emitStatements(expression.body, context)).join('\n')}\n}`;
2303
+ return `|${parameters.join(', ')}| ${body}`;
2304
+ }
2305
+ function emitIteratorCallbackWrapperRust(expression, emittedCallee, context) {
2306
+ const name = getGeneratedTargetNameRust('x', context);
2307
+ return `|${name}| ${emittedCallee}(${name})`;
2308
+ }
2309
+ function emitArrayPredicatePositionRust(receiver, callback, emittedCallback, targetName, context) {
2310
+ let parameterCount;
2311
+ if (callback?.kind === 'function') {
2312
+ parameterCount = callback.parameters.length;
2313
+ }
2314
+ else if (callback?.kind === 'identifier' && callback.reference.kind === 'binding') {
2315
+ const callbackType = context.bindingTypes.get(callback.reference.binding.id);
2316
+ if (callbackType?.kind === 'function')
2317
+ parameterCount = callbackType.parameters.length;
2318
+ }
2319
+ if (!callback || !emittedCallback || parameterCount === undefined || parameterCount < 1 || parameterCount > 2) {
2320
+ emissionError(context, 'array findIndex requires a statically known one- or two-parameter Rust predicate');
2321
+ }
2322
+ const index = getGeneratedTargetNameRust('predicate_index', context);
2323
+ const element = getGeneratedTargetNameRust('predicate_element', context);
2324
+ const arguments_ = [`${element}.clone()`, ...(parameterCount === 2 ? [`${index} as f64`] : [])];
2325
+ return `${receiver}.iter().enumerate().${targetName}(|(${index}, ${element})| (${emittedCallback})(${arguments_.join(', ')})).map(|i| i as f64).unwrap_or(-1.0)`;
2326
+ }
2327
+ function isIrSelfFieldNonCopyRust(fieldName, context) {
2328
+ for (const declaration of context.module.declarations) {
2329
+ if (declaration.kind !== 'class')
2330
+ continue;
2331
+ const field = declaration.fields.find((candidate) => !candidate.static && candidate.name === fieldName);
2332
+ if (field)
2333
+ return !isIrTypeCopyValueRust(field.type);
2334
+ }
2335
+ return false;
2336
+ }
2337
+ function isIrTypeCopyValueRust(type) {
2338
+ return type.kind === 'primitive' && (type.name === 'boolean' || type.name === 'number');
2339
+ }
2340
+ // An index, in the form Rust counts with. A literal whole number is written as one; anything else is
2341
+ // a value in the neutral numeric type and has to be converted.
2342
+ function emitIndexOperandRust(expression, context) {
2343
+ return expression.kind === 'literal' && typeof expression.value === 'number' && Number.isInteger(expression.value)
2344
+ ? String(expression.value)
2345
+ : `${emitExpression(expression, context)} as usize`;
2346
+ }
2347
+ function emitBorrowedNarrowedReceiverRust(object, context) {
2348
+ if (object.kind !== 'identifier' || object.reference.kind !== 'binding')
2349
+ return undefined;
2350
+ if (object.presence !== 'narrowedPresent')
2351
+ return undefined;
2352
+ if (!context.nullableBindingIds.has(object.reference.binding.id))
2353
+ return undefined;
2354
+ return `${emitIdentifierReferenceRust(object.reference, context)}.as_ref().unwrap()`;
2355
+ }
2356
+ // A value on its way into a binding that can hold nothing. The source language stores a value and an
2357
+ // absence in one place without saying so; Rust's `Option` says so, and a present value has to be
2358
+ // wrapped to enter it. A value that is already optional passes through: it is already the shape.
2359
+ function emitOptionalTargetOperandRust(target, value, context) {
2360
+ const source = emitExpression(value, context);
2361
+ if (target.kind !== 'identifier' || target.reference.kind !== 'binding')
2362
+ return source;
2363
+ if (!context.nullableBindingIds.has(target.reference.binding.id))
2364
+ return source;
2365
+ const alreadyOptional = isIrExpressionOptionShapedRust(value, context);
2366
+ return alreadyOptional ? source : `Some(${source})`;
2367
+ }
2368
+ // Text in a position Rust borrows rather than owns. A literal is already a `&str` before it is
2369
+ // owned, so the ownership is simply not taken; anything else is borrowed from the value it names.
2370
+ function emitBorrowedTextRust(expression, context) {
2371
+ return expression.kind === 'literal' && typeof expression.value === 'string'
2372
+ ? JSON.stringify(expression.value)
2373
+ : `&${emitExpression(expression, context)}`;
2374
+ }
2375
+ // A constructor that does nothing but fill its own fields is a Rust struct literal, which is the one
2376
+ // constructor shape Rust has. The body must assign every instance field exactly once and read none of
2377
+ // them back: a field literal cannot see a field the same literal is still building.
2378
+ function getIrClassConstructorFieldAssignmentsRust(declaration, statelessBase) {
2379
+ const constructor = declaration.classConstructor;
2380
+ const instanceFields = declaration.fields.filter((field) => !field.static);
2381
+ if (!constructor || instanceFields.length === 0)
2382
+ return undefined;
2383
+ if (instanceFields.some((field) => field.initializer))
2384
+ return undefined;
2385
+ const assigned = [];
2386
+ for (const statement of constructor.body) {
2387
+ // A base that holds no state has nothing to initialize, so the call that would have initialized
2388
+ // it does nothing and leaves nothing for the struct literal to say.
2389
+ if (statelessBase && isIrStatementSuperConstructorCallRust(statement))
2390
+ continue;
2391
+ if (statement.kind !== 'expression' || statement.expression.kind !== 'assignment')
2392
+ return undefined;
2393
+ const { left, operator, right } = statement.expression;
2394
+ if (operator !== '=' || left.kind !== 'property' || left.object.kind !== 'identifier')
2395
+ return undefined;
2396
+ if (left.object.reference.kind !== 'this' || left.optional)
2397
+ return undefined;
2398
+ if (assigned.some((field) => field.name === left.name))
2399
+ return undefined;
2400
+ if (hasIrExpressionThisReferenceRust(right))
2401
+ return undefined;
2402
+ assigned.push({ name: left.name, value: right });
2403
+ }
2404
+ return assigned.length === instanceFields.length &&
2405
+ instanceFields.every((field) => assigned.some((entry) => entry.name === field.name))
2406
+ ? assigned
2407
+ : undefined;
2408
+ }
2409
+ function getIrClassCompositionConstructorRust(declaration, base) {
2410
+ const constructor = declaration.classConstructor;
2411
+ const instanceFields = declaration.fields.filter((field) => !field.static);
2412
+ if (!constructor || instanceFields.length === 0)
2413
+ return undefined;
2414
+ let superArguments;
2415
+ const childFields = [];
2416
+ for (const statement of constructor.body) {
2417
+ if (!superArguments && isIrStatementSuperConstructorCallRust(statement)) {
2418
+ const call = statement.expression;
2419
+ superArguments = call.arguments;
2420
+ continue;
2421
+ }
2422
+ if (statement.kind !== 'expression' || statement.expression.kind !== 'assignment')
2423
+ return undefined;
2424
+ const { left, operator, right } = statement.expression;
2425
+ if (operator !== '=' || left.kind !== 'property' || left.object.kind !== 'identifier')
2426
+ return undefined;
2427
+ if (left.object.reference.kind !== 'this' || left.optional)
2428
+ return undefined;
2429
+ if (base.fields.some((field) => !field.static && field.name === left.name))
2430
+ return undefined;
2431
+ if (childFields.some((field) => field.name === left.name))
2432
+ return undefined;
2433
+ if (hasIrExpressionThisReferenceRust(right))
2434
+ return undefined;
2435
+ childFields.push({ name: left.name, value: right });
2436
+ }
2437
+ if (!superArguments)
2438
+ return undefined;
2439
+ return childFields.length === instanceFields.length &&
2440
+ instanceFields.every((field) => childFields.some((entry) => entry.name === field.name))
2441
+ ? { superArguments, childFields }
2442
+ : undefined;
2443
+ }
2444
+ function isIrCompositionBaseMemberRust(name, base) {
2445
+ return (base.fields.some((field) => !field.static && field.name === name) ||
2446
+ base.methods.some((method) => !method.static && method.name === name));
2447
+ }
2448
+ function isIrStatementSuperConstructorCallRust(statement) {
2449
+ return (statement.kind === 'expression' &&
2450
+ statement.expression.kind === 'call' &&
2451
+ statement.expression.callee.kind === 'identifier' &&
2452
+ statement.expression.callee.reference.kind === 'super');
2453
+ }
2454
+ function collectAsyncTryStatementsRust(module, analysis) {
2455
+ const result = new Set();
2456
+ for (const machine of analysis.machines) {
2457
+ for (const state of machine.states) {
2458
+ for (const step of state.steps) {
2459
+ if (step.kind !== 'suspend' || step.rejectState === undefined)
2460
+ continue;
2461
+ const tryStatement = getEnclosingTryStatementRust(module, step.path);
2462
+ if (tryStatement)
2463
+ result.add(tryStatement);
2464
+ }
2465
+ }
2466
+ }
2467
+ return result;
2468
+ }
2469
+ function getEnclosingTryStatementRust(module, suspensionPath) {
2470
+ for (let i = suspensionPath.length - 1; i >= 0; i--) {
2471
+ if (suspensionPath[i] === 'tryBody') {
2472
+ return getIrModuleTraversalPathValue(module, suspensionPath.slice(0, i));
2473
+ }
2474
+ }
2475
+ return undefined;
2476
+ }
2477
+ function emitAsyncTryCatchRust(statement, context) {
2478
+ const tryStatements = statement.tryBody.kind === 'block' ? statement.tryBody.statements : [statement.tryBody];
2479
+ const awaitIndex = tryStatements.findIndex((s) => (s.kind === 'expression' && s.expression.kind === 'assignment' && s.expression.right.kind === 'await') ||
2480
+ (s.kind === 'return' && s.expression?.kind === 'await'));
2481
+ if (awaitIndex === -1) {
2482
+ emissionError(context, 'async try/catch requires a recognizable await assignment or return');
2483
+ return [];
2484
+ }
2485
+ const awaitStatement = tryStatements[awaitIndex];
2486
+ const preStatements = tryStatements.slice(0, awaitIndex);
2487
+ const postStatements = tryStatements.slice(awaitIndex + 1);
2488
+ const isReturn = awaitStatement.kind === 'return';
2489
+ let awaitTarget;
2490
+ let assignmentExpression;
2491
+ if (awaitStatement.kind === 'return' && awaitStatement.expression?.kind === 'await') {
2492
+ awaitTarget = awaitStatement.expression.expression;
2493
+ }
2494
+ else if (awaitStatement.kind === 'expression' &&
2495
+ awaitStatement.expression.kind === 'assignment' &&
2496
+ awaitStatement.expression.right.kind === 'await') {
2497
+ assignmentExpression = awaitStatement.expression;
2498
+ awaitTarget = awaitStatement.expression.right.expression;
2499
+ }
2500
+ if (!awaitTarget) {
2501
+ emissionError(context, 'async try/catch requires a direct await expression');
2502
+ return [];
2503
+ }
2504
+ const settleExpr = `${emitOwnedOperandRust(awaitTarget, context)}.settle()`;
2505
+ const lines = [];
2506
+ lines.push(...emitStatements(preStatements, context));
2507
+ if (statement.catchClause) {
2508
+ const catchBinding = statement.catchClause.binding ? safeRustValueName(statement.catchClause.binding.name) : '_';
2509
+ lines.push(`match ${settleExpr} {`);
2510
+ if (isReturn) {
2511
+ lines.push(...indentSourceLines([
2512
+ 'Ok(__value) => {',
2513
+ ...indentSourceLines([...emitStatements(postStatements, context), 'return __value;']),
2514
+ '}',
2515
+ ]));
2516
+ }
2517
+ else {
2518
+ const okBody = [];
2519
+ if (assignmentExpression) {
2520
+ okBody.push(`${emitExpression(assignmentExpression.left, context)} ${emitAssignmentOperatorRust(assignmentExpression.operator, assignmentExpression.semantics, context)} __value;`);
2521
+ }
2522
+ okBody.push(...emitStatements(postStatements, context));
2523
+ lines.push(...indentSourceLines(['Ok(__value) => {', ...indentSourceLines(okBody), '}']));
2524
+ }
2525
+ lines.push(...indentSourceLines([
2526
+ `Err(${catchBinding}) => {`,
2527
+ ...indentSourceLines(emitStatementBody(statement.catchClause.body, context)),
2528
+ '}',
2529
+ ]));
2530
+ lines.push('}');
2531
+ if (statement.finallyBody) {
2532
+ lines.push(...emitStatementBody(statement.finallyBody, context));
2533
+ }
2534
+ }
2535
+ else if (statement.finallyBody) {
2536
+ lines.push(`let __try_result = ${settleExpr};`);
2537
+ lines.push(...emitStatementBody(statement.finallyBody, context));
2538
+ if (isReturn) {
2539
+ lines.push('match __try_result {');
2540
+ lines.push(...indentSourceLines([
2541
+ 'Ok(__value) => return __value,',
2542
+ 'Err(__error) => panic!("unhandled task rejection: {}", __error),',
2543
+ ]));
2544
+ lines.push('}');
2545
+ }
2546
+ else {
2547
+ lines.push('match __try_result {');
2548
+ const okBody = [];
2549
+ if (assignmentExpression) {
2550
+ okBody.push(`${emitExpression(assignmentExpression.left, context)} ${emitAssignmentOperatorRust(assignmentExpression.operator, assignmentExpression.semantics, context)} __value;`);
2551
+ }
2552
+ okBody.push(...emitStatements(postStatements, context));
2553
+ lines.push(...indentSourceLines([
2554
+ 'Ok(__value) => {',
2555
+ ...indentSourceLines(okBody),
2556
+ '}',
2557
+ 'Err(__error) => panic!("unhandled task rejection: {}", __error),',
2558
+ ]));
2559
+ lines.push('}');
2560
+ }
2561
+ }
2562
+ else {
2563
+ emissionError(context, 'async try without catch or finally');
2564
+ }
2565
+ return lines;
2566
+ }
2567
+ function hasIrExpressionThisReferenceRust(expression) {
2568
+ let found = false;
2569
+ analyzeIrStatementSubtreeTraversal({ expression, kind: 'expression' }, {
2570
+ expression(node) {
2571
+ if (node.kind === 'identifier' && node.reference.kind === 'this')
2572
+ found = true;
2573
+ return undefined;
2574
+ },
2575
+ });
2576
+ return found;
2577
+ }
2578
+ function emitParameter(parameter, context) {
2579
+ const parameterType = context.assertedUnknownBindingTypes.get(parameter.binding.id) ?? parameter.type;
2580
+ // The source mutates what this parameter names, and the caller sees the change. Moving the value in
2581
+ // would mutate a copy and drop it — the same source, a different meaning — so the parameter is
2582
+ // borrowed mutably and every call site lends rather than gives.
2583
+ if (context.referentMutatedParameterIds.has(parameter.binding.id)) {
2584
+ if (parameter.initializer || parameter.optional || parameter.rest) {
2585
+ emissionError(context, `parameter ${parameter.binding.name} is mutated through and cannot also be optional or variadic in Rust`);
2586
+ }
2587
+ return `${getBindingTargetNameRust(parameter.binding, context)}: &mut ${emitType(parameterType, context)}`;
2588
+ }
2589
+ // A parameter the body assigns to is a local binding in Rust as much as in the source language, and
2590
+ // Rust will not accept the assignment without `mut`. Emitting it unconditionally would instead earn
2591
+ // an unused-mut warning on every parameter that is only read.
2592
+ const binding = `${context.reboundBindingIds.has(parameter.binding.id) ? 'mut ' : ''}${getBindingTargetNameRust(parameter.binding, context)}`;
2593
+ if (parameter.initializer) {
2594
+ return `${binding}: Option<${emitType(parameterType, context)}>`;
2595
+ }
2596
+ if (parameter.optional) {
2597
+ const type = emitType(parameterType, context);
2598
+ if (hasIrTypeNullMemberRust(parameter.type) && hasIrTypeUndefinedMemberRust(parameter.type)) {
2599
+ emissionError(context, 'optional parameters containing both null and undefined require distinct Rust sentinels');
2600
+ }
2601
+ const optionalType = hasIrTypeUndefinedMemberRust(parameter.type) && !hasIrTypeNullMemberRust(parameter.type)
2602
+ ? type
2603
+ : `Option<${type}>`;
2604
+ return `${binding}: ${optionalType}`;
2605
+ }
2606
+ if (parameter.rest)
2607
+ return `${binding}: ${emitType(parameterType, context)}`;
2608
+ return `${binding}: ${emitType(parameterType, context)}`;
2609
+ }
2610
+ function emitRecord(targetName, properties, typeParameters, exported, context) {
2611
+ // A record a public function names has to be at least as visible as that function, and a record
2612
+ // the source did not export is still named by one often enough that hiding it only produces a
2613
+ // private-interface warning. What leaves the crate is the crate root's decision, not this module's.
2614
+ void exported;
2615
+ const typeContext = { ...context, activeTypeParameters: typeParameters };
2616
+ const lines = [
2617
+ emitRustRecordDerive(properties.map((property) => property.type), typeContext),
2618
+ `pub struct ${targetName}${emitTypeParameters(typeParameters, context)} {`,
2619
+ ];
2620
+ for (const property of properties) {
2621
+ const type = emitType(property.type, typeContext);
2622
+ lines.push(` pub ${safeRustValueName(property.name)}: ${property.optional ? `Option<${type}>` : type},`);
2623
+ }
2624
+ lines.push('}');
2625
+ return lines;
2626
+ }
2627
+ function emitStatementValueExpressionRust(expression, context) {
2628
+ if (expression.callee.kind !== 'function' || expression.arguments.length > 0) {
2629
+ emissionError(context, 'statement-value call requires a zero-argument function carrier');
2630
+ }
2631
+ const completion = expression.callee.body.at(-1);
2632
+ if (completion?.kind !== 'return' || !completion.expression) {
2633
+ emissionError(context, 'statement-value call requires a final value return');
2634
+ }
2635
+ const statements = emitStatements(expression.callee.body.slice(0, -1), context);
2636
+ return `{ ${[...statements, emitExpression(completion.expression, context)].join(' ')} }`;
2637
+ }
2638
+ function emitStatement(statement, context) {
2639
+ switch (statement.kind) {
2640
+ case 'block':
2641
+ return [
2642
+ `${emitControlFlowLabelRust(statement.label)}{`,
2643
+ ...indentSourceLines(emitStatements(statement.statements, context)),
2644
+ '}',
2645
+ ];
2646
+ case 'break':
2647
+ return [`break${statement.target ? ` ${emitControlFlowTargetRust(statement.target)}` : ''};`];
2648
+ case 'continue':
2649
+ return [`continue${statement.target ? ` ${emitControlFlowTargetRust(statement.target)}` : ''};`];
2650
+ case 'do':
2651
+ return [
2652
+ `${emitControlFlowLabelRust(statement.label)}loop {`,
2653
+ ...indentSourceLines(emitStatementBody(statement.body, context)),
2654
+ ` if !(${emitExpression(statement.condition, context)}) { break; }`,
2655
+ '}',
2656
+ ];
2657
+ case 'expression':
2658
+ return [`${emitExpression(statement.expression, context)};`];
2659
+ case 'for':
2660
+ emissionError(context, 'C-style for loops require control-flow lowering before Rust emission');
2661
+ case 'forIn':
2662
+ if ('pattern' in statement.variable)
2663
+ emissionError(context, 'binding patterns require destructuring lowering before Rust emission');
2664
+ if (!statement.keyPlan) {
2665
+ emissionError(context, 'object key iteration requires closed key evidence');
2666
+ }
2667
+ if (statement.keyPlan.evaluation === 'preserve') {
2668
+ emissionError(context, 'effectful object key iteration requires Rust structural-object evaluation lowering');
2669
+ }
2670
+ return [
2671
+ `${emitControlFlowLabelRust(statement.label)}for ${statement.variable.mutable ? 'mut ' : ''}${getBindingTargetNameRust(statement.variable.binding, context)} in [${statement.keyPlan.keys.map((key) => `${JSON.stringify(key)}.to_owned()`).join(', ')}] {`,
2672
+ ...indentSourceLines(emitStatementBody(statement.body, context)),
2673
+ '}',
2674
+ ];
2675
+ case 'forOf': {
2676
+ if (statement.await)
2677
+ emissionError(context, 'async iteration requires Flight task lowering');
2678
+ if ('pattern' in statement.variable)
2679
+ emissionError(context, 'binding patterns require destructuring lowering before Rust emission');
2680
+ const iterableRust = emitExpression(statement.iterable, context);
2681
+ const borrowPrefix = statement.iterable.kind === 'element' ? '&' : '';
2682
+ return [
2683
+ `${emitControlFlowLabelRust(statement.label)}for ${statement.variable.mutable ? 'mut ' : ''}${getBindingTargetNameRust(statement.variable.binding, context)} in ${borrowPrefix}${iterableRust} {`,
2684
+ ...indentSourceLines(emitStatementBody(statement.body, context)),
2685
+ '}',
2686
+ ];
2687
+ }
2688
+ case 'if': {
2689
+ const lines = [
2690
+ `if ${normalizeSourceTextGrouping(emitExpression(statement.condition, context))} {`,
2691
+ ...indentSourceLines(emitStatementBody(statement.consequent, context)),
2692
+ '}',
2693
+ ];
2694
+ if (statement.otherwise)
2695
+ lines.push('else {', ...indentSourceLines(emitStatementBody(statement.otherwise, context)), '}');
2696
+ return lines;
2697
+ }
2698
+ case 'return':
2699
+ // Comparing against `None` is not narrowing. Returning a binding that can be absent from a
2700
+ // function that cannot return one is Rust that does not compile, so it refuses here.
2701
+ if (!context.returnsAbsent &&
2702
+ statement.expression?.kind === 'identifier' &&
2703
+ statement.expression.reference.kind === 'binding' &&
2704
+ statement.expression.presence !== 'narrowedPresent' &&
2705
+ context.nullableBindingIds.has(statement.expression.reference.binding.id)) {
2706
+ emissionError(context, 'returning a nullable binding requires Rust narrowing evidence');
2707
+ }
2708
+ if (statement.expression && context.enclosingReturnType) {
2709
+ const dualSentinelUnion = resolveDualSentinelUnionEnumRust(context.enclosingReturnType, context);
2710
+ if (dualSentinelUnion) {
2711
+ const wrapped = emitDualSentinelUnionConstructionRust(statement.expression, dualSentinelUnion, context);
2712
+ if (wrapped)
2713
+ return [`return ${wrapped};`];
2714
+ }
2715
+ const numericEnum = getIrTypeNumericEnumNamespaceNameRust(context.enclosingReturnType, context);
2716
+ if (numericEnum) {
2717
+ const expressionEnum = getIrExpressionNumericEnumNamespaceNameRust(statement.expression, context);
2718
+ const emitted = emitReturnedExpressionRust(statement.expression, context);
2719
+ return [`return ${expressionEnum === numericEnum ? emitted : `${numericEnum}((${emitted}) as i32)`};`];
2720
+ }
2721
+ const targetEnum = resolvePrimitiveUnionEnumRust(context.enclosingReturnType, context);
2722
+ if (targetEnum) {
2723
+ if (statement.expression.kind === 'identifier' &&
2724
+ statement.expression.reference.kind === 'binding' &&
2725
+ context.primitiveUnionBindingIds.get(statement.expression.reference.binding.id) === targetEnum.name) {
2726
+ return [`return ${emitIdentifierReferenceRust(statement.expression.reference, context)};`];
2727
+ }
2728
+ const wrapped = emitPrimitiveUnionConstructionRust(statement.expression, targetEnum, context);
2729
+ if (wrapped)
2730
+ return [`return ${wrapped};`];
2731
+ }
2732
+ }
2733
+ return [
2734
+ `return${statement.expression ? ` ${normalizeSourceTextGrouping(emitReturnedExpressionRust(statement.expression, context))}` : ''};`,
2735
+ ];
2736
+ case 'switch': {
2737
+ const name = getGeneratedTargetNameRust('switch_value', context);
2738
+ const cases = statement.cases.filter((switchCase) => switchCase.expression);
2739
+ const otherwise = statement.cases.find((switchCase) => !switchCase.expression);
2740
+ const lines = [`let ${name} = ${emitExpression(statement.expression, context)};`];
2741
+ cases.forEach((switchCase, index) => {
2742
+ lines.push(`${index > 0 ? 'else ' : ''}if ${name} == ${emitExpression(switchCase.expression, context)} {`, ...indentSourceLines(emitIrSwitchCaseStatementsRust(switchCase, statement.label, context)), '}');
2743
+ });
2744
+ if (otherwise) {
2745
+ if (cases.length > 0)
2746
+ lines.push('else {');
2747
+ lines.push(...indentSourceLines(emitIrSwitchCaseStatementsRust(otherwise, statement.label, context), cases.length > 0 ? 1 : 0));
2748
+ if (cases.length > 0)
2749
+ lines.push('}');
2750
+ }
2751
+ else if (cases.length > 0) {
2752
+ lines.push('else {', ' unreachable!();', '}');
2753
+ }
2754
+ return [`${emitControlFlowLabelRust(statement.label)}{`, ...indentSourceLines(lines), '}'];
2755
+ }
2756
+ case 'throw': {
2757
+ const thrown = statement.expression;
2758
+ if (thrown.kind === 'new' && thrown.callee.kind === 'identifier' && thrown.arguments.length === 1) {
2759
+ return [`panic!("{}", ${emitExpression(thrown.arguments[0], context)});`];
2760
+ }
2761
+ return [`panic!("{:?}", ${emitExpression(thrown, context)});`];
2762
+ }
2763
+ case 'try': {
2764
+ if (context.asyncTryStatements.has(statement)) {
2765
+ return emitAsyncTryCatchRust(statement, context);
2766
+ }
2767
+ if (statement.finallyBody) {
2768
+ emissionError(context, 'synchronous try/finally requires catch_unwind with resume_unwind');
2769
+ }
2770
+ const catchBinding = statement.catchClause
2771
+ ? statement.catchClause.binding
2772
+ ? safeRustValueName(statement.catchClause.binding.name)
2773
+ : '_'
2774
+ : '_';
2775
+ const matchArms = statement.catchClause
2776
+ ? [
2777
+ 'Ok(__catch_result) => return __catch_result,',
2778
+ `Err(${catchBinding}) => {`,
2779
+ ...indentSourceLines(emitStatementBody(statement.catchClause.body, context)),
2780
+ '}',
2781
+ ]
2782
+ : ['Ok(_) => {}', 'Err(_) => {}'];
2783
+ return [
2784
+ 'match std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {',
2785
+ ...indentSourceLines(emitStatementBody(statement.tryBody, context)),
2786
+ '})) {',
2787
+ ...indentSourceLines(matchArms),
2788
+ '}',
2789
+ ];
2790
+ }
2791
+ case 'variable':
2792
+ return statement.declarations.map((variable) => emitVariable(variable, context));
2793
+ case 'while':
2794
+ // Rust spells a loop with no exit condition `loop`, and warns on `while true` because the two
2795
+ // differ to the borrow checker: only `loop` tells it the body always runs.
2796
+ const condition = normalizeSourceTextGrouping(emitExpression(statement.condition, context));
2797
+ return [
2798
+ `${emitControlFlowLabelRust(statement.label)}${condition === 'true' ? 'loop' : `while ${condition}`} {`,
2799
+ ...indentSourceLines(emitStatementBody(statement.body, context)),
2800
+ '}',
2801
+ ];
2802
+ }
2803
+ }
2804
+ function emitIrSwitchCaseStatementsRust(switchCase, switchLabel, context) {
2805
+ const last = switchCase.statements.at(-1);
2806
+ const localBreak = last?.kind === 'break' && (!last.target || (switchLabel && last.target.id === switchLabel.id));
2807
+ return emitStatements(localBreak ? switchCase.statements.slice(0, -1) : switchCase.statements, context);
2808
+ }
2809
+ function emitControlFlowLabelRust(label) {
2810
+ return label ? `${emitControlFlowTargetRust(label)}: ` : '';
2811
+ }
2812
+ function emitControlFlowTargetRust(label) {
2813
+ return `'${safeRustValueName(label.name)}`;
2814
+ }
2815
+ function emitStatementBody(statement, context) {
2816
+ return statement.kind === 'block'
2817
+ ? emitStatements(statement.statements, context)
2818
+ : emitStatements([statement], context);
2819
+ }
2820
+ function emitStatements(statements, context) {
2821
+ return statements.flatMap((statement) => emitStatement(statement, context));
2822
+ }
2823
+ function emitType(type, context) {
2824
+ switch (type.kind) {
2825
+ case 'array':
2826
+ return `Vec<${emitType(type.element, context)}>`;
2827
+ case 'function': {
2828
+ context.needsRcImport.add('Rc');
2829
+ const parameters = type.parameters.map((parameter) => emitType(parameter.type, context));
2830
+ const returns = emitType(type.returns, context);
2831
+ return `Rc<dyn Fn(${parameters.join(', ')}) -> ${returns}>`;
2832
+ }
2833
+ case 'indexedAccess':
2834
+ case 'conditionalFacet':
2835
+ case 'typeOf':
2836
+ return opaqueHostType(context);
2837
+ case 'keyof': {
2838
+ const resolved = getIrKeyofTypeRust(type.type, context);
2839
+ if (!resolved)
2840
+ return opaqueHostType(context);
2841
+ return emitType(resolved, context);
2842
+ }
2843
+ case 'intersection': {
2844
+ const scalarDomain = getIrTypePrimitiveDomainRust(type, context);
2845
+ if (scalarDomain)
2846
+ return emitType({ kind: 'primitive', name: scalarDomain }, context);
2847
+ const callableObject = getOrCreateCallableObjectRecordRust(type, context);
2848
+ if (callableObject) {
2849
+ return `${callableObject.name}${emitTypeArguments(callableObject.typeParameters, context)}`;
2850
+ }
2851
+ const properties = getIrObjectTypePropertiesRust(type, context);
2852
+ if (properties)
2853
+ return getIrObjectTypeTargetNameRust(properties, context);
2854
+ emissionError(context, 'intersection types require Rust record or trait lowering');
2855
+ }
2856
+ case 'literal':
2857
+ return typeof type.value === 'boolean' ? 'bool' : typeof type.value === 'number' ? 'f64' : 'String';
2858
+ case 'named': {
2859
+ const sourceName = type.reference.kind === 'ambient' ? type.reference.name : undefined;
2860
+ if ((sourceName === 'Readonly' || sourceName === 'Required') && type.typeArguments[0]) {
2861
+ return emitType(type.typeArguments[0], context);
2862
+ }
2863
+ if (sourceName === 'NoInfer' && type.typeArguments.length === 1 && type.typeArguments[0]) {
2864
+ return emitType(type.typeArguments[0], context);
2865
+ }
2866
+ if (sourceName === 'Exclude' || sourceName === 'Extract') {
2867
+ const projected = getIrFilteredTypeRust(sourceName, type.typeArguments, context);
2868
+ if (!projected)
2869
+ emissionError(context, `${sourceName} types require closed Rust type computation lowering`);
2870
+ return emitType(projected, context);
2871
+ }
2872
+ if (sourceName === 'Partial' || sourceName === 'Pick' || sourceName === 'Omit') {
2873
+ const properties = getIrObjectTypePropertiesRust(type, context);
2874
+ if (!properties)
2875
+ emissionError(context, `${sourceName}<T> requires a statically resolvable Rust object shape`);
2876
+ return getIrObjectTypeTargetNameRust(properties, context);
2877
+ }
2878
+ const mapped = getTypeReferenceTargetNameRust(type, context);
2879
+ const arguments_ = type.typeArguments.map((argument) => emitType(argument, context));
2880
+ return `${mapped}${arguments_.length > 0 ? `<${arguments_.join(', ')}>` : ''}`;
2881
+ }
2882
+ case 'never':
2883
+ return '!';
2884
+ case 'null':
2885
+ case 'undefined':
2886
+ return '()';
2887
+ case 'object':
2888
+ return getIrObjectTypeTargetNameRust(type.properties, context);
2889
+ case 'primitive':
2890
+ if (type.name === 'symbol')
2891
+ return recordRuntimeTypeRust('FlightSymbol', context);
2892
+ return { bigint: 'i64', boolean: 'bool', number: 'f64', string: 'String', symbol: 'FlightSymbol', void: '()' }[type.name];
2893
+ case 'tuple': {
2894
+ const elements = type.elements.map((element) => {
2895
+ const emitted = emitType(element.type, context);
2896
+ return element.optional ? `Option<${emitted}>` : emitted;
2897
+ });
2898
+ return `(${elements.join(', ')}${elements.length === 1 ? ',' : ''})`;
2899
+ }
2900
+ case 'union': {
2901
+ const concrete = type.types.filter((item) => item.kind !== 'null' && item.kind !== 'undefined');
2902
+ const optional = concrete.length !== type.types.length;
2903
+ if (hasIrTypeNullMemberRust(type) && hasIrTypeUndefinedMemberRust(type)) {
2904
+ const union = getOrCreateAnonymousUnionEnumRust(type.types, context);
2905
+ return `${union.name}${emitTypeArguments(union.typeParameters, context)}`;
2906
+ }
2907
+ if (concrete.length === 1 && concrete.length !== type.types.length)
2908
+ return `Option<${emitType(concrete[0], context)}>`;
2909
+ const primitiveDomain = getIrUnionPrimitiveDomainRust(concrete, context);
2910
+ if (primitiveDomain) {
2911
+ const emitted = emitType({ kind: 'primitive', name: primitiveDomain }, context);
2912
+ return optional ? `Option<${emitted}>` : emitted;
2913
+ }
2914
+ const primitiveEnum = getOrCreatePrimitiveUnionEnumRust(concrete, context);
2915
+ if (primitiveEnum)
2916
+ return optional ? `Option<${primitiveEnum.name}>` : primitiveEnum.name;
2917
+ const generalEnum = getOrCreateAnonymousUnionEnumRust(concrete, context);
2918
+ const emitted = `${generalEnum.name}${emitTypeArguments(generalEnum.typeParameters, context)}`;
2919
+ return optional ? `Option<${emitted}>` : emitted;
2920
+ }
2921
+ case 'unknown':
2922
+ return opaqueHostType(context);
2923
+ }
2924
+ }
2925
+ // TypeScript's object utilities and intersections are representation decisions in Rust: once every
2926
+ // participating declaration is closed, the result is one concrete record. Keep the resolver local
2927
+ // to the backend because it decides Rust storage, but consume the shared substitution machinery so
2928
+ // generic aliases and inherited interfaces do not acquire a second set of type-argument rules.
2929
+ function getIrObjectTypePropertiesRust(type, context, module = context.module, resolving = new Set()) {
2930
+ if (type.kind === 'object')
2931
+ return type.properties;
2932
+ if (type.kind === 'intersection') {
2933
+ const shapes = type.types.map((member) => getIrObjectTypePropertiesRust(member, context, module, resolving));
2934
+ return shapes.some((shape) => !shape)
2935
+ ? undefined
2936
+ : mergeIrObjectTypePropertiesRust(shapes.flatMap((shape) => shape));
2937
+ }
2938
+ if (type.kind !== 'named')
2939
+ return undefined;
2940
+ if (type.reference.kind === 'ambient') {
2941
+ const utility = type.reference.name;
2942
+ if (utility === 'Record') {
2943
+ if (type.typeArguments.length !== 2 || !type.typeArguments[0] || !type.typeArguments[1])
2944
+ return undefined;
2945
+ const keys = getIrObjectProjectionKeysRust(type.typeArguments[0], context, module, resolving);
2946
+ if (!keys)
2947
+ return undefined;
2948
+ return [...keys].map((name) => ({
2949
+ name,
2950
+ optional: false,
2951
+ readonly: false,
2952
+ type: type.typeArguments[1],
2953
+ }));
2954
+ }
2955
+ if (utility === 'NoInfer' || utility === 'Partial' || utility === 'Readonly' || utility === 'Required') {
2956
+ if (type.typeArguments.length !== 1 || !type.typeArguments[0])
2957
+ return undefined;
2958
+ const properties = getIrObjectTypePropertiesRust(type.typeArguments[0], context, module, resolving);
2959
+ if (!properties)
2960
+ return undefined;
2961
+ return properties.map((property) => ({
2962
+ ...property,
2963
+ ...(utility === 'Partial' ? { optional: true } : {}),
2964
+ ...(utility === 'Readonly' ? { readonly: true } : {}),
2965
+ ...(utility === 'Required' ? { optional: false } : {}),
2966
+ }));
2967
+ }
2968
+ if (utility === 'Exclude' || utility === 'Extract') {
2969
+ const projected = getIrFilteredTypeRust(utility, type.typeArguments, context, module, resolving);
2970
+ return projected ? getIrObjectTypePropertiesRust(projected, context, module, resolving) : undefined;
2971
+ }
2972
+ if (utility !== 'Omit' && utility !== 'Pick')
2973
+ return undefined;
2974
+ if (type.typeArguments.length !== 2 || !type.typeArguments[0] || !type.typeArguments[1])
2975
+ return undefined;
2976
+ const properties = getIrObjectTypePropertiesRust(type.typeArguments[0], context, module, resolving);
2977
+ const keys = getIrObjectProjectionKeysRust(type.typeArguments[1], context, module, resolving);
2978
+ if (!properties || !keys)
2979
+ return undefined;
2980
+ return properties.filter((property) => (utility === 'Pick') === keys.has(property.name));
2981
+ }
2982
+ if (type.reference.path.length > 0)
2983
+ return undefined;
2984
+ if (type.reference.binding.space !== 'type' || type.reference.binding.kind === 'typeParameter')
2985
+ return undefined;
2986
+ const location = getIrNamedTypeDeclarationLocationRust(type.reference.binding, context, module);
2987
+ if (!location)
2988
+ return undefined;
2989
+ const key = `${location.module.packageName}\0${location.module.source}\0${location.declaration.binding.id}`;
2990
+ if (resolving.has(key))
2991
+ return undefined;
2992
+ const active = new Set(resolving).add(key);
2993
+ let plan;
2994
+ try {
2995
+ plan = createIrTypeParameterSubstitutionPlan(location.declaration.typeParameters, type.typeArguments);
2996
+ }
2997
+ catch (error) {
2998
+ if (isCompilerStructuralTypeSubstitutionFailure(error))
2999
+ return undefined;
3000
+ throw error;
3001
+ }
3002
+ if (location.declaration.kind === 'typeAlias') {
3003
+ let resolved;
3004
+ try {
3005
+ resolved = resolveIrTypeStructuralSubstitution(location.declaration.type, plan);
3006
+ }
3007
+ catch (error) {
3008
+ if (isCompilerStructuralTypeSubstitutionFailure(error))
3009
+ return undefined;
3010
+ throw error;
3011
+ }
3012
+ return getIrObjectTypePropertiesRust(resolved, context, location.module, active);
3013
+ }
3014
+ const inherited = location.declaration.extends.map((reference) => {
3015
+ let resolved;
3016
+ try {
3017
+ resolved = resolveIrTypeStructuralSubstitution(reference, plan);
3018
+ }
3019
+ catch (error) {
3020
+ if (isCompilerStructuralTypeSubstitutionFailure(error))
3021
+ return undefined;
3022
+ throw error;
3023
+ }
3024
+ return getIrObjectTypePropertiesRust(resolved, context, location.module, active);
3025
+ });
3026
+ if (inherited.some((properties) => !properties))
3027
+ return undefined;
3028
+ let own;
3029
+ try {
3030
+ own = location.declaration.properties.map((property) => ({
3031
+ ...property,
3032
+ type: resolveIrTypeStructuralSubstitution(property.type, plan),
3033
+ }));
3034
+ }
3035
+ catch (error) {
3036
+ if (isCompilerStructuralTypeSubstitutionFailure(error))
3037
+ return undefined;
3038
+ throw error;
3039
+ }
3040
+ return mergeIrObjectTypePropertiesRust([...inherited.flatMap((properties) => properties), ...own]);
3041
+ }
3042
+ function mergeIrObjectTypePropertiesRust(properties) {
3043
+ const merged = new Map();
3044
+ for (const property of properties) {
3045
+ const existing = merged.get(property.name);
3046
+ if (!existing) {
3047
+ merged.set(property.name, { ...property });
3048
+ continue;
3049
+ }
3050
+ if (JSON.stringify(existing.computedKey) !== JSON.stringify(property.computedKey) ||
3051
+ existing.phantom !== property.phantom ||
3052
+ existing.role !== property.role) {
3053
+ return undefined;
3054
+ }
3055
+ const type = JSON.stringify(existing.type) === JSON.stringify(property.type)
3056
+ ? existing.type
3057
+ : createIrIntersectionTypeRust(existing.type, property.type);
3058
+ merged.set(property.name, {
3059
+ ...existing,
3060
+ optional: existing.optional && property.optional,
3061
+ readonly: existing.readonly && property.readonly,
3062
+ type,
3063
+ });
3064
+ }
3065
+ return [...merged.values()];
3066
+ }
3067
+ function getIrObjectProjectionKeysRust(type, context, module, resolving) {
3068
+ const members = getIrClosedTypeMembersRust(type, context, module, resolving);
3069
+ if (!members || members.some((member) => member.kind !== 'literal' || typeof member.value === 'boolean')) {
3070
+ return undefined;
3071
+ }
3072
+ return new Set(members.map((member) => String(member.value)));
3073
+ }
3074
+ function getIrKeyofTypeRust(type, context) {
3075
+ const properties = getIrObjectTypePropertiesRust(type, context);
3076
+ if (!properties)
3077
+ return undefined;
3078
+ const keys = [];
3079
+ if (properties.some((property) => !property.computedKey && !property.phantom)) {
3080
+ keys.push({ kind: 'primitive', name: 'string' });
3081
+ }
3082
+ if (properties.some((property) => property.computedKey && !property.phantom)) {
3083
+ keys.push({ kind: 'primitive', name: 'symbol' });
3084
+ }
3085
+ return createIrClosedTypeUnionRust(keys);
3086
+ }
3087
+ function getIrFilteredTypeRust(utility, typeArguments, context, module = context.module, resolving = new Set()) {
3088
+ if (typeArguments.length !== 2 || !typeArguments[0] || !typeArguments[1])
3089
+ return undefined;
3090
+ const included = getIrClosedTypeMembersRust(typeArguments[0], context, module, resolving);
3091
+ const filters = getIrClosedTypeMembersRust(typeArguments[1], context, module, resolving);
3092
+ if (!included || !filters)
3093
+ return undefined;
3094
+ const retained = [];
3095
+ for (const member of included) {
3096
+ const matches = filters.map((filter) => isIrTypeAssignableForFilterRust(member, filter, context, module, resolving));
3097
+ if (!matches.includes(true) && matches.includes(undefined))
3098
+ return undefined;
3099
+ const matched = matches.includes(true);
3100
+ if ((utility === 'Extract') === matched)
3101
+ retained.push(member);
3102
+ }
3103
+ return createIrClosedTypeUnionRust(retained);
3104
+ }
3105
+ function getIrClosedTypeMembersRust(type, context, module = context.module, resolving = new Set()) {
3106
+ if (type.kind === 'never')
3107
+ return [];
3108
+ if (type.kind === 'union') {
3109
+ const members = type.types.map((member) => getIrClosedTypeMembersRust(member, context, module, resolving));
3110
+ return members.some((member) => !member) ? undefined : members.flatMap((member) => member);
3111
+ }
3112
+ if (type.kind === 'keyof') {
3113
+ const resolved = getIrKeyofTypeRustInModule(type.type, context, module, resolving);
3114
+ return resolved ? getIrClosedTypeMembersRust(resolved, context, module, resolving) : undefined;
3115
+ }
3116
+ if (type.kind === 'typeOf') {
3117
+ const resolved = getIrTypeOfValueTypeRust(type, context, module);
3118
+ return resolved ? getIrClosedTypeMembersRust(resolved, context, module, resolving) : undefined;
3119
+ }
3120
+ if (type.kind === 'named' && type.reference.kind === 'binding' && type.reference.path.length === 0) {
3121
+ if (type.reference.binding.space !== 'type' || type.reference.binding.kind === 'typeParameter')
3122
+ return undefined;
3123
+ const location = getIrNamedTypeDeclarationLocationRust(type.reference.binding, context, module);
3124
+ if (location?.declaration.kind === 'typeAlias') {
3125
+ const key = `${location.module.packageName}\0${location.module.source}\0${location.declaration.binding.id}`;
3126
+ if (resolving.has(key))
3127
+ return undefined;
3128
+ try {
3129
+ const plan = createIrTypeParameterSubstitutionPlan(location.declaration.typeParameters, type.typeArguments);
3130
+ const resolved = resolveIrTypeStructuralSubstitution(location.declaration.type, plan);
3131
+ return getIrClosedTypeMembersRust(resolved, context, location.module, new Set(resolving).add(key));
3132
+ }
3133
+ catch (error) {
3134
+ if (isCompilerStructuralTypeSubstitutionFailure(error))
3135
+ return undefined;
3136
+ throw error;
3137
+ }
3138
+ }
3139
+ }
3140
+ if (type.kind === 'conditionalFacet' || type.kind === 'indexedAccess' || type.kind === 'unknown') {
3141
+ return undefined;
3142
+ }
3143
+ return [type];
3144
+ }
3145
+ function getIrTypeOfValueTypeRust(type, context, module) {
3146
+ if (type.reference.kind !== 'binding' || type.reference.path.length > 0)
3147
+ return undefined;
3148
+ const binding = type.reference.binding;
3149
+ const local = module.declarations.find((declaration) => declaration.kind === 'variable' && 'binding' in declaration && declaration.binding.id === binding.id);
3150
+ if (local?.kind === 'variable' && 'binding' in local)
3151
+ return getIrVariableTypeRust(local);
3152
+ const imported = module.imports
3153
+ .flatMap((item) => item.bindings.map((candidate) => ({ candidate, specifier: item.specifier })))
3154
+ .find(({ candidate }) => candidate.binding.id === binding.id);
3155
+ if (!imported || imported.candidate.imported === '*' || imported.candidate.imported === 'default')
3156
+ return undefined;
3157
+ const targetModule = resolveImportModuleRust(imported.specifier, imported.candidate.imported, context, module);
3158
+ const declaration = targetModule?.declarations.find((candidate) => candidate.kind === 'variable' && 'binding' in candidate && candidate.binding.name === imported.candidate.imported);
3159
+ return declaration?.kind === 'variable' && 'binding' in declaration ? getIrVariableTypeRust(declaration) : undefined;
3160
+ }
3161
+ function getIrVariableTypeRust(variable) {
3162
+ if ('pattern' in variable)
3163
+ return undefined;
3164
+ if (variable.type && variable.type.kind !== 'unknown')
3165
+ return variable.type;
3166
+ const initializer = variable.initializer;
3167
+ if (initializer?.kind !== 'call')
3168
+ return variable.type;
3169
+ const directSymbol = initializer.callee.kind === 'identifier' &&
3170
+ initializer.callee.reference.kind === 'ambient' &&
3171
+ initializer.callee.reference.name === 'Symbol';
3172
+ const symbolMember = initializer.callee.kind === 'property' &&
3173
+ initializer.callee.object.kind === 'identifier' &&
3174
+ initializer.callee.object.reference.kind === 'ambient' &&
3175
+ initializer.callee.object.reference.name === 'Symbol';
3176
+ return directSymbol || symbolMember ? { kind: 'primitive', name: 'symbol' } : variable.type;
3177
+ }
3178
+ function getIrKeyofTypeRustInModule(type, context, module, resolving) {
3179
+ const properties = getIrObjectTypePropertiesRust(type, context, module, resolving);
3180
+ if (!properties)
3181
+ return undefined;
3182
+ const keys = [];
3183
+ if (properties.some((property) => !property.computedKey && !property.phantom)) {
3184
+ keys.push({ kind: 'primitive', name: 'string' });
3185
+ }
3186
+ if (properties.some((property) => property.computedKey && !property.phantom)) {
3187
+ keys.push({ kind: 'primitive', name: 'symbol' });
3188
+ }
3189
+ return createIrClosedTypeUnionRust(keys);
3190
+ }
3191
+ function isIrTypeAssignableForFilterRust(source, target, context, module, resolving) {
3192
+ if (target.kind === 'primitive') {
3193
+ if (source.kind === 'primitive')
3194
+ return source.name === target.name;
3195
+ if (source.kind !== 'literal')
3196
+ return false;
3197
+ return typeof source.value === target.name;
3198
+ }
3199
+ if (target.kind === 'literal')
3200
+ return source.kind === 'literal' && Object.is(source.value, target.value);
3201
+ if (target.kind === 'null' || target.kind === 'undefined')
3202
+ return source.kind === target.kind;
3203
+ const sourceProperties = getIrObjectTypePropertiesRust(source, context, module, resolving);
3204
+ const targetProperties = getIrObjectTypePropertiesRust(target, context, module, resolving);
3205
+ if (!sourceProperties || !targetProperties)
3206
+ return undefined;
3207
+ // Discriminant filters are closed even when the wider structural comparison is indeterminate.
3208
+ // `Extract<Union, { kind: "x" }>` only asks whether each alternative's named literal slot is
3209
+ // compatible; unrelated fields and their host types cannot affect that decision.
3210
+ if (targetProperties.length > 0 && targetProperties.every((property) => property.type.kind === 'literal')) {
3211
+ const decisions = targetProperties.map((targetProperty) => {
3212
+ const sourceProperty = sourceProperties.find((property) => property.name === targetProperty.name);
3213
+ if (!sourceProperty || sourceProperty.optional)
3214
+ return false;
3215
+ const members = getIrClosedTypeMembersRust(sourceProperty.type, context, module, resolving);
3216
+ if (!members)
3217
+ return undefined;
3218
+ return members.every((member) => member.kind === 'literal' &&
3219
+ targetProperty.type.kind === 'literal' &&
3220
+ Object.is(member.value, targetProperty.type.value));
3221
+ });
3222
+ if (decisions.includes(false))
3223
+ return false;
3224
+ if (decisions.every((decision) => decision === true))
3225
+ return true;
3226
+ }
3227
+ const report = analyzeIrTypeStructuralAssignability({ kind: 'object', properties: sourceProperties }, { kind: 'object', properties: targetProperties });
3228
+ return report.status === 'indeterminate' ? undefined : report.status === 'compatible';
3229
+ }
3230
+ function createIrClosedTypeUnionRust(types) {
3231
+ const unique = [...new Map(types.map((type) => [JSON.stringify(type), type])).values()];
3232
+ if (unique.length === 0)
3233
+ return { kind: 'never' };
3234
+ if (unique.length === 1)
3235
+ return unique[0];
3236
+ return { kind: 'union', types: [unique[0], unique[1], ...unique.slice(2)] };
3237
+ }
3238
+ function createIrIntersectionTypeRust(left, right) {
3239
+ const types = [
3240
+ ...(left.kind === 'intersection' ? left.types : [left]),
3241
+ ...(right.kind === 'intersection' ? right.types : [right]),
3242
+ ];
3243
+ return { kind: 'intersection', types: [types[0], types[1], ...types.slice(2)] };
3244
+ }
3245
+ function getIrUnionPrimitiveDomainRust(types, context) {
3246
+ const domains = types.map((type) => getIrTypePrimitiveDomainRust(type, context));
3247
+ const domain = domains[0];
3248
+ return domain !== undefined && domains.every((candidate) => candidate === domain) ? domain : undefined;
3249
+ }
3250
+ function getIrTypePrimitiveDomainRust(type, context, module = context.module, resolving = new Set()) {
3251
+ if (type.kind === 'literal') {
3252
+ const domain = typeof type.value;
3253
+ return domain === 'boolean' || domain === 'number' || domain === 'string' ? domain : undefined;
3254
+ }
3255
+ if (type.kind === 'primitive' && (type.name === 'boolean' || type.name === 'number' || type.name === 'string')) {
3256
+ return type.name;
3257
+ }
3258
+ if (type.kind === 'typeOf') {
3259
+ const resolved = getIrTypeOfValueTypeRust(type, context, module);
3260
+ return resolved ? getIrTypePrimitiveDomainRust(resolved, context, module, resolving) : undefined;
3261
+ }
3262
+ if (type.kind === 'intersection') {
3263
+ const meaningful = type.types.filter((member) => member.kind !== 'object' && getIrObjectTypePropertiesRust(member, context, module, resolving) === undefined);
3264
+ const domains = meaningful.map((member) => getIrTypePrimitiveDomainRust(member, context, module, resolving));
3265
+ const domain = domains[0];
3266
+ return domain !== undefined && domains.every((candidate) => candidate === domain) ? domain : undefined;
3267
+ }
3268
+ if (type.kind !== 'named' ||
3269
+ type.reference.kind !== 'binding' ||
3270
+ type.reference.path.length > 0 ||
3271
+ type.reference.binding.space !== 'type' ||
3272
+ type.reference.binding.kind === 'typeParameter') {
3273
+ return undefined;
3274
+ }
3275
+ const location = getIrNamedTypeDeclarationLocationRust(type.reference.binding, context, module);
3276
+ if (location?.declaration.kind !== 'typeAlias')
3277
+ return undefined;
3278
+ const key = `${location.module.packageName}\0${location.module.source}\0${location.declaration.binding.id}`;
3279
+ if (resolving.has(key))
3280
+ return undefined;
3281
+ try {
3282
+ const plan = createIrTypeParameterSubstitutionPlan(location.declaration.typeParameters, type.typeArguments);
3283
+ const resolved = resolveIrTypeStructuralSubstitution(location.declaration.type, plan);
3284
+ return getIrTypePrimitiveDomainRust(resolved, context, location.module, new Set(resolving).add(key));
3285
+ }
3286
+ catch (error) {
3287
+ if (isCompilerStructuralTypeSubstitutionFailure(error))
3288
+ return undefined;
3289
+ throw error;
3290
+ }
3291
+ }
3292
+ // A union of string literals is how the source language spells a closed set of names, and the source
3293
+ // treats a value of it as a string everywhere: comparing it, returning it, storing it in a string
3294
+ // field. Rust has no implicit conversion, so a unit-variant enum would need a coercion inserted at
3295
+ // every one of those positions — type-directed work this backend does not do yet.
3296
+ //
3297
+ // So the set becomes the string it is made of, and the closed-ness is what is lost. Haxe keeps the
3298
+ // enum because `from String to String` gives it exactly those coercions for free; that the two
3299
+ // targets diverge here is a property of the targets, not an inconsistency in the compiler.
3300
+ function emitStringLiteralUnionRust(declaration, context) {
3301
+ return [
3302
+ `${declaration.exported ? 'pub ' : ''}type ${getBindingTargetNameRust(declaration.binding, context)} = String;`,
3303
+ ];
3304
+ }
3305
+ function emitTypeAlias(declaration, context) {
3306
+ if (getIrUnionTypeStringLiteralValues(declaration.type))
3307
+ return emitStringLiteralUnionRust(declaration, context);
3308
+ if (declaration.type.kind === 'union' && getIrUnionTypeMemberRecordsRust(declaration.type, context)) {
3309
+ return emitTaggedUnionRust(getBindingTargetNameRust(declaration.binding, context), declaration.type, declaration.exported, context);
3310
+ }
3311
+ const typeContext = { ...context, activeTypeParameters: declaration.typeParameters };
3312
+ if (declaration.type.kind === 'union' &&
3313
+ !hasIrTypeNullMemberRust(declaration.type) &&
3314
+ !hasIrTypeUndefinedMemberRust(declaration.type) &&
3315
+ !getIrUnionPrimitiveDomainRust(declaration.type.types, typeContext)) {
3316
+ return emitGeneralUnionRust(getBindingTargetNameRust(declaration.binding, context), createGeneralUnionVariantsRust(declaration.type.types, typeContext), declaration.typeParameters, declaration.exported, typeContext);
3317
+ }
3318
+ const recordProperties = isIrTypeRecordMaterializationRust(declaration.type)
3319
+ ? getIrObjectTypePropertiesRust(declaration.type, context)
3320
+ : undefined;
3321
+ if (recordProperties) {
3322
+ return emitRecord(getBindingTargetNameRust(declaration.binding, context), recordProperties, declaration.typeParameters, declaration.exported, context);
3323
+ }
3324
+ return [
3325
+ `${declaration.exported ? 'pub ' : ''}type ${getBindingTargetNameRust(declaration.binding, context)}${emitTypeParameters(declaration.typeParameters, context)} = ${emitType(declaration.type, typeContext)};`,
3326
+ ];
3327
+ }
3328
+ function isIrTypeRecordMaterializationRust(type) {
3329
+ if (type.kind === 'object' || type.kind === 'intersection')
3330
+ return true;
3331
+ return (type.kind === 'named' &&
3332
+ type.reference.kind === 'ambient' &&
3333
+ ['Exclude', 'Extract', 'Omit', 'Partial', 'Pick', 'Required'].includes(type.reference.name));
3334
+ }
3335
+ function emitTupleSpreadExpressionRust(expression, context) {
3336
+ const declarations = [];
3337
+ const elements = [];
3338
+ let resultIndex = 0;
3339
+ for (const segment of expression.segments) {
3340
+ if (segment.kind === 'element') {
3341
+ const target = expression.type.elements[resultIndex];
3342
+ if (!segment.element.expression) {
3343
+ elements.push('None');
3344
+ }
3345
+ else {
3346
+ const name = getGeneratedTargetNameRust('tuple_spread_element', context);
3347
+ declarations.push(`let ${name} = ${emitExpression(segment.element.expression, context)};`);
3348
+ elements.push(target.optional ? `Some(${name})` : name);
3349
+ }
3350
+ resultIndex += 1;
3351
+ continue;
3352
+ }
3353
+ segment.type.elements.forEach((element, offset) => {
3354
+ if (!isIrTypeCloneSafeRust(element.type)) {
3355
+ emissionError(context, `fixed tuple spread source index ${String(offset)} lacks clone-safe Rust ownership evidence`);
3356
+ }
3357
+ });
3358
+ const name = getGeneratedTargetNameRust('tuple_spread_value', context);
3359
+ declarations.push(`let ${name} = &(${emitExpression(segment.expression, context)});`);
3360
+ segment.type.elements.forEach((element, offset) => {
3361
+ const value = `${name}.${String(offset)}.clone()`;
3362
+ const target = expression.type.elements[resultIndex + offset];
3363
+ elements.push(target.optional && !element.optional ? `Some(${value})` : value);
3364
+ });
3365
+ resultIndex += segment.type.elements.length;
3366
+ }
3367
+ const tuple = `(${elements.join(', ')}${elements.length === 1 ? ',' : ''})`;
3368
+ return `({ ${declarations.join(' ')} ${tuple} })`;
3369
+ }
3370
+ function emitTypeArguments(parameters, context) {
3371
+ return parameters.length === 0
3372
+ ? ''
3373
+ : `<${parameters.map((parameter) => getBindingTargetNameRust(parameter.binding, context)).join(', ')}>`;
3374
+ }
3375
+ function emitTypeParameters(parameters, context) {
3376
+ if (parameters.length === 0)
3377
+ return '';
3378
+ return `<${parameters
3379
+ .map((parameter) => {
3380
+ const name = getBindingTargetNameRust(parameter.binding, context);
3381
+ // A TypeScript constraint is a value shape, not a Rust trait. Spelling `T extends string` as
3382
+ // `T: String` produces invalid Rust because `String` is a concrete type. Generated records do
3383
+ // clone generic storage, so Clone is the one target capability this declaration can require
3384
+ // without claiming that a source value type is a trait.
3385
+ return `${name}: Clone`;
3386
+ })
3387
+ .join(', ')}>`;
3388
+ }
3389
+ function emitVariable(variable, context) {
3390
+ if ('pattern' in variable)
3391
+ emissionError(context, 'binding patterns require destructuring lowering before Rust emission');
3392
+ const representationType = variable.type?.kind === 'unknown' && variable.initializer
3393
+ ? (inferIrExpressionTypeRust(variable.initializer, context) ?? variable.type)
3394
+ : variable.type;
3395
+ if (variable.initialValue === 'undefined') {
3396
+ if (!variable.type || !isNullableType(variable.type)) {
3397
+ emissionError(context, 'observable undefined function-entry value requires a nullable Rust type domain');
3398
+ }
3399
+ const dualSentinelUnion = resolveDualSentinelUnionEnumRust(variable.type, context);
3400
+ const initial = dualSentinelUnion ? `${dualSentinelUnion.name}::Undefined` : 'None';
3401
+ return `let ${variable.mutable ? 'mut ' : ''}${getBindingTargetNameRust(variable.binding, context)}: ${emitType(variable.type, context)} = ${initial};`;
3402
+ }
3403
+ if (context.cellWrappedBindingIds.has(variable.binding.id)) {
3404
+ context.needsCellImport.add('Cell');
3405
+ context.needsRcImport.add('Rc');
3406
+ const name = getBindingTargetNameRust(variable.binding, context);
3407
+ const type = variable.type ? emitType(variable.type, context) : 'f64';
3408
+ const init = variable.initializer ? emitExpression(variable.initializer, context) : '0.0';
3409
+ return `let ${name}: Rc<Cell<${type}>> = Rc::new(Cell::new(${init}));`;
3410
+ }
3411
+ if (context.refCellWrappedBindingIds.has(variable.binding.id)) {
3412
+ context.needsRefCellImport.add('RefCell');
3413
+ context.needsRcImport.add('Rc');
3414
+ const name = getBindingTargetNameRust(variable.binding, context);
3415
+ const type = variable.type ? emitType(variable.type, context) : 'String';
3416
+ const init = variable.initializer ? emitExpression(variable.initializer, context) : 'Default::default()';
3417
+ return `let ${name}: Rc<RefCell<${type}>> = Rc::new(RefCell::new(${init}));`;
3418
+ }
3419
+ if (variable.type && variable.initializer) {
3420
+ const dualSentinelUnion = resolveDualSentinelUnionEnumRust(variable.type, context);
3421
+ if (dualSentinelUnion) {
3422
+ const wrapped = emitDualSentinelUnionConstructionRust(variable.initializer, dualSentinelUnion, context);
3423
+ if (wrapped) {
3424
+ const mutable = variable.mutable ||
3425
+ (context.referentMutatedBindingIds.has(variable.binding.id) && !isIrTypeTypedArrayRust(variable.type));
3426
+ return `let ${mutable ? 'mut ' : ''}${getBindingTargetNameRust(variable.binding, context)}: ${emitType(variable.type, context)} = ${wrapped};`;
3427
+ }
3428
+ }
3429
+ const targetEnum = resolvePrimitiveUnionEnumRust(variable.type, context);
3430
+ if (targetEnum) {
3431
+ const wrapped = emitPrimitiveUnionConstructionRust(variable.initializer, targetEnum, context);
3432
+ if (wrapped) {
3433
+ const deferred = !variable.initializer && context.deferredBindingIds.has(variable.binding.id);
3434
+ const mutable = (variable.mutable && !deferred) ||
3435
+ (context.referentMutatedBindingIds.has(variable.binding.id) && !isIrTypeTypedArrayRust(variable.type));
3436
+ return `let ${mutable ? 'mut ' : ''}${getBindingTargetNameRust(variable.binding, context)}: ${emitType(variable.type, context)} = ${wrapped};`;
3437
+ }
3438
+ }
3439
+ }
3440
+ const isArrayElementBinding = 'binding' in variable && context.arrayElementBindingIds.has(variable.binding.id);
3441
+ const type = representationType && !(variable.initializer?.kind === 'objectRest' && representationType.kind === 'object')
3442
+ ? `: ${isArrayElementBinding ? `Option<${emitType(representationType, context)}>` : emitType(representationType, context)}`
3443
+ : '';
3444
+ const isCallbackInitializer = variable.type?.kind === 'function' && variable.initializer?.kind === 'function';
3445
+ if (isCallbackInitializer)
3446
+ context.needsRcImport.add('Rc');
3447
+ const isNullableArrayElement = 'binding' in variable &&
3448
+ (context.nullableBindingIds.has(variable.binding.id) || isArrayElementBinding) &&
3449
+ variable.initializer?.kind === 'element' &&
3450
+ !variable.initializer.optional &&
3451
+ variable.initializer.semantics.receivers.includes('array');
3452
+ const initializer = variable.initializer
3453
+ ? ` = ${normalizeSourceTextGrouping(isCallbackInitializer ? emitClosureWithCellClonesRust(variable.initializer, context) : isNullableArrayElement ? emitOptionShapedOperandRust(variable.initializer, context) : emitOwnedOperandRust(variable.initializer, context))}`
3454
+ : '';
3455
+ // A binding declared without a value and written once afterwards is Rust's deferred
3456
+ // initialization, not a mutation: the source hoisted the declaration above the assignment, and
3457
+ // `mut` on it would claim a rebinding that never happens.
3458
+ const deferred = !variable.initializer && context.deferredBindingIds.has(variable.binding.id);
3459
+ // Rust asks for `mut` to reach a value's own fields through a method, where the source language
3460
+ // only asks for it to rebind the name. A `const` the source mutates through is still `mut` here.
3461
+ const mutable = (variable.mutable && !deferred) ||
3462
+ (context.referentMutatedBindingIds.has(variable.binding.id) && !isIrTypeTypedArrayRust(variable.type));
3463
+ return `let ${mutable ? 'mut ' : ''}${getBindingTargetNameRust(variable.binding, context)}${type}${initializer};`;
3464
+ }
3465
+ function emitVariableDeclaration(declaration, context) {
3466
+ if ('pattern' in declaration)
3467
+ emissionError(context, 'binding patterns require destructuring lowering before Rust emission');
3468
+ if (!declaration.initializer || !declaration.type) {
3469
+ emissionError(context, `module variable ${declaration.binding.name} requires an initializer and type`);
3470
+ }
3471
+ if (declaration.mutable)
3472
+ emissionError(context, `mutable module variable ${declaration.binding.name} requires synchronization lowering`);
3473
+ return [
3474
+ `${declaration.exported ? 'pub ' : ''}const ${getBindingTargetNameRust(declaration.binding, context)}: ${emitType(declaration.type, context)} = ${emitExpression(declaration.initializer, context)};`,
3475
+ ];
3476
+ }
3477
+ function getBindingTargetNameRust(binding, context) {
3478
+ const targetName = context.targetNames.get(binding.id);
3479
+ if (!targetName)
3480
+ emissionError(context, `binding ${binding.name} has no Rust target name allocation`);
3481
+ return targetName;
3482
+ }
3483
+ function getGeneratedTargetNameRust(preferredName, context) {
3484
+ let name = preferredName;
3485
+ const separator = /^[A-Z]/u.test(preferredName) ? '' : '_';
3486
+ for (let suffix = 2; context.generatedNames.has(name); suffix += 1) {
3487
+ name = `${preferredName}${separator}${String(suffix)}`;
3488
+ }
3489
+ context.generatedNames.add(name);
3490
+ return name;
3491
+ }
3492
+ function getElementAccessTupleIndexRust(expression, context) {
3493
+ if (expression.semantics.receivers.length !== 1 ||
3494
+ expression.index.kind !== 'literal' ||
3495
+ typeof expression.index.value !== 'number' ||
3496
+ !Number.isSafeInteger(expression.index.value) ||
3497
+ expression.index.value < 0) {
3498
+ emissionError(context, 'tuple projection requires one statically known nonnegative integer index');
3499
+ }
3500
+ return expression.index.value;
3501
+ }
3502
+ function getPreferredBindingNameRust(binding, constants) {
3503
+ if (constants.has(binding.id))
3504
+ return screamingSnakeCase(binding.name);
3505
+ return binding.space === 'type' ||
3506
+ binding.kind === 'class' ||
3507
+ binding.kind === 'enum' ||
3508
+ (binding.kind === 'import' && /^[A-Z]/u.test(binding.name))
3509
+ ? safeRustTypeName(binding.name)
3510
+ : safeRustValueName(binding.name);
3511
+ }
3512
+ function getTypeReferenceTargetNameRust(type, context) {
3513
+ if (type.reference.kind === 'ambient') {
3514
+ const targetName = getCompilerRuntimeExternalSymbolTargetRust(type.reference.name, 'type', context.options.hostBindings);
3515
+ if (!targetName)
3516
+ emissionError(context, `external type ${type.reference.name} has no Rust binding`);
3517
+ return isCompilerRuntimeExternalSymbolProvidedRust(type.reference.name, 'type', context.options.hostBindings)
3518
+ ? recordRuntimeTypeRust(targetName, context)
3519
+ : targetName;
3520
+ }
3521
+ return [
3522
+ getTypeBindingTargetNameRust(type.reference.binding, context),
3523
+ ...type.reference.path.map(safeRustTypeName),
3524
+ ].join('::');
3525
+ }
3526
+ function getTypeBindingTargetNameRust(binding, context) {
3527
+ const allocated = context.targetNames.get(binding.id);
3528
+ if (allocated)
3529
+ return allocated;
3530
+ for (const module of context.sourceModules) {
3531
+ const declaration = module.declarations.find((candidate) => 'binding' in candidate && candidate.binding.id === binding.id);
3532
+ if (declaration && 'binding' in declaration) {
3533
+ return getRustQualifiedTypeName(module, declaration.binding.name, context);
3534
+ }
3535
+ const imported = module.imports
3536
+ .flatMap((item) => item.bindings.map((candidate) => ({ candidate, specifier: item.specifier })))
3537
+ .find(({ candidate }) => candidate.binding.id === binding.id);
3538
+ if (!imported || imported.candidate.imported === '*' || imported.candidate.imported === 'default')
3539
+ continue;
3540
+ const target = resolveImportModuleRust(imported.specifier, imported.candidate.imported, context, module);
3541
+ if (target)
3542
+ return getRustQualifiedTypeName(target, imported.candidate.imported, context);
3543
+ }
3544
+ emissionError(context, `binding ${binding.name} has no Rust type target resolution`);
3545
+ }
3546
+ function getRustQualifiedTypeName(module, name, context) {
3547
+ const targetName = safeRustTypeName(name);
3548
+ if (module.packageName === context.module.packageName) {
3549
+ return `crate::${getRustModuleName(module)}::${targetName}`;
3550
+ }
3551
+ return `${convertPackageNameToRustCrateName(module.packageName).replaceAll('-', '_')}::${targetName}`;
3552
+ }
3553
+ function assertStructuralObjectCompatibilityRust(module, modules, resolution) {
3554
+ const diagnostics = analyzeIrModuleStructuralObjectCompatibilityAcrossModules(module, modules, resolution).diagnostics;
3555
+ const diagnostic = diagnostics.find((candidate) => candidate.disposition !== 'indeterminate') ??
3556
+ diagnostics.find((candidate) => candidate.code !== 'unresolved-named-construction-target');
3557
+ if (diagnostic) {
3558
+ throw createBackendEmissionFailure('rust', module, `structural object compatibility ${diagnostic.code} at ${JSON.stringify(diagnostic.path)}: ${diagnostic.message}`);
3559
+ }
3560
+ }
3561
+ function replaceIrModuleBackendContext(modules, replacement) {
3562
+ return modules.map((module) => module.packageName === replacement.packageName &&
3563
+ module.source === replacement.source &&
3564
+ module.name === replacement.name
3565
+ ? replacement
3566
+ : module);
3567
+ }
3568
+ function assertRuntimeExternalSymbolBindingsRust(module, options) {
3569
+ const completeness = analyzeCompilerRuntimeExternalSymbolCompleteness(collectIrModulesRuntimeExternalSymbolIdentities([module]), createCompilerRuntimeExternalSymbolBindingPlanRust(options.hostBindings));
3570
+ if (completeness.kind === 'complete')
3571
+ return;
3572
+ const problems = [
3573
+ completeness.missingExternalSymbols.length > 0
3574
+ ? `missing: ${completeness.missingExternalSymbols.map(formatRuntimeExternalSymbolIdentity).join(', ')}`
3575
+ : undefined,
3576
+ completeness.duplicateExternalSymbols.length > 0
3577
+ ? `duplicate: ${completeness.duplicateExternalSymbols.map(formatRuntimeExternalSymbolIdentity).join(', ')}`
3578
+ : undefined,
3579
+ ].filter((problem) => problem !== undefined);
3580
+ throw createBackendEmissionFailure('rust', module, `runtime external symbol binding plan is incomplete (${problems.join('; ')})`, 'rust-runtime-external-symbol-binding-incomplete', { classification: 'target-runtime' });
3581
+ }
3582
+ function assertRuntimeExternalConstructorAbiRust(module) {
3583
+ const completeness = analyzeCompilerRuntimeExternalConstructorAbiCompleteness(collectIrModulesRuntimeExternalConstructorInvocations([module]), createCompilerRuntimeExternalConstructorAbiPlanRust());
3584
+ if (completeness.kind === 'complete')
3585
+ return;
3586
+ const problems = [
3587
+ completeness.missingExternalConstructors.length > 0
3588
+ ? `missing: ${completeness.missingExternalConstructors.map(formatRuntimeExternalConstructorInvocation).join(', ')}`
3589
+ : undefined,
3590
+ completeness.duplicateExternalConstructors.length > 0
3591
+ ? `duplicate: ${completeness.duplicateExternalConstructors.map(formatRuntimeExternalSymbolIdentity).join(', ')}`
3592
+ : undefined,
3593
+ completeness.invalidExternalConstructors.length > 0
3594
+ ? `invalid: ${completeness.invalidExternalConstructors.map(formatRuntimeExternalSymbolIdentity).join(', ')}`
3595
+ : undefined,
3596
+ ].filter((problem) => problem !== undefined);
3597
+ throw createBackendEmissionFailure('rust', module, `runtime external constructor ABI plan is incomplete (${problems.join('; ')})`, 'rust-runtime-external-constructor-abi-incomplete', { classification: 'target-runtime' });
3598
+ }
3599
+ function formatRuntimeExternalConstructorInvocation(invocation) {
3600
+ return `${formatRuntimeExternalSymbolIdentity(invocation.externalSymbol)}(${invocation.providedArgumentCount === 'dynamic' ? '...' : String(invocation.providedArgumentCount)})`;
3601
+ }
3602
+ function formatRuntimeExternalSymbolIdentity(identity) {
3603
+ return `${identity.sourceName}[${identity.space}]`;
3604
+ }
3605
+ function isAmbientIdentifier(expression) {
3606
+ return expression.kind === 'identifier' && expression.reference.kind === 'ambient';
3607
+ }
3608
+ function emissionError(context, message) {
3609
+ throw createBackendEmissionFailure('rust', context.module, message);
3610
+ }
3611
+ function collectStringConcatenationOperands(expression) {
3612
+ if (expression.kind === 'binary' &&
3613
+ expression.operator === '+' &&
3614
+ expression.semantics.left.flow === 'string' &&
3615
+ expression.semantics.right.flow === 'string') {
3616
+ return [
3617
+ ...collectStringConcatenationOperands(expression.left),
3618
+ ...collectStringConcatenationOperands(expression.right),
3619
+ ];
3620
+ }
3621
+ return [expression];
3622
+ }
3623
+ function emitStringConcatenationRust(expression, context) {
3624
+ const operands = collectStringConcatenationOperands(expression);
3625
+ const format = operands
3626
+ .map((operand) => operand.kind === 'literal' && typeof operand.value === 'string'
3627
+ ? operand.value.replaceAll('{', '{{').replaceAll('}', '}}')
3628
+ : '{}')
3629
+ .join('');
3630
+ const values = operands.flatMap((operand) => operand.kind === 'literal' && typeof operand.value === 'string' ? [] : [emitExpression(operand, context)]);
3631
+ return `format!(${JSON.stringify(format)}${values.length > 0 ? `, ${values.join(', ')}` : ''})`;
3632
+ }
3633
+ function emitAssignmentOperatorRust(operator, semantics, context) {
3634
+ const emitted = rustAssignmentOperatorEmission[operator];
3635
+ if (!emitted)
3636
+ emissionError(context, `operator ${operator} requires Rust semantic lowering`);
3637
+ if (!isAssignmentOperatorDirectRust(operator, semantics)) {
3638
+ emissionError(context, `operator ${operator} on ${semantics.left.flow} and ${semantics.right.flow} requires Rust type-directed lowering`);
3639
+ }
3640
+ return emitted;
3641
+ }
3642
+ function emitBinaryOperatorRust(operator, semantics, context) {
3643
+ const emitted = rustBinaryOperatorEmission[operator];
3644
+ if (!emitted)
3645
+ emissionError(context, `operator ${operator} requires Rust semantic lowering`);
3646
+ if (!isBinaryOperatorDirectRust(operator, semantics)) {
3647
+ emissionError(context, `operator ${operator} on ${semantics.left.flow} and ${semantics.right.flow} requires Rust type-directed lowering`);
3648
+ }
3649
+ return emitted;
3650
+ }
3651
+ function getStaticTypeofNameRust(domain) {
3652
+ switch (domain) {
3653
+ case 'bigint':
3654
+ case 'boolean':
3655
+ case 'number':
3656
+ case 'string':
3657
+ case 'symbol':
3658
+ case 'undefined':
3659
+ return domain;
3660
+ case 'null':
3661
+ case 'object':
3662
+ case 'unknown':
3663
+ return undefined;
3664
+ }
3665
+ return undefined;
3666
+ }
3667
+ function emitNumericUpdateUnaryRust(expression, context) {
3668
+ const bindingType = expression.operand.kind === 'identifier' && expression.operand.reference.kind === 'binding'
3669
+ ? context.bindingTypes.get(expression.operand.reference.binding.id)
3670
+ : undefined;
3671
+ if (expression.semantics.operand.flow !== 'number' ||
3672
+ expression.semantics.result !== 'number' ||
3673
+ expression.operand.kind !== 'identifier' ||
3674
+ expression.operand.reference.kind !== 'binding' ||
3675
+ bindingType?.kind !== 'primitive' ||
3676
+ bindingType.name !== 'number') {
3677
+ emissionError(context, `operator ${expression.operator} requires a numeric Rust binding target`);
3678
+ }
3679
+ const name = emitIdentifierReferenceRust(expression.operand.reference, context);
3680
+ const arithmetic = expression.operator === '++' ? '+' : '-';
3681
+ if (context.cellWrappedBindingIds.has(expression.operand.reference.binding.id)) {
3682
+ const previous = getGeneratedTargetNameRust('update_previous', context);
3683
+ const updated = `${previous} ${arithmetic} 1.0`;
3684
+ return expression.postfix
3685
+ ? `{ let ${previous} = ${name}.get(); ${name}.set(${updated}); ${previous} }`
3686
+ : `{ let ${previous} = ${name}.get(); ${name}.set(${updated}); ${name}.get() }`;
3687
+ }
3688
+ if (context.refCellWrappedBindingIds.has(expression.operand.reference.binding.id)) {
3689
+ emissionError(context, `operator ${expression.operator} cannot update a non-Copy Rust binding`);
3690
+ }
3691
+ if (!expression.postfix)
3692
+ return `{ ${name} ${arithmetic}= 1.0; ${name} }`;
3693
+ const previous = getGeneratedTargetNameRust('update_previous', context);
3694
+ return `{ let ${previous} = ${name}; ${name} ${arithmetic}= 1.0; ${previous} }`;
3695
+ }
3696
+ function emitPrefixUnaryOperatorRust(operator, semantics, context) {
3697
+ const decision = rustPrefixUnaryOperatorDecision[operator];
3698
+ if ('refusal' in decision)
3699
+ emissionError(context, decision.refusal);
3700
+ if (!isPrefixUnaryOperatorDirectRust(operator, semantics)) {
3701
+ emissionError(context, `operator ${operator} on ${semantics.operand.flow} requires Rust type-directed lowering`);
3702
+ }
3703
+ return decision.emitted;
3704
+ }
3705
+ function isAssignmentOperatorDirectRust(operator, semantics) {
3706
+ if (operator === '=')
3707
+ return true;
3708
+ if (operator === '%=' || operator === '*=' || operator === '+=' || operator === '-=' || operator === '/=') {
3709
+ return hasMatchingOperatorDomains(semantics, ['number']);
3710
+ }
3711
+ return false;
3712
+ }
3713
+ // Which expressions the Rust emitter renders as an `Option`. An optional chain projects into one; an
3714
+ // ordinary value does not, and wrapping it would claim a nullability the emitted type does not have.
3715
+ function isIrExpressionOptionShapedRust(expression, context) {
3716
+ // An optional member is an `Option` field in the emitted record, so reading it is already the shape
3717
+ // the operator needs — the chain is about the object being absent, this is about the member.
3718
+ //
3719
+ // A chain the source wrote over a receiver its own types say cannot be absent produces a plain
3720
+ // value, not an `Option`. The `?.` is redundant there, and treating it as an `Option` asks a value
3721
+ // for a method it does not have.
3722
+ if (expression.kind === 'property') {
3723
+ if (expression.optionalChain?.receiverNullish === 'excluded')
3724
+ return false;
3725
+ return expression.optional || expression.absent === 'optionalMember';
3726
+ }
3727
+ if (expression.kind === 'call')
3728
+ return expression.optional;
3729
+ // An array index is absent-admitting in the source language whatever the index is, which is why
3730
+ // `values[index] ?? fallback` is ordinary code. Rust's `[]` panics instead, so the coalesce reads
3731
+ // through `get`, which is both the Option the operator needs and the faithful behaviour.
3732
+ if (expression.kind === 'element') {
3733
+ return expression.optional || (expression.semantics.receivers.includes('array') && !expression.optional);
3734
+ }
3735
+ if (expression.kind === 'identifier' &&
3736
+ expression.reference.kind === 'binding' &&
3737
+ (context.nullableBindingIds.has(expression.reference.binding.id) ||
3738
+ context.arrayElementBindingIds.has(expression.reference.binding.id)))
3739
+ return true;
3740
+ return expression.kind === 'undefinedDefault';
3741
+ }
3742
+ function emitOptionShapedOperandRust(expression, context) {
3743
+ if (expression.kind === 'element' && !expression.optional && expression.semantics.receivers.includes('array')) {
3744
+ return `${emitExpression(expression.object, context)}.get(${emitIndexOperandRust(expression.index, context)}).cloned()`;
3745
+ }
3746
+ return emitExpression(expression, context);
3747
+ }
3748
+ function isBinaryOperatorDirectRust(operator, semantics) {
3749
+ if (operator === '%' || operator === '*' || operator === '+' || operator === '-' || operator === '/') {
3750
+ return hasMatchingOperatorDomains(semantics, ['number']);
3751
+ }
3752
+ if (operator === '<' || operator === '<=' || operator === '>' || operator === '>=') {
3753
+ return semantics.left.flow === 'number' && semantics.right.flow === 'number' && semantics.result === 'boolean';
3754
+ }
3755
+ if (operator === '&&' || operator === '||') {
3756
+ return hasMatchingOperatorDomains(semantics, ['boolean']);
3757
+ }
3758
+ if (operator === '===' || operator === '!==') {
3759
+ return (semantics.left.flow === semantics.right.flow &&
3760
+ semantics.result === 'boolean' &&
3761
+ (semantics.left.flow === 'boolean' || semantics.left.flow === 'number' || semantics.left.flow === 'string'));
3762
+ }
3763
+ if (operator === '&' || operator === '|' || operator === '^' || operator === '<<' || operator === '>>') {
3764
+ return hasMatchingOperatorDomains(semantics, ['number']);
3765
+ }
3766
+ return false;
3767
+ }
3768
+ function isPrefixUnaryOperatorDirectRust(operator, semantics) {
3769
+ if (operator === '!')
3770
+ return semantics.operand.flow === 'boolean' && semantics.result === 'boolean';
3771
+ if (operator === '+' || operator === '-')
3772
+ return semantics.operand.flow === 'number' && semantics.result === 'number';
3773
+ if (operator === '~')
3774
+ return semantics.operand.flow === 'number' && semantics.result === 'number';
3775
+ return false;
3776
+ }
3777
+ function hasMatchingOperatorDomains(semantics, supported) {
3778
+ return (semantics.left.flow === semantics.right.flow &&
3779
+ semantics.left.flow === semantics.result &&
3780
+ supported.includes(semantics.left.flow));
3781
+ }
3782
+ function isNullableType(type) {
3783
+ return (type.kind === 'null' ||
3784
+ type.kind === 'undefined' ||
3785
+ (type.kind === 'union' && type.types.some((member) => member.kind === 'null' || member.kind === 'undefined')));
3786
+ }
3787
+ function hasIrTypeNullMemberRust(type) {
3788
+ return type.kind === 'null' || (type.kind === 'union' && type.types.some((member) => member.kind === 'null'));
3789
+ }
3790
+ function hasIrTypeUndefinedMemberRust(type) {
3791
+ return (type.kind === 'undefined' || (type.kind === 'union' && type.types.some((member) => member.kind === 'undefined')));
3792
+ }
3793
+ function isIrTypeCloneSafeRust(type) {
3794
+ switch (type.kind) {
3795
+ case 'array':
3796
+ return isIrTypeCloneSafeRust(type.element);
3797
+ case 'literal':
3798
+ case 'never':
3799
+ case 'null':
3800
+ case 'primitive':
3801
+ case 'undefined':
3802
+ return true;
3803
+ case 'tuple':
3804
+ return type.elements.every((element) => isIrTypeCloneSafeRust(element.type));
3805
+ case 'union':
3806
+ return type.types.every(isIrTypeCloneSafeRust);
3807
+ case 'function':
3808
+ case 'conditionalFacet':
3809
+ case 'indexedAccess':
3810
+ case 'intersection':
3811
+ case 'keyof':
3812
+ case 'named':
3813
+ case 'object':
3814
+ case 'typeOf':
3815
+ case 'unknown':
3816
+ return false;
3817
+ }
3818
+ }
3819
+ // `Rc<dyn Fn>` is cloneable but the callable trait object does not implement `Debug`. Deriving
3820
+ // `Debug` for a record that contains one directly, through a container, or through a resolved source
3821
+ // type therefore makes otherwise valid generated Rust fail to compile. Retain the useful derive for
3822
+ // every record where no callable is proven, and omit only the unsupported bound.
3823
+ function emitRustRecordDerive(types, context) {
3824
+ return types.some((type) => containsIrFunctionTypeRust(type, context))
3825
+ ? '#[derive(Clone)]'
3826
+ : '#[derive(Clone, Debug)]';
3827
+ }
3828
+ function containsIrFunctionTypeRust(type, context, module = context.module, resolving = new Set()) {
3829
+ switch (type.kind) {
3830
+ case 'function':
3831
+ return true;
3832
+ case 'array':
3833
+ return containsIrFunctionTypeRust(type.element, context, module, resolving);
3834
+ case 'tuple':
3835
+ return type.elements.some((element) => containsIrFunctionTypeRust(element.type, context, module, resolving));
3836
+ case 'intersection':
3837
+ case 'union':
3838
+ return type.types.some((member) => containsIrFunctionTypeRust(member, context, module, resolving));
3839
+ case 'object':
3840
+ return type.properties.some((property) => containsIrFunctionTypeRust(property.type, context, module, resolving));
3841
+ case 'named': {
3842
+ if (type.typeArguments.some((argument) => containsIrFunctionTypeRust(argument, context, module, resolving))) {
3843
+ return true;
3844
+ }
3845
+ if (type.reference.kind !== 'binding' ||
3846
+ type.reference.path.length > 0 ||
3847
+ type.reference.binding.space !== 'type' ||
3848
+ type.reference.binding.kind === 'typeParameter') {
3849
+ return false;
3850
+ }
3851
+ const binding = type.reference.binding;
3852
+ const location = getIrNamedTypeDeclarationLocationRust(binding, context, module);
3853
+ if (location) {
3854
+ const key = `${location.module.packageName}\0${location.module.source}\0${location.declaration.binding.id}`;
3855
+ if (resolving.has(key))
3856
+ return false;
3857
+ const active = new Set(resolving).add(key);
3858
+ if (location.declaration.kind === 'typeAlias') {
3859
+ try {
3860
+ const plan = createIrTypeParameterSubstitutionPlan(location.declaration.typeParameters, type.typeArguments);
3861
+ return containsIrFunctionTypeRust(resolveIrTypeStructuralSubstitution(location.declaration.type, plan), context, location.module, active);
3862
+ }
3863
+ catch (error) {
3864
+ if (isCompilerStructuralTypeSubstitutionFailure(error))
3865
+ return false;
3866
+ throw error;
3867
+ }
3868
+ }
3869
+ const properties = getIrObjectTypePropertiesRust(type, context, module, resolving);
3870
+ return (properties?.some((property) => containsIrFunctionTypeRust(property.type, context, location.module, active)) ??
3871
+ false);
3872
+ }
3873
+ const classDeclaration = [module, ...context.sourceModules]
3874
+ .flatMap((candidate) => candidate.declarations)
3875
+ .find((candidate) => candidate.kind === 'class' && candidate.binding.id === binding.id);
3876
+ if (classDeclaration?.kind !== 'class')
3877
+ return false;
3878
+ const key = `${module.packageName}\0${module.source}\0${classDeclaration.binding.id}`;
3879
+ if (resolving.has(key))
3880
+ return false;
3881
+ const active = new Set(resolving).add(key);
3882
+ return (classDeclaration.fields.some((field) => containsIrFunctionTypeRust(field.type, context, module, active)) ||
3883
+ (classDeclaration.extends
3884
+ ? containsIrFunctionTypeRust(classDeclaration.extends, context, module, active)
3885
+ : false));
3886
+ }
3887
+ case 'conditionalFacet':
3888
+ case 'indexedAccess':
3889
+ case 'keyof':
3890
+ case 'literal':
3891
+ case 'never':
3892
+ case 'null':
3893
+ case 'primitive':
3894
+ case 'typeOf':
3895
+ case 'undefined':
3896
+ case 'unknown':
3897
+ return false;
3898
+ }
3899
+ }
3900
+ function opaqueHostType(context) {
3901
+ return context.options.opaqueHostType ?? recordRuntimeTypeRust('OpaqueHostValue', context);
3902
+ }
3903
+ function rustImportModule(specifier, context) {
3904
+ if (specifier.startsWith('.')) {
3905
+ const resolvedModule = resolveImportModuleRust(specifier, undefined, context);
3906
+ if (resolvedModule)
3907
+ return `crate::${getRustModuleName(resolvedModule)}`;
3908
+ const target = path.posix.normalize(path.posix.join(path.posix.dirname(context.module.source), specifier.replace(/\.[cm]?js$/u, '.ts')));
3909
+ const resolved = /\.tsx?$/u.test(target) ? target : `${target}.ts`;
3910
+ return `crate::${convertSourcePathToRustModuleName(resolved) ?? `_internal_${snakeCase(path.posix.basename(target))}`}`;
3911
+ }
3912
+ if (specifier.startsWith('@')) {
3913
+ const packageName = /^(@[^/]+\/[^/]+)/u.exec(specifier)?.[1];
3914
+ if (!packageName)
3915
+ emissionError(context, `cannot identify package import ${specifier}`);
3916
+ return convertPackageNameToRustCrateName(packageName).replaceAll('-', '_');
3917
+ }
3918
+ emissionError(context, `external import ${specifier} requires a runtime or standard-library mapping`);
3919
+ }
3920
+ function resolveImportModuleRust(specifier, importedName, context, importer = context.module) {
3921
+ const matching = context.moduleResolution?.edges.filter((edge) => edge.specifier === specifier) ?? [];
3922
+ const exact = matching.filter((edge) => edge.importer && isRustCompilerModuleIdentityEqual(edge.importer, importer));
3923
+ const scoped = exact.length > 0 ? exact : matching.filter((edge) => !edge.importer);
3924
+ const targets = scoped.filter((edge) => edge.importedNames === undefined || (importedName !== undefined && edge.importedNames.includes(importedName)));
3925
+ const resolved = targets.flatMap((edge) => context.sourceModules.filter((module) => module.packageName === edge.target.packageName &&
3926
+ path.posix.normalize(module.source) === path.posix.normalize(edge.target.source)));
3927
+ const unique = [
3928
+ ...new Map(resolved.map((module) => [`${module.packageName}\0${module.source}\0${module.name}`, module])).values(),
3929
+ ];
3930
+ if (unique.length === 1)
3931
+ return unique[0];
3932
+ return specifier.startsWith('.') ? resolveRelativeImportModuleRust(specifier, context, importer) : undefined;
3933
+ }
3934
+ function resolveRelativeImportModuleRust(specifier, context, importer) {
3935
+ const source = path.posix.normalize(path.posix.join(path.posix.dirname(importer.source), specifier.replace(/\.[cm]?js$/u, '.ts')));
3936
+ const candidates = new Set([source, `${source}.ts`, `${source}/index.ts`]);
3937
+ return context.sourceModules.find((module) => module.packageName === importer.packageName && candidates.has(path.posix.normalize(module.source)));
3938
+ }
3939
+ function isRustCompilerModuleIdentityEqual(left, right) {
3940
+ return (left.packageName === right.packageName &&
3941
+ path.posix.normalize(left.source) === path.posix.normalize(right.source) &&
3942
+ left.name === right.name);
3943
+ }
3944
+ function getRustModuleName(module) {
3945
+ return convertSourcePathToRustModuleName(module.source) ?? `_internal_${snakeCase(module.name)}`;
3946
+ }
3947
+ function getRustModuleFilePath(module, sourceModules) {
3948
+ const fileName = `${getRustModuleName(module)}.rs`;
3949
+ const packageNames = new Set(sourceModules.map((candidate) => candidate.packageName));
3950
+ return packageNames.size > 1 ? `${convertPackageNameToRustCrateName(module.packageName)}/src/${fileName}` : fileName;
3951
+ }
3952
+ function safeRustTypeName(name) {
3953
+ const stripped = name.startsWith('#') ? name.slice(1) : name;
3954
+ const value = stripped
3955
+ .split('.')
3956
+ .map((segment) => pascalCase(segment))
3957
+ .join('::');
3958
+ return isRustCompilerKeyword(value) ? `${value}_` : value;
3959
+ }
3960
+ // A union alias becomes a Rust enum only when every alternative is a named record available through
3961
+ // this module's own declarations or imports. Anonymous shapes still have no stable variant identity.
3962
+ function getIrUnionTypeMemberRecordsRust(type, context) {
3963
+ const members = [];
3964
+ for (const member of type.types) {
3965
+ if (member.kind !== 'named' ||
3966
+ member.reference.kind !== 'binding' ||
3967
+ member.reference.binding.space !== 'type' ||
3968
+ member.reference.path.length > 0 ||
3969
+ member.typeArguments.length > 0) {
3970
+ return undefined;
3971
+ }
3972
+ const name = member.reference.binding.name;
3973
+ const declaration = getIrNamedTypeDeclarationLocationRust(member.reference.binding, context, context.module)?.declaration;
3974
+ const properties = declaration?.kind === 'interface' && declaration.typeParameters.length === 0
3975
+ ? declaration.properties
3976
+ : declaration?.kind === 'typeAlias' &&
3977
+ declaration.typeParameters.length === 0 &&
3978
+ declaration.type.kind === 'object'
3979
+ ? declaration.type.properties
3980
+ : undefined;
3981
+ if (!properties)
3982
+ return undefined;
3983
+ members.push({ name, properties, targetName: getTypeBindingTargetNameRust(member.reference.binding, context) });
3984
+ }
3985
+ return members.length > 1 ? members : undefined;
3986
+ }
3987
+ function getIrNamedTypeDeclarationLocationRust(binding, context, module) {
3988
+ const declarationModule = [module, ...context.sourceModules].find((candidateModule) => candidateModule.declarations.some((candidate) => (candidate.kind === 'interface' || candidate.kind === 'typeAlias') && candidate.binding.id === binding.id));
3989
+ const local = declarationModule?.declarations.find((candidate) => (candidate.kind === 'interface' || candidate.kind === 'typeAlias') && candidate.binding.id === binding.id);
3990
+ if (local && declarationModule)
3991
+ return { declaration: local, module: declarationModule };
3992
+ // A flattened imported declaration can retain a type reference introduced by its own module.
3993
+ // Follow the binding back to that importer rather than assuming every inherited property was
3994
+ // rebound into the subject module.
3995
+ const importer = [module, ...context.sourceModules].find((candidateModule) => candidateModule.imports.some((item) => item.bindings.some((candidate) => candidate.binding.id === binding.id)));
3996
+ const imported = importer?.imports
3997
+ .flatMap((item) => item.bindings.map((candidate) => ({ candidate, specifier: item.specifier })))
3998
+ .find(({ candidate }) => candidate.binding.id === binding.id);
3999
+ if (!imported || imported.candidate.imported === '*' || imported.candidate.imported === 'default')
4000
+ return undefined;
4001
+ const targetModule = resolveImportModuleRust(imported.specifier, imported.candidate.imported, context, importer);
4002
+ const declaration = targetModule?.declarations.find((candidate) => (candidate.kind === 'interface' || candidate.kind === 'typeAlias') &&
4003
+ candidate.binding.name === imported.candidate.imported);
4004
+ return declaration && targetModule ? { declaration, module: targetModule } : undefined;
4005
+ }
4006
+ function getIrCallBorrowedPositionsRust(expression, context) {
4007
+ return expression.callee.kind === 'identifier' && expression.callee.reference.kind === 'binding'
4008
+ ? (context.borrowedParameterPositions.get(expression.callee.reference.binding.id) ?? new Set())
4009
+ : new Set();
4010
+ }
4011
+ function getIrClassConcreteBaseRust(declaration, context) {
4012
+ const reference = declaration.extends;
4013
+ if (!reference || reference.kind !== 'named' || reference.reference.kind !== 'binding')
4014
+ return undefined;
4015
+ const binding = reference.reference.binding;
4016
+ const target = context.module.declarations.find((candidate) => candidate.kind === 'class' && candidate.binding.id === binding.id);
4017
+ return target?.kind === 'class' && !target.abstract ? target : undefined;
4018
+ }
4019
+ function getIrClassStatelessAbstractBaseRust(declaration, context) {
4020
+ const reference = declaration.extends;
4021
+ if (!reference || reference.kind !== 'named' || reference.reference.kind !== 'binding')
4022
+ return undefined;
4023
+ const binding = reference.reference.binding;
4024
+ const target = context.module.declarations.find((candidate) => candidate.kind === 'class' && candidate.binding.id === binding.id);
4025
+ return target?.kind === 'class' &&
4026
+ target.abstract &&
4027
+ target.fields.every((field) => field.abstract) &&
4028
+ !target.extends
4029
+ ? target
4030
+ : undefined;
4031
+ }
4032
+ function emitAbstractClassTraitRust(declaration, context) {
4033
+ if (declaration.fields.some((field) => !field.abstract)) {
4034
+ emissionError(context, `abstract class ${declaration.binding.name} carries state a Rust trait cannot hold`);
4035
+ }
4036
+ if (declaration.classConstructor && declaration.classConstructor.body.length > 0) {
4037
+ emissionError(context, `abstract class ${declaration.binding.name} constructor has no Rust trait equivalent`);
4038
+ }
4039
+ const abstractFields = declaration.fields.filter((field) => field.abstract);
4040
+ const fieldNames = new Set(abstractFields.map((field) => field.name));
4041
+ const mutating = getIrClassMutatingMethodNamesRust(declaration);
4042
+ const visibility = declaration.exported || context.apiReferencedBindingIds.has(declaration.binding.id) ? 'pub ' : '';
4043
+ const lines = [
4044
+ `${visibility}trait ${getBindingTargetNameRust(declaration.binding, context)}${emitTypeParameters(declaration.typeParameters, context)} {`,
4045
+ ];
4046
+ abstractFields.forEach((field, index) => {
4047
+ if (index > 0)
4048
+ lines.push('');
4049
+ lines.push(` fn ${safeRustValueName(field.name)}(&self) -> ${emitType(field.type, context)};`);
4050
+ });
4051
+ const previousAbstractFieldNames = context.abstractFieldNames;
4052
+ context.abstractFieldNames = fieldNames;
4053
+ declaration.methods.forEach((method, index) => {
4054
+ if (index > 0 || abstractFields.length > 0)
4055
+ lines.push('');
4056
+ const target = getIrClassMethodTargetNameRust(method);
4057
+ const parameters = [
4058
+ ...(method.static ? [] : [method.accessor === 'set' || mutating.has(target) ? '&mut self' : '&self']),
4059
+ ...method.parameters.map((parameter) => emitParameter(parameter, context)),
4060
+ ].join(', ');
4061
+ const returns = method.accessor === 'set' ? '()' : emitType(method.returns, context);
4062
+ const signature = ` fn ${target}${emitTypeParameters(method.typeParameters, context)}(${parameters}) -> ${returns}`;
4063
+ if (method.abstract) {
4064
+ lines.push(`${signature};`);
4065
+ return;
4066
+ }
4067
+ lines.push(`${signature} {`, ...indentSourceLines(emitStatements(method.body, context), 2), ' }');
4068
+ });
4069
+ context.abstractFieldNames = previousAbstractFieldNames;
4070
+ lines.push('}');
4071
+ return lines;
4072
+ }
4073
+ function getIrExpressionClassDeclarationRust(object, context) {
4074
+ if (object.kind !== 'identifier' || object.reference.kind !== 'binding')
4075
+ return undefined;
4076
+ const binding = object.reference.binding;
4077
+ const declaration = context.module.declarations.find((candidate) => candidate.kind === 'class' && candidate.binding.id === binding.id);
4078
+ return declaration?.kind === 'class' ? declaration : undefined;
4079
+ }
4080
+ function getIrExpressionEnumDeclarationRust(object, context) {
4081
+ if (object.kind !== 'identifier' || object.reference.kind !== 'binding')
4082
+ return undefined;
4083
+ const binding = object.reference.binding;
4084
+ const declaration = context.module.declarations.find((candidate) => candidate.kind === 'enum' && candidate.binding.id === binding.id);
4085
+ return declaration?.kind === 'enum' ? declaration : undefined;
4086
+ }
4087
+ function getIrTypeNumericEnumNamespaceNameRust(type, context) {
4088
+ return type.kind === 'named' && type.reference.kind === 'binding'
4089
+ ? context.numericEnumNamespaceNames.get(type.reference.binding.id)
4090
+ : undefined;
4091
+ }
4092
+ function getIrExpressionNumericEnumNamespaceNameRust(expression, context) {
4093
+ if (expression.kind === 'identifier' && expression.reference.kind === 'binding') {
4094
+ const type = context.bindingTypes.get(expression.reference.binding.id);
4095
+ return type ? getIrTypeNumericEnumNamespaceNameRust(type, context) : undefined;
4096
+ }
4097
+ if (expression.kind !== 'property')
4098
+ return undefined;
4099
+ if (expression.namespaceMember?.kind === 'binding') {
4100
+ return context.numericEnumNamespaceNames.get(expression.namespaceMember.binding.id);
4101
+ }
4102
+ const declaration = getIrExpressionEnumDeclarationRust(expression.object, context);
4103
+ return declaration ? context.numericEnumNamespaceNames.get(declaration.binding.id) : undefined;
4104
+ }
4105
+ function emitNumericEnumOperandRust(expression, context) {
4106
+ const emitted = emitExpression(expression, context);
4107
+ return getIrExpressionNumericEnumNamespaceNameRust(expression, context) ? `((${emitted}).0 as f64)` : emitted;
4108
+ }
4109
+ function getIrExpressionClassAccessorRust(object, name, accessor, context) {
4110
+ if (object.kind !== 'identifier' || object.reference.kind !== 'binding')
4111
+ return false;
4112
+ const className = context.accessorClassNames.get(object.reference.binding.id);
4113
+ if (!className)
4114
+ return false;
4115
+ const declaration = context.module.declarations.find((candidate) => candidate.kind === 'class' && candidate.binding.name === className);
4116
+ return (declaration?.kind === 'class' &&
4117
+ declaration.methods.some((method) => method.accessor === accessor && method.name === name));
4118
+ }
4119
+ function getIrExpressionTaggedUnionRust(expression, context) {
4120
+ if (expression.kind !== 'identifier' || expression.reference.kind !== 'binding')
4121
+ return undefined;
4122
+ return context.taggedUnionBindingNames.get(expression.reference.binding.id);
4123
+ }
4124
+ function collectPrimitiveUnionBindingsRust(module, context) {
4125
+ for (const declaration of module.declarations) {
4126
+ if (declaration.kind !== 'function')
4127
+ continue;
4128
+ for (const parameter of declaration.parameters) {
4129
+ if (parameter.type.kind !== 'union')
4130
+ continue;
4131
+ const concrete = parameter.type.types.filter((t) => t.kind !== 'null' && t.kind !== 'undefined');
4132
+ if (concrete.length < 2)
4133
+ continue;
4134
+ const enumRecord = getOrCreatePrimitiveUnionEnumRust(concrete, context);
4135
+ if (enumRecord) {
4136
+ context.primitiveUnionBindingIds.set(parameter.binding.id, enumRecord.name);
4137
+ }
4138
+ }
4139
+ if (declaration.returns.kind === 'union') {
4140
+ const concrete = declaration.returns.types.filter((t) => t.kind !== 'null' && t.kind !== 'undefined');
4141
+ if (concrete.length >= 2)
4142
+ getOrCreatePrimitiveUnionEnumRust(concrete, context);
4143
+ }
4144
+ }
4145
+ analyzeIrModuleTraversal(module, {
4146
+ variable(variable) {
4147
+ if (!('binding' in variable) || !variable.type || variable.type.kind !== 'union')
4148
+ return;
4149
+ const concrete = variable.type.types.filter((t) => t.kind !== 'null' && t.kind !== 'undefined');
4150
+ if (concrete.length < 2)
4151
+ return;
4152
+ const enumRecord = getOrCreatePrimitiveUnionEnumRust(concrete, context);
4153
+ if (enumRecord) {
4154
+ context.primitiveUnionBindingIds.set(variable.binding.id, enumRecord.name);
4155
+ }
4156
+ },
4157
+ });
4158
+ }
4159
+ function emitPrimitiveUnionEnumRust(union) {
4160
+ const lines = [
4161
+ '#[derive(Clone, Debug)]',
4162
+ // Primitive unions are structural products of a public signature rather than source-named
4163
+ // declarations. Keeping the generated enum private makes every exported function that carries
4164
+ // one unusable outside its module, so the representation itself is part of the public ABI.
4165
+ `pub enum ${union.name} {`,
4166
+ ...union.variants.map((v) => ` ${v.variantName}(${v.rustType}),`),
4167
+ '}',
4168
+ '',
4169
+ `impl ${union.name} {`,
4170
+ ...union.variants.flatMap((v) => [
4171
+ ` fn as_${snakeCase(v.variantName)}(&self) -> &${v.rustType} {`,
4172
+ ' match self {',
4173
+ ` ${union.name}::${v.variantName}(value) => value,`,
4174
+ ...(union.variants.length > 1 ? [` _ => panic!("${union.name} is not ${v.variantName}"),`] : []),
4175
+ ' }',
4176
+ ' }',
4177
+ ]),
4178
+ '}',
4179
+ '',
4180
+ `impl std::fmt::Display for ${union.name} {`,
4181
+ " fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {",
4182
+ ' match self {',
4183
+ ...union.variants.map((v) => ` ${union.name}::${v.variantName}(value) => write!(f, "{}", value),`),
4184
+ ' }',
4185
+ ' }',
4186
+ '}',
4187
+ ];
4188
+ return lines;
4189
+ }
4190
+ function isIrCastTargetNumericRust(type) {
4191
+ if (type.kind === 'primitive')
4192
+ return type.name === 'number' || type.name === 'boolean';
4193
+ return false;
4194
+ }
4195
+ function isIrTypeCopyRust(type) {
4196
+ if (type.kind === 'primitive')
4197
+ return type.name === 'number' || type.name === 'boolean';
4198
+ if (type.kind === 'union') {
4199
+ const nonNull = type.types.filter((member) => member.kind !== 'null' && member.kind !== 'undefined');
4200
+ const sole = nonNull[0];
4201
+ return nonNull.length === 1 && sole !== undefined && isIrTypeCopyRust(sole);
4202
+ }
4203
+ return false;
4204
+ }
4205
+ function emitPrimitiveUnionCastRust(expression, context) {
4206
+ if (expression.type.kind !== 'primitive')
4207
+ return undefined;
4208
+ const targetName = expression.type.name;
4209
+ const primitiveUnion = getIrExpressionPrimitiveUnionRust(expression.expression, context);
4210
+ if (!primitiveUnion)
4211
+ return undefined;
4212
+ const variant = primitiveUnion.variants.find((v) => v.primitiveKind === targetName);
4213
+ if (!variant)
4214
+ return undefined;
4215
+ const emitted = emitExpression(expression.expression, context);
4216
+ if (variant.primitiveKind === 'string')
4217
+ return `${emitted}.as_${snakeCase(variant.variantName)}().clone()`;
4218
+ return `*${emitted}.as_${snakeCase(variant.variantName)}()`;
4219
+ }
4220
+ function emitPrimitiveUnionNarrowedReceiverRust(expression, context) {
4221
+ if (expression.kind !== 'identifier' || !expression.narrowedMember)
4222
+ return undefined;
4223
+ const primitiveUnion = getIrExpressionPrimitiveUnionRust(expression, context);
4224
+ if (!primitiveUnion)
4225
+ return undefined;
4226
+ const variant = primitiveUnion.variants.find((v) => v.primitiveKind === expression.narrowedMember);
4227
+ if (!variant)
4228
+ return undefined;
4229
+ return `${emitIdentifierReferenceRust(expression.reference, context)}.as_${snakeCase(variant.variantName)}()`;
4230
+ }
4231
+ function getIrExpressionPrimitiveUnionRust(expression, context) {
4232
+ if (expression.kind !== 'identifier' || expression.reference.kind !== 'binding')
4233
+ return undefined;
4234
+ const enumName = context.primitiveUnionBindingIds.get(expression.reference.binding.id);
4235
+ if (!enumName)
4236
+ return undefined;
4237
+ for (const union of context.primitiveUnionEnums.values()) {
4238
+ if (union.name === enumName)
4239
+ return union;
4240
+ }
4241
+ return undefined;
4242
+ }
4243
+ function getOrCreatePrimitiveUnionEnumRust(types, context) {
4244
+ if (!types.every((t) => t.kind === 'primitive'))
4245
+ return undefined;
4246
+ const primitives = types.filter((t) => t.kind === 'primitive');
4247
+ const rustPrimitiveInfo = {
4248
+ boolean: { rustType: 'bool', variantName: 'Bool' },
4249
+ number: { rustType: 'f64', variantName: 'F64' },
4250
+ string: { rustType: 'String', variantName: 'Str' },
4251
+ };
4252
+ const variants = primitives.flatMap((p) => {
4253
+ const info = rustPrimitiveInfo[p.name];
4254
+ return info ? [{ primitiveKind: p.name, ...info }] : [];
4255
+ });
4256
+ if (variants.length !== primitives.length)
4257
+ return undefined;
4258
+ const key = variants
4259
+ .map((v) => v.primitiveKind)
4260
+ .sort()
4261
+ .join('|');
4262
+ const existing = context.primitiveUnionEnums.get(key);
4263
+ if (existing)
4264
+ return existing;
4265
+ const name = variants.map((v) => v.variantName).join('Or');
4266
+ const record = { name, variants };
4267
+ context.primitiveUnionEnums.set(key, record);
4268
+ return record;
4269
+ }
4270
+ function getTypeofTypeTestRust(expression, context) {
4271
+ if (expression.operator !== '===' &&
4272
+ expression.operator !== '==' &&
4273
+ expression.operator !== '!==' &&
4274
+ expression.operator !== '!=') {
4275
+ return undefined;
4276
+ }
4277
+ const typeofSide = expression.left.kind === 'unary' && !expression.left.postfix && expression.left.operator === 'typeof'
4278
+ ? expression.left
4279
+ : expression.right.kind === 'unary' && !expression.right.postfix && expression.right.operator === 'typeof'
4280
+ ? expression.right
4281
+ : undefined;
4282
+ const literalSide = typeofSide === expression.left ? expression.right : expression.left;
4283
+ if (!typeofSide || literalSide.kind !== 'literal' || typeof literalSide.value !== 'string')
4284
+ return undefined;
4285
+ const primitiveUnion = getIrExpressionPrimitiveUnionRust(typeofSide.operand, context);
4286
+ if (!primitiveUnion)
4287
+ return undefined;
4288
+ const variant = primitiveUnion.variants.find((v) => v.primitiveKind === literalSide.value);
4289
+ if (!variant)
4290
+ return undefined;
4291
+ return {
4292
+ enumName: primitiveUnion.name,
4293
+ negated: expression.operator === '!==' || expression.operator === '!=',
4294
+ operand: typeofSide.operand,
4295
+ variantName: variant.variantName,
4296
+ };
4297
+ }
4298
+ // A Rust enum plus the accessors that make the alternatives reachable: one per alternative for a
4299
+ // reference control flow narrowed, and one per field every alternative shares for a reference it did
4300
+ // not. An accessor rather than a `match` at each site keeps the emitted shape of the source's own
4301
+ // control flow, which is what makes the two targets comparable.
4302
+ function emitTaggedUnionRust(targetName, type, exported, context) {
4303
+ const members = getIrUnionTypeMemberRecordsRust(type, context);
4304
+ if (!members)
4305
+ emissionError(context, 'non-nullable unions require Rust tagged-union lowering');
4306
+ const visibility = exported ? 'pub ' : '';
4307
+ const lines = [emitRustRecordDerive(type.types, context), `${visibility}enum ${targetName} {`];
4308
+ for (const member of members) {
4309
+ lines.push(` ${pascalCase(member.name)}(${member.targetName}),`);
4310
+ }
4311
+ lines.push('}', '', `impl ${targetName} {`);
4312
+ for (const member of members) {
4313
+ lines.push(` ${visibility}fn as_${safeRustValueName(member.name)}(&self) -> &${member.targetName} {`, ' match self {', ` ${targetName}::${pascalCase(member.name)}(value) => value,`, ...(members.length > 1 ? [` _ => panic!("${targetName} is not ${pascalCase(member.name)}"),`] : []), ' }', ' }');
4314
+ }
4315
+ const shared = members[0].properties.filter((property) => members.every((member) => member.properties.some((candidate) => candidate.name === property.name)));
4316
+ for (const property of shared) {
4317
+ lines.push(` ${visibility}fn ${safeRustValueName(property.name)}(&self) -> ${emitType(property.type, context)} {`, ' match self {', ...members.map((member) => ` ${targetName}::${pascalCase(member.name)}(value) => value.${safeRustValueName(property.name)}.clone(),`), ' }', ' }');
4318
+ }
4319
+ lines.push('}');
4320
+ return lines;
4321
+ }
4322
+ function getOrCreateAnonymousUnionEnumRust(types, context) {
4323
+ const key = JSON.stringify({
4324
+ parameters: context.activeTypeParameters.map((parameter) => parameter.binding.id),
4325
+ types,
4326
+ });
4327
+ const existing = context.anonymousUnionEnums.get(key);
4328
+ if (existing)
4329
+ return existing;
4330
+ const record = {
4331
+ name: getGeneratedTargetNameRust('AnonymousUnion', context),
4332
+ typeParameters: context.activeTypeParameters,
4333
+ variants: [],
4334
+ };
4335
+ // Register the identity before rendering payload types so a recursive named alias can lead back
4336
+ // to this generated enum without allocating a second definition.
4337
+ context.anonymousUnionEnums.set(key, record);
4338
+ record.variants.push(...createGeneralUnionVariantsRust(types, context));
4339
+ return record;
4340
+ }
4341
+ function createGeneralUnionVariantsRust(types, context) {
4342
+ const names = new Map();
4343
+ return types.flatMap((type) => {
4344
+ if (type.kind === 'never')
4345
+ return [];
4346
+ const preferred = getGeneralUnionVariantNameRust(type, context);
4347
+ const occurrence = (names.get(preferred) ?? 0) + 1;
4348
+ names.set(preferred, occurrence);
4349
+ const name = occurrence === 1 ? preferred : `${preferred}${String(occurrence)}`;
4350
+ if (type.kind === 'literal' || type.kind === 'null' || type.kind === 'undefined') {
4351
+ return [{ kind: 'unit', name }];
4352
+ }
4353
+ const properties = type.kind === 'object' || type.kind === 'intersection' ? getIrObjectTypePropertiesRust(type, context) : undefined;
4354
+ if (properties) {
4355
+ return [
4356
+ {
4357
+ fields: properties.map((property) => ({
4358
+ name: safeRustValueName(property.name),
4359
+ optional: property.optional,
4360
+ rustType: emitType(property.type, context),
4361
+ })),
4362
+ kind: 'struct',
4363
+ name,
4364
+ },
4365
+ ];
4366
+ }
4367
+ return [{ kind: 'tuple', name, rustType: emitType(type, context) }];
4368
+ });
4369
+ }
4370
+ function getGeneralUnionVariantNameRust(type, context) {
4371
+ if (type.kind === 'literal') {
4372
+ if (typeof type.value === 'boolean')
4373
+ return type.value ? 'True' : 'False';
4374
+ if (typeof type.value === 'number') {
4375
+ return safeRustTypeName(`Number ${String(type.value).replace('-', 'Negative ')}`) || 'Number';
4376
+ }
4377
+ return safeRustTypeName(type.value) || 'String';
4378
+ }
4379
+ if (type.kind === 'named') {
4380
+ return safeRustTypeName(type.reference.kind === 'ambient'
4381
+ ? type.reference.name
4382
+ : (type.reference.path.at(-1) ?? type.reference.binding.name));
4383
+ }
4384
+ if (type.kind === 'object' || type.kind === 'intersection') {
4385
+ const properties = getIrObjectTypePropertiesRust(type, context);
4386
+ const discriminant = properties?.find((property) => property.type.kind === 'literal' && typeof property.type.value === 'string');
4387
+ if (discriminant?.type.kind === 'literal' && typeof discriminant.type.value === 'string') {
4388
+ return safeRustTypeName(discriminant.type.value) || 'Object';
4389
+ }
4390
+ }
4391
+ return {
4392
+ array: 'Array',
4393
+ conditionalFacet: 'ConditionalFacet',
4394
+ function: 'Function',
4395
+ indexedAccess: 'IndexedAccess',
4396
+ intersection: 'Intersection',
4397
+ keyof: 'Key',
4398
+ never: 'Never',
4399
+ null: 'Null',
4400
+ object: 'Object',
4401
+ primitive: type.kind === 'primitive'
4402
+ ? { bigint: 'I64', boolean: 'Bool', number: 'F64', string: 'String', symbol: 'Symbol', void: 'Void' }[type.name]
4403
+ : 'Value',
4404
+ tuple: 'Tuple',
4405
+ typeOf: 'TypeOf',
4406
+ undefined: 'Undefined',
4407
+ union: 'Union',
4408
+ unknown: 'Unknown',
4409
+ }[type.kind];
4410
+ }
4411
+ function emitGeneralUnionRust(targetName, variants, typeParameters, exported, context) {
4412
+ const visibility = exported ? 'pub ' : '';
4413
+ const lines = ['#[derive(Clone)]', `${visibility}enum ${targetName}${emitTypeParameters(typeParameters, context)} {`];
4414
+ for (const variant of variants) {
4415
+ if (variant.kind === 'unit') {
4416
+ lines.push(` ${variant.name},`);
4417
+ }
4418
+ else if (variant.kind === 'tuple') {
4419
+ lines.push(` ${variant.name}(${variant.rustType}),`);
4420
+ }
4421
+ else {
4422
+ lines.push(` ${variant.name} {`, ...variant.fields.map((field) => ` ${field.name}: ${field.optional ? `Option<${field.rustType}>` : field.rustType},`), ' },');
4423
+ }
4424
+ }
4425
+ lines.push('}');
4426
+ return lines;
4427
+ }
4428
+ // Rust spells a constant in upper snake case, and the name is otherwise the source's own.
4429
+ // A getter keeps the source's name, because a call reads the same way; a setter takes a `set_` name,
4430
+ // because the two accessors share one name in the source and Rust has one namespace for both.
4431
+ function getIrClassMethodTargetNameRust(method) {
4432
+ return method.accessor === 'set' ? `set_${safeRustValueName(method.name)}` : safeRustValueName(method.name);
4433
+ }
4434
+ // A runtime type is named bare where it is used and imported once at the top, which is how Rust
4435
+ // spells a dependency. Recording the name at the point of use is what makes the import exact.
4436
+ // Rust braces a use list only when there is more than one name in it, which is what `rustfmt` leaves
4437
+ // behind and therefore what canonical output looks like.
4438
+ function emitUseTreeRust(names) {
4439
+ return names.length === 1 ? names[0] : `{${names.join(', ')}}`;
4440
+ }
4441
+ function recordRuntimeTypeRust(name, context) {
4442
+ context.runtimeTypeNames.add(name);
4443
+ return name;
4444
+ }
4445
+ function constantRustName(name) {
4446
+ return safeRustValueName(name).toUpperCase();
4447
+ }
4448
+ function safeRustValueName(name) {
4449
+ if (name === 'this')
4450
+ return 'self';
4451
+ const stripped = name.startsWith('#') ? name.slice(1) : name;
4452
+ const value = snakeCase(stripped);
4453
+ return isRustCompilerKeyword(value) ? `${value}_` : value;
4454
+ }
4455
+ function pascalCase(value) {
4456
+ return value
4457
+ .split(/[-_]/u)
4458
+ .filter(Boolean)
4459
+ .map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`)
4460
+ .join('');
4461
+ }
4462
+ function screamingSnakeCase(value) {
4463
+ return snakeCase(value).toUpperCase();
4464
+ }
4465
+ function snakeCase(value) {
4466
+ return value
4467
+ .replace(/([a-z0-9])([A-Z])/gu, '$1_$2')
4468
+ .replace(/([A-Z]+)([A-Z][a-z])/gu, '$1_$2')
4469
+ .replace(/[-\s]+/gu, '_')
4470
+ .toLowerCase();
4471
+ }
4472
+ const rustTypedArrayConstructorNames = new Set([
4473
+ 'Float32Array',
4474
+ 'Float64Array',
4475
+ 'Int8Array',
4476
+ 'Int16Array',
4477
+ 'Int32Array',
4478
+ 'Uint8Array',
4479
+ 'Uint8ClampedArray',
4480
+ 'Uint16Array',
4481
+ 'Uint32Array',
4482
+ ]);
4483
+ const rustTypedArrayReceiverNames = new Set([
4484
+ 'float32Array',
4485
+ 'float64Array',
4486
+ 'int8Array',
4487
+ 'int16Array',
4488
+ 'int32Array',
4489
+ 'uint8Array',
4490
+ 'uint8ClampedArray',
4491
+ 'uint16Array',
4492
+ 'uint32Array',
4493
+ ]);
4494
+ const rustAssignmentOperatorEmission = {
4495
+ '%=': '%=',
4496
+ '&&=': undefined,
4497
+ '&=': '&=',
4498
+ '**=': undefined,
4499
+ '*=': '*=',
4500
+ '+=': '+=',
4501
+ '-=': '-=',
4502
+ '/=': '/=',
4503
+ '<<=': '<<=',
4504
+ '=': '=',
4505
+ '>>=': '>>=',
4506
+ '>>>=': undefined,
4507
+ '??=': undefined,
4508
+ '^=': '^=',
4509
+ '|=': '|=',
4510
+ '||=': undefined,
4511
+ };
4512
+ const rustBinaryOperatorEmission = {
4513
+ '%': '%',
4514
+ '&': '&',
4515
+ '&&': '&&',
4516
+ '*': '*',
4517
+ '**': undefined,
4518
+ '+': '+',
4519
+ ',': undefined,
4520
+ '-': '-',
4521
+ '/': '/',
4522
+ '<': '<',
4523
+ '<<': '<<',
4524
+ '<=': '<=',
4525
+ '!=': '!=',
4526
+ '!==': '!=',
4527
+ '==': '==',
4528
+ '===': '==',
4529
+ '>': '>',
4530
+ '>=': '>=',
4531
+ '>>': '>>',
4532
+ '>>>': undefined,
4533
+ '??': undefined,
4534
+ '^': '^',
4535
+ in: undefined,
4536
+ instanceof: undefined,
4537
+ '|': '|',
4538
+ '||': '||',
4539
+ };
4540
+ const rustPrefixUnaryOperatorDecision = {
4541
+ '!': { emitted: '!' },
4542
+ '+': { emitted: '+' },
4543
+ '++': { refusal: 'prefix ++ requires value-preserving Rust lowering' },
4544
+ '-': { emitted: '-' },
4545
+ '--': { refusal: 'prefix -- requires value-preserving Rust lowering' },
4546
+ delete: { refusal: 'delete requires Rust semantic lowering' },
4547
+ typeof: { refusal: 'typeof requires Rust semantic lowering' },
4548
+ void: { refusal: 'void requires Rust semantic lowering' },
4549
+ '~': { emitted: '!' },
4550
+ };
4551
+ const rustMathSpreadFoldTargets = {
4552
+ max: { folder: 'f64::max', identity: 'f64::NEG_INFINITY' },
4553
+ min: { folder: 'f64::min', identity: 'f64::INFINITY' },
4554
+ };
4555
+ //# sourceMappingURL=rustCompilerBackend.js.map