www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 12541] New: templated __traits(compiles, ...) on value symbols causes a compilation error - under certain conditions

https://d.puremagic.com/issues/show_bug.cgi?id=12541

           Summary: templated __traits(compiles, ...) on value symbols
                    causes a compilation error - under certain conditions
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: major
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: 2krnk gmx.net


--- Comment #0 from det <2krnk gmx.net> 2014-04-07 22:46:42 PDT ---
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(){}

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 07 2014