@shd101wyy/yo 0.1.14 → 0.1.16

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 (60) hide show
  1. package/README.md +43 -1
  2. package/out/cjs/index.cjs +581 -601
  3. package/out/cjs/yo-cli.cjs +739 -733
  4. package/out/cjs/yo-lsp.cjs +11615 -0
  5. package/out/esm/index.mjs +530 -550
  6. package/out/types/src/cache.d.ts +2 -0
  7. package/out/types/src/codegen/exprs/return.d.ts +1 -1
  8. package/out/types/src/codegen/types/generation.d.ts +0 -2
  9. package/out/types/src/codegen/utils/index.d.ts +2 -8
  10. package/out/types/src/doc/extractor.d.ts +4 -0
  11. package/out/types/src/evaluator/builtins/rc-fns.d.ts +0 -5
  12. package/out/types/src/evaluator/context.d.ts +7 -3
  13. package/out/types/src/evaluator/trait-checking.d.ts +2 -0
  14. package/out/types/src/evaluator/types/object.d.ts +2 -1
  15. package/out/types/src/evaluator/types/struct.d.ts +2 -1
  16. package/out/types/src/evaluator/types/utils.d.ts +3 -8
  17. package/out/types/src/evaluator/values/impl.d.ts +9 -1
  18. package/out/types/src/expr.d.ts +1 -2
  19. package/out/types/src/function-value.d.ts +1 -0
  20. package/out/types/src/lsp/completion.d.ts +3 -0
  21. package/out/types/src/lsp/definition.d.ts +3 -0
  22. package/out/types/src/lsp/diagnostics.d.ts +6 -0
  23. package/out/types/src/lsp/document-manager.d.ts +31 -0
  24. package/out/types/src/lsp/folding.d.ts +3 -0
  25. package/out/types/src/lsp/hover.d.ts +3 -0
  26. package/out/types/src/lsp/inlay-hints.d.ts +3 -0
  27. package/out/types/src/lsp/references.d.ts +3 -0
  28. package/out/types/src/lsp/rename.d.ts +16 -0
  29. package/out/types/src/lsp/server.d.ts +1 -0
  30. package/out/types/src/lsp/signature-help.d.ts +3 -0
  31. package/out/types/src/lsp/symbols.d.ts +3 -0
  32. package/out/types/src/lsp/utils.d.ts +11 -0
  33. package/out/types/src/tests/lsp.test.d.ts +1 -0
  34. package/out/types/src/tests/version.test.d.ts +1 -0
  35. package/out/types/src/types/creators.d.ts +2 -3
  36. package/out/types/src/types/definitions.d.ts +3 -6
  37. package/out/types/src/types/guards.d.ts +5 -2
  38. package/out/types/src/types/tags.d.ts +0 -1
  39. package/out/types/src/version-cache.d.ts +7 -0
  40. package/out/types/src/version.d.ts +5 -0
  41. package/out/types/tsconfig.tsbuildinfo +1 -1
  42. package/package.json +3 -1
  43. package/scripts/build-site.ts +32 -15
  44. package/scripts/check-liburing.js +2 -2
  45. package/std/imm/list.yo +254 -0
  46. package/std/imm/map.yo +917 -0
  47. package/std/imm/set.yo +179 -0
  48. package/std/imm/sorted_map.yo +595 -0
  49. package/std/imm/sorted_set.yo +202 -0
  50. package/std/imm/string.yo +667 -0
  51. package/std/imm/vec.yo +456 -0
  52. package/std/prelude.yo +22 -5
  53. package/std/sync/channel.yo +92 -44
  54. package/std/sync/cond.yo +5 -1
  55. package/std/sync/mutex.yo +5 -1
  56. package/std/sync/once.yo +2 -1
  57. package/std/sync/rwlock.yo +2 -1
  58. package/std/sync/waitgroup.yo +2 -1
  59. package/out/types/src/codegen/exprs/arc.d.ts +0 -5
  60. package/out/types/src/evaluator/calls/arc.d.ts +0 -15
