digitalmars.D.bugs - [Issue 1528] New: shouldn't templates conflict with templates?
- d-bugmail puremagic.com (23/23) Sep 22 2007 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (10/10) Sep 22 2007 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (10/10) Sep 22 2009 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (10/10) Dec 24 2011 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (34/34) Dec 24 2011 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (6/6) Dec 24 2011 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (10/10) Jan 21 2012 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (24/24) Aug 25 2012 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (16/17) Aug 25 2012 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (26/35) Aug 25 2012 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (10/10) Dec 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (42/43) Feb 24 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (10/22) Feb 24 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (27/32) Feb 24 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (42/45) Feb 25 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (31/42) Feb 27 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (21/48) Feb 27 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (64/83) Feb 28 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (13/14) Mar 01 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (11/19) Mar 01 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (18/24) Mar 01 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (14/25) Mar 01 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (19/33) Mar 01 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (9/40) Mar 01 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (30/34) Mar 01 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (27/27) Mar 14 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (7/14) Mar 14 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (23/53) Mar 14 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (19/30) Mar 14 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (16/16) Mar 14 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (7/22) Mar 14 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (12/30) Mar 15 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (15/19) Mar 15 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (21/39) Mar 15 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (60/60) Apr 07 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (22/29) Apr 07 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (10/10) Apr 07 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (13/19) Apr 07 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (28/28) Jun 28 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (36/37) Jun 28 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (10/10) Jul 20 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
- d-bugmail puremagic.com (9/9) Oct 23 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1528
http://d.puremagic.com/issues/show_bug.cgi?id=1528 Summary: shouldn't templates conflict with templates? Product: D Version: unspecified Platform: PC OS/Version: Windows Status: NEW Severity: trivial Priority: P2 Component: DMD AssignedTo: bugzilla digitalmars.com ReportedBy: davidl 126.com int[char] v; char m; int d; template toString (U,C,T:U[C]) { char[] toString(U m,C c, T t) { return ""; } } char[] toString(int k){return "";} The confliction can actually be detected till the last moment of instantiation. I don't see why we prevent it at the moment. --
Sep 22 2007
http://d.puremagic.com/issues/show_bug.cgi?id=1528 wbaxter gmail.com changed: What |Removed |Added ---------------------------------------------------------------------------- Summary|shouldn't templates conflict|templates should not |with templates? |conflict with non-templates The ability to do this sort of overloading is scheduled to be added to D2.0, according to the notes from the Walter/Andrei talk at the D conference. --
Sep 22 2007
http://d.puremagic.com/issues/show_bug.cgi?id=1528 Don <clugdbug yahoo.com.au> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords|spec | CC| |clugdbug yahoo.com.au Severity|trivial |enhancement -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 22 2009
http://d.puremagic.com/issues/show_bug.cgi?id=1528 yebblies <yebblies gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |andrei metalanguage.com *** Issue 7134 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: -------
Dec 24 2011
http://d.puremagic.com/issues/show_bug.cgi?id=1528 yebblies <yebblies gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |rejects-valid CC| |yebblies gmail.com Platform|x86 |All Summary|[tdpl] templates should not |[tdpl] overloading template |conflict with non-templates |and non-template functions OS/Version|Windows |All Severity|enhancement |major From Andrei's comment in 7134: This TDPL code does not compile: class A { // Non-overridable method A opBinary(string op)(A rhs) { // Forward to an overridable function return opBinary(op, rhs); } // Overridable method, dispatch string at runtime A opBinary(string op, A rhs) { switch (op) { case "+": break; case "-": break; } } } Overloading template and non-template functions must be implemented. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 24 2011
http://d.puremagic.com/issues/show_bug.cgi?id=1528 09:15:52 PST --- Thanks for consolidating! -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 24 2011
http://d.puremagic.com/issues/show_bug.cgi?id=1528 Andrej Mitrovic <andrej.mitrovich gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |dsimcha yahoo.com 18:22:11 PST --- *** Issue 2972 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: -------
Jan 21 2012
http://d.puremagic.com/issues/show_bug.cgi?id=1528 Simen Kjaeraas <simen.kjaras gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |simen.kjaras gmail.com PDT --- This bug causes problems with disabled default constructors. Given: struct Foo { disable this(); this( T )( T a ) { } } This bug triggers. Given instead: struct Bar { disable this( )( ); this( T )( T a ) { } } The default constructor is not disabled. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 25 2012
http://d.puremagic.com/issues/show_bug.cgi?id=1528 Jonathan M Davis <jmdavisProg gmx.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jmdavisProg gmx.com PDT ---This bug causes problems with disabled default constructors.I don't think that this bug has anything to do with it. And I wouldn't expect disable this()(); to work anyway, because the function that you're trying to disable doesn't exist. It would have to be instantiatied to exist, and it's not possible to call a default constructor on a struct, since they're not legal in the first place, so it can't be instantiated. disable this()(); should probably result in an error. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 25 2012
http://d.puremagic.com/issues/show_bug.cgi?id=1528 PDT ---disable this() does work in some cases: struct Foo { disable this( ); } struct Bar { Foo f; this( int n ) { // Error: constructor Bar.this field f must be initialized in constructor } } void main( ) { Foo f; // Error: variable main.d initializer required for type Foo } However, if you need a templated constructor, this goes out the window, for the reasons outlined above.This bug causes problems with disabled default constructors.I don't think that this bug has anything to do with it.Yes and no. The problems of disable this are exacerbated by this bug.And I wouldn't expect disable this()(); to work anyway, because the function that you're trying to disable doesn't exist. It would have to be instantiatied to exist, and it's not possible to call a default constructor on a struct, since they're not legal in the first place, so it can't be instantiated. disable this()(); should probably result in an error.Nor would I, but when faced with the error that templated and non-templated functions cannot form an overload set together, that is the logical thing to try, and it doesn't work either. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 25 2012
http://d.puremagic.com/issues/show_bug.cgi?id=1528 Kenji Hara <k.hara.pg gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |pull https://github.com/D-Programming-Language/dmd/pull/1409 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=1528 Kenji Hara <k.hara.pg gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords|pull | ---https://github.com/D-Programming-Language/dmd/pull/1409By implementing it, I found some corner cases. How should these behave? int f1(int a, double=10) { return 1; } int f1(int a, string="") { return 2; } int f2(T:int)(T b, double=10) { return 1; } int f2(T:int)(T b, string="") { return 2; } // vs deduced parameter int f3(int a) { return 1; } int f3(T)(T b) { return 2; } // vs specialized parameter int f4(int a) { return 1; } int f4(T:int)(T b) { return 2; } // vs deduced parameter + template constraint (1) int f5(int a) { return 1; } int f5(T)(T b) if (is(T == int)) { return 2; } // vs deduced parameter + template constraint (2) int f6(int a) { return 1; } int f6(T)(T b) if (is(T : int)) { return 2; } void main() { f1(1); // ambiguous error f1(1L); // ambiguous error f2(1); // ambiguous error f2(1L); // ambiguous error f3(1); // ? f3(1L); // ? f4(1); // ? f4(1L); // ? f5(1); // ? f5(1L); // ? f6(1); // ? f6(1L); // ? } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 24 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 21:54:47 PST ---f3(1); // 1 f3(1L); // 2 f4(1); // ambiguous f4(1L); // ambiguous f5(1); // 1 f5(1L); // 1 f6(1); // 1 f6(1L); // 2 }The more specialized overload always wins. The constraint is not considered when evaluating which is "more specialized". (Because in general we cannot evaluate that.) The constraint only determines if an overload is to be considered - it does not determine ordering. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 24 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 ---The more specialized overload always wins. The constraint is not considered when evaluating which is "more specialized". (Because in general we cannot evaluate that.) The constraint only determines if an overload is to be considered - it does not determine ordering.Thanks for quickly answer. So, the resolution result of f5 and f6 should be same as f3, because they are identical when hide their constraints. Right? But, there is still questionable. How to calculate "The more specialized overload" between function template and non-template one? For example, try to consider case for f3(1). That is: 1. Normal function version f3(int) will match exactly to one int argument. 2. Function template version will deduce T <- int, and then instantiated function f3!(int) == void f3(int) will match _exactly_ to one int argument. But, in general, template version is less specialized than non-template version. So, there is something necessary for ordering. --- Consider one another case for f4(1L). That is: 1. Normal function will match to one long argument with conversion (MATCHconvert). 2. Function template version will deduce T <- long and then instantiated function f4!long will match exactly to one long argument. Which is specialized? In general, template version would be intended to pick up non-exact matching for generic cases. But, as far as I infer from current dmd implementation, f4(1L) will be ambiguous (template type parameter deduction without specialization always be MATCHconvert). Therefore, I'd ask question again to Walter: how does above cases behave? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 24 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 timon.gehr gmx.ch changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |timon.gehr gmx.ch... Therefore, I'd ask question again to Walter: how does above cases behave?I have implemented it in accordance with TDPL, and the following behaviour results: int f1(int a, double=10) { return 1; } int f1(int a, string="") { return 2; } int f2(T:int)(T b, double=10) { return 1; } int f2(T:int)(T b, string="") { return 2; } // vs deduced parameter int f3(int a) { return 1; } int f3(T)(T b) { return 2; } // vs specialized parameter int f4(int a) { return 1; } int f4(T:int)(T b) { return 2; } // vs deduced parameter + template constraint (1) int f5(int a) { return 1; } int f5(T)(T b) if (is(T == int)) { return 2; } // vs deduced parameter + template constraint (2) int f6(int a) { return 1; } int f6(T)(T b) if (is(T : int)) { return 2; } void main(){ f1(1); // error: ambiguous f1(1L); // error: ambiguous f2(1); // error: ambiguous f2(1L); // error: no match static assert(f3(1)==1); static assert(f3(1L)==2); static assert(f4(1)==1); static assert(f4(1L)==1); static assert(f5(1)==1); static assert(f5(1L)==1); static assert(f6(1)==1); static assert(f6(1L)==1); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 25 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 monarchdodra gmail.com changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |monarchdodra gmail.comI have implemented it in accordance with TDPL, and the following behaviour results: // vs deduced parameter + template constraint (2) int f6(int a) { return 1; } int f6(T)(T b) if (is(T : int)) { return 2; } void main(){ static assert(f6(1)==1); static assert(f6(1L)==1); }How does that work though, because here, you statically know that 1L will fit in your int. But what about: static assert(f6(1L) == 1); static assert(f6(ulong.max) == 2); // (a) ??? ulong ul = runtime(); static assert(f6(ul) == 2); // (b) ??? How would these resolve? I am not really comfortable with the fact that a call can statically resolve to two different functions depending on the static information of the *value* of a parameter: int f7(ubyte a) { return 1; } int f7(T)(T b) if (is(T : int)) { return 2; } void main(){ static assert(f6(200u)==1); //Calls first static assert(f6(400u)==2); //Calls second (!?) //Run-time variable with TDPL-like range knowledge uint a = 400; static assert(f6(a) == 2); //Calls second ? a = 200; static assert(f6(a) == 1); //But now calls first !? } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 27 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528... static assert(f6(1L) == 1); static assert(f6(ulong.max) == 2); // (a) ???No match.ulong ul = runtime(); static assert(f6(ul) == 2); // (b) ???No match.How would these resolve? I am not really comfortable with the fact that a call can statically resolve to two different functions depending on the static information of the *value* of a parameter:Well, that is how the language is specified. int f8(byte){ return 1; } int f8(long){ return 2; } void main(){ static assert(f8(1)==1); // calls first static assert(f8(256)==2); // calls second int x=1; f8(x); // calls second }int f7(ubyte a) { return 1; } int f7(T)(T b) if (is(T : int)) { return 2; } void main(){ static assert(f6(200u)==1); //Calls firstNo, calls second.static assert(f6(400u)==2); //Calls second (!?)Yes.//Run-time variable with TDPL-like range knowledge uint a = 400;Knowledge lost here.static assert(f6(a) == 2); //Calls second ? a = 200;Ditto.static assert(f6(a) == 1); //But now calls first !? }-- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 27 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 ---// vs specialized parameter int f4(int a) { return 1; } int f4(T:int)(T b) { return 2; }static assert(f4(1)==1);Just only this is wrong. f4(T:int) is specialized to int argument, so f4(1) could match both normal function version and template version *with the same extent*. Then it will be ambiguous.static assert(f4(1L)==1);Ok. f4(T:int) cannot instantiate with T==long, so first version will be called.Both (a) and (b) should be "no match", but with my experimental change, (a) wrongly matches to int. I found an another bug in there, and filed it as bug 9617. Current test case results with my pull request: https://github.com/D-Programming-Language/dmd/pull/1409 is: -------- int f1(int a, double=10) { return 1; } int f1(int a, string="") { return 2; } int f2(T:int)(T b, double=10) { return 1; } int f2(T:int)(T b, string="") { return 2; } // vs deduced parameter int f3(int a) { return 1; } int f3(T)(T b) { return 2; } // vs specialized parameter int f4(int a) { return 1; } int f4(T:int)(T b) { return 2; } // vs deduced parameter + template constraint (1) int f5(int a) { return 1; } int f5(T)(T b) if (is(T == int)) { return 2; } // vs deduced parameter + template constraint (2) int f6(int a) { return 1; } int f6(T)(T b) if (is(T : int)) { return 2; } // vs nallowing conversion int f7(ubyte a) { return 1; } int f7(T)(T b) if (is(T : int)) { return 2; } void main() { static assert(!__traits(compiles, f1(1))); // ambiguous static assert(!__traits(compiles, f1(1L))); // ambiguous static assert(!__traits(compiles, f2(1))); // ambiguous static assert(!__traits(compiles, f2(1L))); // no match assert(f3(1) == 1); assert(f3(1L) == 2); static assert(!__traits(compiles, f4(1))); assert(f4(1L) == 1); assert(f5(1) == 1); assert(f5(1L) == 1); assert(f6(1) == 1); assert(f6(1L) == 1); static assert(!__traits(compiles, f6(ulong.max))); // no match // needs to fix bug 9617 ulong ulval = 1; static assert(!__traits(compiles, f6(ulval))); // no match assert(f7(200u) == 2); assert(f7(400u) == 2); uint uival = 400; // TDPL-like range knowledge lost here. assert(f7(uival) == 2); a = 200; // Ditto. assert(f7(uival) == 2); } -------- I welcome more complicated test case. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------... static assert(f6(1L) == 1); static assert(f6(ulong.max) == 2); // (a) ???No match.ulong ul = runtime(); static assert(f6(ul) == 2); // (b) ???No match.
Feb 28 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 Martin Nowak <code dawg.eu> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |code dawg.eutemplate type parameter deduction without specialization always be MATCHconvertAFAIK this is a kludgy implementation detail to make specialization work. The last time we worked on that we concluded (with Daniel Murphy?) that there should be an additional level between convert and exact. I don't remember the details right now, but I'll try to find the relevant discussion. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 01 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528It is a bug.template type parameter deduction without specialization always be MATCHconvertAFAIK this is a kludgy implementation detailto make specialization work.Why wouldn't they work otherwise?The last time we worked on that we concluded (with Daniel Murphy?) that there should be an additional level between convert and exact. I don't remember the details right now, but I'll try to find the relevant discussion.There already is a level between them (conversion to const.) Anyway, I do not see why another level would be required, or even helpful in any way. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 01 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 ---Are you saying about MATCHdeduced? I had seen the Daniel Murphy's pull request somewhere, but it is completely unnecessary. In IFTI, the match level for template arguments and for function arguments are distinguished. The former is prior than the latter, so there is 3 * 3 + 1 match level in IFTI. For tiargs: exact or const or convert (3) For funargs: exact or const or convert (* 3) noatch (+ 1) During implementation, I found that the two matching levels had not be separated correctly (the bug was in TemplateDeclaration::deduceFunctionTemplateMatch). After fixing the bug, I can believe that MATCHdeduced is not need anymore. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------template type parameter deduction without specialization always be MATCHconvertAFAIK this is a kludgy implementation detail to make specialization work. The last time we worked on that we concluded (with Daniel Murphy?) that there should be an additional level between convert and exact. I don't remember the details right now, but I'll try to find the relevant discussion.
Mar 01 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528... In IFTI, the match level for template arguments and for function arguments are distinguished. The former is prior than the latter, so there is 3 * 3 + 1 match level in IFTI. For tiargs: exact or const or convert (3) For funargs: exact or const or convert (* 3) noatch (+ 1) ...It can be seen that way. They are ordered from worst to best like this: no match ifti convert function convert ifti const function const ifti exact function exact -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 01 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 ---More precisely: MATCHnomatch tiargs:MATCHconvert / funarg:MATCHconvert tiargs:MATCHconvert / funarg:MATCHconst tiargs:MATCHconvert / funarg:MATCHexact tiargs:MATCHconst / funarg:MATCHconvert tiargs:MATCHconst / funarg:MATCHconst tiargs:MATCHconst / funarg:MATCHexact tiargs:MATCHexact / funarg:MATCHconvert tiargs:MATCHexact / funarg:MATCHconst tiargs:MATCHexact / funarg:MATCHexact Additionally, when comparing normal function and template function matching, tiargs MATCH level is treated as equal to funargs level. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------... In IFTI, the match level for template arguments and for function arguments are distinguished. The former is prior than the latter, so there is 3 * 3 + 1 match level in IFTI. For tiargs: exact or const or convert (3) For funargs: exact or const or convert (* 3) noatch (+ 1) ...It can be seen that way. They are ordered from worst to best like this:
Mar 01 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528Ah, now I see what you mean. You are matching foo!tiargs(funargs). I was talking about resolving template vs. non-template overloads in the foo(funargs) setting. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------More precisely: MATCHnomatch tiargs:MATCHconvert / funarg:MATCHconvert tiargs:MATCHconvert / funarg:MATCHconst tiargs:MATCHconvert / funarg:MATCHexact tiargs:MATCHconst / funarg:MATCHconvert tiargs:MATCHconst / funarg:MATCHconst tiargs:MATCHconst / funarg:MATCHexact tiargs:MATCHexact / funarg:MATCHconvert tiargs:MATCHexact / funarg:MATCHconst tiargs:MATCHexact / funarg:MATCHexact Additionally, when comparing normal function and template function matching, tiargs MATCH level is treated as equal to funargs level.... In IFTI, the match level for template arguments and for function arguments are distinguished. The former is prior than the latter, so there is 3 * 3 + 1 match level in IFTI. For tiargs: exact or const or convert (3) For funargs: exact or const or convert (* 3) noatch (+ 1) ...It can be seen that way. They are ordered from worst to best like this:
Mar 01 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 ---Ah, now I see what you mean. You are matching foo!tiargs(funargs). I was talking about resolving template vs. non-template overloads in the foo(funargs) setting.I'm talking about both. You can think type parameters deduction and function arguments matching separately. For example: void foo(T)(T) {} void foo(T:int)(T) {} With first overload version, Phase 1: T is deduced to int. ==> MATCHconvert. Phase 2: 1 matches T (==already deduced to int). ==> MATCHexact. With second overload version, Phase 1: T is deduced to int and is specialized to int. ==> MATCHexact. Phase 2: 1 matches T (==already deduced to int). ==> MATCHexact. Finally, foo(T)(T) is less specialized than foo(T:int)(T). I explain more complicated case. void bar(int, int) {} void bar(T)(T, int) {} bar(1, 1L); With first overload version, Phase 1: normal function is treated as having empty template parameter list, so matching is always exact ==> MATCHexact Phase 2: int <- 1 == MATCHexact, int <- 1L == MATCHconvert. ==> MATCHconvert With second overload version, Phase 1: T <- typeof(int). ==> MATCHconvert Phase 2: T <- 1 == MATCHexact, int <- 1L == MATCHconvert ==> MATCHconvert From the comparison of Phase 1 result, bar(int, int) is more specialized than bar(T)(T, int) for function arguments (1, 1L). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 01 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 I think this rule is problematic for the function vs. deduced parameter case. // vs deduced parameter int f3(int a) { return 1; } int f3(T)(T b) { return 2; } f3(1L); With first overload version, Phase 1: normal function is treated as having empty template parameter list, so matching is always exact ==> MATCHexact Phase 2: int <- 1L == MATCHconvert ==> MATCHconvert With second overload version, Phase 1: T <- typeof(1L) = long ==> MATCHconvert Phase 2: T <- 1L == MATCHexact ==> MATCHexact - the current implementation in the pull request chooses with the function template https://github.com/9rnsr/dmd/blob/b141e29e29b1ec43873c7e0374d27d3fbbae8085/test/runnable/overload.d#L216 https://github.com/9rnsr/dmd/blob/b141e29e29b1ec43873c7e0374d27d3fbbae8085/test/runnable/overload.d#L279 - C++ chooses the function template - For me it's counterintuitive to call with conversion when an exact match can be instantiated. Even an ambiguous error seems more reasonable to me. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 14 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 I find the C++ rule pretty plausible.In most cases a function template behaves just like a normal function when considering overload resolution. The template argument deduction is applied, if it succeeds, the function is added to the candidates set. Such a function is handled like any other function, except when two viable functions are equally good, the non-template one is selected. In case both are a specialisation of a function template, partial ordering rules are applied. The partial ordering rules are out of the scope of this article.http://accu.org/index.php/journals/268#d0e340 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 14 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 ---I think this rule is problematic for the function vs. deduced parameter case. // vs deduced parameter int f3(int a) { return 1; } int f3(T)(T b) { return 2; } f3(1L); With first overload version, Phase 1: normal function is treated as having empty template parameter list, so matching is always exact ==> MATCHexact Phase 2: int <- 1L == MATCHconvert ==> MATCHconvert With second overload version, Phase 1: T <- typeof(1L) = long ==> MATCHconvert Phase 2: T <- 1L == MATCHexact ==> MATCHexact - the current implementation in the pull request chooses with the function template https://github.com/9rnsr/dmd/blob/b141e29e29b1ec43873c7e0374d27d3fbbae8085/test/runnable/overload.d#L216 https://github.com/9rnsr/dmd/blob/b141e29e29b1ec43873c7e0374d27d3fbbae8085/test/runnable/overload.d#L279 - C++ chooses the function template - For me it's counterintuitive to call with conversion when an exact match can be instantiated. Even an ambiguous error seems more reasonable to me.Right now I think that was little bad example. Ques. Why f3(1L) chooses non-template version? Short Ans. Because the given argument 1L is a literal. Long Ans. In D, literals works as like polysemous value. 1L is implicitly convertible to int by Value Range Propagation, so it matchs with MATCHconvert. If you give a runtime long value to f3: long n; f3(n); With first overload version, Phase 1: normal function is treated as having empty template parameter list, so matching is always exact ==> MATCHexact Phase 2: int <- n == MATCHnomatch (changed!!) With second overload version, Phase 1: T <- typeof(1L) = long ==> MATCHconvert Phase 2: T <- 1L == MATCHexact ==> MATCHexact So it will choose template version. How about? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 14 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528I find the C++ rule pretty plausible.C++ does not have template value parameters. The C++ behaviour is approximated closely when IFTI type parameter deduction is treated as exact match. (There is no reason to do anything else, a type is required, and a type is given.) However, it is not too clear that there must be one matching level for the template and one for the function. Kenji, why do you think this is required? Why does one matching level for everything not suffice? Eg, I think the following code should not compile and show an ambiguity error. void foo(double a)(int b){ } void foo(int a)(double b){ } void main(){ foo!1(1); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------In most cases a function template behaves just like a normal function when considering overload resolution. The template argument deduction is applied, if it succeeds, the function is added to the candidates set. Such a function is handled like any other function, except when two viable functions are equally good, the non-template one is selected. In case both are a specialisation of a function template, partial ordering rules are applied. The partial ordering rules are out of the scope of this article.http://accu.org/index.php/journals/268#d0e340
Mar 14 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 It's not about the polysemous literals. What's irritating me is that a function call with conversion is preferred over a function template instantiation with exact arguments. int f3(long) { return 1; } int f3(T)(T) { return 2; } int v = 2; f3(v); MATCHexact / MATCHconvert vs. MATCHconvert / MATCHexact -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 14 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528It's not about the polysemous literals. What's irritating me is that a function call with conversion is preferred over a function template instantiation with exact arguments. int f3(long) { return 1; } int f3(T)(T) { return 2; } int v = 2; f3(v); MATCHexact / MATCHconvert vs. MATCHconvert / MATCHexactIMO the second should be MATCHexact / MATCHexact. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 14 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 ---No. type parameter deduction is less specialized than matching to explicitly specialized type parameter. void foo(T)(T) {} // generic version void foo(T:int)(T) {} // specialized to int foo(1); // calls T:int version That is why f3(v) makes MATCHconvert / MATCHexact with template version. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------It's not about the polysemous literals. What's irritating me is that a function call with conversion is preferred over a function template instantiation with exact arguments. int f3(long) { return 1; } int f3(T)(T) { return 2; } int v = 2; f3(v); MATCHexact / MATCHconvert vs. MATCHconvert / MATCHexactIMO the second should be MATCHexact / MATCHexact.
Mar 15 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528... Parameter deduction is less specialized than matching to explicitly specialized type parameter. ...It's not less specialized than a normal function call without type parameters. A type parameter should match a type argument exactly. Specialization mustn't be confused with the matching level -- it should be checked in a second step, as is done for functions. Why?: Specialization is a partial order, while the matching levels form a full order. There is no way to correctly implement specialization only by abusing matching levels. (At the very least, the logic for template specialization should not interfere with template vs. function overloading!) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 15 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 ---I talked the expected behavior by using the words used in dmd implementation. Yes, MATCH(exact|const|convert|nomatch) might not be the best word to talk language specification. But it is not a true problem. Essentially the thing I talking is: void foo(int) {} // 1 void foo(T:int)(T) {} // 2 void foo(T)(T) {} // 3 foo(1); Non template function (1) is specialized _as same as_ explicitly specialized template function (2). Then, normally deduced template function is less specialized than (1) and (2). My patch represents the specialization order for IFTI by the pair of MATCH value. And, (3) is represented by MATCHconvert / MATCHexact internally. Do not confuse internal representation and expected language specification/behavior. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------... Parameter deduction is less specialized than matching to explicitly specialized type parameter. ...It's not less specialized than a normal function call without type parameters. A type parameter should match a type argument exactly. Specialization mustn't be confused with the matching level -- it should be checked in a second step, as is done for functions. Why?: Specialization is a partial order, while the matching levels form a full order. There is no way to correctly implement specialization only by abusing matching levels. (At the very least, the logic for template specialization should not interfere with template vs. function overloading!)
Mar 15 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 07:33:07 PDT --- Great thread. Sorry I'm late to it! Let me make an appeal to simplicity - even if we come up with a very meaningful and consistent set of overloading rules, we lose if they are complicated. Simplicity is very important for figuring out what function will be called in a context. In that spirit I'd like to propose a basic strategy as follows: 1. Define a SIMPLE partial ordering relation <= between functions called "at least as specialized" (and correspondingly a strict version < meaning "more specialized"). 2. Whenever two or more functions match a call, there is a "winner" only if it is more specialized than all other candidates. (Not all candidates must be partially ordered among themselves, but the winner must be more specialized than all others.) Otherwise, there is ambiguity. Now for the simple partial ordering relation: consider a call to a function fun(args) with two overloads fun1 and fun2 that would accept the arguments, i.e. fun1(args) and fun2(args) would both compile in isolation. To decide whether fun1 and fun2 are partially ordered, we look at the sets of accepted arguments. If fun2 accepts any argument fun1 would accept, we write fun1 <= fun2 and we say "fun1 is at least as specialized as fun2" or "fun2 is not more specialized than fun1". Now, if fun1 <= fun2 and fun2 <= fun1 then the two are "as specialized" so a decision cannot be made between the two. If only one of the relations applies, then one of them is strictly more specialized and it is preferred in an overloaded call. If neither relation applies, the functions are unordered so again a decision cannot be made. On the examples given by Kenji: int f1(int a, double=10) { return 1; } int f1(int a, string="") { return 2; } These functions are not ordered because e.g. f1(2, 3.4) would not be accepted by the second overload and f1(2, "hello") would not be accepted. So the call f1(5) is ambiguous. int f2(T:int)(T b, double=10) { return 1; } int f2(T:int)(T b, string="") { return 2; } Same here, these overloads are not ordered. // vs deduced parameter int f3(int a) { return 1; } int f3(T)(T b) { return 2; } Here the second overload accepts f3("hello") so the first overload is more specialized. It will be preferred even in calls with an implicit conversion, e.g. f3(cast(short) 42). THIS IS A DEPARTURE FROM C++'S RULES. // vs specialized parameter int f4(int a) { return 1; } int f4(T:int)(T b) { return 2; } These two functions are in the same equivalence classes because they accept the same argument sets: f4_1 <= f4_2 and f4_2 <= f4_1. So any call that would match these two would be ambiguous. // vs deduced parameter + template constraint (1) int f5(int a) { return 1; } int f5(T)(T b) if (is(T == int)) { return 2; } The constraint is evaluated first and then "disappears" leaving two functions. Of these, the non-template is more specialized. // vs deduced parameter + template constraint (2) int f6(int a) { return 1; } int f6(T)(T b) if (is(T : int)) { return 2; } Same here. Given that the constraints are arbitrary Boolean expressions, we can't make good estimates on what sets of arguments they'll match. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 07 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 --- [snip] That's the rule described in TDPL. I can completely agree with you. I believe that my patch implements it enough. ---- I'd like to add one note for your better understand.// vs specialized parameter int f4(int a) { return 1; } int f4(T:int)(T b) { return 2; } These two functions are in the same equivalence classes because they accept the same argument sets: f4_1 <= f4_2 and f4_2 <= f4_1. So any call that would match these two would be ambiguous.That's true if and only if one int argument is given. In D, the template specialized parameter (T:int) means "T should exactly matches to int". int fx(T:int)(T b) { return 2; } void main() { fx(1L); } test.d(2): Error: template test.fx does not match any function template declaration. Candidates are: test.d(1): test.fx(T : int)(T b) test.d(2): Error: template test.fx(T : int)(T b) cannot deduce template function from argument types !()(long) So, f4 would match to non-template version if a non-int argument is given. assert(f4(1L) == 1); // not ambiguous -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 07 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 19:13:35 PDT --- Kenji: My bad, I forgot T:int means exact match, thought it's match with conversion. (BTW that's a mistake: The syntax in classes suggests that class T:U means subtyping. But it's too late to fix that now.) So, you're right. Thanks for the clarification! Have you linked a pull request yet? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 07 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 Kenji Hara <k.hara.pg gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |pull ---Kenji: My bad, I forgot T:int means exact match, thought it's match with conversion. (BTW that's a mistake: The syntax in classes suggests that class T:U means subtyping. But it's too late to fix that now.) So, you're right. Thanks for the clarification! Have you linked a pull request yet?Oh, I forgot to add 'pull' tag. Will do. https://github.com/D-Programming-Language/dmd/pull/1409 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 07 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/edd0f6fbeeff70eccd7d2e15429b20418360eca5 fix Issue 1528 - [tdpl] overloading template and non-template functions - Improve `resolveFuncCall` for integrated function call resolution. All of error reporting is done in here. - Remove `overloadResolve` and `deduceFuncitonTemplate` The works was in `overloadResolve` are moved to `resolveFuncCall`, and things was in `deduceFuncitonTemplate` are divided to `templateResolve` and `resolveFuncCall`. - Change the name from `overloadResolveX` to `functionResolve` It is paired with `templateResolve`. - Decide 'most specialized' function based on the two `MATCH` values derived from `tiargs` and `fargs`. With non template functions, `last matching level for tiargs` is treated as `MATCHexact`. ---- The bug that is fixed at the same time: fix Issue 9596 - Ambiguous match is incorrectly hidden by additional lesser match The change in test/runnable/template9.d is related. https://github.com/D-Programming-Language/dmd/commit/fba440cc7dc1210b0450f8b01d18661ebbd0da55 Issue 1528 - [tdpl] overloading template and non-template functions -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jun 28 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 bearophile_hugs eml.cc changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |bearophile_hugs eml.ccCommits pushed to master atThis is a significant improvement. I am testing this feature a little. This is code reduced from your Comment 10: int f1(int a, double=10) { return 1; } int f1(int a, string="") { return 2; } int f2(T:int)(T b, double=10) { return 1; } int f2(T:int)(T b, string="") { return 2; } void main() { f1(1); f2(1L); } It gives the errors: test.d(6): Error: called with argument types: (int) matches both: test.d(1): test.f1(int a, double _param_1 = 10.0000) and: test.d(2): test.f1(int a, string _param_1 = "") test.d(7): Error: template test.f2 does not match any function template declaration. Candidates are: test.d(3): test.f2(T : int)(T b, double = 10) test.d(4): test.f2(T : int)(T b, string = "") test.d(7): Error: template test.f2(T : int)(T b, double = 10) cannot deduce template function from argument types !()(long) For the error at line 6 it nicely indents the lines test.d(1) and test.d(2). While for the error at line 7 it doesn't indent the lines test.d(3) and test.d(4). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jun 28 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 Jonathan M Davis <jmdavisProg gmx.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |mitch.hayenga gmail.com PDT --- *** Issue 4749 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 20 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1528 Kenji Hara <k.hara.pg gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |FIXED -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 23 2013