www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 14741] New: problems with template overload resolution

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

          Issue ID: 14741
           Summary: problems with template overload resolution
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: schuetzm gmx.net

Based on https://issues.dlang.org/show_bug.cgi?id=14735#c4

------------------------------------------------------------------------

    template isInputRange(R) {   
        enum bool isInputRange = !is(R : U[n], U, size_t n);
    }

    ptrdiff_t indexOf(Range)(Range s, dchar c, bool cs = true) // A
        if (isInputRange!Range)
    {
        return 0;
    }

    static if(1)
    ptrdiff_t indexOf(T, size_t n)(ref T[n] s, dchar c, bool cs = true) // B
        if (!isInputRange!(T[n]))
    {
        return 0;
    }

    static if(0)
    ptrdiff_t indexOf(T)(ref T s, dchar c, bool cs = true) // C
        if (is(T : U[n], U, size_t n))
    {
        return 0;
    }

    void main() {       
        char[10] fixedSizeArray = "0123456789";
        pragma(msg, isInputRange!(typeof(fixedSizeArray)));
        assert(indexOf(fixedSizeArray, '2') == 2); // line 30
        pragma(msg, isInputRange!(typeof(fixedSizeArray[])));
        assert(indexOf(fixedSizeArray[], '2') == 2); // line 32
    }

------------------------------------------------------------------------

The above code fails to compile with current DMD:

false
true
xx.d(32): Error: template xx.indexOf cannot deduce function from argument types
!()(char[], char), candidates are:
xx.d(6):        xx.indexOf(Range)(Range s, dchar c, bool cs = true) if
(isInputRange!Range)
xx.d(13):        xx.indexOf(T, ulong n)(ref T[n] s, dchar c, bool cs = true) if
(!isInputRange!(T[n]))

Clearly, the template constraint of overload (A) matches, as witnessed by
second pragma(msg).

However, compilation succeeds if (C) is enabled instead of (B).

Further modification (beginning with the original code, (B) is enabled, (C) is
disabled) reveals:

When the `cs` parameter of (B) is removed completely, the error message
becomes:

xx.d(32): Error: xx.indexOf called with argument types (char[], char) matches
both:
xx.d(6):     xx.indexOf!(char[]).indexOf(char[] s, dchar c, bool cs)
and:
xx.d(13):     xx.indexOf!(char, 10LU).indexOf(ref char[10] s, dchar c)

This is clearly wrong. `char[]` doesn't match overload (B).

Furthermore, when the `cs` parameter of (A) is also removed, it suddenly
compiles successfully.

--
Jun 27 2015