Files
bux-lang/examples/move_field_partial.bux
dimgigov fe3b1e8b6a
ci / build (ubuntu) (push) Has been cancelled
ci / unit + fmt (push) Has been cancelled
ci / examples (push) Has been cancelled
ci / goldens + tools (push) Has been cancelled
ci / apps (push) Has been cancelled
ci / selfhost smoke (push) Has been cancelled
ci / macos smoke (push) Has been cancelled
ci / windows smoke (push) Has been cancelled
ci / CI gate (push) Has been cancelled
selfhost-loop / bootstrap determinism (push) Has been cancelled
feat: macros (multi-rep, hygiene), Drop field-move, lean multi-OS CI
Sessions 56–69: declarative macro! with rep/zip/literal/block and
unhygienic var $name binders; partial field-move skip Drop; @[Release]
polish; LSP type hierarchy; CI Nim cache + lean macOS + Windows smoke.
2026-07-20 17:19:46 +03:00

64 lines
1.8 KiB
Plaintext

// Session 68 — partial field moves out of @[Drop] parents
// `return bag.items` / `let x = bag.items` must skip Bag_Drop (no double-free).
// Non-droppable fields (`bag.tag`) do not mark the parent moved.
import Std::Io::{PrintLine};
import Std::Array::{Array, Array_New, Array_Push, Array_Len, Array_Get};
import Std::String::{String_FromInt, String_Concat};
import Std::Test::{Test_AssertTrue, Test_Pass};
@[Drop]
struct Bag {
items: Array<int>,
tag: int
}
func Bag_Drop(self: *Bag) {
Array_Drop<int>(&self.items);
}
// Move droppable field out via return
func TakeItems() -> Array<int> {
var items: Array<int> = Array_New<int>(4);
Array_Push<int>(&items, 42);
let bag: Bag = Bag { items: items, tag: 7 };
return bag.items;
}
// Move droppable field via let; read non-droppable tag after
func PeekTagAndTake() -> int {
var items: Array<int> = Array_New<int>(2);
Array_Push<int>(&items, 1);
let bag: Bag = Bag { items: items, tag: 99 };
let moved: Array<int> = bag.items;
let t: int = bag.tag;
discard Array_Len<int>(&moved);
return t;
}
// Whole-struct return still moves bag (existing path)
func MakeBag() -> Bag {
var items: Array<int> = Array_New<int>(2);
Array_Push<int>(&items, 10);
Array_Push<int>(&items, 20);
let bag: Bag = Bag { items: items, tag: 3 };
return bag;
}
func Main() -> int {
let taken: Array<int> = TakeItems();
Test_AssertTrue(Array_Len<int>(&taken) == 1);
Test_AssertTrue(Array_Get<int>(&taken, 0) == 42);
let tag: int = PeekTagAndTake();
Test_AssertTrue(tag == 99);
let b: Bag = MakeBag();
Test_AssertTrue(Array_Len<int>(&b.items) == 2);
Test_AssertTrue(Array_Get<int>(&b.items, 0) == 10);
Test_AssertTrue(b.tag == 3);
PrintLine(String_Concat("ok=", String_FromInt(tag as int64)));
Test_Pass("move_field_partial");
return 0;
}