www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - alias and UDAs

reply Andre Pany <andre s-e-a-p.de> writes:
Hi,

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
}

Kind regards
André
May 11 2017
next sibling parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Thursday, 11 May 2017 at 10:39:03 UTC, Andre Pany wrote:
 Hi,

 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
 }

 Kind regards
 André
It should've been alias FooList = Flattened Foo[]; which will generate a compile-time error (UDAs not allowed for alias declarations). And then: static assert(hasUDA!(baz.fooList2, Flattened)); No quotes, since Flattened is an enum, not a string
May 11 2017
parent Andre Pany <andre s-e-a-p.de> writes:
On Thursday, 11 May 2017 at 10:57:22 UTC, Stanislav Blinov wrote:
 On Thursday, 11 May 2017 at 10:39:03 UTC, Andre Pany wrote:
 [...]
It should've been alias FooList = Flattened Foo[]; which will generate a compile-time error (UDAs not allowed for alias declarations). And then: static assert(hasUDA!(baz.fooList2, Flattened)); No quotes, since Flattened is an enum, not a string
Thanks for the explanation. I think I will create a bug report for this statement: Flattened alias FooList = Foo[]; The UDA has no effect as far as I understand. Kind regards André
May 11 2017
prev sibling parent ag0aep6g <anonymous example.com> writes:
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
May 11 2017