Mixin and introspection ordering

Paul Backus snarwin at gmail.com
Tue Oct 15 19:50:33 UTC 2019


On Tuesday, 15 October 2019 at 19:19:58 UTC, Sebastiaan Koppe 
wrote:
> You would expect 2 to print `tuple(a)` as well, but it doesn't. 
> Don't know if it is a bug.

Any time you use a construct that mutates the AST (template 
mixin, string mixin, static if, static foreach), it's possible to 
catch it in both "before" and "after" states. For example:

pragma(msg, __traits(allMembers, S1).stringof); // tuple()
struct S1 { mixin("int n;"); }
pragma(msg, __traits(allMembers, S1).stringof); // tuple("n")

pragma(msg, __traits(allMembers, S2).stringof); // tuple()
struct S2 { static foreach (_; 0 .. 1) int n; }
pragma(msg, __traits(allMembers, S2).stringof); // tuple("n")

This can cause some "interesting" things to happen when using 
templates like the ones in std.traits to do reflection, since the 
result of template instantiation is cached:

import std.traits: hasMember;
struct S3() {
     static if (!hasMember!(S3, "b")) {
         int a;
     }
     mixin("int b;");
}
pragma(msg, hasMember!(S3!(), "b")); // false
pragma(msg, __traits(allMembers, S3!())); // tuple("a", "b")


More information about the Digitalmars-d-learn mailing list