www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 18898] New: std.algorithm.iteration : each & overloads of

https://issues.dlang.org/show_bug.cgi?id=18898

          Issue ID: 18898
           Summary: std.algorithm.iteration : each & overloads of opApply
                    don't play well together
           Product: D
           Version: D2
          Hardware: x86
                OS: Mac OS X
            Status: NEW
          Severity: major
          Priority: P1
         Component: phobos
          Assignee: nobody puremagic.com
          Reporter: sascha.orlov gmail.com

Given more opApply overloads with the same amount of delegate arguments,
std.algorithm.iteration.each works only with the first defined. 

Given 

´´´
enum p = 1; 

void main()
{
    import std.algorithm : each; 
    auto c = Container(); 

    static if(p == 1)
    {
        c.each!((string a) => {}); // why this line does not compile?
    }
    else static if(p == 2)
    {
        c.each!((int a, string b) => {}); 
    }
}

struct Container
{
    static if(p == 1)
    {
        int opApply(int delegate(string, ref int) operations){ assert(0); }
        int opApply(int delegate(int) operations){ assert(0); }
        int opApply(int delegate(ref string) operations){ assert(0); }
        //int opApply(int delegate(ref int, ref string) operations){ assert(0);
}
    }
    else static if(p == 2)
    {
        int opApply(int delegate(string, ref int) operations){ assert(0); }
        //int opApply(int delegate(int) operations){ assert(0); }
        //int opApply(int delegate(ref string) operations){ assert(0); }
        int opApply(int delegate(ref int, ref string) operations){ assert(0); }
    }
}
´´´

There are two problems with such a construction.
Case 1: 
Trying to use each, with many opApply overloads, in case, when there is another
one before them defined. Then, all the applicable overloads are hidden. 
Error message: 

/usr/local/opt/dmd/include/dlang/dmd/std/algorithm/iteration.d(966,21): Error:
function literal `__lambda1(string a)` is not callable using argument types
`(string, int)`
source/app.d(10,4): Error: template instance
`std.algorithm.iteration.each!(function (string a) => ()
{
}
).each!(Container)` error instantiating
dmd failed with exit code 1.

Case 2: 
If there are more then one opApply overloads defined, only the first is
accessible by each. Even explicitly defining argument types inside the lambda
does not help. 
Error message: 

/usr/local/opt/dmd/include/dlang/dmd/std/algorithm/iteration.d(966,21): Error:
function literal `__lambda1(int a, string b)` is not callable using argument
types `(string, int)`
/usr/local/opt/dmd/include/dlang/dmd/std/algorithm/iteration.d(966,21):       
cannot pass argument `_param_0` of type `string` to parameter `int a`
source/app.d(14,7): Error: template instance
`std.algorithm.iteration.each!(function (int a, string b) => ()
{
}
).each!(Container)` error instantiating
dmd failed with exit code 1.


All possible foreach statements work as expected. 

See also 
https://forum.dlang.org/post/kyzwhjgjhaolvflstkqd forum.dlang.org

--
May 23 2018