@shd101wyy/yo 0.1.29 → 0.1.31

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 (186) hide show
  1. package/.github/skills/yo-async-effects/SKILL.md +3 -3
  2. package/.github/skills/yo-async-effects/async-effects-recipes.md +19 -11
  3. package/.github/skills/yo-core-patterns/core-patterns-cheatsheet.md +33 -13
  4. package/.github/skills/yo-project-workflow/workflow-cheatsheet.md +1 -1
  5. package/.github/skills/yo-syntax/syntax-cheatsheet.md +59 -21
  6. package/README.md +4 -3
  7. package/out/cjs/index.cjs +964 -710
  8. package/out/cjs/yo-cli.cjs +1119 -855
  9. package/out/cjs/yo-lsp.cjs +1003 -749
  10. package/out/esm/index.mjs +964 -710
  11. package/out/types/src/codegen/exprs/async.d.ts +2 -0
  12. package/out/types/src/codegen/exprs/await.d.ts +1 -0
  13. package/out/types/src/codegen/exprs/closures.d.ts +4 -0
  14. package/out/types/src/codegen/functions/context.d.ts +6 -0
  15. package/out/types/src/codegen/index.d.ts +1 -1
  16. package/out/types/src/compiler-utils.d.ts +1 -1
  17. package/out/types/src/env.d.ts +2 -0
  18. package/out/types/src/evaluator/builtins/pragma.d.ts +9 -0
  19. package/out/types/src/evaluator/builtins/unsafe.d.ts +8 -0
  20. package/out/types/src/evaluator/context.d.ts +2 -0
  21. package/out/types/src/evaluator/index.d.ts +1 -1
  22. package/out/types/src/evaluator/memory-safety.d.ts +14 -0
  23. package/out/types/src/evaluator/types/flowability.d.ts +6 -0
  24. package/out/types/src/evaluator/utils/closure.d.ts +2 -1
  25. package/out/types/src/evaluator/utils.d.ts +3 -0
  26. package/out/types/src/evaluator/values/impl.d.ts +14 -0
  27. package/out/types/src/expr-traversal.d.ts +1 -0
  28. package/out/types/src/expr.d.ts +4 -1
  29. package/out/types/src/public-safe-report.d.ts +19 -0
  30. package/out/types/src/tests/comptime-ref-gate.test.d.ts +1 -0
  31. package/out/types/src/tests/pragma-validation.test.d.ts +1 -0
  32. package/out/types/src/tests/public-safe-report.test.d.ts +1 -0
  33. package/out/types/src/tests/thread-safety-codegen.test.d.ts +1 -0
  34. package/out/types/src/tests/type-representation-pointer.test.d.ts +1 -0
  35. package/out/types/src/tests/unsafe-gate.test.d.ts +1 -0
  36. package/out/types/src/tests/unsafe-report-classify.test.d.ts +1 -0
  37. package/out/types/src/types/definitions.d.ts +2 -0
  38. package/out/types/src/types/utils.d.ts +4 -0
  39. package/out/types/src/unsafe-report.d.ts +29 -0
  40. package/out/types/src/value.d.ts +1 -0
  41. package/out/types/tsconfig.tsbuildinfo +1 -1
  42. package/package.json +1 -1
  43. package/scripts/add-pragma-for-pointer-decls.ts +134 -0
  44. package/scripts/add-pragma.ts +58 -0
  45. package/scripts/migrate-amp-method-calls.ts +186 -0
  46. package/scripts/migrate-clone-calls.ts +93 -0
  47. package/scripts/migrate-get-unwrap.ts +166 -0
  48. package/scripts/migrate-index-patterns.ts +210 -0
  49. package/scripts/migrate-index-trait.ts +142 -0
  50. package/scripts/migrate-iterator.ts +150 -0
  51. package/scripts/migrate-self-ptr.ts +220 -0
  52. package/scripts/migrate-skip-pragmas.ts +109 -0
  53. package/scripts/migrate-tostring.ts +134 -0
  54. package/scripts/trim-pragma.ts +130 -0
  55. package/scripts/wrap-extern-calls.ts +161 -0
  56. package/std/alg/hash.yo +3 -2
  57. package/std/allocator.yo +6 -5
  58. package/std/async.yo +2 -2
  59. package/std/build.yo +5 -2
  60. package/std/collections/array_list.yo +59 -40
  61. package/std/collections/btree_map.yo +19 -18
  62. package/std/collections/deque.yo +9 -8
  63. package/std/collections/hash_map.yo +101 -13
  64. package/std/collections/hash_set.yo +5 -4
  65. package/std/collections/linked_list.yo +39 -4
  66. package/std/collections/ordered_map.yo +3 -3
  67. package/std/collections/priority_queue.yo +14 -13
  68. package/std/crypto/md5.yo +2 -1
  69. package/std/crypto/random.yo +16 -15
  70. package/std/crypto/sha256.yo +2 -1
  71. package/std/encoding/base64.yo +14 -14
  72. package/std/encoding/hex.yo +3 -3
  73. package/std/encoding/json.yo +59 -10
  74. package/std/encoding/punycode.yo +24 -23
  75. package/std/encoding/toml.yo +4 -3
  76. package/std/encoding/utf16.yo +2 -2
  77. package/std/env.yo +43 -28
  78. package/std/error.yo +6 -6
  79. package/std/fmt/display.yo +2 -2
  80. package/std/fmt/index.yo +6 -5
  81. package/std/fmt/to_string.yo +39 -38
  82. package/std/fmt/writer.yo +9 -8
  83. package/std/fs/dir.yo +34 -33
  84. package/std/fs/file.yo +52 -51
  85. package/std/fs/metadata.yo +10 -9
  86. package/std/fs/temp.yo +24 -13
  87. package/std/fs/walker.yo +10 -9
  88. package/std/gc.yo +1 -0
  89. package/std/glob.yo +7 -7
  90. package/std/http/client.yo +15 -14
  91. package/std/http/http.yo +6 -6
  92. package/std/http/index.yo +1 -1
  93. package/std/imm/list.yo +34 -1
  94. package/std/imm/map.yo +2 -1
  95. package/std/imm/set.yo +1 -0
  96. package/std/imm/sorted_map.yo +2 -1
  97. package/std/imm/sorted_set.yo +1 -0
  98. package/std/imm/string.yo +27 -23
  99. package/std/imm/vec.yo +18 -2
  100. package/std/io/reader.yo +2 -1
  101. package/std/io/writer.yo +3 -2
  102. package/std/libc/assert.yo +1 -0
  103. package/std/libc/ctype.yo +1 -0
  104. package/std/libc/dirent.yo +1 -0
  105. package/std/libc/errno.yo +1 -0
  106. package/std/libc/fcntl.yo +1 -0
  107. package/std/libc/float.yo +1 -0
  108. package/std/libc/limits.yo +1 -0
  109. package/std/libc/math.yo +1 -0
  110. package/std/libc/signal.yo +1 -0
  111. package/std/libc/stdatomic.yo +251 -1
  112. package/std/libc/stdint.yo +1 -0
  113. package/std/libc/stdio.yo +1 -0
  114. package/std/libc/stdlib.yo +1 -0
  115. package/std/libc/string.yo +1 -0
  116. package/std/libc/sys/stat.yo +1 -0
  117. package/std/libc/time.yo +1 -0
  118. package/std/libc/unistd.yo +1 -0
  119. package/std/libc/wctype.yo +1 -0
  120. package/std/libc/windows.yo +2 -0
  121. package/std/log.yo +7 -6
  122. package/std/net/addr.yo +5 -4
  123. package/std/net/dns.yo +7 -6
  124. package/std/net/errors.yo +8 -8
  125. package/std/net/tcp.yo +19 -18
  126. package/std/net/udp.yo +13 -12
  127. package/std/os/signal.yo +3 -3
  128. package/std/path.yo +1 -0
  129. package/std/prelude.yo +398 -184
  130. package/std/process/command.yo +40 -23
  131. package/std/process/index.yo +2 -1
  132. package/std/regex/compiler.yo +10 -9
  133. package/std/regex/index.yo +41 -41
  134. package/std/regex/match.yo +2 -2
  135. package/std/regex/parser.yo +21 -21
  136. package/std/regex/vm.yo +42 -41
  137. package/std/string/rune.yo +4 -0
  138. package/std/string/string.yo +95 -40
  139. package/std/string/string_builder.yo +9 -9
  140. package/std/string/unicode.yo +50 -49
  141. package/std/sync/atomic.yo +557 -0
  142. package/std/sync/channel.yo +59 -43
  143. package/std/sync/cond.yo +12 -7
  144. package/std/sync/mutex.yo +79 -18
  145. package/std/sync/once.yo +25 -19
  146. package/std/sync/rwlock.yo +18 -15
  147. package/std/sync/waitgroup.yo +25 -16
  148. package/std/sys/advise.yo +1 -0
  149. package/std/sys/bufio/buf_reader.yo +17 -16
  150. package/std/sys/bufio/buf_writer.yo +10 -9
  151. package/std/sys/clock.yo +1 -0
  152. package/std/sys/copy.yo +1 -0
  153. package/std/sys/dir.yo +10 -9
  154. package/std/sys/dns.yo +6 -5
  155. package/std/sys/errors.yo +11 -11
  156. package/std/sys/events.yo +1 -0
  157. package/std/sys/externs.yo +38 -37
  158. package/std/sys/file.yo +17 -16
  159. package/std/sys/future.yo +4 -3
  160. package/std/sys/iov.yo +1 -0
  161. package/std/sys/mmap.yo +1 -0
  162. package/std/sys/path.yo +1 -0
  163. package/std/sys/perm.yo +2 -1
  164. package/std/sys/pipe.yo +1 -0
  165. package/std/sys/process.yo +5 -4
  166. package/std/sys/signal.yo +1 -0
  167. package/std/sys/socketpair.yo +1 -0
  168. package/std/sys/sockinfo.yo +1 -0
  169. package/std/sys/statfs.yo +2 -1
  170. package/std/sys/statx.yo +1 -0
  171. package/std/sys/sysinfo.yo +1 -0
  172. package/std/sys/tcp.yo +15 -14
  173. package/std/sys/temp.yo +1 -0
  174. package/std/sys/time.yo +2 -1
  175. package/std/sys/timer.yo +6 -6
  176. package/std/sys/tty.yo +2 -1
  177. package/std/sys/udp.yo +13 -12
  178. package/std/sys/unix.yo +12 -11
  179. package/std/testing/bench.yo +4 -3
  180. package/std/thread.yo +7 -6
  181. package/std/time/datetime.yo +18 -15
  182. package/std/time/duration.yo +11 -10
  183. package/std/time/instant.yo +4 -4
  184. package/std/time/sleep.yo +1 -0
  185. package/std/url/index.yo +3 -3
  186. package/std/worker.yo +4 -3
