www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 12510] New: Templated overload ignored

reply d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12510

           Summary: Templated overload ignored
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: regression
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: jmdavisProg gmx.com


--- Comment #0 from Jonathan M Davis <jmdavisProg gmx.com> 2014-04-03 00:26:37
PDT ---
This code results in infinite recursion:

class C
{
    bool foo(C rhs)
    {
        return false;
    }
}

bool foo(T, U)(T lhs, U rhs)
    if (is(T == class) && is(U == class) &&
        is(typeof(lhs.foo(rhs)) == bool) &&
        is(typeof(rhs.foo(lhs)) == bool))
{
    return true;
}

bool foo()(const C lhs, const C rhs)
{
    return foo(cast()lhs, cast()rhs);
}

void main()
{
    const C a = new C;
    const C b = new C;
    auto d = foo(a, b);
}

And whether a and b are const or not doesn't matter. The first overload is
simply never called. It always calls the second overload. And making it so that
the second overload isn't templatized has no effect. It used to be that this
would compile, because it was working in this pull request:

https://github.com/D-Programming-Language/druntime/pull/459

whereas that pull request now results in infinite recursion.

I'd have to try it on several older versions of dmd though to figure out when
it broke, but this definitely worked before. My first guess is that it broke
when it was fixed so that templated and non-template functions could be
overloaded.

The fact that the first overload fails with const objects should force them to
use the second overload (because C.foo isn't const), whereas if they're not
const, then the first should match better than the second. And to make matters
worse, if I change the code to

class C
{
    bool foo(C rhs)
    {
        return false;
    }
}

bool foo(T, U)(T lhs, U rhs)
{
    return true;
}

bool foo()(const C lhs, const C rhs)
{
    return foo(cast()lhs, cast()rhs);
}

void main()
{
    const C a = new C;
    const C b = new C;
    auto d = foo(a, b);
}


it still compiles with the same result, whereas it _should_ result in a
compilation error due to ambiguity, because both functions match equally well.
Instead, the second function is always called, whether it's templatized or not
and whether the arguments are const or not.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 03 2014
next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12510


Martin Nowak <code dawg.eu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |code dawg.eu


--- Comment #1 from Martin Nowak <code dawg.eu> 2014-04-03 01:16:47 PDT ---
I think this might be the result of bug 1528. Not sure, but I think the empty
template arguments are matched with MATCHexact, just like a plain function
declaration. And subsequently converting both function arguments to const is
deemed a better match than the template.

You can use this instead.

bool foo (const C lhs, const C rhs)
{
    foo!(C, C)(cast()lhs, cast()rhs);
}

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 03 2014
prev sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12510


Kenji Hara <k.hara.pg gmail.com> changed:

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


--- Comment #2 from Kenji Hara <k.hara.pg gmail.com> 2014-04-03 01:36:24 PDT ---
(In reply to comment #1)
 I think this might be the result of bug 1528. Not sure, but I think the empty
 template arguments are matched with MATCHexact, just like a plain function
 declaration. And subsequently converting both function arguments to const is
 deemed a better match than the template.
 
 You can use this instead.
 
 bool foo (const C lhs, const C rhs)
 {
     foo!(C, C)(cast()lhs, cast()rhs);
 }

Yes, this is correct result caused by fixing issue 1528. Another way is to supply "specialized foo" for const C parameters, like as: bool foo(T:Object, U:Object)(const T lhs, const U rhs) { return foo(cast()lhs, cast()rhs); } -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 03 2014