www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Really in need of help with std.container.array.d

reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
I'm trying to figure out how to add complete support for 
constness in std.container.array.Array at

https://github.com/D-Programming-Language/phobos/commit/703305f0bfb1cc22eff3e44e351cc3db3e03f94f#commitcomment-8114056

My current solution (which currently fails) at

https://github.com/nordlow/phobos/commit/5c57cb18c2b9d340a19d19207deca5af0339cf7e#diff-0

tries to solve the problem by making wrapper struct Range a 
template that captures the constness of parenting Array. My 
current implementation of array.d at

https://github.com/nordlow/phobos/blob/inout-array-range/std/container/array.d#L221

however fails its unittests as

array.d(223,19): Error: variable 
std.container.array.Array!int.Array.Range!(inout(Array!int)).Range._outer 
only parameters or stack based variables can be inout
array.d(430,5): Error: template instance 
std.container.array.Array!int.Array.Range!(inout(Array!int)) 
error instantiating
array.d(833,5):        instantiated from here: Array!int
array.d(862,5): Error: static assert  (!true) is false

and I have no clue how to proceed with this. Please help, me and 
at least one other D developer is hindered by this.
Oct 12 2014
parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Sunday, 12 October 2014 at 20:17:38 UTC, Nordlöw wrote:
https://github.com/nordlow/phobos/commit/5c57cb18c2b9d340a19d19207deca5af0339cf7e#diff-0

Made some corrections

https://github.com/nordlow/phobos/compare/inout-array-range

but gives a similar error

array.d(223,19): Error: variable 
std.container.array.Array!int.Array.Range!(inout(Array!int)).Range._outer 
only parameters or stack based variables can be inout
array.d(430,5): Error: template instance 
std.container.array.Array!int.Array.Range!(inout(Array!int)) 
error instantiating
array.d(833,5):        instantiated from here: Array!int
array.d(816,5): Error: template instance 
std.container.array.Array!int.Array.Range!(Array!int) error 
instantiating
array.d(833,5):        instantiated from here: Array!int
array.d(862,5): Error: static assert  (!true) is false
Oct 12 2014
parent reply "Robert burner Schadek" <rburners gmail.com> writes:
hm, the problems seams to be that "inout Array" is not becoming 
"const Array" and friends.

A blunt force solution would be to create a range as
Range!(ReturnType!Array...)(cast(Array!T)this, low, high);
and then do the correct casts in Range.
The ReturnType would be the ReturnType of opIndex of the Range 
type and the Array would be stored as plain array without any 
qualifier.

other than that I'm not sure how to go about this.
Oct 13 2014
next sibling parent =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Monday, 13 October 2014 at 13:46:56 UTC, Robert burner Schadek 
wrote:
 other than that I'm not sure how to go about this.
