Bug 3072 – tuples can't be aliases ( except when the aliases are templates. )
Status
RESOLVED
Resolution
WORKSFORME
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
Windows
Creation time
2009-06-16T20:55:00Z
Last change time
2015-06-09T05:11:55Z
Keywords
accepts-invalid, rejects-valid, spec
Assigned to
nobody
Creator
shro8822
Comments
Comment #0 by shro8822 — 2009-06-16T20:55:16Z
D1.0
import std.stdio;
template Ta(alias t){void Tfn(){writef(t);}}
template Tt(t...){void Tfn(){writef(t);}}
struct S
{
int i; int j; int k;
mixin Ta!(i); // passes
mixin Tt!(i,j); // fails
}
this causes issues for mixin function that are supposed to work on a subset of the members of the enclosing type. The string mixin work around is just flat ugly.
I don't think the spec says this shouldn't work so I'm calling it a bug.
Comment #1 by sandford — 2010-10-20T10:59:44Z
In general template tuples can't contain alias template parameters but it appears that there is an exception to this rule when the parameter is itself a template.
DMD 2.049
T foo(T)(T t) { return t; }
template map1(fun...) {
enum map1 = 42;
}
template map2(T, U...) {
static if(U.length > 0) enum map2 = map2!(U);
else enum map2 = 42;
}
void main() {
auto x = map1!(char,foo); // compiles
auto y = map2!(char,foo); // doesn't compile
auto z = map1!(char,map1); // compiles
auto w = map2!(char,map1); // doesn't compile
return;
}
I've added the accepts-invalid, rejects-valid and spec keywords, since tuples of aliases should either work or not-work and the behavior should be documented in the spec. I'd lean towards not-work, since tuples of aliases seem to be buggy (i.e. Issue 5087) not to mention that alias parameters are buggy(i.e. issue 5082)
Comment #2 by k.hara.pg — 2015-02-23T04:55:29Z
With 1.076, the OP code in comment#0 compiles successfully.
And with 2.067a, dmd accepts the following code.
import std.stdio;
template Ta(alias t){ void Tfn() { writeln(t); } }
template Tt(t...) { void Tfn() { writeln(t); } }
struct S
{
int i; int j; int k;
mixin Ta!(i); // passes
mixin Tt!(i,j); // also passes
}
Therefore the original issue is already fixed in D1 and D2.
Comment #3 by k.hara.pg — 2015-02-23T04:58:47Z
(In reply to Rob Jacques from comment #1)
> In general template tuples can't contain alias template parameters but it
> appears that there is an exception to this rule when the parameter is itself
> a template.
>
> DMD 2.049
>
> T foo(T)(T t) { return t; }
> template map1(fun...) {
> enum map1 = 42;
> }
> template map2(T, U...) {
> static if(U.length > 0) enum map2 = map2!(U);
> else enum map2 = 42;
> }
>
> void main() {
> auto x = map1!(char,foo); // compiles
> auto y = map2!(char,foo); // doesn't compile
> auto z = map1!(char,map1); // compiles
> auto w = map2!(char,map1); // doesn't compile
> return;
> }
>
> I've added the accepts-invalid, rejects-valid and spec keywords, since
> tuples of aliases should either work or not-work and the behavior should be
> documented in the spec. I'd lean towards not-work, since tuples of aliases
> seem to be buggy (i.e. Issue 5087) not to mention that alias parameters are
> buggy(i.e. issue 5082)
This test case is invalid. map2 is recursively instantiated, but in the line:
> static if(U.length > 0) enum map2 = map2!(U);
the instantiation map2!(foo) or map2!(map1) fails because any template symbols cannot match to the type parameter T.