Skip to content

Commit

Permalink
fix Issue 4953 - Regression(2.031): templates don't do implicit conve…
Browse files Browse the repository at this point in the history
…rsion properly
  • Loading branch information
9rnsr committed Mar 24, 2012
1 parent 60d7fad commit 91093c7
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 31 deletions.
8 changes: 7 additions & 1 deletion src/template.c
Original file line number Diff line number Diff line change
Expand Up @@ -1445,6 +1445,12 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objec
//if (tf->hasWild())
// printf("\twildmatch = x%x m = %d\n", wildmatch, m);

/* If no match, see if the argument can be matched by using
* implicit conversions.
*/
if (!m)
m = farg->implicitConvTo(fparam->type);

/* If no match, see if there's a conversion to a delegate
*/
if (!m)
Expand Down Expand Up @@ -1994,7 +2000,7 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc,
ti = new TemplateInstance(loc, td_best, tdargs);
ti->semantic(sc, fargs);
fd_best = ti->toAlias()->isFuncDeclaration();
if (!fd_best || !((TypeFunction*)fd_best->type)->callMatch(ethis, fargs, flags))
if (!fd_best || !((TypeFunction*)fd_best->type)->callMatch(ethis, fargs))
goto Lerror;

/* As Bugzilla 3682 shows, a template instance can be matched while instantiating
Expand Down
117 changes: 87 additions & 30 deletions test/runnable/opover.d
Original file line number Diff line number Diff line change
Expand Up @@ -215,11 +215,11 @@ void test3()

struct Foo4
{
int a;
int opCmp(Foo4 b)
{
return a < b.a;
}
int a;
int opCmp(Foo4 b)
{
return a < b.a;
}
}

void test4()
Expand Down Expand Up @@ -694,39 +694,39 @@ interface IWriter

class Writer : IWriter
{
int opShl (string i)
{
printf("Writer.opShl(char[])\n");
return 1;
}
int opShl (string i)
{
printf("Writer.opShl(char[])\n");
return 1;
}

int opShl (int i)
{
printf("Writer.opShl(int)\n");
return 2;
}
int opShl (int i)
{
printf("Writer.opShl(int)\n");
return 2;
}
}

class BinaryWriter : Writer
{
alias Writer.opShl opShl;
alias Writer.opShl opShl;

override int opShl (int i)
{
printf("BinaryWriter.opShl(int)\n");
return 3;
}
override int opShl (int i)
{
printf("BinaryWriter.opShl(int)\n");
return 3;
}
}

void test8()
{
BinaryWriter bw = new BinaryWriter();
int i;
BinaryWriter bw = new BinaryWriter();
int i;

i = bw << "test";
assert(i == 1);
i = bw << 1;
assert(i == 3);
i = bw << "test";
assert(i == 1);
i = bw << 1;
assert(i == 3);
}

/**************************************/
Expand Down Expand Up @@ -867,7 +867,7 @@ class Foo14

int opIn(int x)
{
return a + x;
return a + x;
}
}

Expand Down Expand Up @@ -909,9 +909,62 @@ void test15()
}

/**************************************/
// 4953

//void bug4953(T = void)(short x) {}
//static assert(is(typeof(bug4953(3))));
struct S4953a
{
short _x;
bool opBinaryRight(string op)(short x) if (op == "in")
{
return x == _x;
}
}
void test4953a()
{
S4953a s;
5 in s;
}

struct S4953b
{
void opBinary(string op)(short x)
{}
}
void test4953b()
{
S4953b s;
s + 5;
}


struct S4953c
{
void funOpAssign(float[1u] data) { }
void opOpAssign(string op)(float[1u] data) if(op=="<<") { }
}
void test4953c()
{
// dmd v2.054, v2.055
S4953c s;
float[1u] a = [1.0f]; // OK: Implicit cast from float[] compiles
s.funOpAssign([1.0f]); // OK: Implicit cast from float[] compiles
s <<= [1.0f]; // Issue: Implicit cast from float[] does not compile
s <<= cast(float[1u])[1.0f]; // OK: Explicit cast from float[] compiles
}

void f4953d1 (dstring d) { dstring e = d; }
void f4953d2()(dstring d) { dstring e = d; }
void f4953d3 ( byte[] b) { byte[] c = b; }
void f4953d4()( byte[] b) { byte[] c = b; }
void test4953d()
{
f4953d1("abc"); // OK
f4953d2("abc"); // OK
f4953d3([1,2,3]); // OK
f4953d4([1,2,3]);
// Error: template test2.f() does not match any function template declaration
// Error: template test2.f() cannot deduce template function from argument types !()(int[])
}

/**************************************/
// 4993
Expand Down Expand Up @@ -949,6 +1002,10 @@ int main()
test13();
test14();
test15();
test4953a();
test4953b();
test4953c();
test4953d();
test4993();

printf("Success\n");
Expand Down
6 changes: 6 additions & 0 deletions test/runnable/template9.d
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,12 @@ void test2579()
foo2579( (in Object o) { return 15; } );
}

/**********************************/
// 4953

void bug4953(T = void)(short x) {}
static assert(is(typeof(bug4953(3))));

/**********************************/
// 5886 & 5393

Expand Down

0 comments on commit 91093c7

Please sign in to comment.