I tried replace inout with a C++-style member duplication at https://github.com/nordlow/phobos/commit/b2a4ca28bf25bf7c6149566d066cbb54118b36b4 Now it instead errors as Error: mutable method std.container.array.Array!int.Array.__fieldPostBlit is not callable using a const object array.d(252,26): Error: cast(inout(int))this._outer.opIndex(this._a) is not an lvalue array.d(258,26): Error: cast(inout(int))this._outer.opIndex(this._b - 1LU) is not an lvalue ../../std/algorithm.d(2364,9): Error: cannot modify const expression result array.d(276,24): Error: template instance std.algorithm.move!(const(int)) error instantiating array.d(439,5): instantiated from here: Range!(const(Array!int)) array.d(851,5): instantiated from here: Array!int array.d(294,26): Error: cast(inout(int))this._outer.opIndex(this._a + i) is not an lvalue Error: mutable method std.container.array.Array!int.Array.~this is not callable using a const object array.d(320,30): Error: None of the overloads of 'opSliceAssign' are callable using a const object, candidates are: array.d(507,10): std.container.array.Array!int.Array.opSliceAssign(int value) array.d(514,10): std.container.array.Array!int.Array.opSliceAssign(int value, ulong i, ulong j) array.d(326,38): Error: None of the overloads of 'opSliceAssign' are callable using a const object, candidates are: array.d(507,10): std.container.array.Array!int.Array.opSliceAssign(int value) array.d(514,10): std.container.array.Array!int.Array.opSliceAssign(int value, ulong i, ulong j) array.d(299,32): Error: mutable method std.container.array.Array!int.Array.Range!(Array!int).Range.this is not callable using a const object array.d(309,32): Error: mutable method std.container.array.Array!int.Array.Range!(Array!int).Range.this is not callable using a const object array.d(443,5): Error: template instance std.container.array.Array!int.Array.Range!(Array!int) error instantiating array.d(851,5): instantiated from here: Array!int ../../std/typecons.d(3889,17): Error: template instance object.destroy!(Payload) error instantiating array.d(169,26): instantiated from here: RefCounted!(Payload, cast(RefCountedAutoInitialize)0) array.d(851,5): instantiated from here: Array!int array.d(880,5): Error: static assert (!true) is false Ideas?
Oct 14 2014
prev sibling parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Monday, 13 October 2014 at 13:46:56 UTC, Robert burner Schadek 
wrote:
 A blunt force solution would be to create a range as
 Range!(ReturnType!Array...)(cast(Array!T)this, low, high);
 and then do the correct casts in Range.
 The ReturnType would be the ReturnType of opIndex of the Range 
 type and the Array would be stored as plain array without any
Do you mean a mutable array containing references to inout data?
 qualifier.
Could you please give me a code example? I'm not skilled enough in D to follow this description.
Oct 14 2014
parent reply "Robert burner Schadek" <rburners gmail.com> writes:
On Tuesday, 14 October 2014 at 12:51:29 UTC, Nordlöw wrote:

 Could you please give me a code example? I'm not skilled enough 
 in D to follow this description.
struct Range(T) { Array!S array; T opIndex(size_t i) { return cast(T)array[i]; } } struct Array(T) { Range!(const(T)) opSlice() const { return Range!(const(T))(cast(Array!T)array, 0, length); } Range!(T) opSlice() const { return Range!(T)(cast(Array!T)array, 0, length); } }
Oct 14 2014
parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Tuesday, 14 October 2014 at 16:08:31 UTC, Robert burner 
Schadek wrote:
 On Tuesday, 14 October 2014 at 12:51:29 UTC, Nordlöw wrote:

 Could you please give me a code example? I'm not skilled 
 enough in D to follow this description.
struct Range(T) { Array!S array; T opIndex(size_t i) { return cast(T)array[i]; } } struct Array(T) { Range!(const(T)) opSlice() const { return Range!(const(T))(cast(Array!T)array, 0, length); } Range!(T) opSlice() const { return Range!(T)(cast(Array!T)array, 0, length); } }
I tried that at https://github.com/nordlow/phobos/commit/9daf235d7091f76cd941e29e3c167d559bf56a94 but that triggers a new interesting suite of errors Error: mutable method std.container.array.Array!int.Array.__fieldPostBlit is not callable using a const object array.d(252,26): Error: cast(inout(int))this._outer.opIndex(this._a) is not an lvalue array.d(258,26): Error: cast(inout(int))this._outer.opIndex(this._b - 1LU) is not an lvalue ../../std/algorithm.d(2364,9): Error: cannot modify const expression result array.d(276,24): Error: template instance std.algorithm.move!(const(int)) error instantiating array.d(444,5): instantiated from here: Range!(const(Array!int)) array.d(856,5): instantiated from here: Array!int array.d(299,26): Error: cast(int)this._outer.opIndex(this._a + i) is not an lvalue Error: mutable method std.container.array.Array!int.Array.~this is not callable using a const object array.d(325,30): Error: None of the overloads of 'opSliceAssign' are callable using a const object, candidates are: array.d(512,10): std.container.array.Array!int.Array.opSliceAssign(int value) array.d(519,10): std.container.array.Array!int.Array.opSliceAssign(int value, ulong i, ulong j) array.d(331,38): Error: None of the overloads of 'opSliceAssign' are callable using a const object, candidates are: array.d(512,10): std.container.array.Array!int.Array.opSliceAssign(int value) array.d(519,10): std.container.array.Array!int.Array.opSliceAssign(int value, ulong i, ulong j) array.d(304,32): Error: mutable method std.container.array.Array!int.Array.Range!(Array!int).Range.this is not callable using a const object array.d(314,32): Error: mutable method std.container.array.Array!int.Array.Range!(Array!int).Range.this is not callable using a const object array.d(448,5): Error: template instance std.container.array.Array!int.Array.Range!(Array!int) error instantiating array.d(856,5): instantiated from here: Array!int ../../std/typecons.d(3889,17): Error: template instance object.destroy!(Payload) error instantiating array.d(169,26): instantiated from here: RefCounted!(Payload, cast(RefCountedAutoInitialize)0) array.d(856,5): instantiated from here: Array!int array.d(885,5): Error: static assert (!true) is false Comint exited abnormally with code 1 at Wed Oct 15 23:14:37 I'm stuck. Need help.
Oct 15 2014
next sibling parent reply "Robert burner Schadek" <rburners gmail.com> writes:
On Wednesday, 15 October 2014 at 21:15:14 UTC, Nordlöw wrote:

 Comint exited abnormally with code 1 at Wed Oct 15 23:14:37

 I'm stuck. Need help.
