2013/5/14 Timon Gehr <[email protected]> > On 05/14/2013 11:30 AM, Timon Gehr wrote: > >> On 05/14/2013 10:04 AM, deadalnix wrote: >> >>> On Tuesday, 14 May 2013 at 07:28:57 UTC, Timothee Cour wrote: >>> >>>> >>>>> I think that should be consistent with the deduction mechanism proposed >>>>> >>>>>> in the DIP: foo is struct not in scope until template foo(T) is >>>>>> instantiated. >>>>>> >>>>>> >>>>> >>>> No it is not. The DIP states "find all constructors". >>>>> >>>> >>>> >>>> it said 'Find all matching class/struct types in scope', isn't that >>>> enough >>>> or am I missing something? >>>> >>>> To clarify, I've added 3 out of scope structs named A in the example >>>> section to clarify that they won't be included in the overload set. >>>> see the ones marked '//not in scope' >>>> >>> >>> I think the best here is to specify that the rule is the same than >>> eponymous funtion and IFTY. Otherwise we'll have 2 different specs with >>> small difference here and there. And that sucks. >>> >> >> There is no spec for the IFTI case. (i.e. what happens if the eponymous >> declaration inside the template is an overload set?) >> > > DMD's strategy is roughly: use the first eponymous declaration that can be > found without analysing the template body for IFTI, then use the first > eponymous declaration in the analyzed template body to resolve the > eponymous declaration after instantiation. > > --- > import std.stdio; > template fun(T){ > int fun(double arg){ return 1; } > int fun(T arg){ return 0; } > } > void main(){ writeln(fun(2)); } // error > > --- > import std.stdio; > template fun(T){ > int fun(T arg){ return 0; } > int fun(double arg){ return 1; } > } > void main(){ writeln(fun(2)); } // ok > > --- > > This has funny implications, as the compiler may decide to resolve to a > different declaration than was used for IFTI later, without doing any kind > of overload resolution within the template body. > > --- > template fun(T){ > int fun(T arg){ return 0; } > static if(true) int fun(double arg){ return 1; } > } > pragma(msg, fun(2)); // 0 > --- > template fun(T){ > static if(true) int fun(double arg){ return 1; } > int fun(T arg){ return 0; } > } > pragma(msg, fun(2)); // 1 > --- > > In the second case, instantiation is performed with the second function, > so T is resolved to 'int', but in the end, the 'double' overload is called > with an implicit conversion. >
Current dmd behavior is definitely a bug. Could you please file it in bugzilla? Kenji Hara