package/std/imm/vec.yo ADDED
@@ -0,0 +1,456 @@
1
+ //! Persistent immutable vector with efficient indexed access and append.
2
+ //!
3
+ //! `Vec(T)` is an immutable vector backed by `atomic object` for thread-safe
4
+ //! structural sharing. All mutations return new vectors, leaving the original
5
+ //! unchanged.
6
+ //!
7
+ //! All elements must implement `Send` to guarantee thread safety.
8
+ //!
9
+ //! # Examples
10
+ //!
11
+ //! ```rust
12
+ //! { Vec } :: import "std/imm/vec";
13
+ //!
14
+ //! v := Vec(i32).new();
15
+ //! v = v.push(i32(1)).push(i32(2)).push(i32(3));
16
+ //! assert((v.get(usize(0)).unwrap() == i32(1)), "first element");
17
+ //! assert((v.len() == usize(3)), "length is 3");
18
+ //! ```
19
+
20
+ { GlobalAllocator } :: import "../allocator.yo";
21
+ { malloc, free } :: GlobalAllocator;
22
+
23
+ /// Persistent immutable vector.
24
+ ///
25
+ /// Backed by a shared flat array with copy-on-write semantics.
26
+ /// All mutations create a new vector, sharing the backing buffer via
27
+ /// atomic reference counting when possible.
28
+ Vec :: (fn(comptime(T) : Type, where(T <: Send)) -> comptime(Type))(
29
+ atomic object(
30
+ _ptr : *(T),
31
+ _len : usize,
32
+ _cap : usize
33
+ )
34
+ );
35
+
36
+ impl(forall(T : Type), where(T <: Send), Vec(T), Dispose(
37
+ dispose : (fn(self: Self) -> unit)({
38
+ i := usize(0);
39
+ while (i < self._len), (i = (i + usize(1))), {
40
+ unsafe.drop((self._ptr &+ i).*);
41
+ };
42
+ free(.Some(*(void)(self._ptr)));
43
+ })
44
+ ));
45
+
46
+ /// Result of a pop operation.
47
+ PopResult :: (fn(comptime(T) : Type, where(T <: Send)) -> comptime(Type))(
48
+ struct(vec: Vec(T), value: Option(T))
49
+ );
50
+
51
+ impl(forall(T : Type), where(T <: Send), Vec(T),
52
+ /// Allocate raw buffer without creating an intermediate atomic object.
53
+ _raw_alloc : (fn(cap: usize) -> *(T))({
54
+ alloc_cap := cond(
55
+ (cap > usize(0)) => cap,
56
+ true => usize(1)
57
+ );
58
+ sz := (sizeof(T) * alloc_cap);
59
+ match(malloc(sz),
60
+ .Some(p) => *(T)(p),
61
+ .None => panic("imm.Vec: allocation failed")
62
+ )
63
+ }),
64
+
65
+ /// Copy elements element-by-element so RC-backed values duplicate correctly.
66
+ _copy_elems : (fn(
67
+ dst: *(T), src: *(T),
68
+ dst_offset: usize, src_offset: usize, count: usize
69
+ ) -> unit)({
70
+ i := usize(0);
71
+ while (i < count), (i = (i + usize(1))), {
72
+ consume((dst &+ (dst_offset + i)).* = (src &+ (src_offset + i)).*);
73
+ };
74
+ }),
75
+
76
+ /// Create a new empty vector.
77
+ new : (fn() -> Self)(
78
+ Self(_ptr: Self._raw_alloc(usize(4)), _len: usize(0), _cap: usize(4))
79
+ ),
80
+
81
+ /// Create a new empty vector with the given initial capacity.
82
+ with_capacity : (fn(cap: usize) -> Self)(
83
+ Self(_ptr: Self._raw_alloc(cap), _len: usize(0), _cap: cap)
84
+ ),
85
+
86
+ /// Number of elements in the vector.
87
+ len : (fn(self: Self) -> usize)(self._len),
88
+
89
+ /// Check if the vector is empty.
90
+ is_empty : (fn(self: Self) -> bool)(self._len == usize(0)),
91
+
92
+ /// Get the element at `idx`, or `.None` if out of bounds.
93
+ get : (fn(self: Self, idx: usize) -> Option(T))({
94
+ if((idx >= self._len), {
95
+ return .None;
96
+ });
97
+ .Some((self._ptr &+ idx).*)
98
+ }),
99
+
100
+ /// Return a new vector with the element at `idx` replaced by `val`.
101
+ /// Panics if `idx >= len`.
102
+ set : (fn(own(self): Self, idx: usize, val: T) -> Self)({
103
+ assert((idx < self._len), "imm.Vec.set: index out of bounds");
104
+ if((rc(self) == usize(1)), {
105
+ unsafe.drop((self._ptr &+ idx).*);
106
+ consume((self._ptr &+ idx).* = val);
107
+ return self;
108
+ });
109
+ new_ptr := Self._raw_alloc(self._len);
110
+ if((self._len > usize(0)), {
111
+ Self._copy_elems(new_ptr, self._ptr, usize(0), usize(0), self._len);
112
+ });
113
+ unsafe.drop((new_ptr &+ idx).*);
114
+ consume((new_ptr &+ idx).* = val);
115
+ result := Self(_ptr: new_ptr, _len: self._len, _cap: self._len);
116
+ unsafe.drop(self);
117
+ result
118
+ }),
119
+
120
+ /// Return a new vector with `val` appended.
121
+ push : (fn(own(self): Self, val: T) -> Self)({
122
+ if((rc(self) == usize(1)), {
123
+ if((self._len >= self._cap), {
124
+ new_cap := (self._cap * usize(2));
125
+ new_ptr := Self._raw_alloc(new_cap);
126
+ if((self._len > usize(0)), {
127
+ Self._copy_elems(new_ptr, self._ptr, usize(0), usize(0), self._len);
128
+ });
129
+ free(.Some(*(void)(self._ptr)));
130
+ self._ptr = new_ptr;
131
+ self._cap = new_cap;
132
+ });
133
+ consume((self._ptr &+ self._len).* = val);
134
+ self._len = (self._len + usize(1));
135
+ return self;
136
+ });
137
+ new_cap := cond(
138
+ (self._len < self._cap) => self._cap,
139
+ (self._cap == usize(0)) => usize(4),
140
+ true => (self._cap * usize(2))
141
+ );
142
+ new_ptr := Self._raw_alloc(new_cap);
143
+ if((self._len > usize(0)), {
144
+ Self._copy_elems(new_ptr, self._ptr, usize(0), usize(0), self._len);
145
+ });
146
+ consume((new_ptr &+ self._len).* = val);
147
+ result := Self(_ptr: new_ptr, _len: (self._len + usize(1)), _cap: new_cap);
148
+ unsafe.drop(self);
149
+ result
150
+ }),
151
+
152
+ /// Return the first element, or `.None` if empty.
153
+ first : (fn(self: Self) -> Option(T))({
154
+ if(self.is_empty(), {
155
+ return .None;
156
+ });
157
+ .Some(self._ptr.*)
158
+ }),
159
+
160
+ /// Return the last element, or `.None` if empty.
161
+ last : (fn(self: Self) -> Option(T))({
162
+ if(self.is_empty(), {
163
+ return .None;
164
+ });
165
+ .Some((self._ptr &+ (self._len - usize(1))).*)
166
+ }),
167
+
168
+ /// Return a new vector without the last element, and the removed element.
169
+ pop : (fn(own(self): Self) -> PopResult(T))({
170
+ if(self.is_empty(), {
171
+ return PopResult(T)(vec: self, value: .None);
172
+ });
173
+ val := (self._ptr &+ (self._len - usize(1))).*;
174
+ new_len := (self._len - usize(1));
175
+ if((rc(self) == usize(1)), {
176
+ self._len = new_len;
177
+ return PopResult(T)(vec: self, value: .Some(val));
178
+ });
179
+ new_ptr := Self._raw_alloc(self._cap);
180
+ if((new_len > usize(0)), {
181
+ Self._copy_elems(new_ptr, self._ptr, usize(0), usize(0), new_len);
182
+ });
183
+ new_vec := Self(_ptr: new_ptr, _len: new_len, _cap: self._cap);
184
+ unsafe.drop(self);
185
+ PopResult(T)(vec: new_vec, value: .Some(val))
186
+ }),
187
+
188
+ /// Return a new vector containing only elements in range [start, end).
189
+ slice : (fn(self: Self, start: usize, end: usize) -> Self)({
190
+ (actual_start : usize) = cond(
191
+ (start > self._len) => self._len,
192
+ true => start
193
+ );
194
+ (actual_end : usize) = cond(
195
+ (end > self._len) => self._len,
196
+ true => end
197
+ );
198
+ if((actual_start >= actual_end), {
199
+ return Self.new();
200
+ });
201
+ new_len := (actual_end - actual_start);
202
+ new_ptr := Self._raw_alloc(new_len);
203
+ Self._copy_elems(new_ptr, self._ptr, usize(0), actual_start, new_len);
204
+ Self(_ptr: new_ptr, _len: new_len, _cap: new_len)
205
+ }),
206
+
207
+ /// Return a new vector that is the concatenation of self and other.
208
+ concat : (fn(own(self): Self, other: Self) -> Self)({
209
+ total := (self._len + other._len);
210
+ if((rc(self) == usize(1)), {
211
+ if((total <= self._cap), {
212
+ if((other._len > usize(0)), {
213
+ Self._copy_elems(self._ptr, other._ptr, self._len, usize(0), other._len);
214
+ });
215
+ self._len = total;
216
+ return self;
217
+ });
218
+ new_cap := cond(
219
+ (total > (self._cap * usize(2))) => total,
220
+ true => (self._cap * usize(2))
221
+ );
222
+ new_ptr := Self._raw_alloc(new_cap);
223
+ if((self._len > usize(0)), {
224
+ Self._copy_elems(new_ptr, self._ptr, usize(0), usize(0), self._len);
225
+ });
226
+ if((other._len > usize(0)), {
227
+ Self._copy_elems(new_ptr, other._ptr, self._len, usize(0), other._len);
228
+ });
229
+ free(.Some(*(void)(self._ptr)));
230
+ self._ptr = new_ptr;
231
+ self._len = total;
232
+ self._cap = new_cap;
233
+ return self;
234
+ });
235
+ new_ptr := Self._raw_alloc(total);
236
+ if((self._len > usize(0)), {
237
+ Self._copy_elems(new_ptr, self._ptr, usize(0), usize(0), self._len);
238
+ });
239
+ if((other._len > usize(0)), {
240
+ Self._copy_elems(new_ptr, other._ptr, self._len, usize(0), other._len);
241
+ });
242
+ result := Self(_ptr: new_ptr, _len: total, _cap: total);
243
+ unsafe.drop(self);
244
+ result
245
+ }),
246
+
247
+ /// Return a new vector with elements reversed.
248
+ reverse : (fn(own(self): Self) -> Self)({
249
+ if((self._len <= usize(1)), {
250
+ return self;
251
+ });
252
+ if((rc(self) == usize(1)), {
253
+ left := usize(0);
254
+ right := (self._len - usize(1));
255
+ while (left < right), { left = (left + usize(1)); right = (right - usize(1)); }, {
256
+ tmp := (self._ptr &+ left).*;
257
+ consume((self._ptr &+ left).* = (self._ptr &+ right).*);
258
+ consume((self._ptr &+ right).* = tmp);
259
+ };
260
+ return self;
261
+ });
262
+ new_ptr := Self._raw_alloc(self._len);
263
+ i := usize(0);
264
+ while (i < self._len), (i = (i + usize(1))), {
265
+ (new_ptr &+ i).* = (self._ptr &+ ((self._len - usize(1)) - i)).*;
266
+ };
267
+ result := Self(_ptr: new_ptr, _len: self._len, _cap: self._len);
268
+ unsafe.drop(self);
269
+ result
270
+ }),
271
+
272
+ /// Apply a function to each element, producing a new vector.
273
+ map : (fn(forall(U : Type), self: Self, f: Impl(Fn(a: T) -> U), where(U <: Send)) -> Vec(U))({
274
+ new_ptr := Vec(U)._raw_alloc(self._len);
275
+ i := usize(0);
276
+ while (i < self._len), (i = (i + usize(1))), {
277
+ (new_ptr &+ i).* = f((self._ptr &+ i).*);
278
+ };
279
+ Vec(U)(_ptr: new_ptr, _len: self._len, _cap: self._len)
280
+ }),
281
+
282
+ /// Filter elements by a predicate, returning a new vector.
283
+ filter : (fn(self: Self, f: Impl(Fn(a: T) -> bool)) -> Self)({
284
+ new_ptr := Self._raw_alloc(self._len);
285
+ count := usize(0);
286
+ i := usize(0);
287
+ while (i < self._len), (i = (i + usize(1))), {
288
+ elem := (self._ptr &+ i).*;
289
+ if(f(elem), {
290
+ (new_ptr &+ count).* = elem;
291
+ count = (count + usize(1));
292
+ });
293
+ };
294
+ Self(_ptr: new_ptr, _len: count, _cap: self._len)
295
+ }),
296
+
297
+ /// Left fold over elements.
298
+ fold : (fn(forall(U : Type), self: Self, init: U, f: Impl(Fn(acc: U, elem: T) -> U)) -> U)({
299
+ (acc : U) = init;
300
+ i := usize(0);
301
+ while (i < self._len), (i = (i + usize(1))), {
302
+ acc = f(acc, (self._ptr &+ i).*);
303
+ };
304
+ acc
305
+ }),
306
+
307
+ /// Check if any element satisfies the predicate.
308
+ any : (fn(self: Self, f: Impl(Fn(a: T) -> bool)) -> bool)({
309
+ i := usize(0);
310
+ (found : bool) = false;
311
+ while ((i < self._len) && !(found)), (i = (i + usize(1))), {
312
+ if(f((self._ptr &+ i).*), {
313
+ found = true;
314
+ });
315
+ };
316
+ found
317
+ }),
318
+
319
+ /// Check if all elements satisfy the predicate.
320
+ all : (fn(self: Self, f: Impl(Fn(a: T) -> bool)) -> bool)({
321
+ i := usize(0);
322
+ (ok : bool) = true;
323
+ while ((i < self._len) && ok), (i = (i + usize(1))), {
324
+ if(!(f((self._ptr &+ i).*)), {
325
+ ok = false;
326
+ });
327
+ };
328
+ ok
329
+ }),
330
+
331
+ /// Find the first element satisfying the predicate.
332
+ find : (fn(self: Self, f: Impl(Fn(a: T) -> bool)) -> Option(T))({
333
+ i := usize(0);
334
+ (result : Option(T)) = .None;
335
+ while ((i < self._len) && result.is_none()), (i = (i + usize(1))), {
336
+ elem := (self._ptr &+ i).*;
337
+ if(f(elem), {
338
+ result = .Some(elem);
339
+ });
340
+ };
341
+ result
342
+ }),
343
+
344
+ /// Return the index of the first element equal to `val`, or `.None`.
345
+ index_of : (fn(self: Self, val: T, where(T <: Eq(T))) -> Option(usize))({
346
+ i := usize(0);
347
+ (result : Option(usize)) = .None;
348
+ while ((i < self._len) && result.is_none()), (i = (i + usize(1))), {
349
+ if(((self._ptr &+ i).* == val), {
350
+ result = .Some(i);
351
+ });
352
+ };
353
+ result
354
+ }),
355
+
356
+ /// Check if the vector contains `val`.
357
+ contains : (fn(self: Self, val: T, where(T <: Eq(T))) -> bool)(
358
+ self.index_of(val).is_some()
359
+ ),
360
+
361
+ /// Return a new vector with duplicate elements removed (preserves first occurrence).
362
+ dedup : (fn(own(self): Self, where(T <: Eq(T))) -> Self)({
363
+ if((self._len <= usize(1)), {
364
+ return self;
365
+ });
366
+ if((rc(self) == usize(1)), {
367
+ count := usize(1);
368
+ i := usize(1);
369
+ while (i < self._len), (i = (i + usize(1))), {
370
+ elem := (self._ptr &+ i).*;
371
+ (found : bool) = false;
372
+ j := usize(0);
373
+ while ((j < count) && !(found)), (j = (j + usize(1))), {
374
+ if(((self._ptr &+ j).* == elem), {
375
+ found = true;
376
+ });
377
+ };
378
+ if(!(found), {
379
+ if((count != i), {
380
+ consume((self._ptr &+ count).* = elem);
381
+ });
382
+ count = (count + usize(1));
383
+ });
384
+ };
385
+ self._len = count;
386
+ return self;
387
+ });
388
+ new_ptr := Self._raw_alloc(self._len);
389
+ count := usize(0);
390
+ i := usize(0);
391
+ while (i < self._len), (i = (i + usize(1))), {
392
+ elem := (self._ptr &+ i).*;
393
+ (found : bool) = false;
394
+ j := usize(0);
395
+ while ((j < count) && !(found)), (j = (j + usize(1))), {
396
+ if(((new_ptr &+ j).* == elem), {
397
+ found = true;
398
+ });
399
+ };
400
+ if(!(found), {
401
+ (new_ptr &+ count).* = elem;
402
+ count = (count + usize(1));
403
+ });
404
+ };
405
+ result := Self(_ptr: new_ptr, _len: count, _cap: self._len);
406
+ unsafe.drop(self);
407
+ result
408
+ }),
409
+
410
+ /// Zip two vectors together using a combining function.
411
+ zip_with : (fn(forall(U : Type, V : Type), self: Self, other: Vec(U), f: Impl(Fn(a: T, b: U) -> V), where(U <: Send, V <: Send)) -> Vec(V))({
412
+ min_len := cond(
413
+ (self._len < other._len) => self._len,
414
+ true => other._len
415
+ );
416
+ new_ptr := Vec(V)._raw_alloc(min_len);
417
+ i := usize(0);
418
+ while (i < min_len), (i = (i + usize(1))), {
419
+ (new_ptr &+ i).* = f((self._ptr &+ i).*, other.get(i).unwrap());
420
+ };
421
+ Vec(V)(_ptr: new_ptr, _len: min_len, _cap: min_len)
422
+ }),
423
+
424
+ /// Create a vector from a slice, copying all elements.
425
+ from_slice : (fn(s: Slice(T)) -> Self)({
426
+ slen := s.len();
427
+ cap := cond(
428
+ (slen > usize(0)) => slen,
429
+ true => usize(4)
430
+ );
431
+ new_ptr := Self._raw_alloc(cap);
432
+ if((slen > usize(0)), {
433
+ Self._copy_elems(new_ptr, s.ptr(), usize(0), usize(0), slen);
434
+ });
435
+ Self(_ptr: new_ptr, _len: slen, _cap: cap)
436
+ })
437
+ );
438
+
439
+ /// Eq trait for Vec(T) — element-wise equality.
440
+ impl(forall(T : Type), where(T <: (Send, Eq(T))), Vec(T), Eq(Vec(T))(
441
+ (==) : (fn(lhs: Self, rhs: Self) -> bool)({
442
+ if((lhs._len != rhs._len), {
443
+ return false;
444
+ });
445
+ i := usize(0);
446
+ (equal : bool) = true;
447
+ while ((i < lhs._len) && equal), (i = (i + usize(1))), {
448
+ if(((lhs._ptr &+ i).* != (rhs._ptr &+ i).*), {
449
+ equal = false;
450
+ });
451
+ };
452
+ equal
453
+ })
454
+ ));
455
+
456
+ export Vec, PopResult;
package/std/prelude.yo CHANGED
@@ -4077,6 +4077,8 @@ StructKind :: enum(
4077
4077
  Struct,
4078
4078
  /// Reference-counted object.
4079
4079
  Object,
4080
+ /// Atomic reference-counted object.
4081
+ AtomicObject,
4080
4082
  /// Single-field newtype wrapper.
4081
4083
  NewType
4082
4084
  );
@@ -4222,7 +4224,6 @@ TypeInfo :: enum(
4222
4224
  Function(info : FunctionInfo),
4223
4225
  Ptr(pointee : Type),
4224
4226
  Iso(child : Type),
4225
- Arc(child : Type),
4226
4227
  Dyn(
4227
4228
  required_traits : ComptimeList(TraitInfo),
4228
4229
  negative_traits : ComptimeList(TraitInfo)
@@ -5483,12 +5484,28 @@ impl(forall(T : Type), Iso(T),
5483
5484
  export (^);
5484
5485
 
5485
5486
  /// === Arc ===
5486
- arc :: (fn(forall(T : Type), own(value) : T) -> Arc(T))
5487
- Arc(T)(value)
5487
+ /// Arc an atomically reference-counted, thread-safe container for a single value.
5488
+ ///
5489
+ /// Use `arc(value)` to allocate. Access the inner value with `a.*`.
5490
+ ///
5491
+ /// # Example
5492
+ /// ```rust
5493
+ /// a := arc(i32(42));
5494
+ /// assert((a.* == i32(42)), "inner value is 42");
5495
+ /// ```
5496
+ Arc :: (fn(comptime(V) : Type, where(V <: (Send, Acyclic))) -> comptime(Type))
5497
+ atomic object(
5498
+ (*) : V
5499
+ )
5488
5500
  ;
5489
- impl(forall(T : Type), Arc(T), Send());
5501
+ /// Allocate a value inside an Arc, returning an `Arc(V)`.
5502
+ arc :: (fn(forall(V : Type), own(value) : V, where(V <: (Send, Acyclic))) -> Arc(V))
5503
+ Arc(V)(value)
5504
+ ;
5505
+
5506
+ impl(forall(T : Type), where(T <: (Send, Acyclic)), Arc(T), Send());
5490
5507
 
5491
- export arc;
5508
+ export Arc, arc;
5492
5509
 
5493
5510
  /// === MaybeUninit ===
5494
5511
  extern "Yo",