I will give it a try
Oct 16 2014
parent =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Thursday, 16 October 2014 at 13:56:18 UTC, Robert burner 
Schadek wrote:
 I'm stuck. Need help.
I will give it a try
Thank you.
Oct 16 2014
prev sibling parent reply "anonymous" <anonymous example.com> writes:
On Wednesday, 15 October 2014 at 21:15:14 UTC, Nordlöw wrote:
 https://github.com/nordlow/phobos/commit/9daf235d7091f76cd941e29e3c167d559bf56a94

 but that triggers a new interesting suite of errors

 Error: mutable method 
 std.container.array.Array!int.Array.__fieldPostBlit is not 
 callable using a const object
[...]
 Error: mutable method std.container.array.Array!int.Array.~this 
 is not callable using a const object
[...]
 I'm stuck. Need help.
I reduced it to this: ---- struct RefCounted { this(this) /* const doesn't help */ {} ~this() /* const doesn't help */ {} } struct Array { RefCounted _data; } void main() {const Array a; const copy = a;} /* works */ struct RangeM {Array a;} /* works */ struct RangeC {const Array a;} /* error */ ---- Looks like a compiler bug to me. And here's a workaround: ---- struct RangeC { const Array[1] a_; property ref const(Array) a() {return a_[0];} } ---- Using it in std.container.array: ---- static struct Range(A) { private A[1] _outer_; private property ref const(A) _outer() const {return _outer_[0];} private property ref A _outer() {return _outer_[0];} /* ... */ private this(ref A data, size_t a, size_t b) { version(none) _outer = data; /* "Error: mutable method [...].Array.opAssign is not callable using a const object" */ else version(none) _outer_[0] = data; /* Errors about postblit. */ else _outer_ = data; /* works */ /* ... */ } ---- Then you also have to disable any methods/overloads that would return mutable data when A isn't mutable, e.g.: ---- static if (isMutable!A) property ref T front() {/* ... */} ---- Related: `front` and `back` cannot be inout, because the constness depends not on Range's constness, but on Array's.
Oct 19 2014
next sibling parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Sunday, 19 October 2014 at 15:21:02 UTC, anonymous wrote:
              version(none) _outer = data; /* "Error: mutable 
 method
                  [...].Array.opAssign is not callable using a
 const object" */
What do these comments containing Error messages mean? Doesn't this code compile?
Oct 19 2014
parent reply "anonymous" <anonymous example.com> writes:
On Sunday, 19 October 2014 at 18:58:50 UTC, Nordlöw wrote:
 On Sunday, 19 October 2014 at 15:21:02 UTC, anonymous wrote:
             version(none) _outer = data; /* "Error: mutable 
 method
                 [...].Array.opAssign is not callable using a
 const object" */
