Bug 16390 – __traits not accepted where a type is expected

Status
RESOLVED
Resolution
FIXED
Severity
minor
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2016-08-15T13:15:47Z
Last change time
2020-03-21T03:56:37Z
Keywords
spec
Assigned to
No Owner
Creator
Lodovico Giaretta

Comments

Comment #0 by lodovico — 2016-08-15T13:15:47Z
For example, this does not work: template ParentType(T) { alias ParentType = __traits(parent, T); } This leads to awkward workarounds: template ParentType(T) { alias ParentType = AliasSeq!(__traits(parent, T))[0]; }
Comment #1 by b2.temp — 2016-08-15T16:06:43Z
This is really common to use typeof() on the result of a __traits() template ParentType(T) { alias ParentType = typeof(__traits(parent, T)); }
Comment #2 by lodovico — 2016-08-15T17:26:24Z
(In reply to b2.temp from comment #1) > This is really common to use typeof() on the result of a __traits() > > template ParentType(T) > { > alias ParentType = typeof(__traits(parent, T)); > } If this was meant to be a workaround, it doesn't seem to work for me (the trait returns a type, while typeof expects an expression). If it was meant to be another situation where __traits should be allowed but are not, it looks like they are currently allowed inside typeof.
Comment #3 by b2.temp — 2016-08-15T18:27:39Z
(In reply to Lodovico Giaretta from comment #2) > (In reply to b2.temp from comment #1) > If this was meant to be a workaround, it doesn't seem to work for me (the > trait returns a type, while typeof expects an expression). > > If it was meant to be another situation where __traits should be allowed but > are not, it looks like they are currently allowed inside typeof. Yes, second case, sorry. It clearly doesn't work with the parent __traits.
Comment #4 by issues.dlang — 2016-08-15T19:23:19Z
Similarly, template members(T) { alias members = __traits(allMembers, T); } doesn't work, whereas template members(T) { alias members = AliasSeq!(__traits(allMembers, T)); } does. And that's even more bizarre when you consider not only that AliasSeq is supposed to be equivalent to the "tuple" that the compiler uses for stuff like the result of __traits(allMembers, T), but this code import std.meta; template members(T) { alias members = AliasSeq!(__traits(allMembers, T)); } struct S { int i; string s; } void main() { pragma(msg, __traits(allMembers, S)); pragma(msg, AliasSeq!(__traits(allMembers, S))); pragma(msg, members!S); } prints tuple("i", "s") tuple("i", "s") tuple("i", "s") meaning that all 3 are equivalent as far as pragma(msg, ...) is concerned. And changing main to pragma(msg, typeof(__traits(allMembers, S))); pragma(msg, typeof(AliasSeq!(__traits(allMembers, S)))); pragma(msg, typeof(members!S)); results in (string, string) (string, string) (string, string) So, it really seems like the fact that the result of __traits can't be aliased is a bug. And if it's not a bug, then it's an unnecessary (and confusing) inconsistency, and IMHO, it really should be fixed.
Comment #5 by cauterite — 2016-08-17T15:08:59Z
Comment #6 by b2.temp — 2019-07-05T17:13:12Z
This syntax works nowadays. it was the same as issue 7804 btw