digitalmars.D - resolving template instantiations
- Christian Kamm (44/44) Jun 30 2009 I started out wanting to document implicit function template instantiati...
- Paul D. Anderson (5/11) Jul 01 2009 Have you entered this into Bugzilla to keep your list of spec issues cur...
- Christian Kamm (7/9) Jul 02 2009 No, I haven't yet. I was hoping to get an explanation for DMD's behavior...
I started out wanting to document implicit function template instantiation (IFTI) and type deduction and ended up reading the DMD frontend code for template instantiation. There I discovered that choosing the correct template declaration involves more logic than the spec indicates. The specification says that if a template instantiation has an argument list that fits more than one template declaration, the most specialized declaration is chosen. If the declarations are equally specialized or there is no such order, an error is raised. Determining which declaration is more specialized is done in a way inherited from C++: if the first declaration could be instantiated with any argument list that's valid for the second, the first is equally or less specialized than the second. In the DMD frontend though, there's another factor that eliminates some candidates before the ordering criterion is applied: each template declaration matches the template argument list either exactly or with conversions (similar to function overloads). If there is at least one exact match, the most specialized declaration is chosen among the exact matches. Only if there are no exact matches is the ordering criterion used to find the most specialized among the matches-with-conversion. It gets interesting when you throw in the fact that template type parameters without specialization will generally be considered to be match-with- conversion only (a comment states: "so that matches with specializations are better"). For instance template Foo1(T) { pragma(msg, "type"); } template Foo1(alias T) { pragma(msg, "alias"); } alias Foo1!(Object) f1; // alias (type is only match-with-conversions) but template Foo2(T : Object) { pragma(msg, "type"); } template Foo2(alias T) { pragma(msg, "alias"); } alias Foo2!(Object) f2; // type (both match exactly, type is more specialized) (the same works with a tuple parameter instead of the alias parameter). It's easy to see that for value parameters looking at the match quality is a good idea template Bar1(int i) { pragma(msg, "int"); } template Bar1(uint i) { pragma(msg, "uint"); } alias Bar1!(42) b1; // int (uint only matches with conversions) as the template instantiation would be ambiguous otherwise - neither declaration is more specialized than the other. Is this intended behavior? If so, what's the rationale for checking the match quality for non-value parameters? Is there a case where mere template ordering would produce inferior results with type parameters? If it is intended, let's document and explain it in the specification. If it isn't, it needs to be changed or removed before the D2 freeze makes code into law.
Jun 30 2009
Christian Kamm Wrote:<snip/>If it is intended, let's document and explain it in the specification. If it isn't, it needs to be changed or removed before the D2 freeze makes code into law.Have you entered this into Bugzilla to keep your list of spec issues current? Thanks for doing that, by the way. :-) Paul
Jul 01 2009
Paul D. Anderson wrote:Have you entered this into Bugzilla to keep your list of spec issues current?No, I haven't yet. I was hoping to get an explanation for DMD's behavior from Walter, maybe even a discussion about the correct way to select template declarations and whether ordering by specialization is even still needed when you have template constraints. But I will make sure the issues get a Bugzilla entry if they can't be resolved directly.
Jul 02 2009