www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - std.container.array of struct inside a struct fails

reply Anton Fediushin <fediushin.anton yandex.ru> writes:
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.
Jul 14 2017
parent reply drug <drug2004 bk.ru> writes:
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.
Jul 14 2017
parent reply Anton Fediushin <fediushin.anton yandex.ru> writes:
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!
Jul 14 2017
parent drug <drug2004 bk.ru> writes:
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!
Jul 14 2017