//# publish module 0x1.Coin { struct Coin { value: u64 } public value(c: &Self.Coin): u64 { label b0: return *&move(c).Coin::value; } public zero(): Self.Coin { label b0: return Coin { value: 0 }; } public destroy_zero(c: Self.Coin) { label b0: Coin {} = move(c); assert(() == 0, 42); return; } } //# publish module 0x42.MoneyHolder { import 0x1.Coin; struct T { money: Coin.Coin } public new(m: Coin.Coin): Self.T { label b0: return T{ money: move(m) }; } public value(this :&Self.T): u64 { let ref: &Coin.Coin; let val: u64; label b0: ref = ©(this).T::money; val = Coin.value(move(ref)); _ = move(this); return move(val); } public destroy_t(t: Self.T) { let money: Coin.Coin; label b0: T{ money } = move(t); Coin.destroy_zero(move(money)); return; } } //# publish module 0x42.Bar { struct T has drop {baz: u64} public new(m: u64): Self.T { label b0: return T{baz: move(m)}; } public value(this: &Self.T): u64 { let ref: &u64; label b0: ref = &move(this).T::baz; return *move(ref); } } //# run import 0x42.MoneyHolder; import 0x42.Bar; import 0x1.Coin; main() { let coin: Coin.Coin; let money_holder: MoneyHolder.T; let money_holder_ref: &MoneyHolder.T; let value: u64; let v: u64; let bar: Bar.T; let bar_ref: &Bar.T; let v2: u64; label b0: coin = Coin.zero(); money_holder = MoneyHolder.new(move(coin)); money_holder_ref = &money_holder; value = MoneyHolder.value(move(money_holder_ref)); assert(copy(value) == 0, 42); MoneyHolder.destroy_t(move(money_holder)); v = 1; bar = Bar.new(copy(v)); bar_ref = &bar; v2 = Bar.value(move(bar_ref)); assert(copy(v) == copy(v2), 42); return; }