Thread overview
[Issue 5896] New: const overload with Template function
Apr 27, 2011
Kenji Hara
[Issue 5896] const overload matching is succumb to template parameter one
Apr 29, 2011
Don
Apr 29, 2011
Kenji Hara
Jul 14, 2011
Kenji Hara
Apr 23, 2012
SomeDude
Apr 24, 2012
Kenji Hara
April 27, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5896

           Summary: const overload with Template function
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: k.hara.pg@gmail.com


--- Comment #0 from Kenji Hara <k.hara.pg@gmail.com> 2011-04-27 01:54:51 PDT ---
This code doesn't compile when -version=expect.
----
struct X
{
  version(expect)
  {
    T opCast(T)()      { return 10; }  // 1a
    T opCast(T)()const { return 11; }  // 1b
  }
  else
  {
    T opCast(T:int)()      { return 10; }  // 2a
    T opCast(T:int)()const { return 11; }  // 2b
  }
}
void main()
{
  auto xm = X();
  auto xc = const(X)();
  assert(cast(int)xm == 10);
  assert(cast(int)xc == 11);
}
----
test.d(18): Error: template test.X.opCast(T) opCast(T) matches more than one
template declaration, test.d(5):opCast(T) and test.d(6):opCast(T)
----

Template function matching processed by template.c
TemplateDeclaration::deduceFunctionTemplateMatch(), and
const overload matching is more priority than template parameter one.

T:int(2a,2b) is more specialized from T(1a,1b), then first priority is
MATCHexact and second is MATCHconvert.

Next, currently const overload matching returns MATCHconst or not, but the priority of T(MATCHconvert) is less than MATCHconst, so both 1a and 1b return MATCHconvert, then make ambiguous.

It seems to me that more priority level is need:
Priority name
0 MATCHnomatch
1 MATCHconvertconst  ... const conversion + template parameter conversion (new)
2 MATCHconvert       ... template parameter conversion
3 MATCHconst         ... const conversion
4 MATCHexact         ... exact match

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 29, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5896


Don <clugdbug@yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug@yahoo.com.au


--- Comment #1 from Don <clugdbug@yahoo.com.au> 2011-04-29 08:51:07 PDT ---
I don't understand why case 2a,2b works.
It seems to me that case 1 is identical to:

struct X{}

T  foo(T)(const(X) _this) { return 10; }

T  foo(T)(X _this) { return 11; }

void main(){
    auto xm = X();
    assert(foo!int(xm)==11);
}

Which fails in exactly the same way.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 29, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5896



--- Comment #2 from Kenji Hara <k.hara.pg@gmail.com> 2011-04-29 16:53:00 PDT ---
(In reply to comment #1)
> I don't understand why case 2a,2b works.
> It seems to me that case 1 is identical to:
> 
> struct X{}
> 
> T  foo(T)(const(X) _this) { return 10; }
> 
> T  foo(T)(X _this) { return 11; }
> 
> void main(){
>     auto xm = X();
>     assert(foo!int(xm)==11);
> }
> 
> Which fails in exactly the same way.

I have just started reading the code around the template, template function matching may have three steps:

1. Tempate parameter vs explicit template arguments.
   ex. opCast(T)() vs opCast!X() -> T vs X
2. const overload matching on ethis
   void f(T)() vs const void f(T)() -> (mutable) vs const
3. function parameters type matching (and may inference of implict template
parameters)
   void f(X x) vs void f(const(X) x) -> X vs const(X)

The cause of this issue may be step 1 and 2, and cause of your test case may be 3.

----
Re-explain of my test case. on xm (type is X) lookup...
1a matching:
  step1: opCast(T) vs opCast!(int) -> MATCHconvert
  step2: through                   -> MATCHconst
  -> afterward result: MATCHconvert
1b matching:
  step1: opCast(T) vs opCast!(int) -> MATCHconvert
  step2: MATCHconst if can         -> !!! MATCHconst is succomb to MATCHconvert
  -> afterward result: MATCHconvert
Both result of 1a and 1b are MATCHconvert, so make ambiguous.

2a matching:
  step1: opCast(T:int) vs opCast!(int) -> MATCHexact
  step2: through
  -> afterward result: MATCHexact
2b matching:
  step1: opCast(T:int) vs opCast!(int) -> MATCHexact
  step2: MATCHconst if can             -> MATCHconst
  -> afterward result: MATCHconvert
2a is more specialized than 2b, then 2a is selected.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 14, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5896


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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch, rejects-valid


--- Comment #3 from Kenji Hara <k.hara.pg@gmail.com> 2011-07-14 04:20:08 PDT ---
Patch and discussions: https://github.com/D-Programming-Language/dmd/pull/45

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 23, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=5896


SomeDude <lovelydear@mailmetrash.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |lovelydear@mailmetrash.com


--- Comment #4 from SomeDude <lovelydear@mailmetrash.com> 2012-04-23 12:50:13 PDT ---
The 2 examples compile with 2.059

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 24, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=5896



--- Comment #5 from Kenji Hara <k.hara.pg@gmail.com> 2012-04-23 17:45:58 PDT ---
More complicated test from my pull is still broken.

----
struct X5896
{
                 T opCast(T)(){ return 1; }    // L3
           const T opCast(T)(){ return 2; }    // L4
       immutable T opCast(T)(){ return 3; }
          shared T opCast(T)(){ return 4; }    // L6
    const shared T opCast(T)(){ return 5; }    // L7
}
void test5896()
{
    auto xm =              X5896  ();
    auto xc =        const(X5896) ();
    auto xi =    immutable(X5896) ();
    auto xs =       shared(X5896) ();
    auto xcs= const(shared(X5896))();
    assert(cast(int)xm == 1);    // L16
    assert(cast(int)xc == 2);
    assert(cast(int)xi == 3);    // L18
    assert(cast(int)xs == 4);    // L19
    assert(cast(int)xcs== 5);
}

Errors:
----
test.d(16): Error: template test.X5896.opCast matches more than one template
declaration, test.d(3):opCast(T) and test.d(4):opCast(T)
test.d(18): Error: template test.X5896.opCast matches more than one template
declaration, test.d(4):opCast(T) and test.d(7):opCast(T)
test.d(19): Error: template test.X5896.opCast matches more than one template
declaration, test.d(6):opCast(T) and test.d(7):opCast(T)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 12, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=5896



--- Comment #6 from github-bugzilla@puremagic.com 2012-05-12 11:35:38 PDT ---
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/60d7fadd7100c52746a29fade983c5644a4c8cfb fix Issue 5896 - const overload matching is succumb to template parameter one

Treat matching levels separately based on initial template arguments and inferred from function arguments.

https://github.com/D-Programming-Language/dmd/commit/f21d0cc53e2af192c8441ee8de786981d3bbca57 Merge pull request #45 from 9rnsr/fix5896

Issue 5896 - const overload matching is succumb to template parameter one

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------