What do these comments containing Error messages mean? Doesn't this code compile?
Yes, they don't compile. It's three slightly different versions of initializing _outer. The first one, `_outer = data;`, is the original one. It's understandable that it doesn't work anymore with the workaround in place. I don't know why the second one, `_outer_[0] = data;`, doesn't work. Maybe it triggers the same (or a related) postblit compiler bug again. It's essentially the same as the third one, `_outer_ = data;`, which happens to work.
Oct 19 2014
parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Sunday, 19 October 2014 at 19:13:33 UTC, anonymous wrote:
 Yes, they don't compile. It's three slightly different versions
 of initializing _outer.

 The first one, `_outer = data;`, is the original one. It's
 understandable that it doesn't work anymore with the workaround
 in place.

 I don't know why the second one, `_outer_[0] = data;`, doesn't
 work. Maybe it triggers the same (or a related) postblit 
 compiler
 bug again. It's essentially the same as the third one, `_outer_ 
 =
 data;`, which happens to work.
So there's currently no complete solution to this problem yet, then?
Oct 19 2014
parent reply "anonymous" <anonymous example.com> writes:
On Sunday, 19 October 2014 at 19:30:40 UTC, Nordlöw wrote:
 On Sunday, 19 October 2014 at 19:13:33 UTC, anonymous wrote:
 Yes, they don't compile. It's three slightly different versions
 of initializing _outer.

 The first one, `_outer = data;`, is the original one. It's
 understandable that it doesn't work anymore with the workaround
 in place.

 I don't know why the second one, `_outer_[0] = data;`, doesn't
 work. Maybe it triggers the same (or a related) postblit 
 compiler
 bug again. It's essentially the same as the third one, 
 `_outer_ =
 data;`, which happens to work.
So there's currently no complete solution to this problem yet, then?
The last variant works: `_outer_ = data;`. And that one is enabled in my code, while the other two are `version(none)`-ed away.
Oct 19 2014
parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Sunday, 19 October 2014 at 19:36:46 UTC, anonymous wrote:
 On Sunday, 19 October 2014 at 19:30:40 UTC, Nordlöw wrote:
 On Sunday, 19 October 2014 at 19:13:33 UTC, anonymous wrote:
 Yes, they don't compile. It's three slightly different 
 versions
 of initializing _outer.

 The first one, `_outer = data;`, is the original one. It's
 understandable that it doesn't work anymore with the 
 workaround
 in place.

 I don't know why the second one, `_outer_[0] = data;`, doesn't
 work. Maybe it triggers the same (or a related) postblit 
 compiler
 bug again. It's essentially the same as the third one, 
 `_outer_ =
 data;`, which happens to work.
So there's currently no complete solution to this problem yet, then?
The last variant works: `_outer_ = data;`. And that one is enabled in my code, while the other two are `version(none)`-ed away.
Used your ideas here https://github.com/nordlow/phobos/commit/be6b5f8c4d428a9708a52757a3f31aab6878d379 but unittests now fails as array.d(234,13): Error: mutable method std.container.array.Array!int.Array.opAssign is not callable using a const object ../../std/algorithm.d(2364,9): Error: cannot modify const expression result array.d(297,24): Error: template instance std.algorithm.move!(const(int)) error instantiating array.d(465,5): instantiated from here: Range!(const(Array!int)) array.d(877,5): instantiated from here: Array!int array.d(320,26): Error: cast(int)__dop1738.opIndex(this._a + i) is not an lvalue array.d(346,30): Error: None of the overloads of 'opSliceAssign' are callable using a const object, candidates are: array.d(533,10): std.container.array.Array!int.Array.opSliceAssign(int value) array.d(540,10): std.container.array.Array!int.Array.opSliceAssign(int value, ulong i, ulong j) array.d(352,38): Error: None of the overloads of 'opSliceAssign' are callable using a const object, candidates are: array.d(533,10): std.container.array.Array!int.Array.opSliceAssign(int value) array.d(540,10): std.container.array.Array!int.Array.opSliceAssign(int value, ulong i, ulong j) array.d(325,32): Error: mutable method std.container.array.Array!int.Array.Range!(Array!int).Range.this is not callable using a const object array.d(335,32): Error: mutable method std.container.array.Array!int.Array.Range!(Array!int).Range.this is not callable using a const object array.d(469,5): Error: template instance std.container.array.Array!int.Array.Range!(Array!int) error instantiating array.d(877,5): instantiated from here: Array!int ../../std/typecons.d(3889,17): Error: template instance object.destroy!(Payload) error instantiating array.d(169,26): instantiated from here: RefCounted!(Payload, cast(RefCountedAutoInitialize)0) array.d(877,5): instantiated from here: Array!int array.d(906,5): Error: static assert (!true) is false Comint exited abnormally with code 1 at Sun Oct 19 22:06:48
Oct 19 2014
parent reply "anonymous" <anonymous example.com> writes:
On Sunday, 19 October 2014 at 20:10:33 UTC, Nordlöw wrote:
 Used your ideas here

 https://github.com/nordlow/phobos/commit/be6b5f8c4d428a9708a52757a3f31aab6878d379

 but unittests now fails as

 array.d(234,13): Error: mutable method 
 std.container.array.Array!int.Array.opAssign is not callable 
 using a const object
You didn't make the change we just discussed. Change line 234 from `_outer = data;` to `_outer_ = data;`. You also need to guard much more with `static if (isMutable!A)`: * everything that returns (non-const) T, * everything that returns Range!A, * everything that mutates elements (e.g. opSliceAssign). And you can't do `return typeof(this)(...);` when the return type is `Range!(const(A))`, because `typeof(this)` can be `const(Range!A)` which is not the same. Spell the type out or use `typeof(result)`.
Oct 19 2014
next sibling parent "anonymous" <anonymous example.com> writes:
On Sunday, 19 October 2014 at 20:39:18 UTC, anonymous wrote:
 Spell the type out or  use `typeof(result)`.
Should be `typeof(return)`.
Oct 19 2014
prev sibling parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Sunday, 19 October 2014 at 20:39:18 UTC, anonymous wrote:
 array.d(234,13): Error: mutable method 
 std.container.array.Array!int.Array.opAssign is not callable 
 using a const object
You didn't make the change we just discussed. Change line 234 from `_outer = data;` to `_outer_ = data;`. You also need to guard much more with `static if (isMutable!A)`: * everything that returns (non-const) T, * everything that returns Range!A, * everything that mutates elements (e.g. opSliceAssign). And you can't do `return typeof(this)(...);` when the return type is `Range!(const(A))`, because `typeof(this)` can be `const(Range!A)` which is not the same. Spell the type out or use `typeof(result)`.
New response at https://github.com/nordlow/phobos/commit/ce6b9e9ae600b7c28ecddd1e3af7b1516247fb33 now errors as array.d(927,15): Error: None of the overloads of 'opSlice' are callable using a const object, candidates are: array.d(472,25): std.container.array.Array!int.Array.opSlice() array.d(495,25): std.container.array.Array!int.Array.opSlice(ulong i, ulong j)
Oct 19 2014
parent reply "anonymous" <anonymous example.com> writes:
On Sunday, 19 October 2014 at 22:19:05 UTC, Nordlöw wrote:
 https://github.com/nordlow/phobos/commit/ce6b9e9ae600b7c28ecddd1e3af7b1516247fb33

 now errors as

 array.d(927,15): Error: None of the overloads of 'opSlice' are 
 callable using a const object, candidates are:
 array.d(472,25):        
 std.container.array.Array!int.Array.opSlice()
 array.d(495,25):        
 std.container.array.Array!int.Array.opSlice(ulong i, ulong j)
The error is because of this (lines 470 through 483): ---- static if (isMutable!T) { Range!(Array!T) opSlice() { return typeof(return)(this, 0, length); } } else { Range!(const(Array!T)) opSlice() const { return typeof(return)(this, 0, length); } } ---- You're disabling the const version when T is mutable. Consider const(Array!int): T is int is mutable, so there is no const opSlice. But the Array itself is const, so the non-const version can't be used. Do not disable the const versions of the methods. Only ever disable the non-const ones. Also, the opSlice we're looking at here is Array's, not Array.Range's. You don't need to touch Array's methods at all. Only Array.Range's non-const methods need special treatment, because you need to catch the special case when the Range is mutable, but the referenced Array is not. And it's really `isMutableA!`, not `isMutable!T`. I guess you went for that because `A` is only defined in Array.Range, not in Array itself. But T's mutability isn't of interest. For example, Array.Range.opSlice should look like this: ---- static if (isMutable!A) /* !A, not !T */ { Range!(A) opSlice() {/* ... */} Range!(A) opSlice(size_t i, size_t j) {/* ... */} } /* No `else`, the const versions should always be available. */ Range!(const(A)) opSlice() const {/* ... */} Range!(const(A)) opSlice(size_t i, size_t j) const {/* ... */} ---- Then there are still various methods of Array.Range left to be `static if(isMutable!A)` guarded: * move* * opIndex * opSlice* By the way, since we're in D.learn, I'm assuming you want to do this yourself. But if you'd like, I could make a pull request with my suggestions to your branch.
Oct 20 2014
parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Monday, 20 October 2014 at 10:56:43 UTC, anonymous wrote:
 On Sunday, 19 October 2014 at 22:19:05 UTC, Nordlöw wrote:
 By the way, since we're in D.learn, I'm assuming you want to do
 this yourself. But if you'd like, I could make a pull request
 with my suggestions to your branch.
Yes, please! That would be very kind of you. /Thx
Oct 20 2014
parent reply "anonymous" <anonymous example.com> writes:
On Monday, 20 October 2014 at 11:20:30 UTC, Nordlöw wrote:
 On Monday, 20 October 2014 at 10:56:43 UTC, anonymous wrote:
 On Sunday, 19 October 2014 at 22:19:05 UTC, Nordlöw wrote:
 By the way, since we're in D.learn, I'm assuming you want to do
 this yourself. But if you'd like, I could make a pull request
 with my suggestions to your branch.
Yes, please! That would be very kind of you.
Forgot to mention it here, not sure if you noticed it: https://github.com/nordlow/phobos/pull/1
Oct 20 2014
parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Monday, 20 October 2014 at 18:01:11 UTC, anonymous wrote:
 Forgot to mention it here, not sure if you noticed it: 
 https://github.com/nordlow/phobos/pull/1
Superb.
Oct 20 2014
parent reply "thedeemon" <dlang thedeemon.com> writes:
Speaking of this module, since I cannot currently login to 
bugtracker, I'd like to note here that there are two major bugs 
in one little function: Array.Payload.length setter. One is this
https://issues.dlang.org/show_bug.cgi?id=13619

and the other is reallocating without notifying GC of the 
pointers, which leads to having dangling pointers in the array 
after a GC cycle.
Oct 20 2014
parent "thedeemon" <dlang thedeemon.com> writes:
On Tuesday, 21 October 2014 at 04:22:37 UTC, thedeemon wrote:
 Speaking of this module, since I cannot currently login to 
 bugtracker, I'd like to note here that there are two major bugs 
 in one little function: Array.Payload.length setter. One is this
 https://issues.dlang.org/show_bug.cgi?id=13619

 and the other is reallocating without notifying GC of the 
 pointers, which leads to having dangling pointers in the array 
 after a GC cycle.
Submitted the second one here: https://issues.dlang.org/show_bug.cgi?id=13642
Oct 20 2014
prev sibling parent "anonymous" <anonymous example.com> writes:
On Sunday, 19 October 2014 at 15:21:02 UTC, anonymous wrote:
 ----
 struct RefCounted
 {
      this(this) /* const doesn't help */ {}
      ~this() /* const doesn't help */ {}
 }
 struct Array
 {
      RefCounted _data;
 }
 void main() {const Array a; const copy = a;} /* works */
 struct RangeM {Array a;} /* works */
 struct RangeC {const Array a;} /* error */
 ----

 Looks like a compiler bug to me.
Has already been filed: https://issues.dlang.org/show_bug.cgi?id=13629
Oct 19 2014