`issue.d`:
struct Array(E) {}
struct Enum(T...) {T t;}
alias NodeArray = Array!Node;
struct Object {NodeArray values;}
alias Node = Enum!(Object);
void main() {}
`dmd issue.d` fails and gives the following messages.
issue.d(3): Error: template instance `Array!Node` recursive template expansion
issue.d(5): Error: template instance `issue.Enum!(Object)` error instantiating
Moving `NodeArray` below `Object` or `Node` suppresses the issue.
Comment #1 by b2.temp — 2024-04-04T22:11:46Z
slightly minimized
```
struct Array(E) {}
struct Enum(T) {T t;} // <-- here T size is not known yet
alias NodeArray = Array!(Enum!(Object));
struct Object {NodeArray values;}
```
IMO the error message is correct, for example
```
struct Array(E) {}
struct Enum(T) {T t;}
alias NodeArray = Array!(Enum!(Object*));
struct Object {NodeArray values;}
```
compiles. However that's a typical case of "how forward references are handled in D" is under-specified.
Comment #2 by b2.temp — 2024-04-04T22:51:56Z
Moving decls does not solve anything, just try
```
struct Array(E) { E e;}
struct Enum(T) {T t;}
struct Object {NodeArray values;}
alias NodeArray = Array!Node;
alias Node = Enum!(Object);
```
The point is that at some point you must know the size of a member. When the member is a pointer you can guess the size without knowing the actual pointee type size. Might be zero, might be 3 Billions, but in fine it's a pointer so let's see that later ;)
Comment #3 by scrubereal — 2024-04-04T23:08:43Z
Right; and an actual array would store an `E[]` or an `E*`. When `e`'s type is one of those, the program compiles.
Comment #4 by robert.schadek — 2024-12-13T19:34:27Z