Thread overview
[Issue 8850] New: Nested struct creation by a template
Oct 18, 2012
Jesse Phillips
Oct 19, 2012
Jesse Phillips
Oct 19, 2012
timon.gehr@gmx.ch
Nov 07, 2012
Kenji Hara
Nov 07, 2012
Kenji Hara
Nov 07, 2012
Kenji Hara
Nov 07, 2012
timon.gehr@gmx.ch
Nov 08, 2012
Kenji Hara
October 18, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8850

           Summary: Nested struct creation by a template
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: Jesse.K.Phillips+D@gmail.com


--- Comment #0 from Jesse Phillips <Jesse.K.Phillips+D@gmail.com> 2012-10-18 14:15:06 PDT ---
I'm not sure the intended behavior but currently is inconsistent. The following code fails to compile with:

bad.d(2): Error: function D main is a nested function and cannot be accessed
from bad.fun!(R).fun

T fun(T)() if(is(T == struct)) {
    T s;
    return s;
}

void main() {
    struct R {
        void f() { }
    }

    auto m = fun!R();
}

However removing the function from the struct definition (include other values if desired) then it will compile. I'd think we'd want templates to have the ability to create a nested struct.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 19, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8850


Jesse Phillips <Jesse.K.Phillips+D@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |Jesse.K.Phillips+D@gmail.co
                   |                            |m


--- Comment #1 from Jesse Phillips <Jesse.K.Phillips+D@gmail.com> 2012-10-19 11:24:26 PDT ---
May be duplicating or related to: http://d.puremagic.com/issues/show_bug.cgi?id=8542

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 19, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8850


monarchdodra@gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |monarchdodra@gmail.com


--- Comment #2 from monarchdodra@gmail.com 2012-10-19 13:14:58 PDT ---
(In reply to comment #0)
> I'm not sure the intended behavior but currently is inconsistent. The following code fails to compile with:
> 
> bad.d(2): Error: function D main is a nested function and cannot be accessed
> from bad.fun!(R).fun
> 
> T fun(T)() if(is(T == struct)) {
>     T s;
>     return s;
> }
> 
> void main() {
>     struct R {
>         void f() { }
>     }
> 
>     auto m = fun!R();
> }
> 
> However removing the function from the struct definition (include other values if desired) then it will compile. I'd think we'd want templates to have the ability to create a nested struct.

Nested structs keep a frame pointer (or something alike) to be able to access
anything inside main, from outside of main. As such, you can't use them (as is)
as a template parameter.

HOWEVER, you can declare your struct as "static" explicitly stating that the struct does not keep any extra info, at which point it becomes useable:

T fun(T)() if(is(T == struct)) {
   T s;
   return s;
}

void main() {
   static struct R {
       void f() { }
   }

   auto m = fun!R();
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 19, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8850


timon.gehr@gmx.ch changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |timon.gehr@gmx.ch


--- Comment #3 from timon.gehr@gmx.ch 2012-10-19 15:30:32 PDT ---
I think it is supposed to work, the following does work:

T fun(T, alias f)(){
    T s;
    return s;
}

void main() {
    int x=2;
    void f(){}
    struct R { int f() { return x; } }
    auto m = fun!(R,f)();
}

(The reason why it works is that the alias function parameter forces local
template instantiation.)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 07, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8850



--- Comment #4 from Kenji Hara <k.hara.pg@gmail.com> 2012-11-07 04:50:03 PST ---
(In reply to comment #0)
> T fun(T)() if(is(T == struct)) {
>     T s;    // [a]
>     return s;
> }
> void main() {
>     struct R {
>         void f() { }
>     }
>     auto m = fun!R();
> }

In this case, R in main is a nested struct, and fun!T cannot access main's
frame pointer to construct R at the point [a], then the code correctly fail to
compile.
This behavior is introduced by fixing bug 8339, so it is intended behavior.

> However removing the function from the struct definition (include other values
if desired) then it will compile. I'd think we'd want templates to have the ability to create a nested struct.

If you remove member function f() from R, R is implicitly treated as static, because no code would access to the frame of main. Then, the need to access frame of main from fun!R is eliminated, and the compilation will succeed.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 07, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8850



--- Comment #5 from Kenji Hara <k.hara.pg@gmail.com> 2012-11-07 04:55:54 PST ---
(In reply to comment #3)
> I think it is supposed to work, the following does work:

In Currently, I answer: No.
Even if TemplateTypeParameter gets nested struct type, a template instantiation
will not capture the enclosing scope frame of the nested struct. It is intended
behavior.

> T fun(T, alias f)(){
>     T s;
>     return s;
> }
> 
> void main() {
>     int x=2;
>     void f(){}
>     struct R { int f() { return x; } }
>     auto m = fun!(R,f)();
> }
> 
> (The reason why it works is that the alias function parameter forces local
> template instantiation.)

In this case, as you say, func!(R, f) captures main's frame pointer (In other
words, func!(R, f) will be instantiated as a _nested template_ in main).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 07, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8850


Kenji Hara <k.hara.pg@gmail.com> changed:

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


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 07, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8850


timon.gehr@gmx.ch changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|INVALID                     |


--- Comment #6 from timon.gehr@gmx.ch 2012-11-07 09:55:21 PST ---
(In reply to comment #5)
> (In reply to comment #3)
> > I think it is supposed to work, the following does work:
> 
> In Currently, I answer: No.
> Even if TemplateTypeParameter gets nested struct type, a template instantiation
> will not capture the enclosing scope frame of the nested struct. It is intended
> behavior.
> 

On second thought, you are right.

> > T fun(T, alias f)(){
> >     T s;
> >     return s;
> > }
> > 
> > void main() {
> >     int x=2;
> >     void f(){}
> >     struct R { int f() { return x; } }
> >     auto m = fun!(R,f)();
> > }
> > 
> > (The reason why it works is that the alias function parameter forces local
> > template instantiation.)
> 
> In this case, as you say, func!(R, f) captures main's frame pointer (In other
> words, func!(R, f) will be instantiated as a _nested template_ in main).

I still think it might be sub-optimal that this has an influence on whether the context pointer for R is available, but it is not a big deal.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 08, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8850



--- Comment #7 from Kenji Hara <k.hara.pg@gmail.com> 2012-11-07 16:23:43 PST ---
(In reply to comment #6)
> (In reply to comment #5)
> I still think it might be sub-optimal that this has an influence on whether the
> context pointer for R is available, but it is not a big deal.

If you think that should work, you should open a new issue instead of reopen this,  because it is an enhancement.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------