Currently, there doesn't appear any way to distinguish traits tested on an alias and the symbol it aliases.
```
module funcs;
alias FuncPtr = void function();
@ChooseMe FuncPtr funcPtr;
alias anotherName = funcPtr;
module foo;
foreach(sym; __traits(getAllMembers, funcs))
// Call hasUDA, isFunctionPtr, etc...
```
Here, I want to single out funcPtr, but it's impossible as any test that is true for funcPtr is also true for anotherName. An isAlias trait would be quite helpful for this situation.
I would point to the spec here: http://dlang.org/spec/declaration.html#AliasDeclaration
> `AliasDeclarations` create a symbol that is an alias for another type, and can be used anywhere that other type may appear.
> Aliased types are semantically identical to the types they are aliased to. The debugger cannot distinguish between them, and there is no difference as far as function overloading is concerned.
To me, it sounds like you are looking to create a subtype, in which case `Typedef` would be a better approach. `alias` is just not designed for this. This really sounds like a DIP to me.
Comment #3 by aldacron — 2017-01-23T11:10:48Z
Not at all. allMembers returns FuncPtr and funcPtr as distinct symbols. What I'm looking for is a generic way to know that one is an alias declaration and the other is not.
Comment #4 by aldacron — 2017-01-23T11:12:21Z
(In reply to Mike Parker from comment #3)
> Not at all. allMembers returns FuncPtr and funcPtr as distinct symbols. What
> I'm looking for is a generic way to know that one is an alias declaration
> and the other is not.
And to be clear, I'm talking about at compile time. I realize it's not possible at runtime, but surely the compiler knows the difference.
Comment #5 by b2.temp — 2017-01-23T18:27:42Z
(In reply to Mike Parker from comment #4)
> (In reply to Mike Parker from comment #3)
> > Not at all. allMembers returns FuncPtr and funcPtr as distinct symbols. What
> > I'm looking for is a generic way to know that one is an alias declaration
> > and the other is not.
>
> And to be clear, I'm talking about at compile time. I realize it's not
> possible at runtime, but surely the compiler knows the difference.
Imagine a text-based serializer (like JSON, in opposite to a binary serializer)
- The serializer writes a size_t under a x86_64 OS and send it over the network
- An x86 machine reads it in a size_t
=> overflow...
In this case I wish to use __traits(isAlias) in a template constraint or in a static assert to reject the value (e.g "cannot write an aliased type"). The serializer, without type info, really doesn't want any platform specific type.
To get the info at CT or at RT doesn't make any difference. Any custom type info structure would use __traits(isAlias) to generate a static instance for an aggregate field of whatever.
Comment #6 by bugzilla — 2018-02-09T02:00:44Z
I see this is a feature that could lead to a lot of unforeseen consequences. The language semantics very much rely on an alias being indistinguishable from the target.
As for the size_t example, it's not even possible to serialize it as a size_t. It will go out as int or long. Name mangle a size_t, and there is no size_t mangling, it's int or long.
> __traits(getAllMembers, funcs)
Perhaps a better solution is to have getAllMembers ignore aliases, as aliases are members only for the purpose of symbol lookup.
Comment #7 by aldacron — 2018-02-12T03:30:06Z
(In reply to Walter Bright from comment #6)
>
> > __traits(getAllMembers, funcs)
>
> Perhaps a better solution is to have getAllMembers ignore aliases, as
> aliases are members only for the purpose of symbol lookup.
That's fine, too. Anything that allows filtering out the aliases from the actual symbols during reflection to avoid redundancy.
Comment #8 by b2.temp — 2020-01-30T06:06:51Z
another very typical case where the fact that allMembers trait doesn't filter out aliases is when using an alias to deprecate the name of a symbol.
---
//library...
enum Iter;
struct Foo
{
@Iter Object[] items;
/// will be removed on 01-01-2021
deprecated alias elements = items;
}
//app...
void main()
{
import std.traits;
alias Iterable = getSymbolsByUDA!(Foo, Iter);
}
---
Comment #9 by robert.schadek — 2024-12-13T18:44:22Z