Thread overview
[Issue 20009] isForwardRange doesn't work with alias range this or inheritance
Jun 28, 2019
Dlang Bot
Jun 29, 2019
shove
Jul 06, 2019
shove
Jul 08, 2019
Ali Ak
Jul 08, 2019
shove
Dec 17, 2022
Iain Buclaw
June 28, 2019
https://issues.dlang.org/show_bug.cgi?id=20009

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull

--- Comment #1 from Dlang Bot <dlang-bot@dlang.rocks> ---
@shove70 created dlang/phobos pull request #7095 "Fix issue 20009 - isForwardRange doesn't work with alias range this o…" fixing this issue:

- Fix issue 20009 - isForwardRange doesn't work with alias range this or inheritance

https://github.com/dlang/phobos/pull/7095

--
June 29, 2019
https://issues.dlang.org/show_bug.cgi?id=20009

shove <shove@163.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |shove@163.com

--- Comment #2 from shove <shove@163.com> ---
(In reply to Ali Ak from comment #0)
> struct FR {
>   bool empty = true;
>   void popFront() {}
>   auto front() { return 0; }
>   FR save() { return this; }
> }
> 
> struct S {
>   FR range;
>   alias range this;
> }
> 
> pragma(msg, isInputRange!S); // true
> pragma(msg, isForwardRange!S); // false
> 
> It's because isForwardRange is defined as:
> 
> isInputRange!R && is(ReturnType!((R r) => r.save) == R);
> 
> But it should be:
> 
> isInputRange!R && is(R : ReturnType!((R r) => r.save));
> 
> The same thing will happen if you try an inherit from an interface that is a forward range, and if the save function returns the base class it will fail.


Since struct S inherits from struct FR, I think it should have the
characteristics of ForwardRange too.
But unfortunately, after I do it according to your idea, although struct S
passed the isForwardRange test, it caused a lot of compilation errors in the
entire Phobos, including function code and assertions in unit tests. The
reasons for this include at least the following:

1. is(T1 : T2) is somewhat different than what I have understood before:
    is(R!(int) : int[]) will pass the test, obviously this is not what is
expected here.
2. Too many templates and APIs assume that the return type of save() is exactly
equal to itself, and cannot be equal to the base class. It is equal to the base
class that will overturn these assumptions and cause the program to fail or
assert the failure. Such as:

    std.std.algorithm.searching.d line 3359:
    Range least = range.save;

    Obviously, the base type cannot be assigned to a derived type, and this
assumption has limited the expectations of this issue.

Therefore, if you want isForwardRange to support derived types, then Phobos has too many places to change, and the workload is a bit large.

It might be a good idea to add a new template to the existing one that is specifically designed to test derived types with ForwardRange attributes:

template isDerivedForwardRange(R)
{
    static if (isInputRange!R && is(typeof((R r) => r.save) RT))
        enum bool isForwardRange = !is(R == ReturnType!RT) && is(R :
ReturnType!RT);
    else
        enum bool isForwardRange = false;
}

But I don't know if it has practical use.

--
July 06, 2019
https://issues.dlang.org/show_bug.cgi?id=20009

shove <shove@163.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |INVALID

--
July 08, 2019
https://issues.dlang.org/show_bug.cgi?id=20009

Ali Ak <ali.akhtarzada@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|INVALID                     |---

--- Comment #3 from Ali Ak <ali.akhtarzada@gmail.com> ---
Why mark this invalid? Are interfaces and alias this'd ranges not supposed to work?

--
July 08, 2019
https://issues.dlang.org/show_bug.cgi?id=20009

--- Comment #4 from shove <shove@163.com> ---
(In reply to Ali Ak from comment #3)
> Why mark this invalid? Are interfaces and alias this'd ranges not supposed to work?

Misread the title and misoperate it. I'm sorry.

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

Iain Buclaw <ibuclaw@gdcproject.org> changed:

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

--