Bug 8850 – Nested struct creation by a template

Status
REOPENED
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-10-18T14:15:06Z
Last change time
2024-12-13T18:01:45Z
Assigned to
No Owner
Creator
Jesse Phillips
Moved to GitHub: dmd#18476 →

Comments

Comment #0 by Jesse.K.Phillips+D — 2012-10-18T14:15:06Z
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.
Comment #1 by Jesse.K.Phillips+D — 2012-10-19T11:24:26Z
May be duplicating or related to: http://d.puremagic.com/issues/show_bug.cgi?id=8542
Comment #2 by monarchdodra — 2012-10-19T13:14:58Z
(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(); }
Comment #3 by timon.gehr — 2012-10-19T15:30:32Z
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.)
Comment #4 by k.hara.pg — 2012-11-07T04:50:03Z
(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.
Comment #5 by k.hara.pg — 2012-11-07T04:55:54Z
(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).
Comment #6 by timon.gehr — 2012-11-07T09:55:21Z
(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.
Comment #7 by k.hara.pg — 2012-11-07T16:23:43Z
(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.
Comment #8 by robert.schadek — 2024-12-13T18:01:45Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18476 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB