Thread overview | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 15, 2014 [Issue 12571] Regression (2.063): Can no longer use static introspection on circular references | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=12571 Vladimir Panteleev <thecybershadow@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |thecybershadow@gmail.com --- Comment #1 from Vladimir Panteleev <thecybershadow@gmail.com> --- Introduced in https://github.com/D-Programming-Language/dmd/pull/1662 -- |
April 15, 2014 [Issue 12571] Regression (2.063): Can no longer use static introspection on circular references | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=12571 --- Comment #2 from Kenji Hara <k.hara.pg@gmail.com> --- (In reply to Andrej Mitrovic from comment #0) > ----- > mixin template getScopeName() > { > enum scopeName = __traits(identifier, __traits(parent, scopeName)); > } > > void main() > { > mixin getScopeName; > pragma(msg, scopeName); > } > ----- I don't think the code should work. When declaring scopeName variable, referring it in its initializer should cause forward reference error. > There is also a library workaround but it introduces symbol bloat: [snip] More simple another way exists. mixin template getScopeName() { // enum scopeName = __traits(identifier, __traits(parent, scopeName)); enum scopeName = __traits(identifier, __traits(parent, getScopeName)); } void main() { mixin getScopeName; pragma(msg, scopeName); } Mixed-in template also have parent, so __traits(parent, getScopeName) will return the mixed in scope. -- |
April 15, 2014 [Issue 12571] Regression (2.063): Can no longer use static introspection on circular references | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=12571 --- Comment #3 from Andrej Mitrovic <andrej.mitrovich@gmail.com> --- (In reply to Kenji Hara from comment #2) > (In reply to Andrej Mitrovic from comment #0) > > ----- > > mixin template getScopeName() > > { > > enum scopeName = __traits(identifier, __traits(parent, scopeName)); > > } > > > > void main() > > { > > mixin getScopeName; > > pragma(msg, scopeName); > > } > > ----- > > I don't think the code should work. When declaring scopeName variable, referring it in its initializer should cause forward reference error. > > > There is also a library workaround but it introduces symbol bloat: > [snip] > > More simple another way exists. > > mixin template getScopeName() > { > // enum scopeName = __traits(identifier, __traits(parent, scopeName)); > enum scopeName = __traits(identifier, __traits(parent, getScopeName)); > } > > void main() > { > mixin getScopeName; > pragma(msg, scopeName); > } > > Mixed-in template also have parent, so __traits(parent, getScopeName) will > return the mixed in scope. That doesn't work. It will return 'test' which is the module name rather than 'main'. -- |
April 15, 2014 [Issue 12571] Regression (2.063): Can no longer use static introspection on circular references | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=12571 --- Comment #4 from Andrej Mitrovic <andrej.mitrovich@gmail.com> --- (In reply to Kenji Hara from comment #2) > I don't think the code should work. When declaring scopeName variable, referring it in its initializer should cause forward reference error. Note that C seems to have a greater ability than D w.r.t. this issue. For example a piece of code I ran into recently: ----- int** arr = malloc(sizeof(**arr) * 10); ----- This works in C but can't in D. Whether that's a good thing or not, I don't know. -- |
April 15, 2014 [Issue 12571] Regression (2.063): Can no longer use static introspection on circular references | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=12571 --- Comment #5 from Kenji Hara <k.hara.pg@gmail.com> --- (In reply to Andrej Mitrovic from comment #3) > That doesn't work. It will return 'test' which is the module name rather than 'main'. Oh, sorry. I didn't see the local execution result carefully. ---- I confirmed root problem. The opening code must not work. But, if the type of scopeName is explicitly specified, it should work. mixin template getScopeName() { // NG, circular reference to scopeName // enum scopeName = __traits(identifier, __traits(parent, scopeName)); // should be OK enum string scopeName = __traits(identifier, __traits(parent, scopeName)); } In original case, the type of scopeName is inferred from its initializer. Therefore on the evaluation of __traits(parent, scopeName), it will recursively invoke semantic analysis of the initialize, then it will cause forward reference. By adding variable type, the declaration and definition of scopeName variable will be properly separated. Therefore on __traits(parent, scopeName), it should not cause recursive semantic analysis of the initializer. Finally it should work as expected. ---- But, currently the code will cause ICE. It is definitely a compiler bug. I'll open a pull request to fix it. -- |
April 15, 2014 [Issue 12571] __traits(parent) should work for typed manifest constant in initializer | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=12571 Kenji Hara <k.hara.pg@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |ice Summary|Regression (2.063): Can no |__traits(parent) should |longer use static |work for typed manifest |introspection on circular |constant in initializer |references | Severity|regression |major -- |
April 15, 2014 [Issue 12571] __traits(parent) should work for typed manifest constant in initializer | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=12571 --- Comment #6 from Andrej Mitrovic <andrej.mitrovich@gmail.com> --- (In reply to Kenji Hara from comment #5) > By adding variable type, the declaration and definition of scopeName variable will be properly separated. Therefore on __traits(parent, scopeName), it should not cause recursive semantic analysis of the initializer. Finally it should work as expected. Interesting. Thanks for examining this. I'll CC Philippe Sigaud so he's up-to-date on what needs fixing in the Templates book. -- |
April 15, 2014 [Issue 12571] __traits(parent) should work for typed manifest constant in initializer | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=12571 Andrej Mitrovic <andrej.mitrovich@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |philippe.sigaud@gmail.com -- |
April 15, 2014 [Issue 12571] __traits(parent) should work for typed manifest constant in initializer | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=12571 Kenji Hara <k.hara.pg@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |pull --- Comment #7 from Kenji Hara <k.hara.pg@gmail.com> --- https://github.com/D-Programming-Language/dmd/pull/3456 -- |
April 15, 2014 [Issue 12571] __traits(parent) should work for typed manifest constant in initializer | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=12571 github-bugzilla@puremagic.com changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution|--- |FIXED -- |
Copyright © 1999-2021 by the D Language Foundation