digitalmars.D.bugs - [Issue 4028] New: delegates with differing default arguments lead to same template instantiation
- d-bugmail puremagic.com (87/87) Mar 29 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4028
- d-bugmail puremagic.com (10/10) Mar 29 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4028
- d-bugmail puremagic.com (9/9) Apr 04 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4028
- d-bugmail puremagic.com (25/25) Apr 04 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4028
- d-bugmail puremagic.com (10/10) Apr 07 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4028
- d-bugmail puremagic.com (15/15) Aug 17 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4028
- d-bugmail puremagic.com (9/9) Jan 06 2011 http://d.puremagic.com/issues/show_bug.cgi?id=4028
- d-bugmail puremagic.com (11/11) Jan 07 2011 http://d.puremagic.com/issues/show_bug.cgi?id=4028
- d-bugmail puremagic.com (13/18) Apr 05 2011 http://d.puremagic.com/issues/show_bug.cgi?id=4028
- d-bugmail puremagic.com (12/12) Apr 06 2011 http://d.puremagic.com/issues/show_bug.cgi?id=4028
- d-bugmail puremagic.com (16/19) Apr 06 2011 http://d.puremagic.com/issues/show_bug.cgi?id=4028
- d-bugmail puremagic.com (6/6) Jun 08 2011 http://d.puremagic.com/issues/show_bug.cgi?id=4028
- d-bugmail puremagic.com (12/12) Jul 03 2011 http://d.puremagic.com/issues/show_bug.cgi?id=4028
http://d.puremagic.com/issues/show_bug.cgi?id=4028 Summary: delegates with differing default arguments lead to same template instantiation Product: D Version: 1.057 Platform: Other OS/Version: All Status: NEW Keywords: wrong-code Severity: major Priority: P2 Component: DMD AssignedTo: nobody puremagic.com ReportedBy: nfxjfg gmail.com Look at these two delegates: void delegate(int x = 123) D_A; void delegate(int x) D_B; They have the same type, but they behave differently. E.g. you can call D_A(), but not D_B(). They lead to the same template instantiation: void foo(T)(T del) { } foo(D_A) and foo(D_B) will be the same template instantiations. This is a bug, because foo(D_B) will think that del has a default parameter, which is obviously not the case. dmd should instantiate two different templates for it. Maybe make delegates with different default args have different types. Here's a test case, which demonstrates how this can lead to trouble in real world programs. The code is ripped out from a scripting wrapper, which tries to support default arguments. (The reason why doMethod is templated on a delegate and not on the class/method is to drastically reduce the number of template instantiations.) import std.stdio; template ParameterTupleOf( Fn ) { static if( is( Fn Params == function ) ) alias Params ParameterTupleOf; else static if( is( Fn Params == delegate ) ) alias ParameterTupleOf!(Params) ParameterTupleOf; else static if( is( Fn Params == Params* ) ) alias ParameterTupleOf!(Params) ParameterTupleOf; else static assert( false, "Argument has no parameters." ); } int requiredArgCount(alias Fn)() { alias ParameterTupleOf!(typeof(Fn)) Params; Params p; static if (is(typeof(Fn()))) return 0; foreach (int idx, x; p) { static if (is(typeof(Fn(p[0..idx+1])))) return idx+1; } assert(false); } class Foo { void moo1() {} void moo2(short x) {} void moo3(int x = 123) {} void moo4(int x) {} } void doMethod(T)(T del, char[] name, char[] expect) { writefln("method %s, required arg count: got %s, expected %s", name, requiredArgCount!(del)(), expect); } void method(Class, char[] name)(char[] expect) { auto fn = mixin("&Class." ~ name); doMethod(fn, name, expect); } void main() { //just to prove that the other code works method!(Foo, "moo1")("0"); method!(Foo, "moo2")("1"); //here starts the problem //moo3 instantiates doMethod!(void delegate(int x = 123)) method!(Foo, "moo3")("0"); //moo4 _should_ instantiate doMethod!(void delegate(int x)) //but it really insantiates the same as moo3: // doMethod!(void delegate(int x = 123)) //this is obviously wrong! //doMethod() will think that moo4 has a default argument, when it //really hasn't (you can see that in the runtime output of this program) method!(Foo, "moo4")("1"); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 29 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4028 PS: the worst thing about this bug is that the actual delegate type the template is using is practically chosen randomly. E.g. the program above thinks moo4 has a default argument. If you switch the order method!(Foo, "moo3") and method!(Foo, "moo4") are called, moo4 will be handled correctly, but it thinks moo3 has a required argument. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 29 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4028 I decided that this bug can't be fixed. Even if you'd try to make it behave correctly, you would somehow have to include the default arguments expressions into the name mangling of template instantiations. What are you going to do, Wallter? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 04 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4028 Before I'm trying to forget this bug while cursing dmd to hell and inventing awkward, code-inflating work arounds in my code, here's a simpler test case that demonstrates the bug: import std.stdio; alias void delegate(int x = 123) Dg1; alias void delegate(int x) Dg2; void main() { writefln("%s", Dg1.stringof); writefln("%s", Dg2.stringof); } Output, expected: void delegate(int x = 123) void delegate(int x) Output, actual with dmd 1.057: void delegate(int x = 123) void delegate(int x = 123) Don't forget that this doesn't really scratch the template instantiation issue; one could say that there are actually two bugs: 1. accidentally merging the types Dg1 and Dg2 into one type, and 2. template instantiations with delegates/functionpointers that have default arguments. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 04 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4028 The two delegates *are* the same type, so they are supposed to lead to the same template instantiation. Introducing a default parameter does not create a new type. I'm not sure why function pointers with default parameters are accepted at all. I think it should be an error. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 07 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4028 Jonathan M Davis <jmdavisProg gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jmdavisProg gmail.com 19:11:33 PDT --- Well, either they need to be separate or default parameters for function pointers, delegates, and lambdas need to become errors. It seems like it might be nice for them to be able to have default parameters, but the more I think about it, the weirder it seems. I'm not quite sure why that would be all that useful. It seems like it's trying to subvert the type of function by currying it. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 17 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4028 nfxjfg gmail.com changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |WONTFIX -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 06 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4028 Gide Nwawudu <gide nwawudu.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords|wrong-code |accepts-invalid Status|RESOLVED |REOPENED CC| |gide nwawudu.com Resolution|WONTFIX | -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 07 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4028 Walter Bright <bugzilla digitalmars.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |bugzilla digitalmars.com 22:15:35 PDT ---The two delegates *are* the same type, so they are supposed to lead to the same template instantiation. Introducing a default parameter does not create a new type. I'm not sure why function pointers with default parameters are accepted at all. I think it should be an error.I suspect the only way to deal with this is, as you suggest, disallowing default arguments for function pointers. I don't know what the downside of that is, though. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 05 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4028 bearophile_hugs eml.cc changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |bearophile_hugs eml.cc Is it possible/good to encode the simple constant default arguments (ints, strings, etc) in the type/signature of the delegate, and refuse the other types of default arguments? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 06 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4028 Don <clugdbug yahoo.com.au> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |clugdbug yahoo.com.auIs it possible/good to encode the simple constant default arguments (ints, strings, etc) in the type/signature of the delegate, and refuse the other types of default arguments?What good would adding that corner case be? I think it's just a bizarre and silly feature. It's a horrendously complicated and confusing way of doing one special case of currying. If you really need this ability (which I doubt), you can achieve the same thing via a struct with two opCall overloads. Just kill it. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 06 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4028 *** Issue 4664 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: -------
Jun 08 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4028 yebblies <yebblies gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|REOPENED |RESOLVED CC| |yebblies gmail.com Resolution| |DUPLICATE *** This issue has been marked as a duplicate of issue 3646 *** -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 03 2011