Bug 5784 – Template instantiation with enum constant as parameter, missing implicit cast
Status
RESOLVED
Resolution
WORKSFORME
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Windows
Creation time
2011-03-24T22:42:00Z
Last change time
2014-03-19T16:36:18Z
Assigned to
nobody
Creator
pszturmaj
Comments
Comment #0 by pszturmaj — 2011-03-24T22:42:41Z
When template is instantiated for the first time, using integral literal, everything is ok. But if the same template is instantiated for the first time, using enum constant as its parameter then instantiation can't be matched using is expression.
struct A(int n)
{
bool[n] nBooleans;
}
template isA(T)
{
static if (is(T X == A!N, int N))
enum isA = true;
else
enum isA = false;
}
enum int boolCount = 5;
Now, when first instantiation is using integer literal, it works ok:
alias A!5 fromLiteral;
alias A!boolCount fromEnum;
static assert(isA!(A!5)); // pass
static assert(isA!(A!boolCount)); // pass
static assert(is(A!5 == A!boolCount)); // pass
But, when first instantiation is using enum constant, the is expression fails:
alias A!boolCount fromEnum;
alias A!5 fromLiteral;
static assert(isA!(A!5)); // fail
static assert(isA!(A!boolCount)); // fail
static assert(is(A!5 == A!boolCount)); // pass
Note that only difference is order of alias declarations.
The cause of this bug is enum constant which is not implicitly casted to its base type (int). With explicit casting everything is ok:
alias A!(cast(int)boolCount) fromEnum;
alias A!5 fromLiteral;
static assert(isA!(A!5)); // pass
static assert(isA!(A!boolCount)); // pass
static assert(is(A!5 == A!boolCount)); // pass
Comment #1 by lt.infiltrator — 2014-03-19T16:36:18Z
This seems to be fixed as of v2.065. The following compiles.
-------------------------------------------------------
struct A(int n)
{
bool[n] nBooleans;
}
template isA(T)
{
static if (is(T X == A!N, int N))
enum isA = true;
else
enum isA = false;
}
enum int boolCount = 5;
alias A!boolCount fromEnum;
alias A!5 fromLiteral;
static assert(isA!(A!5)); // no longer fails
static assert(isA!(A!boolCount)); // no longer fails
static assert(is(A!5 == A!boolCount)); // pass
-------------------------------------------------------