digitalmars.D.bugs - [Issue 5498] New: array of elements of subtypes of a common supertype
- d-bugmail puremagic.com (99/99) Jan 28 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5498
- d-bugmail puremagic.com (14/14) Mar 09 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5498
- d-bugmail puremagic.com (11/11) Mar 09 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5498
- d-bugmail puremagic.com (16/16) Feb 01 2012 http://d.puremagic.com/issues/show_bug.cgi?id=5498
- d-bugmail puremagic.com (10/10) Jul 07 2012 http://d.puremagic.com/issues/show_bug.cgi?id=5498
http://d.puremagic.com/issues/show_bug.cgi?id=5498 Summary: array of elements of subtypes of a common supertype Product: D Version: D2 Platform: All OS/Version: All Status: NEW Severity: normal Priority: P2 Component: DMD AssignedTo: nobody puremagic.com ReportedBy: denis.spir gmail.com --- Hello, Seems there is no way to create an array of elements which types are subtypes of a common supertype: void test0 () { auto t1 = new T1(); auto t2 = new T2(); T0[] array = [t1, t2]; } ==> Error: cannot implicitly convert expression (t1) of type __trials__.T0 to __trials__.T2 Error: cannot implicitly convert expression ([(__error),t2]) of type T2[] to T0[] The array value is obviously correct. But there is here no common compatible type between T1 & T2 that D could directly choose; instead, they have a common super-type, which is the one intended as array element type. D logically does not take our specification of the wished common type, in the target part of the assignment, into account; since the source array must in any case first exist at all. And it does not try to guess a common supertype by climbing up the type hierarchy tree. This would be naughty-bug-prone since D could find a common type which is not the intended one, precisely in case of programmer error. And anyway Object would always be convenient, while this is certainly not the programmer intention in the general case. The core issue is that the language must first create a valid array value, before any attempt to convert to any explicitely specified type (if ever this feature was implemented). For this reason, cast or to! applied on the array cannot help neither; the original array must first initially be correct according to D rules for literal: T0[] array = cast(T0[])[t1, t2]; ==> Same error. A workaround is to cast one of the elements, instead of the array, to the intended common type (*): void test2 () { auto t1 = new T1(); auto t2 = new T2(); T0[] array1 = [cast(T0)t1, t2]; // ok T0[] array2 = [t1, cast(T0)t2]; // ok } But this trick raises a conceptual problem: what we mean is specifying the array literal's common type; what is in fact written is a cast of an element. Far to be obvious. A library solution can be made via an "array-feeding" helper function; it uses a variadic argument to avoid the user writing an array literal: void feed (T) (ref T[] array, T[] elements...) { array ~= elements; } void test3 () { auto t1 = new T1(); auto t2 = new T2(); T0[] array; array.feed(t1, t2); // means: array = [t1,t2]; array.feed(t2, t1); // means: array ~= [t2,t1]; writeln(array); } ==> [arraydef.T1, arraydef.T2, arraydef.T2, arraydef.T1] As shown, feed can also extend an existing array, replacing "~=" which fails for the same cause as "=". (Reason why I called the func "feed", not "init".) This is still a workaround, maybe a better one. Programmers need to know about the issue and the provided solution, thus this should be mentionned in good place in doc about arrays. A true solution would require having a way to hint the compiler about the intended type, in literal syntax itself --a hint taken into account by the language before any initial array is created. Just like postfixes 'w' & 'd' for chars and strings. The best I could think at is, by analogy, postfixing the element type to the array literal: T0[] array = [t1, t2]T0; Not very nice :-( Denis (*) to! cannot be used at all because we hit another, unrelated, bug; namely one about non mutually exclusive template constraints: T0[] array1 = [to!(T0)(t1), t2]; ==> /usr/include/d/dmd/phobos/std/conv.d(99): Error: template std.conv.toImpl(T,S) if (!implicitlyConverts!(S,T) && isSomeString!(T) && isInputRange!(Unqual!(S)) && isSomeChar!(ElementType!(S))) toImpl(T,S) if (!implicitlyConverts!(S,T) && isSomeString!(T) && isInputRange!(Unqual!(S)) && isSomeChar!(ElementType!(S))) matches more than one template declaration, /usr/include/d/dmd/phobos/std/conv.d(559):toImpl(Target,Source) if (implicitlyConverts!(Source,Target)) and /usr/include/d/dmd/phobos/std/conv.d(626):toImpl(T,S) if (is(S : Object) && is(T : Object)) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 28 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5498 Steven Schveighoffer <schveiguy yahoo.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |schveiguy yahoo.com 05:39:44 PST --- I just noticed, your example lacks definition of T0, T1 and T2. Should be: class T0 {} class T1 : T0 {} class T2 : T0 {} -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 09 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5498 Steven Schveighoffer <schveiguy yahoo.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |wilfried.kirschenmann gmail | |.com 05:41:07 PST --- *** Issue 5723 has been marked as a duplicate of this issue. *** -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 09 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5498 yebblies <yebblies gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |pull, rejects-valid CC| |yebblies gmail.com Version|D2 |D1 & D2 AssignedTo|nobody puremagic.com |yebblies gmail.com Summary|array of elements of |wrong common type deduction |subtypes of a common |for array of classes |supertype | https://github.com/D-Programming-Language/dmd/pull/684 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 01 2012
http://d.puremagic.com/issues/show_bug.cgi?id=5498 yebblies <yebblies gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jens.k.mueller gmx.de *** Issue 8353 has been marked as a duplicate of this issue. *** -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 07 2012