D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 10100 - Identifiers with double underscores and allMembers
Summary: Identifiers with double underscores and allMembers
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 regression
Assignee: No Owner
URL:
Keywords: pull
Depends on:
Blocks:
 
Reported: 2013-05-16 19:38 UTC by Maxim Fomin
Modified: 2020-02-20 21:56 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Maxim Fomin 2013-05-16 19:38:03 UTC
After fixing issue 10096 following code

struct S
{
   void __aggrPostBlit(){}
   void __aggrPostBlit_blah(){}
   this(int x){}
}

pragma(msg, __traits(allMembers, S));

void main(){}

prints only __ctor

I think either dmd should grep special names from sources (and not just compare first two characters for underscores) or ban __identifiers at all.
Comment 1 Ethan Watson 2016-11-29 13:17:21 UTC
Just hit this myself. Another case of allMembers not returning all members.
Comment 2 Iain Buclaw 2017-06-11 09:04:10 UTC
This bug also means you can't pull a list of all gdc builtins at compile time, all to which are prefixed with `__builtin_'.

i.e:
---
import gcc.builtins;
enum builtins = [__traits(allMembers, gcc.builtins)];
pragma(msg, builtins);   // prints ["object"]
Comment 3 Iain Buclaw 2019-12-25 17:13:18 UTC
I'd call this a regression.

First bad PR https://github.com/dlang/dmd/pull/2043
Comment 4 Dlang Bot 2019-12-25 18:31:59 UTC
@ibuclaw created dlang/dmd pull request #10697 "fix Issue 10100 - Identifiers with double underscores and allMembers" fixing this issue:

- fix Issue 10100 - Identifiers with double underscores and allMembers
  
  Convert the identifier whitelist into a blacklist of all possible
  internal D language declarations.

https://github.com/dlang/dmd/pull/10697
Comment 5 Dlang Bot 2019-12-26 02:41:01 UTC
dlang/dmd pull request #10697 "fix Issue 10100 - Identifiers with double underscores and allMembers" was merged into master:

- 3aa3da224f6e6b075de0ddfb2416c52ee90f049c by Iain Buclaw:
  fix Issue 10100 - Identifiers with double underscores and allMembers
  
  Convert the identifier whitelist into a blacklist of all possible
  internal D language declarations.

https://github.com/dlang/dmd/pull/10697
Comment 6 Dlang Bot 2020-02-20 21:56:50 UTC
dlang/dmd pull request #10791 "[dmd-cxx] Implement static foreach, aliasing traits, and fix allMembers." was merged into dmd-cxx:

- 2c7947d0507d34e0f72899e9835b88ddf19c31e1 by Iain Buclaw:
  [dmd-cxx] Implement static foreach, aliasing traits, and fix allMembers.
  
  ----
  
  Implement DIP 1010 - (Static foreach)
  
  Support for `static foreach` has been added.
  
  `static foreach` is a conditional compilation construct that is to `foreach` what `static if` is to `if`.
  It is a convenient way to generate declarations and statements by iteration.
  
  ```
  import std.conv: to;
  
  static foreach(i; 0 .. 10)
  {
  
      // a `static foreach` body does not introduce a nested scope
      // (similar to `static if`).
  
      // The following mixin declaration is at module scope:
      mixin(`enum x` ~ to!string(i) ~ ` = i;`); // declares 10 variables x0, x1, ..., x9
  }
  
  import std.range: iota;
  // all aggregate types that can be iterated with a standard `foreach`
  // loop are also supported by static foreach:
  static foreach(i; iota(10))
  {
      // we access the declarations generated in the first `static foreach`
      pragma(msg, "x", i, ": ", mixin(`x` ~ to!string(i)));
      static assert(mixin(`x` ~ to!string(i)) == i);
  }
  
  void main()
  {
      import std.conv: text;
      import std.typecons: tuple;
      import std.algorithm: map;
      import std.stdio: writeln;
  
      // `static foreach` has both declaration and statement forms
      // (similar to `static if`).
  
      static foreach(x; iota(3).map!(i => tuple(text("x", i), i)))
      {
          // generates three local variables x0, x1 and x2.
          mixin(text(`int `,x[0],` = x[1];`));
  
          scope(exit) // this is within the scope of `main`
          {
              writeln(mixin(x[0]));
          }
      }
  
      writeln(x0," ",x1," ",x2); // first runtime output
  }
  ```
  
  ----
  
  Aliases can be created directly from a `__trait`.
  
  Aliases can be created directly from the traits that return symbol(s) or tuples.
  This includes `getMember`, `allMembers`, `derivedMembers`, `parent`, `getOverloads`,
  `getVirtualFunctions`, `getVirtualMethods`, `getUnitTests`, `getAttributes` and finally `getAliasThis`.
  Previously an `AliasSeq` was necessary in order to alias their return.
  Now the grammar allows to write shorter declarations:
  
  ```
  struct Foo
  {
      static int a;
  }
  
  alias oldWay = AliasSeq!(__traits(getMember, Foo, "a"))[0];
  alias newWay = __traits(getMember, Foo, "a");
  ```
  
  To permit this it was more interesting to include `__trait` in the basic types
  rather than just changing the alias syntax. So additionally, wherever a type appears
  a `__trait` can be used, for example in a variable declaration:
  
  ```
  struct Foo { static struct Bar {} }
  const(__traits(getMember, Foo, "Bar")) fooBar;
  static assert(is(typeof(fooBar) == const(Foo.Bar)));
  ```
  
  ----
  
  fix Issue 10100 - Identifiers with double underscores and allMembers
  
  Convert the identifier whitelist into a blacklist of all possible
  internal D language declarations.

https://github.com/dlang/dmd/pull/10791