// Invoking a Closure-typed struct field as `self.field()` from a
// method whose receiver is `*Self`. The field access must auto-deref
// the pointer before extracting the closure value.

#import "modules/std.sx";

Holder :: struct {
    cb: Closure() = ---;
    has: bool = false;

    set :: (self: *Holder, fn: Closure()) {
        self.cb = fn;
        self.has = true;
    }

    // Direct invocation through *self.
    call_direct :: (self: *Holder) {
        if self.has == false { return; }
        self.cb();
    }

    // Hoist-then-call form — must agree with the direct form.
    call_hoisted :: (self: *Holder) {
        if self.has == false { return; }
        fn := self.cb;
        fn();
    }
}

ticks : i32 = 0;

main :: () -> i32 {
    h : Holder = .{};
    h.set(() => { ticks += 1; });

    h.call_direct();
    h.call_hoisted();

    return ticks;
}
