On Tuesday, December 10, 2013 08:29:02 Kenji Hara wrote: > On Tuesday, 10 December 2013 at 07:15:43 UTC, Jonathan M Davis > > wrote: > > On Monday, December 09, 2013 22:59:49 Ali Çehreli wrote: > >> On 12/09/2013 10:52 PM, Jonathan M Davis wrote: > >> > On Tuesday, December 10, 2013 07:47:38 FreeSlave wrote: > >> >> I just found weird D behavior about inference of array > >> >> types. > >> >> > >> >> Let's suppose we have these overloaded functions: > >> >> > >> >> import std.stdio; > >> >> > >> >> void bar(const(int[3]) arr) > >> >> { > >> >> > >> >> writeln("static array"); > >> >> > >> >> } > >> >> > >> >> void bar(const(int[]) arr) > >> >> { > >> >> > >> >> writeln("array slice"); > >> >> > >> >> } > >> >> > >> >> // In main we have something like that: > >> >> int main(string[] args) > >> >> { > >> >> > >> >> bar([1,2,3]); > >> >> writeln(typeof([1,2,3]).stringof); > >> >> return 0; > >> >> > >> >> } > >> >> > >> >> Weird thing is that the static array version of bar is > >> >> called, > >> >> but typeof().stringof is int[], not int[3]. > >> > > >> > Array literals are always dynamic arrays. int[3] is a static > >> > array. > >> > > >> > - Jonathan M Davis > >> > >> The original question is valid then: [1,2,3] goes to the > >> static array > >> overload. > > > > Then AFAIK, that's a bug. The type of array literals is always > > a dynamic > > array, so they should match dynamic array overloads rather than > > static array > > overloads, or if they match both due to an implicit conversion, > > there should > > be an ambiguity error. Choosing the static array overload over > > the dynamic one > > is just plain wrong. > > This is an intended behavior. An array literal has dynamic array > type *by default*. > But all of literals in D behave as polymorphic. > > char c = 'A'; // character literal has char type by default > dchar d = 'A'; // but it may be implicitly typed as wchar/dchar > > string str = "hello"; > dstring dstr = "hello"; // string literal is implicitly typed as > dstring > > int[] darr = [1,2,3]; > int[3] darr = [1,2,3]; // implicitly typed as int[3] > > So, an array literal [1,2,3] is implicitly convertible both to > int[] and int[3]. > And, int[3] is more specialized than int[], so overload > resolution will choose the first 'bar'.
I'd argue that it would be far better to give an ambiguity error rather than silently pick one over the other. In general, having a literal of any kind pick a particular overload when it can match multiple is just begging for trouble. - Jonathan M Davis