digitalmars.D - Template expansion bug?
- Steven Schveighoffer (42/42) May 31 2013 While doing some testing, I came across this behavior:
- Simen Kjaeraas (10/19) May 31 2013 I'm not certain, but it could be ambiguity:
- Steven Schveighoffer (13/32) May 31 2013 This is true, but there is an implicit call going on in the function
- monarch_dodra (22/27) May 31 2013 I do believe that the idea is that once a template is
While doing some testing, I came across this behavior: template foo(T) { void foo() {} } void main() { foo!(int).foo(); //foo!(int)(); // this works } Error: testbug.d(7): Error: template testbug.foo does not match any function template declaration. Candidates are: testbug.d(1): testbug.foo(T)() testbug.d(7): Error: template testbug.foo(T)() cannot deduce template function from argument types !()(void) This happens on 2.063 and 2.061. From D spec: http://dlang.org/template.html If a template has exactly one member in it, and the name of that member is the same as the template name, that member is assumed to be referred to in a template instantiation: template Foo(T) { T Foo; // declare variable Foo of type T } void test() { Foo!(int) = 6; // instead of Foo!(int).Foo } ... I would have expected that foo!(int).foo() is equivalent to foo!(int)(). Is this no longer the case? Is there some issue here with DMD aggressively evaluating foo!(int) to be a call because of the no-arg function? Actually, it does seem that way, if I change foo to accept a parameter, and call: foo!(int).foo(1); I get: testbug.d(7): Error: foo (int t) is not callable using argument types () testbug.d(7): Error: foo (int t) is not callable using argument types () (and yes, double the error). I can't at the moment think of a reason why anyone would ever use the full syntax, but I would expect it to be accessible, and for the compiler to treat foo as a template first, function call second. -Steve
May 31 2013
On 2013-05-31, 16:42, Steven Schveighoffer wrote:While doing some testing, I came across this behavior: template foo(T) { void foo() {} } void main() { foo!(int).foo(); //foo!(int)(); // this works }I'm not certain, but it could be ambiguity: template foo(T) { struct foo { T foo; } } auto bar = foo!int.foo; // Is bar an int or a foo!int struct? -- Simen
May 31 2013
On Fri, 31 May 2013 13:18:13 -0400, Simen Kjaeraas <simen.kjaras gmail.com> wrote:On 2013-05-31, 16:42, Steven Schveighoffer wrote:This is true, but there is an implicit call going on in the function version. Incidentally, testing shows that foo!int.foo in your case is the int, not the struct. Renaming the foo member to foox, it now complains similarly (can't find member foo, did you mean foox?). It appears that the expanded version of eponymous templates is pretty much disabled at this point. I'm not sure this is a bad thing, but it should at least be documented. I'm pretty sure this used to work, but I'd have to download an old version of DMD to figure that out :) -SteveWhile doing some testing, I came across this behavior: template foo(T) { void foo() {} } void main() { foo!(int).foo(); //foo!(int)(); // this works }I'm not certain, but it could be ambiguity: template foo(T) { struct foo { T foo; } } auto bar = foo!int.foo; // Is bar an int or a foo!int struct?
May 31 2013
On Friday, 31 May 2013 at 14:42:32 UTC, Steven SchveighoI can't at the moment think of a reason why anyone would ever use the full syntax, but I would expect it to be accessible, and for the compiler to treat foo as a template first, function call second. -SteveI do believe that the idea is that once a template is "eponymous", then all calls are supposed to be aggressively expanded to the internal name, and not just "can be omitted". Once you've written the template, it is immediately "assumed" to be the eponymous call. At that point, trying to make a fully qualified call fails, because the template was already "expanded" (for lack of a better word). Leaving the possibility to choose both syntax would allow ambiguity, which is never good: Your template is either eponymous, or it isn't. It's not "sometimes eponymous". From what you have shown, I'd just say 2.062 introduced a bug, which was fixed by 2.063. EDIT: Allow I think that there is a bug that a template becomes eponymous when it contains a single public function that is eponymous, regardless of other functions. IMO, that is a good thing, but the spec state that there should be ONLY members with the same name. As for the "Exactly one": That's bullocks, unless you mean that overloads define a single function. There are tons of places where we use a template with overloaded eponymous resolution. I think the spec is wrong on that one.
May 31 2013