Thread overview
[Issue 15413] Foreach over range with @disable this(this) doesn't work
[Issue 15413] Foreach over range with @disable this doesn't work
Jun 30, 2016
ZombineDev
Jun 30, 2016
ZombineDev
Jun 30, 2016
ZombineDev
Sep 14, 2016
Ali Cehreli
Oct 25, 2019
Jonathan M Davis
Oct 25, 2019
Jonathan M Davis
Nov 10, 2019
Johannes Pfau
Dec 17, 2022
Iain Buclaw
June 30, 2016
https://issues.dlang.org/show_bug.cgi?id=15413

ZombineDev <petar.p.kirov@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |petar.p.kirov@gmail.com

--
June 30, 2016
https://issues.dlang.org/show_bug.cgi?id=15413

--- Comment #1 from ZombineDev <petar.p.kirov@gmail.com> ---
I wonder if the solution could be as simple* as changing the lowering to:

for ( ; !ir.empty; ir.popFront()) {
    auto v = __r.front;
}

That way foreach will work with truly input-only ranges (such as ones with
@disabled this(this)) and the users could optionally insert a .save call, if
needed, when they're working with forward ranges.

If this is an unacceptable breaking change, we could use the new lowering only when the postblit is disabled.

* I'm not very familiar the compiler internals, so I have no idea if this would be actually simple in practice.

--
June 30, 2016
https://issues.dlang.org/show_bug.cgi?id=15413

--- Comment #2 from ZombineDev <petar.p.kirov@gmail.com> ---
I meant:

foreach (v; ir)
{
    // user code
}

// =====v====

for ( ; !ir.empty; ir.popFront())
{
    auto v = ir.front;
    // user code
}

--
September 14, 2016
https://issues.dlang.org/show_bug.cgi?id=15413

Ali Cehreli <acehreli@yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |acehreli@yahoo.com
            Summary|Foreach over range with     |Foreach over range with
                   |@disable this doesn't work  |@disable this(this) doesn't
                   |                            |work

--
October 25, 2019
https://issues.dlang.org/show_bug.cgi?id=15413

Jonathan M Davis <issues.dlang@jmdavisProg.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |issues.dlang@jmdavisProg.co
                   |                            |m
           Severity|normal                      |enhancement

--- Comment #3 from Jonathan M Davis <issues.dlang@jmdavisProg.com> ---
foreach specifically copies the range that it's given. If it didn't, then iterating over a dynamic array would consume it. It does unfortunately mean that whether a range is consumed or not depends on whether it's a reference type, pseudo-reference type, or value type, but that's a general problem with copying ranges. Either way, changing how foreach worked would break a lot of code.

So, in order for this to work, ranges which are non-copyable would have to be treated differently from other ranges when using foreach. However, considering that almost all range-based code copies ranges, I find it hard to believe that having a non-copyable range makes much sense. And if you specifically are looking for foreach to work, you should just be able to use opApply instead of making the object a range.

--
October 25, 2019
https://issues.dlang.org/show_bug.cgi?id=15413

--- Comment #4 from Jonathan M Davis <issues.dlang@jmdavisProg.com> ---
I would note that this issue has some similarities to issue #14478, but 14478 deals with elements which are non-copyable, whereas this deals with ranges which are non-copyable (though a range with non-copyable elements would also be non-copyable if the elements were contained directly in the range).

--
November 10, 2019
https://issues.dlang.org/show_bug.cgi?id=15413

Johannes Pfau <johannespfau@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |johannespfau@gmail.com

--- Comment #5 from Johannes Pfau <johannespfau@gmail.com> ---
> However, considering that almost all range-based code copies ranges, I find it hard to believe that having a non-copyable range makes much sense.

All implementations of Unique however work by disabling this(this), which means you can't foreach over unique ranges.

One place where this would be really idiomatic is this: I'd like to return a Range which maps d2sqlite3 result rows to the deserialized types. However, in SQLite you have to explicitly keep track of & finalize the statement which was use to generate the query. Ideally you could do just this:

foreach(value; db.query!Commit(/*sha =*/ "abcd") {}

and when the range goes out of scope it finalizes the statement. Because of foreachs implicit copying, you now have to use reference counting instead...

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=15413

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P4

--
December 13
https://issues.dlang.org/show_bug.cgi?id=15413

--- Comment #6 from dlangBugzillaToGithub <robert.schadek@posteo.de> ---
THIS ISSUE HAS BEEN MOVED TO GITHUB

https://github.com/dlang/dmd/issues/19076

DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB

--