Thread overview
AliasAssign - is this a bug?
Apr 28, 2021
Mathias LANG
Apr 28, 2021
Mitacha
April 27, 2021
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!
April 28, 2021

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:

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;
}
April 28, 2021

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:

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
Why use static foreach to get alias this memeber? You could use something like this:

template AliasThisType(T) {
    alias AliasThisMember = __traits(getAliasThis, T);
    alias AliasThisType = typeof(__traits(getMember, T, AliasThisMember));
}