www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - AliasAssign - is this a bug?

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Here's an example reduced from a more complex use case:

import std.meta : AliasSeq, staticMap;
template AliasThisType(T) {
     alias A = AliasSeq!();
     static foreach (U; AliasSeq!(__traits(getMember, T, "xyz"))) {
         alias A = AliasSeq!(A, typeof(U));
     }
     alias AliasThisType = A;
}

struct HasNoAliasThis {
}

struct HasAliasThis {
     HasNoAliasThis xyz;
     alias xyz this;
}

alias X = AliasThisType!HasAliasThis;

This should work, shouldn't it? When trying to compile I get:

test.d(7): Error: alias 
`test.AliasThisType!(HasAliasThis).__anonymous.A` conflicts with alias 
`test.AliasThisType!(HasAliasThis).A` at test.d(4)
HasNoAliasThis
test.d(20): Error: template instance `test.AliasThisType!(HasAliasThis)` 
error instantiating

Is this a bug? If not, where is the mistake in the code? If so, what 
would be a workaround? Thanks!
Apr 27 2021
parent reply Mathias LANG <geod24 gmail.com> writes:
On Wednesday, 28 April 2021 at 00:29:46 UTC, Andrei Alexandrescu 
wrote:
 Is this a bug? If not, where is the mistake in the code?
Not a bug, since `static foreach` does not introduce a scope, you're trying to declare twice the same alias at the same scope, the compiler rightfully flags it.
 If so, what would be a workaround? Thanks!
Depends on what you want to do. Either use a different name, but it will fail as soon as you have more than one instantiation, or re-assign the alias: ```D template AliasThisType(T) { alias A = AliasSeq!(); static foreach (U; AliasSeq!(__traits(getMember, T, "xyz"))) { A = AliasSeq!(A, typeof(U)); // No more `alias` here } alias AliasThisType = A; } ```
Apr 28 2021
parent Mitacha <mateusz.mitaszka gmail.com> writes:
On Wednesday, 28 April 2021 at 09:07:15 UTC, Mathias LANG wrote:
 On Wednesday, 28 April 2021 at 00:29:46 UTC, Andrei 
 Alexandrescu wrote:
 Is this a bug? If not, where is the mistake in the code?
Not a bug, since `static foreach` does not introduce a scope, you're trying to declare twice the same alias at the same scope, the compiler rightfully flags it.
 If so, what would be a workaround? Thanks!
Depends on what you want to do. Either use a different name, but it will fail as soon as you have more than one instantiation, or re-assign the alias: ```D template AliasThisType(T) { alias A = AliasSeq!(); static foreach (U; AliasSeq!(__traits(getMember, T, "xyz"))) { A = AliasSeq!(A, typeof(U)); // No more `alias` here } alias AliasThisType = A; } ```
Looks like alias reassignment is supported since this [PR](https://github.com/dlang/dmd/pull/11846) Why use `static foreach` to get alias this memeber? You could use something like this: ```D template AliasThisType(T) { alias AliasThisMember = __traits(getAliasThis, T); alias AliasThisType = typeof(__traits(getMember, T, AliasThisMember)); } ```
Apr 28 2021