Possible D2 solution to the upcasting array problem, and a related problem with const and nested arrays

Stewart Gordon smjg_1998 at yahoo.com
Fri Jan 2 08:21:37 PST 2009


I've looked at invariant a bit, and found a few things.

     void func(const(int)[] answers) {
         invariant(int)[][] invar = [[]];
         const(int)[][] unsafe = invar;
         unsafe[0] = answers;
     }

This is unsafe, since answers, which is merely a read-only view, has 
been sneaked into invar, thereby disguising it as something that will 
never change.  So invariant is just like plain mutable in this instance. 
  OTOH, it would be OK assigned to a const(int[])[], or even a 
const(invariant(int)[])[].  (My experiment shows that the transitivity 
of invariant overrides that of const, though this doesn't seem to be in 
the spec.)


OTOH, an invariant class array can be upcast no problem

     invariant(DerivedClass)[]
to
     invariant(BaseClass)[]
or to either of these replacing invariant with const.  But we still need 
const on levels that are further out:
     invariant(DerivedClass)[][]
to
     const(invariant(DerivedClass)[])[]
     const(invariant(BaseClass)[])[]
     const(BaseClass[])[]


So we can rewrite my proposed set of rules:

1. Generalise the definition of an upcast to be any of the following:
(a) conversion of a class type to a class type further up the hierarchy
(b) conversion of a mutable or invariant type to a const version of that 
type
(c) an implicit conversion permitted by rule 2

2. If U is an upcast of T, then a legal implicit conversion is any of:
(a) T[] to const(U)[]
(b) T* to const(U)*
(c) invariant(T)[] to invariant(U)[]
(d) invariant(T)* to invariant(U)*
Any other conversion from T[] to U[] or T* to U* is illegal.


Notice that:

- the case of const(T)[] to const(U)[] is covered, since const(const(U)) 
is the same as const(U)

- given invariant(int)[][], both possible conversions are covered
-- const(int[])[] by first applying 1(b) to invariant(int) and then by 
applying 2(a) with T = const(int)[]
-- const(invariant(int)[])[] by just applying 1(b) to invariant(int)[]


That leaves AAs to consider....

Stewart.



More information about the Digitalmars-d mailing list