Thread overview
std.container.array of struct inside a struct fails
Jul 14, 2017
Anton Fediushin
Jul 14, 2017
drug
Jul 14, 2017
Anton Fediushin
Jul 14, 2017
drug
July 14, 2017
This code:
-----
import std.container.array;

struct Test {
	Array!Test t;
}
-----

Fails with an error:
-----
/usr/include/dlang/dmd/std/traits.d(2404): Error: struct arrayissue.Test no size because of forward reference
/usr/include/dlang/dmd/std/traits.d(3462): Error: template instance std.traits.FieldTypeTuple!(Test) error instantiating
/usr/include/dlang/dmd/std/container/array.d(276):        instantiated from here: hasElaborateDestructor!(Test)
arrayissue.d(4):        instantiated from here: Array!(Test)
/usr/include/dlang/dmd/std/container/array.d(280): Error: template instance std.traits.hasIndirections!(Test) error instantiating
arrayissue.d(4):        instantiated from here: Array!(Test)
/usr/include/dlang/dmd/std/traits.d(2613): Error: template instance std.traits.RepresentationTypeTuple!(Test) error instantiating
/usr/include/dlang/dmd/std/traits.d(2934):        instantiated from here: hasRawAliasing!(Test)
/usr/include/dlang/dmd/std/algorithm/mutation.d(1362):        instantiated from here: hasAliasing!(Test)
/usr/include/dlang/dmd/std/algorithm/mutation.d(1206):        instantiated from here: moveEmplace!(Test)
/usr/include/dlang/dmd/std/algorithm/mutation.d(1200):        ... (3 instantiations, -v to show) ...
/usr/include/dlang/dmd/std/container/array.d(487):        instantiated from here: RangeT!(Array!(Test))
arrayissue.d(4):        instantiated from here: Array!(Test)
/usr/include/dlang/dmd/std/traits.d(2934): Error: template instance std.traits.hasObjects!(Test) error instantiating
/usr/include/dlang/dmd/std/algorithm/mutation.d(1362):        instantiated from here: hasAliasing!(Test)
/usr/include/dlang/dmd/std/algorithm/mutation.d(1206):        instantiated from here: moveEmplace!(Test)
/usr/include/dlang/dmd/std/algorithm/mutation.d(1200):        instantiated from here: moveImpl!(Test)
/usr/include/dlang/dmd/std/algorithm/mutation.d(1162):        ... (2 instantiations, -v to show) ...
/usr/include/dlang/dmd/std/container/array.d(487):        instantiated from here: RangeT!(Array!(Test))
arrayissue.d(4):        instantiated from here: Array!(Test)
/usr/include/dlang/dmd/std/algorithm/mutation.d(1372): Error: template instance std.traits.hasElaborateAssign!(Test) error instantiating
/usr/include/dlang/dmd/std/algorithm/mutation.d(1206):        instantiated from here: moveEmplace!(Test)
/usr/include/dlang/dmd/std/algorithm/mutation.d(1200):        instantiated from here: moveImpl!(Test)
/usr/include/dlang/dmd/std/algorithm/mutation.d(1162):        instantiated from here: trustedMoveImpl!(Test)
/usr/include/dlang/dmd/std/container/array.d(148):        ... (1 instantiations, -v to show) ...
/usr/include/dlang/dmd/std/container/array.d(487):        instantiated from here: RangeT!(Array!(Test))
arrayissue.d(4):        instantiated from here: Array!(Test)
/usr/include/dlang/dmd/std/algorithm/mutation.d(1379): Error: template instance std.traits.hasElaborateCopyConstructor!(Test) error instantiating
/usr/include/dlang/dmd/std/algorithm/mutation.d(1206):        instantiated from here: moveEmplace!(Test)
/usr/include/dlang/dmd/std/algorithm/mutation.d(1200):        instantiated from here: moveImpl!(Test)
/usr/include/dlang/dmd/std/algorithm/mutation.d(1162):        instantiated from here: trustedMoveImpl!(Test)
/usr/include/dlang/dmd/std/container/array.d(148):        ... (1 instantiations, -v to show) ...
/usr/include/dlang/dmd/std/container/array.d(487):        instantiated from here: RangeT!(Array!(Test))
arrayissue.d(4):        instantiated from here: Array!(Test)
-----

But if I use `Test[] t;` instead, everything is fine.

Also, same code with `class` instead of `struct` works fine, and using `union` produces this error message:
-----
/usr/include/dlang/dmd/std/traits.d(2404): Error: union arrayissue.Test no size because of forward reference
/usr/include/dlang/dmd/std/traits.d(3025): Error: template instance std.traits.FieldTypeTuple!(Test) error instantiating
/usr/include/dlang/dmd/std/container/array.d(280):        instantiated from here: hasIndirections!(Test)
arrayissue.d(4):        instantiated from here: Array!(Test)
/usr/include/dlang/dmd/std/traits.d(2613): Error: template instance std.traits.RepresentationTypeTuple!(Test) error instantiating
/usr/include/dlang/dmd/std/traits.d(2934):        instantiated from here: hasRawAliasing!(Test)
/usr/include/dlang/dmd/std/algorithm/mutation.d(1362):        instantiated from here: hasAliasing!(Test)
/usr/include/dlang/dmd/std/algorithm/mutation.d(1206):        instantiated from here: moveEmplace!(Test)
/usr/include/dlang/dmd/std/algorithm/mutation.d(1200):        ... (3 instantiations, -v to show) ...
/usr/include/dlang/dmd/std/container/array.d(487):        instantiated from here: RangeT!(Array!(Test))
arrayissue.d(4):        instantiated from here: Array!(Test)
----


So, is it a bug, which should be fixed or it cannot be implemented at all? In this case it should be documented.

July 14, 2017
14.07.2017 19:12, Anton Fediushin пишет:
> This code:
> -----
> import std.container.array;
>
> struct Test {
>     Array!Test t;
> }
> -----
>
> Fails with an error:
> -----
> /usr/include/dlang/dmd/std/traits.d(2404): Error: struct arrayissue.Test
> no size because of forward reference
>
It's because Array(T) is a value type and needs type size to define itself, so you have expected forward reference. But T[] is reference type and its size is known in advance - it doesn't depend on type, it's always pointer.sizeof + length.sizeof, for 64x architecture it is 16 bytes, so in this case you have no the issue.
It's not a bug at all.
July 14, 2017
On Friday, 14 July 2017 at 16:42:59 UTC, drug wrote:
> It's because Array(T) is a value type and needs type size to define itself, so you have expected forward reference. But T[] is reference type and its size is known in advance - it doesn't depend on type, it's always pointer.sizeof + length.sizeof, for 64x architecture it is 16 bytes, so in this case you have no the issue.
> It's not a bug at all.

Thank you!
July 14, 2017
14.07.2017 19:53, Anton Fediushin пишет:
> On Friday, 14 July 2017 at 16:42:59 UTC, drug wrote:
>> It's because Array(T) is a value type and needs type size to define
>> itself, so you have expected forward reference. But T[] is reference
>> type and its size is known in advance - it doesn't depend on type,
>> it's always pointer.sizeof + length.sizeof, for 64x architecture it is
>> 16 bytes, so in this case you have no the issue.
>> It's not a bug at all.
>
> Thank you!
You're welcome!