Bug 20758 – __traits(getAttributes) as template argument results in broken template instances
Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2020-04-22T10:45:02Z
Last change time
2020-05-24T05:34:15Z
Keywords
pull, rejects-valid
Assigned to
No Owner
Creator
Max Samukha
Comments
Comment #0 by maxsamukha — 2020-04-22T10:45:02Z
template foo(a...) {
static int x;
}
void attr1() {}
// enum attr2 = 1;
// struct attr3 {}
@attr1 int x;
alias f1 = foo!attr1;
alias f2 = foo!(__traits(getAttributes, x));
// passes
static assert(f1.mangleof == f2.mangleof);
// fails, should pass
static assert(__traits(isSame, f1, f2));
void main() {
auto p1 = &f1.x;
auto p2 = &f2.x;
// passes
assert(p1 == p2);
// but this fails
assert(&f1.x == &f2.x);
}
The bug seems to manifest only for attributes that are functions. If attr1 is replaced with attr2 or attr3, the assertions pass.
Comment #1 by moonlightsentinel — 2020-05-23T17:30:06Z
@NilsLankila created dlang/dmd pull request #11183 "fix issue 20758 - __traits(getAttributes) as template argument result…" fixing this issue:
- fix issue 20758 - __traits(getAttributes) as template argument results in broken template instances
Using a `TupleExp` obtained by a `__traits` had for effect to instantiate a template with a `VarExp` that was never translated to a D symbol.
The fix is to do the translation only when the var is for a function, which means that the intention is not to instantiate using the function *result* but well the function itself.
https://github.com/dlang/dmd/pull/11183
Comment #3 by dlang-bot — 2020-05-24T05:34:15Z
dlang/dmd pull request #11183 "fix issue 20758 - __traits(getAttributes) as template argument result…" was merged into stable:
- 5ef80bb6fdfeb538c4d28eaede8a6c8d16c53dcf by Nils Lankila:
fix issue 20758 - __traits(getAttributes) as template argument results in broken template instances
Using a `TupleExp` obtained by a `__traits` had for effect to instantiate a template with a `VarExp` that was never translated to a D symbol.
The fix is to do the translation only when the var is for a function, which means that the intention is not to instantiate using the function *result* but well the function itself.
https://github.com/dlang/dmd/pull/11183