Bug 20686 – failed static assert using a combination of __traits and unfinished type

Status
NEW
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2020-03-19T20:22:48Z
Last change time
2024-12-13T19:07:52Z
Keywords
rejects-valid
Assigned to
No Owner
Creator
elpenguino+D
Moved to GitHub: dmd#19683 →

Comments

Comment #0 by elpenguino+D — 2020-03-19T20:22:48Z
``` 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
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19683 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB