Bug 12541 – templated __traits(compiles, ...) on value symbols causes a compilation error - under certain conditions
Status
RESOLVED
Resolution
DUPLICATE
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-04-07T22:46:00Z
Last change time
2014-04-09T18:49:15Z
Assigned to
nobody
Creator
2krnk
Comments
Comment #0 by 2krnk — 2014-04-07T22:46:42Z
now this is quite intricate, please bear with me.
under certain conditions (see below), compilation fails with an unsubstantiated error message when trying to assign the outcome of a __traits(compiles, ...) reflection via template.
in the two following code examples (compile separately) 'test' is the test symbol that shall be validated, i.e., tested via __traits(compiles, ...). this shall happen indirectly through the template 'valid'.
the two examples demonstrate two slightly different conditions under which compilation fails with error message "variable [...] had semantic errors when compiling".
this buggy behavior occurs only if the test symbol in question is a value (enum, const, inmutable). test symbols that are functions, structs, classes or empty enums don't cause any problems.
this is quite a show-stopper for the meta / code reflection / code generation stuff i am working on. it probably contains the root cause for many other issues that are very difficult to reduce. it is actually an example for a heisenbug: if you add a pragma(msg, ...) at the right place for inspection (see example/condition 2), the bug will disappear!
=== CODE EXAMPLE / CONDITION 1 ===
/++
bug condition 1:
if first call to __traits(compiles, ...) is via template, then
compilation fails for test symbols that are enum, const and immutable values
but:
o always works for test symbols that are funcs, structs, classes and empty enums
++/
enum fails = valid!(test);
// Error: variable fails had semantic errors when compiling
pragma(msg, "fails: "~fails.stringof); // true
// always works (as expected):
enum ok = __traits(compiles, test);
pragma(msg, "ok: "~ok.stringof); // true
enum test = 13; // fails
// immutable test = 42;// fails
// const test = 42; // fails
//BUT:
// enum test; // works
// void test(){} // works
// struct test{} // works
// class test{} // works
// always works (as expected):
enum ok2 = valid!(test);
pragma(msg, "ok2: "~ok2.stringof); // true
template valid(alias sym){
enum valid = __traits(compiles, sym);
} // no difference if this template is declared first
void main(){}
=== CODE EXAMPLE / CONDITION 2 ===
/++
bug condition 2:
if first call to __traits(compiles, ...) happens from module level
and is not inquiring about the test symbol, then
compilation fails for test symbols that are enum, const and immutable values.
but:
o will compile if first call is __traits(compiles, test)
o always works for test symbols that are funcs, structs, classes and empty enums
++/
enum ok = __traits(compiles, main); // 'enum fails' below will not compile!
// pragma(msg, __traits(compiles, test) ); // 'enum fails' below will compile now
// enum ok = __traits(compiles, test); // 'enum fails' below will compile now
// pragma(msg, "ok: "~ok.stringof); // true
enum fails = valid!(test);
// Error: variable fails had semantic errors when compiling
pragma(msg, "fails: "~fails.stringof); // true
enum test = 13;
// enum test; // no compilation errors if test symbol is not a value
// fails only for enum, const and immutable values
// (but always works for functions, structs, classes and empty enums)
// always works (as expected):
enum ok2 = valid!(test);
pragma(msg, "ok2: "~ok2.stringof); // true
template valid(alias sym){
enum valid = __traits(compiles, sym);
} // no difference if this template is declared first
void main(){}
Comment #1 by 2krnk — 2014-04-09T18:49:15Z
this is a result of issue 12553 which covers the bug more generally
*** This issue has been marked as a duplicate of issue 12553 ***