www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 5896] New: const overload with Template function

reply d-bugmail puremagic.com writes:
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



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: -------
Apr 27 2011
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5896


Don <clugdbug yahoo.com.au> changed:

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



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: -------
Apr 29 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5896





 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: -------
Apr 29 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
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



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: -------
Jul 14 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5896


SomeDude <lovelydear mailmetrash.com> changed:

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



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: -------
Apr 23 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5896




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: -------
Apr 23 2012
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5896




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


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: -------
May 12 2012