```
struct El(T) {
long x;
void f2() {
f("");
}
void f(T2)(T2) {
static assert(getSymbolsByUDA!(El!T, AliasSeq!("x", "f2")).length > 0);
}
}
alias X = El!int;
void main() {
X().f((char[]).init);
}
private template getSymbolsByUDA(alias symbol, names...)
{
static if (names.length == 0)
{
alias getSymbolsByUDA = AliasSeq!();
}
else
{
alias getSymbolsByUDA = AliasSeq!(__traits(getMember, symbol, names[0]), getSymbolsByUDA!(symbol, names[1 .. $]));
}
}
template AliasSeq(TList...)
{
alias AliasSeq = TList;
}
```
Currently, in DMD 2.091, compiling this results in this error:
```
onlineapp.d(7): Error: no property length for type void
onlineapp.d(7): while evaluating: static assert(getSymbolsByUDAImpl!(El!int, "f", "f2").length > 0)
```
I'm not entirely sure what's going on here. This reduced getSymbolsByUDA implementation will always return a tuple and should never be void...
This specific error seems to have been introduced with DMD 2.066. Last compiled successfully in DMD 2.062.
Comment #1 by simen.kjaras — 2020-03-21T01:06:52Z
By prodding the code a bit, I was able to get a compiler crash. I believe the core issue is the same. Here's the simplified code:
struct S() {
void fun() {
gun("");
}
void gun(T)(T) {
alias buggy = bug;
}
}
alias X = S!();
void main() {
X().gun(0);
}
alias bug = __traits(getMember, X, "fun");
I've not been able to reduce it beyond this.
Comment #2 by moonlightsentinel — 2020-03-21T02:46:13Z
According to run.dlang.io it's a regression from 2.087.0:
2.084.1 to 2.086.1: Failure with output: onlineapp.d(16): Error: `__traits(getMember, S!(), "fun")` does not give a valid type
Since 2.087.1: Segfault and no output
Comment #3 by moonlightsentinel — 2020-03-21T03:12:56Z
Bisection blames this commit:
commit caf888bd949a119c2136be6ee7011eedbf3f5f0b
Author: Basile Burg <[email protected]>
Date: Sat Jul 6 13:37:10 2019 +0200
fix issue 19708 - Can't use __traits(getAttributes, ...)[...] as a type
Introduced in https://github.com/dlang/dmd/pull/10144
Comment #4 by boris2.9 — 2020-03-21T09:05:12Z
Simen Kjaeraas: that is a different bug which I just solved a few hours ago, it can show with nested alias declarations with the trait get member or similar.
Gonna file a new issue.
Comment #5 by boris2.9 — 2020-03-21T10:08:45Z
related issue 20692
Comment #6 by b2.temp — 2020-05-04T14:13:36Z
reduced to make reasoning on the problem easier
---
alias AliasSeq(TList...) = TList;
struct El(T) {
void f2() { f(null); }
void f(T2)(T2) { static assert(getSymbols!(El!T, "f2").length); }
}
alias X = El!char;
void main() {
X().f('a');
}
template getSymbols(alias symbol, names...) {
static if (names.length == 0)
alias getSymbols = AliasSeq!();
else
alias getSymbols =
AliasSeq!(__traits(getMember, symbol, names[0]),
getSymbols!(symbol, names[1 .. $]));
}
---
observations:
1. if you move the X definition in main() then that compiles ;
2. if you use this insted of El!T in El.f() then this compiles ;
3. if you use f('0') in El.f2() then this compiles,
because this matches to the instance called in main() ;
The 3rd point seems meaningful.
Comment #7 by robert.schadek — 2024-12-13T19:07:52Z