Jump to page: 1 2
Thread overview
[Issue 12571] Regression (2.063): Can no longer use static introspection on circular references
Apr 15, 2014
Vladimir Panteleev
Apr 15, 2014
Kenji Hara
Apr 15, 2014
Andrej Mitrovic
Apr 15, 2014
Andrej Mitrovic
Apr 15, 2014
Kenji Hara
[Issue 12571] __traits(parent) should work for typed manifest constant in initializer
Apr 15, 2014
Kenji Hara
Apr 15, 2014
Andrej Mitrovic
Apr 15, 2014
Andrej Mitrovic
Apr 15, 2014
Kenji Hara
April 15, 2014
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
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
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
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
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
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
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
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
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
https://issues.dlang.org/show_bug.cgi?id=12571

github-bugzilla@puremagic.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED

--
« First   ‹ Prev
1 2