alias and UDAs

ag0aep6g via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu May 11 04:52:42 PDT 2017


On 05/11/2017 12:39 PM, Andre Pany wrote:
> in this example, both asserts fails. Is my assumption right, that UDA on
> alias have no effect? If yes, I would like to see a compiler warning.
>
> But anyway, I do not understand why the second assertion fails. Are UDAs
> on arrays not allowed?
>
> import std.traits: hasUDA;
>
> enum Flattened;
>
> struct Foo
> {
>     int bar;
> }
>
> @Flattened alias FooList = Foo[];
>
> struct Baz
> {
>     FooList fooList1;
>     @Flattened FooList[] fooList2;
> }
>
> void main()
> {
>     Baz baz;
>     static assert(hasUDA!(baz.fooList1, "Flattened")); // => false
>     static assert(hasUDA!(baz.fooList2, "Flattened")); // => false
> }

1) You have to test against `Flattened`, not `"Flattened"`. A string is 
a valid UDA, but you're not using the string on the declarations.

When you fix this, the second assert passes.

2) `Baz.fooList1` doesn't have any attributes. Attributes apply to 
declarations. If it's valid, the attribute on `FooList` applies only to 
`FooList`. It doesn't transfer to `Baz.fooList1`.

If anything, you could assert that `hasUDA!(FooList, Flattened)` holds. 
Maybe you could, if it compiled.

3) Why does `hasUDA!(FooList, Flattened)` fail to compile?

The error message reads: "template instance hasUDA!(Foo[], Flattened) 
does not match template declaration hasUDA(alias symbol, alias attribute)".

We see that `FooList` has been replaced by `Foo[]`. It's clear then why 
the instantiation fails: `Foo[]` isn't a symbol.

Unfortunately, the spec is a bit muddy on this topic. On the one hand it 
says that "AliasDeclarations create a symbol", but it also says that 
"Aliased types are semantically identical to the types they are aliased 
to" [1].

In practice, the compiler doesn't seem to create a symbol. The alias 
identifier is simply replaced with the aliased thing, and you can't use 
the alias identifier as a symbol.

That means, you might be able to add an attribute to `FooList`, but you 
can't get back to it, because whenever you use `FooList` it's always 
replaced by `Foo[]`. And `Foo[]` doesn't have the attribute, of course.

I agree that it would probably make sense to disallow putting attributes 
on aliases. You can also mark aliases `const`, `static`, `pure`, etc. 
And they all have no effect.


[1] http://dlang.org/spec/declaration.html#AliasDeclaration


More information about the Digitalmars-d-learn mailing list