I think Foo[] shouldn't be implicitly castable to Object[] (and
perhaps not even explicitly castable).

I see that you know, that according to the specs this behaviour
currently is not a bug (except that the ints are not initialized).
If this implicit casting will be declared as an error, then I see
at least an asymmetry to the implicit casting that can be made with
unions
<code>
import std.stdio;
void main() {
union U{
int a;
Object p;
};
U u;
u.p= new Object;
writefln(u.a);
}
</code>
which also prints out a nonnull value.
Because I see reasons to allow implicit castings with unions I
would rather add to the docs that the basetype to which array
handles can be implicitely casted has to be treated as though it
_is_ a union of its derived types.
-manfred

I think Foo[] shouldn't be implicitly castable to Object[] (and
perhaps not even explicitly castable).

I see that you know, that according to the specs this behaviour
currently is not a bug (except that the ints are not initialized).

correct - maybe I shouldn't have posted this to the D.bugs list but it seems
like a pretty obvious bug IMO.

If this implicit casting will be declared as an error, then I see
at least an asymmetry to the implicit casting that can be made with
unions
<code>
import std.stdio;
void main() {
union U{
int a;
Object p;
};
U u;
u.p= new Object;
writefln(u.a);
}
</code>
which also prints out a nonnull value.

I don't see where there are any implicit casts in that example. With unions
the definition is that is reuses the same storage locations for different
types without knowing which is "active". So there isn't a cast but a reuse
of storage. The two are different in that a cast takes a value and makes a
new value while storage reuses takes some bits and interprets them in a new
value. Besides, D unions are treated like C unions, and in C it is illegal
to do
short** x;
int** y = x;
and that's essentially what implicitly casting arrays of object references
is doing.

The two are different in that a cast takes a value and makes a
new value while storage reuses takes some bits and interprets
them in a new value.

Is that really true?
<code>
uint u= uint.max;
int i= u;
</code>
Now what should that "new value" be that you proposed? I think that
sometimes casts have to degrade to storage reuses (or
interpretation changes), so that there is no clear line to
distinguish between them.

Besides, D unions are treated like C unions, and in C
it is illegal to do
short** x;
int** y = x;
and that's essentially what implicitly casting arrays of object
references is doing.

Agreed that it is currently this way. But again I see an asymmetry:
why shouldn't derived types be (implicitely) castable, if their
base types are (implicitely) castable to _each_ other and the
structure of the derivation is identical?
And after stating this I agree with you, that at least the
implicitely casting this thread started with should be treated as
an error and the specs changed, because the base type `Object' is
_not_ castable into its dericed type.
-manfred

The two are different in that a cast takes a value and makes a
new value while storage reuses takes some bits and interprets
them in a new value.

Is that really true?
<code>
uint u= uint.max;
int i= u;
</code>
Now what should that "new value" be that you proposed? I think that
sometimes casts have to degrade to storage reuses (or
interpretation changes), so that there is no clear line to
distinguish between them.

Are we really going to argue about casting? sigh. I guess so since you
believe that unions involve casting - though I hope I'm misunderstanding
you. Casting between types tries as best it can to preserve the value when
it creates the new value. For example casting from 1.0 as a floating point
number to 1 as an int doesn't take the bits in a double and interpret them
as an int - it make a new value with a different bit pattern. In the case
you give about a value out of range for the destination type C does indeed
take the bit pattern in the source value (but not the storage location -
there is a huge difference) and creates the new value with the same bit
pattern. Casting pointers reinterprets the bits in a given storage location
(or in the case of casting to void* it throws away any interpretation at
all). Unions don't involve any casting but do involve sharing storage
locations which is why people sometimes get it confused with casting, I
guess. Anyhow, for a reference I dusted off K+R C second ed and I recommend
sections A8.3, A7.5 and A6 for more info.

Besides, D unions are treated like C unions, and in C
it is illegal to do
short** x;
int** y = x;
and that's essentially what implicitly casting arrays of object
references is doing.

Agreed that it is currently this way. But again I see an asymmetry:
why shouldn't derived types be (implicitely) castable, if their
base types are (implicitely) castable to _each_ other and the
structure of the derivation is identical?
And after stating this I agree with you, that at least the
implicitely casting this thread started with should be treated as
an error and the specs changed, because the base type `Object' is
_not_ castable into its dericed type.
-manfred