digitalmars.D.learn - Recursive template instantiation
- Jack Applegame (48/48) Mar 13 2017 I'm pretty sure that this code should compile
- Jack Applegame (1/1) Mar 13 2017 Is this a bug?
- Stefan Koch (15/16) Mar 13 2017 No it's not
- ag0aep6g (22/38) Mar 13 2017 I don't think that's it.
- ag0aep6g (11/31) Mar 13 2017 It compiles when it's a normal method instead of a destructor:
- Stefan Koch (2/40) Mar 13 2017 Try to use m.
- ag0aep6g (23/35) Mar 13 2017 Works no problem?
I'm pretty sure that this code should compile (https://dpaste.dzfl.pl/cf1e1ee6ef4b): struct A(T) { ~this() { char[T.sizeof] data; } } struct B(T) { A!T foo; } struct C { B!C bar; } void main() { C c; } But it doesn't: /d300/f416.d(3): Error: struct f416.C no size because of forward reference /d300/f416.d(12): Error: template instance f416.B!(C) error instantiating Notice that the same C++ code compiles without problems: template<typename T> struct A { ~A() { char data[sizeof(T)]; } }; template<typename T> struct B { A<T> foo; }; struct C { B<C> bar; }; int main() { C c; } A simple recursion is compiled successfully (https://dpaste.dzfl.pl/5a8ff73bfa88): struct A(T) { ~this() { char[T.sizeof] data; } } struct C { A!C bar; } void main() { C c; }
Mar 13 2017
On Monday, 13 March 2017 at 22:05:24 UTC, Jack Applegame wrote:Is this a bug?No it's not struct C { B!C; } is an error. Howto compute C ? <------\ let's check the members; | The member needs a template. | Howto compute the template ? | let's compute the parameters. | What is the first Parameter ? | Its C. | Howoto compute C -------/
Mar 13 2017
On 03/13/2017 11:58 PM, Stefan Koch wrote:On Monday, 13 March 2017 at 22:05:24 UTC, Jack Applegame wrote:I don't think that's it. Here's a variant where B is not instantiated with C: ---- struct A() { ~this() { enum s = C.sizeof; } } struct B() { A!() foo; } struct C { B!() bar; } ---- How to compute C? Check members. For member `B!() bar;`, resolve `B!()`. Check members of `B!()`. For member `A!() foo;` resolve `A!()`. Check members of `A!()`. No members => size = 0 (or rather 1, I guess). Bubble up. But the compiler seems to get confused by the destructor. I guess it incorrectly(?) sees a need to analyze C again before it can finish up `A!()`?Is this a bug?No it's not struct C { B!C; } is an error. Howto compute C ? <------\ let's check the members; | The member needs a template. | Howto compute the template ? | let's compute the parameters. | What is the first Parameter ? | Its C. | Howoto compute C -------/
Mar 13 2017
On 03/13/2017 03:26 PM, Jack Applegame wrote:I'm pretty sure that this code should compile (https://dpaste.dzfl.pl/cf1e1ee6ef4b): struct A(T) { ~this() { char[T.sizeof] data; } } struct B(T) { A!T foo; } struct C { B!C bar; } void main() { C c; } But it doesn't: /d300/f416.d(3): Error: struct f416.C no size because of forward reference /d300/f416.d(12): Error: template instance f416.B!(C) error instantiatingIt compiles when it's a normal method instead of a destructor: ---- struct A(T) { void m() { char[T.sizeof] data; } } /* ... rest as above ... */ ---- I don't see how the destructor makes a difference. Soo, bug?
Mar 13 2017
On Monday, 13 March 2017 at 22:59:36 UTC, ag0aep6g wrote:On 03/13/2017 03:26 PM, Jack Applegame wrote:Try to use m.I'm pretty sure that this code should compile (https://dpaste.dzfl.pl/cf1e1ee6ef4b): struct A(T) { ~this() { char[T.sizeof] data; } } struct B(T) { A!T foo; } struct C { B!C bar; } void main() { C c; } But it doesn't: /d300/f416.d(3): Error: struct f416.C no size because of forward reference /d300/f416.d(12): Error: template instance f416.B!(C) error instantiatingIt compiles when it's a normal method instead of a destructor: ---- struct A(T) { void m() { char[T.sizeof] data; } } /* ... rest as above ... */ ---- I don't see how the destructor makes a difference. Soo, bug?
Mar 13 2017
On 03/14/2017 12:02 AM, Stefan Koch wrote:On Monday, 13 March 2017 at 22:59:36 UTC, ag0aep6g wrote:[...]Works no problem? ---- struct A(T) { void m() { char[T.sizeof] data; import std.stdio; writeln(T.sizeof); } } struct B(T) { A!T foo; } struct C { B!C bar; } void main() { C c; c.bar.foo.m(); } ---- Prints "1".---- struct A(T) { void m() { char[T.sizeof] data; } } /* ... rest as above ... */ ---- I don't see how the destructor makes a difference. Soo, bug?Try to use m.
Mar 13 2017