package/std/prelude.yo CHANGED
@@ -1,14 +1,16 @@
1
- // @skip_prelude
2
1
  //! Prelude — automatically imported into every Yo source file.
3
2
  //!
4
3
  //! Provides core language primitives: traits (`Comptime`, `Runtime`, `Clone`,
5
4
  //! `Eq`, `Ord`, `Hash`, …), fundamental types (`Option`, `Result`, `Box`,
6
5
  //! `Slice`, `Range`, `String`, …), operator traits (`Add`, `Sub`, …), type
7
6
  //! reflection (`TypeInfo`), conversion (`Into`, `From`), the async runtime
8
- //! (`IO`, `Future`, `JoinHandle`), and derive rules.
7
+ //! (`Io`, `Future`, `JoinHandle`), and derive rules.
9
8
  //!
10
9
  //! **Do NOT import `std/prelude`** — it is loaded automatically and an
11
10
  //! explicit import will produce a compile error.
11
+ // === Foundational traits ===
12
+ // `Comptime` and `Runtime` are defined first because every other
13
+ // type (including `Pragma` below) is type-checked against them.
12
14
  /// Comptime trait — indicates a type that can be used at compile-time.
13
15
  /// Examples: `i32`, `bool`, `Type`, `comptime_int`, `comptime_float`, `comptime_string`.
14
16
  /// Non-examples: `int`, `ushort` (runtime-only types).
@@ -23,6 +25,49 @@ Runtime :: trait(
23
25
  id := "Runtime"
24
26
  );
25
27
  export(Runtime);
28
+
29
+ // === Pragma — file-level privilege flags ===
30
+ //
31
+ // `Pragma` is defined here (right after the foundational traits and
32
+ // BEFORE any extern/asm/pointer-op site) so the prelude can declare
33
+ // its own `pragma(Pragma.AllowUnsafe);` via ordinary evaluation. The
34
+ // prelude is the foundation of Yo's unsafe-capable machinery
35
+ // (raw-pointer impls, FFI declarations, the async runtime, …); the
36
+ // pragma must be registered before the first extern/asm/pointer-op
37
+ // declaration fires the Phase C gates.
38
+ //
39
+ // `SkipPrelude` is recognized via a separate AST-level pre-scan that
40
+ // runs before the prelude loads (chicken-and-egg: a file with
41
+ // `pragma(Pragma.SkipPrelude);` doesn't have the prelude in scope).
42
+ // All other pragma variants are validated by ordinary evaluation
43
+ // against this enum. See plans/MEMORY_SAFETY.md.
44
+ /// File-level privilege flag for the `pragma(...)` builtin. Declared
45
+ /// at the top of a Yo file (e.g. `pragma(Pragma.AllowUnsafe);`) to
46
+ /// opt the file into compiler-recognized behaviors. See
47
+ /// plans/MEMORY_SAFETY.md.
48
+ Pragma :: enum(
49
+ /// File is permitted to use raw pointer ops, `unsafe(...)`,
50
+ /// `asm(...)`, and `extern(...)`. Without this, those constructs
51
+ /// produce compile errors.
52
+ AllowUnsafe,
53
+ /// Disable the auto-import of `std/prelude`. Used by the prelude
54
+ /// itself, and by any tool/test that wants to bootstrap manually.
55
+ /// Recognized at the AST level before the prelude loads.
56
+ SkipPrelude,
57
+ /// Test-runner directive: skip this test file on ALL WASM targets.
58
+ SkipWasm,
59
+ /// Test-runner directive: skip when target is wasm32-emscripten.
60
+ SkipWasm32Emscripten,
61
+ /// Test-runner directive: skip when target is wasm32-wasi.
62
+ SkipWasm32Wasi
63
+ );
64
+ export(Pragma);
65
+
66
+ // Prelude opts itself out of the implicit self-prelude import and
67
+ // into unsafe-capable mode. Both calls evaluate normally against the
68
+ // `Pragma` enum defined just above.
69
+ pragma(Pragma.SkipPrelude);
70
+ pragma(Pragma.AllowUnsafe);
26
71
  // === Builtin Yo functions ===
27
72
  extern(
28
73
  "Yo",
@@ -180,15 +225,30 @@ export(Dispose);
180
225
  Index :: (fn(comptime(Idx) : Type) -> comptime(Trait))(
181
226
  trait(
182
227
  Output : Type,
183
- index : (fn(self : *(Self), idx : Idx) -> *(Self.Output))
228
+ index : (fn(ref(self) : Self, idx : Idx) -> *(Self.Output))
184
229
  )
185
230
  );
186
231
  export(Index);
232
+ /// Indexable trait — projection-style indexing yielding a borrow.
233
+ /// Companion to `Index`, but instead of returning a raw `*(T)` the
234
+ /// `project` method returns a `ref(Element)` — a second-class
235
+ /// reference that flows through Yo's flowability rule (R1–R4) and
236
+ /// can be received by a `ref(name) := coll.project(pos);` local
237
+ /// binding. The for-loop macro lowers iteration through this trait
238
+ /// so user code never sees a raw pointer. See
239
+ /// plans/ITERATOR_REDESIGN.md.
240
+ Indexable :: (fn(comptime(Idx) : Type) -> comptime(Trait))(
241
+ trait(
242
+ Element : Type,
243
+ project : (fn(ref(self) : Self, pos : Idx) -> ref(Self.Element))
244
+ )
245
+ );
246
+ export(Indexable);
187
247
  /// ComptimeIndex — compile-time indexing trait for constant expressions.
188
248
  ComptimeIndex :: (fn(comptime(Idx) : Type, where(Idx <: Comptime)) -> comptime(Trait))(
189
249
  trait(
190
250
  Output : Type,
191
- index : (fn(comptime(self) : *(Self), comptime(idx) : Idx) -> comptime(*(Self.Output))),
251
+ index : (fn(comptime(ref(self)) : Self, comptime(idx) : Idx) -> comptime(*(Self.Output))),
192
252
  where(Self <: Comptime, Self.Output <: Comptime)
193
253
  )
194
254
  );
@@ -652,14 +712,14 @@ Hash :: trait(
652
712
  * Compute the hash of a value
653
713
  * Returns a u64 hash value
654
714
  */
655
- (hash) : (fn(self : *(Self)) -> u64)
715
+ (hash) : (fn(ref(self) : Self) -> u64)
656
716
  );
657
717
  export(Hash);
658
718
  /// Clone trait — deep-copy a value.
659
719
  Clone :: trait(
660
720
  /// Create an independent clone of `self`.
661
721
  clone :
662
- fn(self : *(Self)) -> Self
722
+ fn(ref(self) : Self) -> Self
663
723
  );
664
724
  export(Clone);
665
725
  /// Isolation trait — runtime check whether a value can be safely transferred.
@@ -672,6 +732,13 @@ ComptimeToString :: trait(
672
732
  to_comptime_string : (fn(comptime(self) : Self) -> comptime(comptime_string)),
673
733
  where(Self <: Comptime)
674
734
  );
735
+ // SAFETY: All builtin primitive types (unit, void, comptime_int,
736
+ // comptime_float, comptime_string, bool, i8/i16/i32/i64, u8/u16/u32/u64,
737
+ // f32/f64, isize/usize, char/int/uint/short/ushort/long/ulong/longlong/
738
+ // ulonglong/longdouble) are plain value types with no heap allocations
739
+ // or thread-local state. They are trivially safe to send across threads
740
+ // and cannot form reference cycles. For these types, Send and Acyclic are
741
+ // structural properties of the underlying C types.
675
742
  // === Builtin types ===
676
743
  /// unit
677
744
  impl(unit, Acyclic());
@@ -985,7 +1052,7 @@ impl(
985
1052
  Clone(
986
1053
  clone : (
987
1054
  (self) ->
988
- __yo_return_self(self.*)
1055
+ __yo_return_self(self)
989
1056
  )
990
1057
  )
991
1058
  );
@@ -995,7 +1062,7 @@ impl(
995
1062
  (hash) : (
996
1063
  (self) ->
997
1064
  cond(
998
- self.* => u64(1),
1065
+ self => u64(1),
999
1066
  true => u64(0)
1000
1067
  )
1001
1068
  )
@@ -1141,13 +1208,13 @@ impl(
1141
1208
  impl(
1142
1209
  i8,
1143
1210
  Hash(
1144
- (hash) : ((self) -> u64(self.*))
1211
+ (hash) : ((self) -> u64(self))
1145
1212
  )
1146
1213
  );
1147
1214
  impl(
1148
1215
  i8,
1149
1216
  Clone(
1150
- clone : ((self) -> __yo_return_self(self.*))
1217
+ clone : ((self) -> __yo_return_self(self))
1151
1218
  )
1152
1219
  );
1153
1220
  impl(
@@ -1431,13 +1498,13 @@ impl(
1431
1498
  impl(
1432
1499
  i16,
1433
1500
  Hash(
1434
- (hash) : ((self) -> u64(self.*))
1501
+ (hash) : ((self) -> u64(self))
1435
1502
  )
1436
1503
  );
1437
1504
  impl(
1438
1505
  i16,
1439
1506
  Clone(
1440
- clone : ((self) -> __yo_return_self(self.*))
1507
+ clone : ((self) -> __yo_return_self(self))
1441
1508
  )
1442
1509
  );
1443
1510
  impl(
@@ -1783,7 +1850,7 @@ impl(
1783
1850
  Hash(
1784
1851
  (hash) : (
1785
1852
  (self) -> {
1786
- u32_value := u32(self.*);
1853
+ u32_value := u32(self);
1787
1854
  u64(u32_value)
1788
1855
  }
1789
1856
  )
@@ -1794,7 +1861,7 @@ impl(
1794
1861
  Clone(
1795
1862
  clone : (
1796
1863
  (self) ->
1797
- __yo_return_self(self.*)
1864
+ __yo_return_self(self)
1798
1865
  )
1799
1866
  )
1800
1867
  );
@@ -2019,13 +2086,13 @@ impl(
2019
2086
  impl(
2020
2087
  i64,
2021
2088
  Hash(
2022
- (hash) : ((self) -> u64(self.*))
2089
+ (hash) : ((self) -> u64(self))
2023
2090
  )
2024
2091
  );
2025
2092
  impl(
2026
2093
  i64,
2027
2094
  Clone(
2028
- clone : ((self) -> __yo_return_self(self.*))
2095
+ clone : ((self) -> __yo_return_self(self))
2029
2096
  )
2030
2097
  );
2031
2098
  impl(
@@ -2309,13 +2376,13 @@ impl(
2309
2376
  impl(
2310
2377
  u8,
2311
2378
  Hash(
2312
- (hash) : ((self) -> u64(self.*))
2379
+ (hash) : ((self) -> u64(self))
2313
2380
  )
2314
2381
  );
2315
2382
  impl(
2316
2383
  u8,
2317
2384
  Clone(
2318
- clone : ((self) -> __yo_return_self(self.*))
2385
+ clone : ((self) -> __yo_return_self(self))
2319
2386
  )
2320
2387
  );
2321
2388
  impl(
@@ -2589,13 +2656,13 @@ impl(
2589
2656
  impl(
2590
2657
  u16,
2591
2658
  Hash(
2592
- (hash) : ((self) -> u64(self.*))
2659
+ (hash) : ((self) -> u64(self))
2593
2660
  )
2594
2661
  );
2595
2662
  impl(
2596
2663
  u16,
2597
2664
  Clone(
2598
- clone : ((self) -> __yo_return_self(self.*))
2665
+ clone : ((self) -> __yo_return_self(self))
2599
2666
  )
2600
2667
  );
2601
2668
  impl(
@@ -2869,13 +2936,13 @@ impl(
2869
2936
  impl(
2870
2937
  u32,
2871
2938
  Hash(
2872
- (hash) : ((self) -> u64(self.*))
2939
+ (hash) : ((self) -> u64(self))
2873
2940
  )
2874
2941
  );
2875
2942
  impl(
2876
2943
  u32,
2877
2944
  Clone(
2878
- clone : ((self) -> __yo_return_self(self.*))
2945
+ clone : ((self) -> __yo_return_self(self))
2879
2946
  )
2880
2947
  );
2881
2948
  impl(
@@ -3149,13 +3216,13 @@ impl(
3149
3216
  impl(
3150
3217
  u64,
3151
3218
  Hash(
3152
- (hash) : ((self) -> self.*)
3219
+ (hash) : ((self) -> self)
3153
3220
  )
3154
3221
  );
3155
3222
  impl(
3156
3223
  u64,
3157
3224
  Clone(
3158
- clone : ((self) -> __yo_return_self(self.*))
3225
+ clone : ((self) -> __yo_return_self(self))
3159
3226
  )
3160
3227
  );
3161
3228
  impl(
@@ -3409,13 +3476,13 @@ impl(
3409
3476
  impl(
3410
3477
  f32,
3411
3478
  Hash(
3412
- (hash) : ((self) -> u64(i32(self.*)))
3479
+ (hash) : ((self) -> u64(i32(self)))
3413
3480
  )
3414
3481
  );
3415
3482
  impl(
3416
3483
  f32,
3417
3484
  Clone(
3418
- clone : ((self) -> __yo_return_self(self.*))
3485
+ clone : ((self) -> __yo_return_self(self))
3419
3486
  )
3420
3487
  );
3421
3488
  impl(
@@ -3610,13 +3677,13 @@ impl(
3610
3677
  impl(
3611
3678
  f64,
3612
3679
  Hash(
3613
- (hash) : ((self) -> u64(i64(self.*)))
3680
+ (hash) : ((self) -> u64(i64(self)))
3614
3681
  )
3615
3682
  );
3616
3683
  impl(
3617
3684
  f64,
3618
3685
  Clone(
3619
- clone : ((self) -> __yo_return_self(self.*))
3686
+ clone : ((self) -> __yo_return_self(self))
3620
3687
  )
3621
3688
  );
3622
3689
  impl(
@@ -3836,13 +3903,13 @@ impl(
3836
3903
  impl(
3837
3904
  isize,
3838
3905
  Hash(
3839
- (hash) : ((self) -> u64(self.*))
3906
+ (hash) : ((self) -> u64(self))
3840
3907
  )
3841
3908
  );
3842
3909
  impl(
3843
3910
  isize,
3844
3911
  Clone(
3845
- clone : ((self) -> __yo_return_self(self.*))
3912
+ clone : ((self) -> __yo_return_self(self))
3846
3913
  )
3847
3914
  );
3848
3915
  impl(
@@ -4129,13 +4196,13 @@ impl(
4129
4196
  impl(
4130
4197
  usize,
4131
4198
  Hash(
4132
- (hash) : ((self) -> u64(self.*))
4199
+ (hash) : ((self) -> u64(self))
4133
4200
  )
4134
4201
  );
4135
4202
  impl(
4136
4203
  usize,
4137
4204
  Clone(
4138
- clone : ((self) -> __yo_return_self(self.*))
4205
+ clone : ((self) -> __yo_return_self(self))
4139
4206
  )
4140
4207
  );
4141
4208
  impl(
@@ -4413,13 +4480,13 @@ impl(
4413
4480
  impl(
4414
4481
  char,
4415
4482
  Hash(
4416
- (hash) : ((self) -> u64(self.*))
4483
+ (hash) : ((self) -> u64(self))
4417
4484
  )
4418
4485
  );
4419
4486
  impl(
4420
4487
  char,
4421
4488
  Clone(
4422
- clone : ((self) -> __yo_return_self(self.*))
4489
+ clone : ((self) -> __yo_return_self(self))
4423
4490
  )
4424
4491
  );
4425
4492
  _char :: char;
@@ -4523,13 +4590,13 @@ impl(
4523
4590
  impl(
4524
4591
  int,
4525
4592
  Hash(
4526
- (hash) : ((self) -> u64(self.*))
4593
+ (hash) : ((self) -> u64(self))
4527
4594
  )
4528
4595
  );
4529
4596
  impl(
4530
4597
  int,
4531
4598
  Clone(
4532
- clone : ((self) -> __yo_return_self(self.*))
4599
+ clone : ((self) -> __yo_return_self(self))
4533
4600
  )
4534
4601
  );
4535
4602
  _int :: int;
@@ -4633,13 +4700,13 @@ impl(
4633
4700
  impl(
4634
4701
  uint,
4635
4702
  Hash(
4636
- (hash) : ((self) -> u64(self.*))
4703
+ (hash) : ((self) -> u64(self))
4637
4704
  )
4638
4705
  );
4639
4706
  impl(
4640
4707
  uint,
4641
4708
  Clone(
4642
- clone : ((self) -> __yo_return_self(self.*))
4709
+ clone : ((self) -> __yo_return_self(self))
4643
4710
  )
4644
4711
  );
4645
4712
  _uint :: uint;
@@ -4743,13 +4810,13 @@ impl(
4743
4810
  impl(
4744
4811
  short,
4745
4812
  Hash(
4746
- (hash) : ((self) -> u64(self.*))
4813
+ (hash) : ((self) -> u64(self))
4747
4814
  )
4748
4815
  );
4749
4816
  impl(
4750
4817
  short,
4751
4818
  Clone(
4752
- clone : ((self) -> __yo_return_self(self.*))
4819
+ clone : ((self) -> __yo_return_self(self))
4753
4820
  )
4754
4821
  );
4755
4822
  _short :: short;
@@ -4853,13 +4920,13 @@ impl(
4853
4920
  impl(
4854
4921
  ushort,
4855
4922
  Hash(
4856
- (hash) : ((self) -> u64(self.*))
4923
+ (hash) : ((self) -> u64(self))
4857
4924
  )
4858
4925
  );
4859
4926
  impl(
4860
4927
  ushort,
4861
4928
  Clone(
4862
- clone : ((self) -> __yo_return_self(self.*))
4929
+ clone : ((self) -> __yo_return_self(self))
4863
4930
  )
4864
4931
  );
4865
4932
  _ushort :: ushort;
@@ -4963,13 +5030,13 @@ impl(
4963
5030
  impl(
4964
5031
  long,
4965
5032
  Hash(
4966
- (hash) : ((self) -> u64(self.*))
5033
+ (hash) : ((self) -> u64(self))
4967
5034
  )
4968
5035
  );
4969
5036
  impl(
4970
5037
  long,
4971
5038
  Clone(
4972
- clone : ((self) -> __yo_return_self(self.*))
5039
+ clone : ((self) -> __yo_return_self(self))
4973
5040
  )
4974
5041
  );
4975
5042
  _long :: long;
@@ -5073,13 +5140,13 @@ impl(
5073
5140
  impl(
5074
5141
  ulong,
5075
5142
  Hash(
5076
- (hash) : ((self) -> u64(self.*))
5143
+ (hash) : ((self) -> u64(self))
5077
5144
  )
5078
5145
  );
5079
5146
  impl(
5080
5147
  ulong,
5081
5148
  Clone(
5082
- clone : ((self) -> __yo_return_self(self.*))
5149
+ clone : ((self) -> __yo_return_self(self))
5083
5150
  )
5084
5151
  );
5085
5152
  _ulong :: ulong;
@@ -5183,13 +5250,13 @@ impl(
5183
5250
  impl(
5184
5251
  longlong,
5185
5252
  Hash(
5186
- (hash) : ((self) -> u64(self.*))
5253
+ (hash) : ((self) -> u64(self))
5187
5254
  )
5188
5255
  );
5189
5256
  impl(
5190
5257
  longlong,
5191
5258
  Clone(
5192
- clone : ((self) -> __yo_return_self(self.*))
5259
+ clone : ((self) -> __yo_return_self(self))
5193
5260
  )
5194
5261
  );
5195
5262
  _longlong :: longlong;
@@ -5293,13 +5360,13 @@ impl(
5293
5360
  impl(
5294
5361
  ulonglong,
5295
5362
  Hash(
5296
- (hash) : ((self) -> u64(self.*))
5363
+ (hash) : ((self) -> u64(self))
5297
5364
  )
5298
5365
  );
5299
5366
  impl(
5300
5367
  ulonglong,
5301
5368
  Clone(
5302
- clone : ((self) -> __yo_return_self(self.*))
5369
+ clone : ((self) -> __yo_return_self(self))
5303
5370
  )
5304
5371
  );
5305
5372
  _ulonglong :: ulonglong;
@@ -5403,18 +5470,23 @@ impl(
5403
5470
  impl(
5404
5471
  longdouble,
5405
5472
  Hash(
5406
- (hash) : ((self) -> u64(i64(self.*)))
5473
+ (hash) : ((self) -> u64(i64(self)))
5407
5474
  )
5408
5475
  );
5409
5476
  impl(
5410
5477
  longdouble,
5411
5478
  Clone(
5412
- clone : ((self) -> __yo_return_self(self.*))
5479
+ clone : ((self) -> __yo_return_self(self))
5413
5480
  )
5414
5481
  );
5415
5482
  _longdouble :: longdouble;
5416
5483
  export(longdouble : _longdouble);
5417
5484
  /// Ptr
5485
+ // SAFETY: A raw pointer *(T) is Send only when the pointee T is Send —
5486
+ // the pointer itself is a plain value (an address), and Send implies
5487
+ // that any T reachable through it is safe to access from another thread.
5488
+ // *(T) is unconditionally Acyclic because raw pointers do not participate
5489
+ // in Yo's ARC reference-counting cycle analysis.
5418
5490
  impl(forall(T : Type), where(T <: Send), *(T), Send());
5419
5491
  impl(forall(T : Type), *(T), Acyclic());
5420
5492
  impl(forall(T : Type), where(T <: Comptime), *(T), Comptime());
@@ -5476,6 +5548,10 @@ impl(
5476
5548
  )
5477
5549
  );
5478
5550
  /// Array
5551
+ // SAFETY: Array(T, U) is a fixed-size array value type. It is Send when T
5552
+ // is Send because an array value is copied across threads (each thread
5553
+ // gets an independent copy). It is unconditionally Acyclic because arrays
5554
+ // are value-typed — they do not participate in ARC reference counting.
5479
5555
  impl(forall(T : Type, U : usize), where(T <: Send), Array(T, U), Send());
5480
5556
  impl(forall(T : Type, U : usize), Array(T, U), Acyclic());
5481
5557
  impl(forall(T : Type, U : usize), where(T <: Comptime), Array(T, U), Comptime());
@@ -5483,7 +5559,7 @@ impl(forall(T : Type, U : usize), where(T <: Runtime), Array(T, U), Runtime());
5483
5559
  impl(
5484
5560
  forall(T : Type, U : usize),
5485
5561
  Array(T, U),
5486
- len : (fn(self : *(Self)) -> usize)({
5562
+ len : (fn(ref(self) : Self) -> usize)({
5487
5563
  return(U);
5488
5564
  })
5489
5565
  /*
@@ -5505,13 +5581,17 @@ impl(
5505
5581
  })
5506
5582
  );
5507
5583
  /// Array Index impls
5584
+ /// Bodies take `&(self)` so the `*(Array(T, N))`-expecting builtin
5585
+ /// receives the right C-ABI shape — `ref(self) : Self` gives the body
5586
+ /// a value-typed view of `self` even though the runtime passes a
5587
+ /// pointer. See plans/ITERATOR_REDESIGN.md.
5508
5588
  impl(
5509
5589
  forall(T : Type, N : usize),
5510
5590
  Array(T, N),
5511
5591
  Index(usize)(
5512
5592
  Output : T,
5513
- index : (fn(self : *(Self), idx : usize) -> *(Self.Output))(
5514
- __yo_array_index(self, idx)
5593
+ index : (fn(ref(self) : Self, idx : usize) -> *(Self.Output))(
5594
+ __yo_array_index(&(self), idx)
5515
5595
  )
5516
5596
  )
5517
5597
  );
@@ -5520,8 +5600,8 @@ impl(
5520
5600
  Array(T, N),
5521
5601
  Index(Range(usize))(
5522
5602
  Output : Slice(T),
5523
- index : (fn(self : *(Self), idx : Range(usize)) -> *(Self.Output))(
5524
- __yo_array_index_range(self, idx)
5603
+ index : (fn(ref(self) : Self, idx : Range(usize)) -> *(Self.Output))(
5604
+ __yo_array_index_range(&(self), idx)
5525
5605
  )
5526
5606
  )
5527
5607
  );
@@ -5530,12 +5610,37 @@ impl(
5530
5610
  Array(T, N),
5531
5611
  Index(RangeInclusive(usize))(
5532
5612
  Output : Slice(T),
5533
- index : (fn(self : *(Self), idx : RangeInclusive(usize)) -> *(Self.Output))(
5534
- __yo_array_index_range_inclusive(self, idx)
5613
+ index : (fn(ref(self) : Self, idx : RangeInclusive(usize)) -> *(Self.Output))(
5614
+ __yo_array_index_range_inclusive(&(self), idx)
5615
+ )
5616
+ )
5617
+ );
5618
+ /// Array Indexable impl — projection-style indexing yielding `ref(T)`.
5619
+ /// Body takes `&(self)` so `__yo_array_index`'s `self : *(Array(T, N))`
5620
+ /// parameter is satisfied — the `ref(self) : Self` binding gives the
5621
+ /// body a value-typed view of `self` even though the C ABI passes a
5622
+ /// pointer. The `unsafe` wrap is the trusted escape from the
5623
+ /// flowability rule (privileged code only). See plans/ITERATOR_REDESIGN.md.
5624
+ impl(
5625
+ forall(T : Type, N : usize),
5626
+ Array(T, N),
5627
+ Indexable(usize)(
5628
+ Element : T,
5629
+ project : (fn(ref(self) : Self, pos : usize) -> ref(T))(
5630
+ cond(
5631
+ (pos >= N) => panic("Array: project out of bounds"),
5632
+ true => unsafe(__yo_array_index(&(self), pos))
5633
+ )
5535
5634
  )
5536
5635
  )
5537
5636
  );
5538
5637
  /// Slice
5638
+ // SAFETY: Slice(T) is a value-typed view (pointer + length) over a backing
5639
+ // array. Sending a slice across threads copies the header; both threads
5640
+ // can independently read the backing array. The backing array's lifetime
5641
+ // is managed by its owning collection (which must itself be Send to cross
5642
+ // threads). Slice is always Acyclic — it is a value type with no ARC.
5643
+ impl(forall(T : Type), where(T <: Send), Slice(T), Send());
5539
5644
  impl(forall(T : Type), Slice(T), Acyclic());
5540
5645
  impl(forall(T : Type), where(T <: Comptime), Slice(T), Comptime());
5541
5646
  impl(forall(T : Type), where(T <: Runtime), Slice(T), Runtime());
@@ -5558,14 +5663,14 @@ impl(
5558
5663
  __yo_slice_ptr(self)
5559
5664
  )
5560
5665
  );
5561
- /// Slice Index impls
5666
+ /// Slice Index impls (same `&(self)` rationale as Array above).
5562
5667
  impl(
5563
5668
  forall(T : Type),
5564
5669
  Slice(T),
5565
5670
  Index(usize)(
5566
5671
  Output : T,
5567
- index : (fn(self : *(Self), idx : usize) -> *(Self.Output))(
5568
- __yo_slice_index(self, idx)
5672
+ index : (fn(ref(self) : Self, idx : usize) -> *(Self.Output))(
5673
+ __yo_slice_index(&(self), idx)
5569
5674
  )
5570
5675
  )
5571
5676
  );
@@ -5574,8 +5679,8 @@ impl(
5574
5679
  Slice(T),
5575
5680
  Index(Range(usize))(
5576
5681
  Output : Slice(T),
5577
- index : (fn(self : *(Self), idx : Range(usize)) -> *(Self.Output))(
5578
- __yo_slice_index_range(self, idx)
5682
+ index : (fn(ref(self) : Self, idx : Range(usize)) -> *(Self.Output))(
5683
+ __yo_slice_index_range(&(self), idx)
5579
5684
  )
5580
5685
  )
5581
5686
  );
@@ -5584,8 +5689,22 @@ impl(
5584
5689
  Slice(T),
5585
5690
  Index(RangeInclusive(usize))(
5586
5691
  Output : Slice(T),
5587
- index : (fn(self : *(Self), idx : RangeInclusive(usize)) -> *(Self.Output))(
5588
- __yo_slice_index_range_inclusive(self, idx)
5692
+ index : (fn(ref(self) : Self, idx : RangeInclusive(usize)) -> *(Self.Output))(
5693
+ __yo_slice_index_range_inclusive(&(self), idx)
5694
+ )
5695
+ )
5696
+ );
5697
+ /// Slice Indexable impl — see Array Indexable above.
5698
+ impl(
5699
+ forall(T : Type),
5700
+ Slice(T),
5701
+ Indexable(usize)(
5702
+ Element : T,
5703
+ project : (fn(ref(self) : Self, pos : usize) -> ref(T))(
5704
+ cond(
5705
+ (pos >= self.len()) => panic("Slice: project out of bounds"),
5706
+ true => unsafe(__yo_slice_index(&(self), pos))
5707
+ )
5589
5708
  )
5590
5709
  )
5591
5710
  );
@@ -5596,7 +5715,7 @@ impl(
5596
5715
  Array(T, N),
5597
5716
  ComptimeIndex(usize)(
5598
5717
  Output : T,
5599
- index : (fn(comptime(self) : *(Self), comptime(idx) : usize) -> comptime(*(Self.Output)))(
5718
+ index : (fn(comptime(ref(self)) : Self, comptime(idx) : usize) -> comptime(*(Self.Output)))(
5600
5719
  __yo_comptime_array_index(self, idx)
5601
5720
  )
5602
5721
  )
@@ -5607,7 +5726,7 @@ impl(
5607
5726
  Array(T, N),
5608
5727
  ComptimeIndex(Range(usize))(
5609
5728
  Output : Slice(T),
5610
- index : (fn(comptime(self) : *(Self), comptime(idx) : Range(usize)) -> comptime(*(Self.Output)))(
5729
+ index : (fn(comptime(ref(self)) : Self, comptime(idx) : Range(usize)) -> comptime(*(Self.Output)))(
5611
5730
  __yo_comptime_array_index_range(self, idx)
5612
5731
  )
5613
5732
  )
@@ -5618,7 +5737,7 @@ impl(
5618
5737
  Array(T, N),
5619
5738
  ComptimeIndex(RangeInclusive(usize))(
5620
5739
  Output : Slice(T),
5621
- index : (fn(comptime(self) : *(Self), comptime(idx) : RangeInclusive(usize)) -> comptime(*(Self.Output)))(
5740
+ index : (fn(comptime(ref(self)) : Self, comptime(idx) : RangeInclusive(usize)) -> comptime(*(Self.Output)))(
5622
5741
  __yo_comptime_array_index_range_inclusive(self, idx)
5623
5742
  )
5624
5743
  )
@@ -5630,7 +5749,7 @@ impl(
5630
5749
  Slice(T),
5631
5750
  ComptimeIndex(usize)(
5632
5751
  Output : T,
5633
- index : (fn(comptime(self) : *(Self), comptime(idx) : usize) -> comptime(*(Self.Output)))(
5752
+ index : (fn(comptime(ref(self)) : Self, comptime(idx) : usize) -> comptime(*(Self.Output)))(
5634
5753
  __yo_comptime_slice_index(self, idx)
5635
5754
  )
5636
5755
  )
@@ -5641,7 +5760,7 @@ impl(
5641
5760
  Slice(T),
5642
5761
  ComptimeIndex(Range(usize))(
5643
5762
  Output : Slice(T),
5644
- index : (fn(comptime(self) : *(Self), comptime(idx) : Range(usize)) -> comptime(*(Self.Output)))(
5763
+ index : (fn(comptime(ref(self)) : Self, comptime(idx) : Range(usize)) -> comptime(*(Self.Output)))(
5645
5764
  __yo_comptime_slice_index_range(self, idx)
5646
5765
  )
5647
5766
  )
@@ -5652,7 +5771,7 @@ impl(
5652
5771
  Slice(T),
5653
5772
  ComptimeIndex(RangeInclusive(usize))(
5654
5773
  Output : Slice(T),
5655
- index : (fn(comptime(self) : *(Self), comptime(idx) : RangeInclusive(usize)) -> comptime(*(Self.Output)))(
5774
+ index : (fn(comptime(ref(self)) : Self, comptime(idx) : RangeInclusive(usize)) -> comptime(*(Self.Output)))(
5656
5775
  __yo_comptime_slice_index_range_inclusive(self, idx)
5657
5776
  )
5658
5777
  )
@@ -5808,7 +5927,7 @@ impl(
5808
5927
  ComptimeList(T),
5809
5928
  ComptimeIndex(usize)(
5810
5929
  Output : T,
5811
- index : (fn(comptime(self) : *(Self), comptime(idx) : usize) -> comptime(*(Self.Output)))(
5930
+ index : (fn(comptime(ref(self)) : Self, comptime(idx) : usize) -> comptime(*(Self.Output)))(
5812
5931
  __yo_comptime_list_index(self, idx)
5813
5932
  )
5814
5933
  )
@@ -5819,7 +5938,7 @@ impl(
5819
5938
  ComptimeList(T),
5820
5939
  ComptimeIndex(Range(usize))(
5821
5940
  Output : ComptimeList(T),
5822
- index : (fn(comptime(self) : *(Self), comptime(idx) : Range(usize)) -> comptime(*(Self.Output)))(
5941
+ index : (fn(comptime(ref(self)) : Self, comptime(idx) : Range(usize)) -> comptime(*(Self.Output)))(
5823
5942
  __yo_comptime_list_index_range(self, idx)
5824
5943
  )
5825
5944
  )
@@ -5830,7 +5949,7 @@ impl(
5830
5949
  ComptimeList(T),
5831
5950
  ComptimeIndex(RangeInclusive(usize))(
5832
5951
  Output : ComptimeList(T),
5833
- index : (fn(comptime(self) : *(Self), comptime(idx) : RangeInclusive(usize)) -> comptime(*(Self.Output)))(
5952
+ index : (fn(comptime(ref(self)) : Self, comptime(idx) : RangeInclusive(usize)) -> comptime(*(Self.Output)))(
5834
5953
  __yo_comptime_list_index_range_inclusive(self, idx)
5835
5954
  )
5836
5955
  )
@@ -6697,7 +6816,7 @@ __derive_clone :: (fn(comptime(T) : Type, comptime(ctx) : DeriveContext, comptim
6697
6816
  "",
6698
6817
  (fn(comptime(a) : comptime_string, comptime(fi) : usize) -> comptime(comptime_string))({
6699
6818
  fname :: fields.get(fi).name;
6700
- part :: __s3("(&(self.*.", fname, ")).clone()");
6819
+ part :: __s3("self.", fname, ".clone()");
6701
6820
  cond(
6702
6821
  (a == "") => part,
6703
6822
  true => __s3(a, ", ", part)
@@ -6741,8 +6860,8 @@ __derive_clone :: (fn(comptime(T) : Type, comptime(ctx) : DeriveContext, comptim
6741
6860
  (fn(comptime(a) : comptime_string, comptime(fi) : usize) -> comptime(comptime_string))({
6742
6861
  fname :: v.fields.get(fi).name;
6743
6862
  cond(
6744
- (a == "") => __s3("(&(__v_", fname, ")).clone()"),
6745
- true => __s4(a, ", (&(__v_", fname, ")).clone()")
6863
+ (a == "") => __s3("__v_", fname, ".clone()"),
6864
+ true => __s4(a, ", __v_", fname, ".clone()")
6746
6865
  )
6747
6866
  })
6748
6867
  );
@@ -6761,7 +6880,7 @@ __derive_clone :: (fn(comptime(T) : Type, comptime(ctx) : DeriveContext, comptim
6761
6880
  )
6762
6881
  })
6763
6882
  );
6764
- match_body :: __s3("match(self.*,\n ", clone_branches, "\n )");
6883
+ match_body :: __s3("match(self,\n ", clone_branches, "\n )");
6765
6884
  ctx.make_impl(
6766
6885
  quote(
6767
6886
  Clone(
@@ -6774,7 +6893,7 @@ __derive_clone :: (fn(comptime(T) : Type, comptime(ctx) : DeriveContext, comptim
6774
6893
  ctx.make_impl(
6775
6894
  quote(
6776
6895
  Clone(
6777
- clone : ((self) -> self.*)
6896
+ clone : ((self) -> self)
6778
6897
  )
6779
6898
  )
6780
6899
  )
@@ -6804,8 +6923,8 @@ __derive_hash :: (fn(comptime(T) : Type, comptime(ctx) : DeriveContext, comptime
6804
6923
  (fn(comptime(a) : comptime_string, comptime(fi) : usize) -> comptime(comptime_string))({
6805
6924
  fname :: fields.get(fi).name;
6806
6925
  cond(
6807
- (fi == 0) => __s3("(h : u64) = (&(self.*.", fname, ")).hash()"),
6808
- true => __s4(a, ";\n h = ((h * u64(31)) + (&(self.*.", fname, ")).hash())")
6926
+ (fi == 0) => __s3("(h : u64) = self.", fname, ".hash()"),
6927
+ true => __s4(a, ";\n h = ((h * u64(31)) + self.", fname, ".hash())")
6809
6928
  )
6810
6929
  })
6811
6930
  );
@@ -6848,7 +6967,7 @@ __derive_hash :: (fn(comptime(T) : Type, comptime(ctx) : DeriveContext, comptime
6848
6967
  __s3("(h : u64) = u64(", vi_str, ")"),
6849
6968
  (fn(comptime(a) : comptime_string, comptime(fi) : usize) -> comptime(comptime_string))({
6850
6969
  fname :: v.fields.get(fi).name;
6851
- __s4(a, "; h = ((h * u64(31)) + (&(__v_", fname, ")).hash())")
6970
+ __s4(a, "; h = ((h * u64(31)) + __v_", fname, ".hash())")
6852
6971
  })
6853
6972
  );
6854
6973
  __s5(
@@ -6866,7 +6985,7 @@ __derive_hash :: (fn(comptime(T) : Type, comptime(ctx) : DeriveContext, comptime
6866
6985
  )
6867
6986
  })
6868
6987
  );
6869
- match_body :: __s3("match(self.*,\n ", hash_branches, "\n )");
6988
+ match_body :: __s3("match(self,\n ", hash_branches, "\n )");
6870
6989
  ctx.make_impl(
6871
6990
  quote(
6872
6991
  Hash(
@@ -7279,9 +7398,9 @@ impl(
7279
7398
  clone : (
7280
7399
  (self) ->
7281
7400
  match(
7282
- self.*,
7401
+ self,
7283
7402
  .None => Option(T).None,
7284
- .Some(v) => Option(T).Some((&(v)).clone())
7403
+ .Some(v) => Option(T).Some(v.clone())
7285
7404
  )
7286
7405
  )
7287
7406
  )
@@ -7315,9 +7434,9 @@ impl(
7315
7434
  clone : (
7316
7435
  (self) ->
7317
7436
  match(
7318
- self.*,
7319
- .Ok(v) => Result(T, E).Ok((&(v)).clone()),
7320
- .Err(e) => Result(T, E).Err((&(e)).clone())
7437
+ self,
7438
+ .Ok(v) => Result(T, E).Ok(v.clone()),
7439
+ .Err(e) => Result(T, E).Err(e.clone())
7321
7440
  )
7322
7441
  )
7323
7442
  )
@@ -7375,7 +7494,7 @@ impl(
7375
7494
  where(T <: Hash),
7376
7495
  Box(T),
7377
7496
  Hash(
7378
- (hash) : ((self) -> (self.*).*.hash())
7497
+ (hash) : ((self) -> self.*.hash())
7379
7498
  )
7380
7499
  );
7381
7500
  impl(
@@ -7383,7 +7502,10 @@ impl(
7383
7502
  where(T <: Eq(T)),
7384
7503
  Box(T),
7385
7504
  Eq(Box(T))(
7386
- (==) : ((lhs, rhs) -> (lhs.* == rhs.*))
7505
+ // SAFETY: Box always holds a non-null pointer to Rc-managed
7506
+ // storage; the deref is sound for as long as either operand
7507
+ // is alive, which covers the duration of this comparison.
7508
+ (==) : ((lhs, rhs) -> unsafe(lhs.* == rhs.*))
7387
7509
  )
7388
7510
  );
7389
7511
  impl(
@@ -7391,7 +7513,7 @@ impl(
7391
7513
  where(T <: Clone),
7392
7514
  Box(T),
7393
7515
  Clone(
7394
- clone : ((self) -> box((&(self.*.*)).clone()))
7516
+ clone : ((self) -> box(self.*.clone()))
7395
7517
  )
7396
7518
  );
7397
7519
  export(
@@ -7399,13 +7521,21 @@ export(
7399
7521
  box
7400
7522
  );
7401
7523
  /// Iso — an isolated reference-counted value that can be sent across threads.
7524
+ // SAFETY: Iso(T) is unconditionally Send (no `T <: Send` bound) because
7525
+ // Iso's public API exposes no operation on the inner T except extract(),
7526
+ // which atomically verifies rc == 1 before returning. If you add any new
7527
+ // method to Iso(T) that touches the inner T (map, peek, read, &self
7528
+ // borrow, etc.), this Send claim becomes unsound and must be revoked.
7529
+ // See plans/THREAD_SAFETY.md "Iso(T) design notes — precedent and known
7530
+ // risks" for the full argument.
7402
7531
  impl(forall(T : Type), Iso(T), Send());
7403
7532
  impl(forall(T : Type), where(T <: Acyclic), Iso(T), Acyclic());
7404
7533
  impl(
7405
7534
  forall(T : Type),
7406
7535
  Iso(T),
7407
- /// Attempt to extract the inner value if this `Iso` holds the only reference.
7408
- extract : (fn(self : Self) -> Option(T))(
7536
+ /// Extract the inner value if this `Iso` holds the only reference.
7537
+ /// Panics if rc != 1 or if this Iso has already been extracted.
7538
+ extract : (fn(self : Self) -> T)(
7409
7539
  __yo_iso_extract(self)
7410
7540
  )
7411
7541
  );
@@ -7481,6 +7611,9 @@ Arc :: (fn(comptime(V) : Type, where(V <: (Send, Acyclic))) -> comptime(Type))(
7481
7611
  );
7482
7612
  /// Allocate a value inside an Arc, returning an `Arc(V)`.
7483
7613
  arc :: (fn(forall(V : Type), own(value) : V, where(V <: (Send, Acyclic))) -> Arc(V))(Arc(V)(value));
7614
+ // SAFETY: Arc(T) is an atomic reference-counted wrapper. It is Send when
7615
+ // the inner T is Send (all fields of the atomic-object must be Send per
7616
+ // auto-derive) and Acyclic (prevents permanent leaks from Arc cycles).
7484
7617
  impl(forall(T : Type), where(T <: (Send, Acyclic)), Arc(T), Send());
7485
7618
  export(Arc, arc);
7486
7619
  /// === MaybeUninit ===
@@ -7521,8 +7654,8 @@ impl(
7521
7654
  /// Create a new uninitialized value.
7522
7655
  new : (fn() -> Self)(__yo_maybe_uninit_new(Self)),
7523
7656
  /// Get a mutable pointer to the underlying value.
7524
- as_ptr : (fn(self : *(Self)) -> *(BaseType))(
7525
- __yo_maybe_uninit_as_ptr(Self, BaseType, self)
7657
+ as_ptr : (fn(ref(self) : Self) -> *(BaseType))(
7658
+ __yo_maybe_uninit_as_ptr(Self, BaseType, &(self))
7526
7659
  ),
7527
7660
  /// Assume the value is initialized and extract it. **Undefined behavior if not initialized.**
7528
7661
  assume_init : (fn(own(self) : Self) -> BaseType)(
@@ -7536,7 +7669,7 @@ Iterator :: trait(
7536
7669
  Item : Type,
7537
7670
  /// Advance the iterator and return the next value, or `None` when exhausted.
7538
7671
  next :
7539
- fn(self : *(Self)) -> Option(Self.Item)
7672
+ fn(ref(self) : Self) -> Option(Self.Item)
7540
7673
  );
7541
7674
  export(Iterator);
7542
7675
  /// IntoIterator trait — convert a collection into an iterator.
@@ -7549,29 +7682,25 @@ IntoIterator :: trait(
7549
7682
  );
7550
7683
  export(IntoIterator);
7551
7684
  /// === Array Iterator ===
7552
- /**
7553
- * Pointer iterator for Array(T, N) - yields *(T) pointers to each element
7554
- * Used by Array.iter()
7555
- */
7556
- ArrayIterPtr :: (fn(comptime(T) : Type) -> comptime(Type))(
7557
- struct(
7558
- _ptr : *(T),
7559
- _index : usize,
7560
- _len : usize
7561
- )
7685
+ /// Position iterator for Array(T, N) — yields `usize` indices.
7686
+ /// Used by `Array.iter()`; the for-macro pairs each yielded position
7687
+ /// with `Array.project(pos)` (Indexable trait) to hand the body a
7688
+ /// `ref(T)`-binding into the element. See plans/ITERATOR_REDESIGN.md.
7689
+ _ArrayPosIter :: struct(
7690
+ _index : usize,
7691
+ _len : usize
7562
7692
  );
7563
7693
  impl(
7564
- forall(T : Type),
7565
- ArrayIterPtr(T),
7694
+ _ArrayPosIter,
7566
7695
  Iterator(
7567
- Item : *(T),
7568
- next : (fn(self : *(Self)) -> Option(*(T)))(
7696
+ Item : usize,
7697
+ next : (fn(ref(self) : Self) -> Option(usize))(
7569
7698
  cond(
7570
7699
  (self._index >= self._len) =>.None,
7571
7700
  true => {
7572
- element_ptr := (self._ptr &+ self._index);
7701
+ out := self._index;
7573
7702
  self._index = (self._index + usize(1));
7574
- .Some(element_ptr)
7703
+ .Some(out)
7575
7704
  }
7576
7705
  )
7577
7706
  )
@@ -7580,34 +7709,30 @@ impl(
7580
7709
  impl(
7581
7710
  forall(T : Type, N : usize),
7582
7711
  Array(T, N),
7583
- iter : (fn(self : *(Self)) -> ArrayIterPtr(T))(
7584
- ArrayIterPtr(T)(_ptr : &((self.*)(usize(0))), _index : usize(0), _len : N)
7712
+ iter : (fn(ref(self) : Self) -> _ArrayPosIter)(
7713
+ _ArrayPosIter(_index : usize(0), _len : N)
7585
7714
  )
7586
7715
  );
7587
- export(ArrayIterPtr);
7588
7716
  /// === Slice Iterator ===
7589
- /**
7590
- * Pointer iterator for Slice(T) - yields *(T) pointers to each element
7591
- * Used by Slice.iter()
7592
- */
7593
- SliceIterPtr :: (fn(comptime(T) : Type) -> comptime(Type))(
7594
- struct(
7595
- _slice : Slice(T),
7596
- _index : usize
7597
- )
7717
+ /// Position iterator for Slice(T) — yields `usize` indices into the
7718
+ /// slice. Used by `Slice.iter()`; the for-macro pairs each yielded
7719
+ /// position with `Slice.project(pos)` (Indexable) to bind the body's
7720
+ /// `ref`-name. See plans/ITERATOR_REDESIGN.md.
7721
+ _SlicePosIter :: struct(
7722
+ _index : usize,
7723
+ _len : usize
7598
7724
  );
7599
7725
  impl(
7600
- forall(T : Type),
7601
- SliceIterPtr(T),
7726
+ _SlicePosIter,
7602
7727
  Iterator(
7603
- Item : *(T),
7604
- next : (fn(self : *(Self)) -> Option(*(T)))(
7728
+ Item : usize,
7729
+ next : (fn(ref(self) : Self) -> Option(usize))(
7605
7730
  cond(
7606
- (self._index >= self._slice.len()) =>.None,
7731
+ (self._index >= self._len) =>.None,
7607
7732
  true => {
7608
- ptr := &((self._slice)(self._index));
7733
+ out := self._index;
7609
7734
  self._index = (self._index + usize(1));
7610
- .Some(ptr)
7735
+ .Some(out)
7611
7736
  }
7612
7737
  )
7613
7738
  )
@@ -7616,11 +7741,10 @@ impl(
7616
7741
  impl(
7617
7742
  forall(T : Type),
7618
7743
  Slice(T),
7619
- iter : (fn(self : *(Self)) -> SliceIterPtr(T))(
7620
- SliceIterPtr(T)(_slice : self.*, _index : usize(0))
7744
+ iter : (fn(ref(self) : Self) -> _SlicePosIter)(
7745
+ _SlicePosIter(_index : usize(0), _len : self.len())
7621
7746
  )
7622
7747
  );
7623
- export(SliceIterPtr);
7624
7748
  /// TryFrom trait — fallible conversion from one type to another.
7625
7749
  TryFrom :: (fn(comptime(From) : Type) -> comptime(Trait))(
7626
7750
  trait(
@@ -7684,17 +7808,38 @@ try :: (fn(quote(expr_to_try) : Expr) -> unquote(Expr))({
7684
7808
  })
7685
7809
  });
7686
7810
  export(try);
7687
- /// `for` macro — iterate over a collection using the `Iterator` trait.
7811
+ /// `for` macro — iterate over a collection. The lambda's binding shape
7812
+ /// dictates whether the iteration borrows or consumes:
7688
7813
  ///
7689
- /// # Example
7814
+ /// `for(coll, ref(x) => body)` — borrow form. Calls `coll.iter()`
7815
+ /// (must yield positions) + `coll.project(pos)` for each. `x` is
7816
+ /// `ref`-bound to the element; reads auto-deref, writes propagate
7817
+ /// back to the collection; `coll` survives the loop.
7818
+ ///
7819
+ /// `for(coll, (x) => body)` — value form. Calls `coll.into_iter()`
7820
+ /// and binds `x` to each yielded value. The collection is moved
7821
+ /// into the iterator and consumed.
7822
+ ///
7823
+ /// Combinator chains (`coll.iter().map(f)`, etc.) only support the
7824
+ /// value form — they yield computed values, not borrows. A blanket
7825
+ /// `into_iter` impl on `Iterator` (below) makes the value form work
7826
+ /// transparently on iterator chains.
7827
+ ///
7828
+ /// See plans/ITERATOR_REDESIGN.md.
7829
+ ///
7830
+ /// # Examples
7690
7831
  /// ```rust
7691
- /// for arr.iter(), (value) => {
7692
- /// printf("value %d\n", value.*);
7693
- /// };
7832
+ /// // Borrow form mutate elements in place.
7833
+ /// for(arr, ref(x) => {
7834
+ /// x = (x + i32(1));
7835
+ /// });
7836
+ ///
7837
+ /// // Value form — consume the collection.
7838
+ /// for(list.into_iter(), (x) => print(x));
7694
7839
  /// ```
7695
7840
  for :: (
7696
7841
  fn(
7697
- quote(iter) : Expr,
7842
+ quote(coll) : Expr,
7698
7843
  quote(handle) : Expr
7699
7844
  ) -> unquote(Expr)
7700
7845
  )({
@@ -7709,21 +7854,68 @@ for :: (
7709
7854
  comptime_assert(args.len() == 2, "'for' macro requires 2 arguments in the function handle");
7710
7855
  variable :: args.car();
7711
7856
  body :: args.cdr().car();
7712
- iter_var :: gensym("for_iter_var");
7713
- temp_var :: gensym("for_temp_var");
7714
- quote({
7715
- unquote(iter_var) := unquote(iter);
7716
- while(runtime(true), {
7717
- unquote(temp_var) := &(unquote(iter_var)).next();
7718
- match(
7719
- unquote(temp_var),
7720
- .Some(unquote(variable)) => unquote(body),
7721
- .None => {
7722
- break;
7723
- }
7724
- )
7725
- });
7726
- })
7857
+ // Detect `ref(name) => body` — borrow form. Otherwise
7858
+ // it's the value form `(name) => body`.
7859
+ is_ref_form :: cond(
7860
+ variable.is_fn_call() => {
7861
+ v_callee :: variable.get_callee();
7862
+ v_callee.is_atom() && (v_callee == quote(ref))
7863
+ },
7864
+ true => false
7865
+ );
7866
+ cond(
7867
+ is_ref_form => {
7868
+ v_args :: variable.get_args();
7869
+ comptime_assert(v_args.len() == 1, "'for' macro: ref(name) requires exactly one name");
7870
+ name :: v_args.car();
7871
+ iter_var :: gensym("for_iter_var");
7872
+ pos_var :: gensym("for_pos_var");
7873
+ // Note: the borrow form does NOT materialize a local
7874
+ // copy of `coll`. Writes through `ref(x) := …
7875
+ // coll.project(pos)` need to propagate to the caller's
7876
+ // storage; a value-typed local copy would receive the
7877
+ // writes silently. The for-macro consumes `coll` as an
7878
+ // expression directly so the `&coll` pointer it
7879
+ // implicitly forms reaches the caller's collection.
7880
+ // (This is correct for `coll : Array(T, N)` /
7881
+ // `Slice(T)` / `String` value-typed collections and
7882
+ // for `ref(coll)`-bound parameter inputs; for owning
7883
+ // collections like `ArrayList` whose internal storage
7884
+ // is heap, the receiver-by-ref semantics already work.)
7885
+ quote({
7886
+ unquote(iter_var) := unquote(coll).iter();
7887
+ while(runtime(true), {
7888
+ match(
7889
+ unquote(iter_var).next(),
7890
+ .Some(unquote(pos_var)) => {
7891
+ ref(unquote(name)) := unquote(coll).project(unquote(pos_var));
7892
+ unquote(body);
7893
+ },
7894
+ .None => {
7895
+ break;
7896
+ }
7897
+ );
7898
+ });
7899
+ })
7900
+ },
7901
+ true => {
7902
+ iter_var :: gensym("for_iter_var");
7903
+ temp_var :: gensym("for_temp_var");
7904
+ quote({
7905
+ unquote(iter_var) := unquote(coll).into_iter();
7906
+ while(runtime(true), {
7907
+ unquote(temp_var) := unquote(iter_var).next();
7908
+ match(
7909
+ unquote(temp_var),
7910
+ .Some(unquote(variable)) => unquote(body),
7911
+ .None => {
7912
+ break;
7913
+ }
7914
+ )
7915
+ });
7916
+ })
7917
+ }
7918
+ )
7727
7919
  },
7728
7920
  true => {
7729
7921
  comptime_assert(false, "for macro requires a function handle with `=>`");
@@ -7764,9 +7956,9 @@ impl(
7764
7956
  IterMap(I, B, F),
7765
7957
  Iterator(
7766
7958
  Item : B,
7767
- next : (fn(self : *(Self)) -> Option(B))(
7959
+ next : (fn(ref(self) : Self) -> Option(B))(
7768
7960
  match(
7769
- &(self._inner).next(),
7961
+ self._inner.next(),
7770
7962
  .None =>.None,
7771
7963
  .Some(item) =>.Some((self._f)(item))
7772
7964
  )
@@ -7791,10 +7983,10 @@ impl(
7791
7983
  IterFilter(I, F),
7792
7984
  Iterator(
7793
7985
  Item : A,
7794
- next : (fn(self : *(Self)) -> Option(A))({
7986
+ next : (fn(ref(self) : Self) -> Option(A))({
7795
7987
  (loop_result : Option(A)) =.None;
7796
7988
  while(runtime(true), {
7797
- candidate := &(self._inner).next();
7989
+ candidate := self._inner.next();
7798
7990
  match(
7799
7991
  candidate,
7800
7992
  .None => {
@@ -7831,12 +8023,12 @@ impl(
7831
8023
  IterTake(I),
7832
8024
  Iterator(
7833
8025
  Item : A,
7834
- next : (fn(self : *(Self)) -> Option(A))(
8026
+ next : (fn(ref(self) : Self) -> Option(A))(
7835
8027
  cond(
7836
8028
  (self._remaining == usize(0)) =>.None,
7837
8029
  true => {
7838
8030
  self._remaining = (self._remaining - usize(1));
7839
- &(self._inner).next()
8031
+ self._inner.next()
7840
8032
  }
7841
8033
  )
7842
8034
  )
@@ -7859,9 +8051,9 @@ impl(
7859
8051
  IterSkip(I),
7860
8052
  Iterator(
7861
8053
  Item : A,
7862
- next : (fn(self : *(Self)) -> Option(A))({
8054
+ next : (fn(ref(self) : Self) -> Option(A))({
7863
8055
  while(self._to_skip > usize(0), {
7864
- result := &(self._inner).next();
8056
+ result := self._inner.next();
7865
8057
  match(
7866
8058
  result,
7867
8059
  .None => {
@@ -7873,7 +8065,7 @@ impl(
7873
8065
  }
7874
8066
  );
7875
8067
  });
7876
- &(self._inner).next()
8068
+ self._inner.next()
7877
8069
  })
7878
8070
  )
7879
8071
  );
@@ -7895,9 +8087,9 @@ impl(
7895
8087
  IterEnumerate(I),
7896
8088
  Iterator(
7897
8089
  Item : IterPair(usize, A),
7898
- next : (fn(self : *(Self)) -> Option(IterPair(usize, A)))(
8090
+ next : (fn(ref(self) : Self) -> Option(IterPair(usize, A)))(
7899
8091
  match(
7900
- &(self._inner).next(),
8092
+ self._inner.next(),
7901
8093
  .None =>.None,
7902
8094
  .Some(item) => {
7903
8095
  idx := self._index;
@@ -7926,12 +8118,12 @@ impl(
7926
8118
  IterZip(I, J),
7927
8119
  Iterator(
7928
8120
  Item : IterPair(A, B),
7929
- next : (fn(self : *(Self)) -> Option(IterPair(A, B)))(
8121
+ next : (fn(ref(self) : Self) -> Option(IterPair(A, B)))(
7930
8122
  match(
7931
- &(self._left).next(),
8123
+ self._left.next(),
7932
8124
  .None =>.None,
7933
8125
  .Some(a) => match(
7934
- &(self._right).next(),
8126
+ self._right.next(),
7935
8127
  .None =>.None,
7936
8128
  .Some(b) =>.Some(IterPair(A, B)(_0 : a, _1 : b))
7937
8129
  )
@@ -7943,6 +8135,18 @@ export(IterZip);
7943
8135
  // ---------------------------------------------------------------------------
7944
8136
  // Blanket methods — added to all types implementing Iterator
7945
8137
  // ---------------------------------------------------------------------------
8138
+ /// Blanket `into_iter` — every `Iterator` is its own `IntoIterator`,
8139
+ /// returning `self`. This lets `for(combinator_chain, (x) => body)`
8140
+ /// expand to `combinator_chain.into_iter().next()` uniformly with
8141
+ /// `for(coll, (x) => body)` — the macro always calls `.into_iter()`
8142
+ /// for the value-iteration form, and for an iterator we hand back
8143
+ /// self. See plans/ITERATOR_REDESIGN.md.
8144
+ impl(
8145
+ forall(I : Type),
8146
+ where(I <: Iterator),
8147
+ I,
8148
+ into_iter : (fn(self : Self) -> Self)(self)
8149
+ );
7946
8150
  impl(
7947
8151
  forall(I : Type),
7948
8152
  where(I <: Iterator),
@@ -8026,7 +8230,7 @@ impl(
8026
8230
  iter := self;
8027
8231
  while(runtime(true), {
8028
8232
  match(
8029
- (&(iter)).next(),
8233
+ iter.next(),
8030
8234
  .None => {
8031
8235
  break;
8032
8236
  },
@@ -8049,7 +8253,7 @@ impl(
8049
8253
  iter := self;
8050
8254
  while(runtime(true), {
8051
8255
  match(
8052
- (&(iter)).next(),
8256
+ iter.next(),
8053
8257
  .None => {
8054
8258
  break;
8055
8259
  },
@@ -8071,7 +8275,7 @@ impl(
8071
8275
  iter := self;
8072
8276
  while(runtime(true), {
8073
8277
  match(
8074
- (&(iter)).next(),
8278
+ iter.next(),
8075
8279
  .None => {
8076
8280
  break;
8077
8281
  },
@@ -8095,7 +8299,7 @@ impl(
8095
8299
  iter := self;
8096
8300
  while(runtime(true), {
8097
8301
  match(
8098
- (&(iter)).next(),
8302
+ iter.next(),
8099
8303
  .None => {
8100
8304
  break;
8101
8305
  },
@@ -8125,7 +8329,7 @@ impl(
8125
8329
  iter := self;
8126
8330
  while(runtime(true), {
8127
8331
  match(
8128
- (&(iter)).next(),
8332
+ iter.next(),
8129
8333
  .None => {
8130
8334
  break;
8131
8335
  },
@@ -8154,6 +8358,8 @@ FutureState :: enum(
8154
8358
  /// The future was aborted (e.g., via `unwind`).
8155
8359
  Aborted = -(2)
8156
8360
  );
8361
+ // SAFETY: FutureState is a plain enum of integer values (Pending, Done,
8362
+ // Aborted) with no heap allocations. It is trivially Send and Acyclic.
8157
8363
  impl(FutureState, Acyclic());
8158
8364
  impl(FutureState, Runtime());
8159
8365
  impl(FutureState, Send());
@@ -8174,12 +8380,16 @@ JoinHandle :: (fn(comptime(T) : Type) -> comptime(Type))(
8174
8380
  __future : *(T)
8175
8381
  )
8176
8382
  );
8383
+ // Phase L (THREAD_SAFETY): JoinHandle is NOT Send — the inner future state
8384
+ // machine lives on the spawner's event-loop thread. Cross-thread result
8385
+ // delivery uses Channel(T).
8386
+ impl(forall(T : Type), JoinHandle(T), !(Send()));
8177
8387
  export(JoinHandle);
8178
- /// IO module — the async runtime effect.
8388
+ /// Io module — the async runtime effect.
8179
8389
  ///
8180
8390
  /// Provides `io.async`, `io.await`, `io.spawn`, and `io.state` operations.
8181
- /// Automatically injected into `main` when declared with `io : IO`.
8182
- IO :: struct(
8391
+ /// Automatically injected into `main` when declared with `io : Io`.
8392
+ Io :: struct(
8183
8393
  /// Create a new `Future` from an async closure.
8184
8394
  async : (fn(forall(T : Type, E : Type.Struct), action : Impl(Fn(e : E) -> T)) -> Impl(Future(T, E))),
8185
8395
  /// Await a `Future`, suspending until its result is ready.
@@ -8189,7 +8399,11 @@ IO :: struct(
8189
8399
  /// Spawn a `Future` as an independent task, returning a `JoinHandle`.
8190
8400
  spawn : (fn(forall(T : Type, E : Type.Struct), fut : Impl(Future(T, E)), e : E) -> JoinHandle(T))
8191
8401
  );
8192
- export(IO);
8402
+ // Phase L (THREAD_SAFETY): Io is NOT Send — the async runtime it represents
8403
+ // is per-thread (per AGENTS.md). Sending Io across a thread boundary would
8404
+ // reference a scheduler on the wrong thread.
8405
+ impl(Io, !(Send()));
8406
+ export(Io);
8193
8407
  extern(
8194
8408
  "Yo",
8195
8409
  __yo_io_async : (fn(forall(T : Type, E : Type.Struct), action : Impl(Fn(e : E) -> T)) -> Impl(Future(T, E))),
@@ -8197,19 +8411,19 @@ extern(
8197
8411
  __yo_io_state : (fn(forall(T : Type, E : Type), fut : Impl(Future(T, E))) -> FutureState),
8198
8412
  __yo_io_spawn : (fn(forall(T : Type, E : Type.Struct), fut : Impl(Future(T, E)), e : E) -> JoinHandle(T))
8199
8413
  );
8200
- /// Built-in IO module instance. Automatically injected for `main` functions
8201
- /// with `io : IO`.
8202
- __yo_builtin_io :: IO(
8414
+ /// Built-in Io module instance. Automatically injected for `main` functions
8415
+ /// with `io : Io`.
8416
+ __yo_builtin_io :: Io(
8203
8417
  async : __yo_io_async,
8204
8418
  await : __yo_io_await,
8205
8419
  state : __yo_io_state,
8206
8420
  spawn : __yo_io_spawn
8207
8421
  );
8208
8422
  export(__yo_builtin_io);
8209
- /// JoinHandle methods — defined after IO so `io : IO` resolves.
8423
+ /// JoinHandle methods — defined after Io so `io : Io` resolves.
8210
8424
  extern(
8211
8425
  "Yo",
8212
- __yo_join_handle_await : (fn(forall(T : Type), self : JoinHandle(T), io : IO) -> Option(T))
8426
+ __yo_join_handle_await : (fn(forall(T : Type), self : JoinHandle(T), io : Io) -> Option(T))
8213
8427
  );
8214
8428
  impl(
8215
8429
  forall(T : Type),