On Sunday, 17 January 2021 at 12:15:00 UTC, Fynn Schröder wrote:
I'm puzzled why RefCounted and foreach do not work well together, i.e.:

```
auto range = refCounted(nonCopyableRange); // ok
foreach(e; range) // Error: struct is not copyable because it is annotated with @disable
    // do something
```

See https://run.dlang.io/is/u271nK for a full example where I also compared the foreach compiler rewrite and the manual rewrite of foreach to a simple for loop.

Somehow foreach makes a copy of the internal payload of RefCounted (run the example and look at the address of the payload/range).
Is this a bug and is there any way around it?


foreach first copy range and then iterate over it.
RefCounted is not range, foreach directly copy element of RefCounted.

//this code is equivalent to yours
void notOk() {
        auto r = refCounted(Range());
        writeln("before ", r.front);
        Range tmp_r = r;
        foreach (i; tmp_r)
                writeln("loop ", i);
        writeln("after ", r.front);
    assert(r.i == 3, "r.ri != 3");
}

You need something like RefCountedRange with methods popFront, front, empty.

Reply via email to