Bug 4217 – Function overloads are not distinguished when instantiating templates

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2010-05-21T04:32:00Z
Last change time
2014-02-15T02:46:33Z
Keywords
patch, wrong-code
Assigned to
nobody
Creator
rsinfu
Blocks
4312

Attachments

IDFilenameSummaryContent-TypeSize
639fix-overloaded-temparg.patchPatch for DMD svn r496text/plain871
640fix-overloaded-temparg-2.patchPatch for DMD svn r496text/plain885
641fix-overloaded-temparg-3.patchPatch for DMD svn r496text/plain885
762matchfunc-equals.patchPatch against dmd r680, implements FuncDeclaration::equals()text/plain1194

Comments

Comment #0 by rsinfu — 2010-05-21T04:32:09Z
Created attachment 639 Patch for DMD svn r496 -------------------- interface I { int test(int); real test(real); } pragma(msg, typeof(__traits(getOverloads, I, "test"))); template Test(alias func) { pragma(msg, "Test: ", typeof(func)); } alias Test!(__traits(getOverloads, I, "test")[0]) Test0; alias Test!(__traits(getOverloads, I, "test")[1]) Test1; static assert(!__traits(isSame, Test0, Test1)); -------------------- (int(int), real(real)) Test: int(int) test.d(12): Error: static assert (!true) is false -------------------- There is no "Test: real(real)" in the output. And the two aliases are reported as the same; the first instance Test0 is reused for the second instantiation (Test1). The attached patch fixes the problem by adding a check for overloaded functions to the match() function in template.c.
Comment #1 by rsinfu — 2010-05-21T15:42:50Z
Created attachment 640 Patch for DMD svn r496 I've forgotten to add the essential check: f1 != f2.
Comment #2 by rsinfu — 2010-05-21T15:54:17Z
Created attachment 641 Patch for DMD svn r496
Comment #3 by rsinfu — 2010-09-21T11:16:09Z
Created attachment 762 Patch against dmd r680, implements FuncDeclaration::equals() Updated patch and a cleaned up test case. -------------------- test.d template Return(alias fun) { static if (is(typeof(fun) R == return)) alias R Return; } interface I { int square(int n); real square(real n); } alias Return!( __traits(getOverloads, I, "square")[0] ) R0; alias Return!( __traits(getOverloads, I, "square")[1] ) R1; static assert(! is(R0 == R1)); // (14) -------------------- % dmd -o- -c test.d test.d(14): Error: static assert (!true) is false -------------------- The problem is that template alias (symbol) parameters are matched in terms of the identifier via Dsymbol::equals(). The new patch implements FuncDeclaration::equals() that checks for function type.
Comment #4 by k.hara.pg — 2010-10-12T10:12:03Z
Tested similar code: -------- template Seq(T...){ alias T Seq; } class A{ int f() const{ return 0; } int f() immutable{ return 0; } } alias Seq!(__traits(getOverloads, A, "f")) Overloads; template Typeof(alias a) { pragma(msg, typeof(a)); alias typeof(a) Typeof; } static assert(is(Typeof!(Overloads[0]) == typeof(Overloads[0]))); static assert(is(Typeof!(Overloads[1]) == typeof(Overloads[1]))); //should be OK -------- It is important for writing meta.algorithm against overload set.
Comment #5 by bugzilla — 2010-12-05T23:52:59Z