[Issue 10100] Identifiers with double underscores and allMembers

d-bugmail at puremagic.com d-bugmail at puremagic.com
Thu Feb 20 21:56:50 UTC 2020


https://issues.dlang.org/show_bug.cgi?id=10100

--- Comment #6 from Dlang Bot <dlang-bot at dlang.rocks> ---
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

--


More information about the Digitalmars-d-bugs mailing list