module 0x2::A { use std::signer; struct R1 has key { f: T } fun mutate_r1(addr: address) acquires R1 { borrow_global_mut>(addr).f = true; } spec mutate_r1 { ensures global>(addr) == update_field(old(global>(addr)), f, true); } #[test(s=@0x2)] public fun check_mem_label_set(s: &signer) acquires R1 { let a = signer::address_of(s); let r = R1 { f: false }; move_to(s, r); mutate_r1(a); spec { assert global>(a).f; }; } struct R2 has key { f1: T, f2: T } fun mutate_r2(addr: address) acquires R2 { let r = borrow_global_mut>(addr); let f = r.f1; r.f1 = r.f2; r.f2 = f; } spec mutate_r2 { ensures old(spec_get_r2(addr).f1) == spec_get_r2(addr).f2; ensures old(spec_get_r2(addr).f2) == spec_get_r2(addr).f1; } spec fun spec_get_r2(addr: address): R2 { global>(addr) } #[test(s=@0x2)] public fun check_mem_label_swap(s: &signer) acquires R2 { let a = signer::address_of(s); let r = R2 { f1: true, f2: false }; move_to(s, r); mutate_r2(a); spec { assert !global>(a).f1; assert global>(a).f2; }; } }