Skip to content

Commit

Permalink
Fix Issue 15243 - rejects-valid on variadic
Browse files Browse the repository at this point in the history
  • Loading branch information
JinShil committed Dec 7, 2017
1 parent 0da1457 commit 8d719d6
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 7 deletions.
31 changes: 31 additions & 0 deletions changelog/fix15243_PR7403.dd
@@ -0,0 +1,31 @@
Variadic template arguments no longer require `alias` workaround

Prior to this release, the following code would not compile.

----
class C(Types...)
{
void apply(U)(U delegate(Types[0]) f0) { } // Error: cannot deduce function from argument types
}

void test()
{
C!int c;

int f(int) { return 0; }

c.apply(&f);
}
----

It could be worked around by `alias`ing the individual template arguments.

----
class C(Types...)
{
alias Types[0] T0;
void apply(U)(U delegate(T0) f0) { } // OK
}
----

Starting with this release, the workaround is no longer required.
26 changes: 19 additions & 7 deletions src/ddmd/dtemplate.d
Expand Up @@ -3601,20 +3601,32 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
return;
}

size_t nfargs = Parameter.dim(t.parameters);
size_t nfparams = Parameter.dim(tp.parameters);

// https://issues.dlang.org/show_bug.cgi?id=2579
// Apply function parameter storage classes to parameter types
for (size_t i = 0; i < nfparams; i++)
foreach (fparam; *tp.parameters)
{
Parameter fparam = Parameter.getNth(tp.parameters, i);
// https://issues.dlang.org/show_bug.cgi?id=2579
// Apply function parameter storage classes to parameter types
fparam.type = fparam.type.addStorageClass(fparam.storageClass);
fparam.storageClass &= ~(STC_TYPECTOR | STCin);

// https://issues.dlang.org/show_bug.cgi?id=15243
// Resolve parameter type if it's not related with template parameters
if (!reliesOnTident(fparam.type, parameters, inferStart))
{
auto tx = fparam.type.typeSemantic(Loc(), sc);
if (tx.ty == Terror)
{
result = MATCH.nomatch;
return;
}
fparam.type = tx;
}
}
//printf("\t. this = %d, ", t.ty); t.print();
//printf("\t. tparam = %d, ", tparam.ty); tparam.print();

size_t nfargs = Parameter.dim(t.parameters);
size_t nfparams = Parameter.dim(tp.parameters);

/* See if tuple match
*/
if (nfparams > 0 && nfargs >= nfparams - 1)
Expand Down
30 changes: 30 additions & 0 deletions test/runnable/template9.d
Expand Up @@ -4848,6 +4848,35 @@ void test15781()
static assert(is(typeof(foo(cs, cs)) == const S));
}

/******************************************/
// https://issues.dlang.org/show_bug.cgi?id=15243

struct S15243(Types...)
{
void apply1(U)(U delegate(Types[0]) f0) {}

void apply2(U)(U delegate(Types) f0) {}

void apply3(U)(U delegate(Types[1..$]) f0) {}
}

void test15243()
{
int f1(int) { return 0; }
int f2(int, long) { return 0; }
int f3(long, string) { return 0; }

S15243!(int) s1;
s1.apply1(&f1);
s1.apply2(&f1);

S15243!(int, long) s2;
s2.apply2(&f2);

S15243!(int, long, string) s3;
s3.apply3(&f3);
}

/******************************************/

int main()
Expand Down Expand Up @@ -4962,6 +4991,7 @@ int main()
test14735();
test14802();
test15116();
test15243();

printf("Success\n");
return 0;
Expand Down

0 comments on commit 8d719d6

Please sign in to comment.