Lyricdev
GitHub

LYR-SEM0172

a 'mut fn' generator on a value type changes a copy

warning · spec 10-concurrency · lint generator-copies-this, group correctness, warn unless said

A non-static mut fn method of a struct or enum is a generator: it returns Coroutine<…> and yields.

Explanation

A generator holds its receiver as a call holds an argument, and a value type is copied into it. What the body writes to this changes the copy; the caller's value stays as it was. That is allowed, and said where the method is declared.

Yield what changed instead of writing it to this, or make the type a class, whose object the generator shares with the caller.

Wrong

struct Counter {
    var n: int,

    mut fn count(): Coroutine<int> {
        this.n += 1;
        yield this.n;
    }
}

fn main(): void {
    var c = Counter { n = 0 };
    for (x in c.count()) { assert(x == 1); }
}
class Counter {
    var n: int,

    mut fn count(): Coroutine<int> {
        this.n += 1;
        yield this.n;
    }
}

fn main(): void {
    let c = Counter { n = 0 };
    for (x in c.count()) { assert(x == 1); }
}