The use of auto with an assignment from an overloaded function results in an ambiguous type. The type of the variable is depends on the order that the overloads are defined. switch the order and the type changes (see code below). BTW this bug also exists in DMC.
------------------------
void main()
{
S s;
int delegate(int) dlp_i = &s.fn;
int delegate() dlp_v = &s.fn;
auto dlp_x = &s.fn;
dlp_i(1); // works
dlp_v(); // works
dlp_x(); // what type is dlp_x ??
dlp_x(1); // it depends in the order of fn's in S
// same problem with fn ptrs
int function(int) fnp_i = &fn;
int function() fnp_v = &fn;
auto fnp_x = &fn;
fnp_i(1); // works
fnp_v(); // works
fnp_x(); // what type is fnp_x ??
fnp_x(1); // it depends in the order of fn's in S
}
struct S
{
int j;
// swap these to change the type of dlp_x
int fn(int i) { j = i; return j; }
int fn() { j = 0; return j; }
}
// swap these to change the type of fnp_x
int fn(int i) { return i; }
int fn() { return 0; }
Comment #1 by smjg — 2006-05-18T07:29:52Z
AFAIK this also occurs with typeof, and probably functions overloaded to take function pointers as well. While the spec doesn't comment in the ambiguity, it's incompatible with something that the spec does say somewhere or other: that the semantics of a program should never be altered by the order of declarations.
Comment #2 by wbaxter — 2006-11-28T19:24:17Z
Ugh. I just hit this using my flexible signals and slots wrapper.
widget.value_changed.fconnect(&other_widget.value);
Doh!
I really don't want writing a gui to involve gobs of code like:
widget.value_changed.fconnect!(
typeof(&other_widget.value))(&other_widget.value);
Now I really wish I had a tool to find property-like methods in my source code so I can at least make sure they are in the right lexical ordering. :-(
Has there been any bug/enhancement filed on this that I can keep a watch on?
For my case I'm not even sure what would be the right thing for it to do. What I really need to happen is for fconnect to prefer methods with non-trivial argument lists, but I can't rule out the possibility someone actually wants to connect up a no-argument slot like "updateGui()" to a signal.
Maybe we need to be able to optionally specify the arguments when taking a delegates, like:
connect(&obj.value(int));
Comment #3 by wbaxter — 2006-11-28T19:33:47Z
(In reply to comment #2)
> Has there been any bug/enhancement filed on this that I can keep a watch on?
Sorry, obviously this is the bug (I just did a sloppy c&p from newsgroup article digitalmars.com digitalmars.D:44742 ).
And if it's not clear what the problem is above, it's that the ''standard D idiom'' to define property methods like:
int value() { return m_value; }
int value(int v) { return m_value=v; }
I use this in Luigi everywhere (http://www.dsource.org/projects/luigi).
I also use signals and slots in Luigi. I've got a very handy automatic slot wrapper mechanism that will let you connect any slot with a _compatible_ signature to a signal. The slot doesn't have to have a void return type, for example. This is handy because it lets you connect the 'value' property above directly to the signal (or at least apparently so from the users perspective).
*** Bug 1006 has been marked as a duplicate of this bug. ***
Comment #6 by gide — 2009-04-07T03:12:20Z
The example below does not compile. Has this been fixed?
DMD v1.041
bug52.d(11): Error: expected 1 arguments, not 0
bug52.d(26): Error: expected 0 arguments, not 1
DMD v2.027
bug52.d(11): Error: expected 1 function arguments, not 0
bug52.d(20): Error: cannot infer type from overloaded function symbol & fn
bug52.d(26): Error: expected 0 arguments, not 1 for non-variadic function type int()
Comment #7 by gide — 2009-04-07T05:31:54Z
(In reply to comment #6)
> The example below does not compile...
The example in the issue description does not compile anymore. Has this issue been fixed and is it ok to close this bug?
Comment #8 by smjg — 2009-04-07T06:25:44Z
No. If you actually read this bug, you'll see that it isn't about lines 11 and 26, but about the fact that ambiguous function pointers are silently accepted.
The errors should be at lines 6 and 20. If you take out the lines where errors actually are reported, you'll find that it incorrectly compiles without error (just checked in 1.043).
Also, if there are Dstress testcases, please check these before proposing to close a bug.
http://www.digitalmars.com/d/archives/digitalmars/D/bugs/bugzilla_usage_tips_10071.html
Comment #9 by clugdbug — 2009-07-20T23:58:17Z
This is fixed in DMD2, and the main part of the code (with error message)
is in the DMD1 source, but not enabled (it won't compile). So it seems Walter got halfway through fixing this, then got distracted?
(I'm removing 'spec' from the keywords, since it's clear this is just a bug).
Doing a copy-and-paste of the uniqueness test from D2, and disabling the overload test, it _seems_ to work.
I'm assuming that the 'hasOverloads' member in D2 is for overload sets? In any case, with this change, the D1 compiler passes the DM test suite, and the phobos1 unit tests. Of course, if that member isn't for overload sets, this patch isn't correct, regardless of what the tests say...
(In that case, the code relating to 'hasOverloads' should also be copied from D2).
----
From D2, in expression.c, in
Type *ExpInitializer::inferType(Scope *sc),
enable the code inside #if DMDV2.
But change the line:
if (se->hasOverloads && !se->var->isFuncDeclaration()->isUnique())
into:
if (!se->var->isFuncDeclaration()->isUnique())
And then in func.c, add this code from DMD2.
static int fpunique(void *param, FuncDeclaration *f)
{ FuncDeclaration **pf = (FuncDeclaration **)param;
if (*pf)
{ *pf = NULL;
return 1; // ambiguous, done
}
else
{ *pf = f;
return 0;
}
}
FuncDeclaration *FuncDeclaration::isUnique()
{ FuncDeclaration *result = NULL;
overloadApply(this, &fpunique, &result);
return result;
}
Comment #10 by bugzilla — 2009-10-03T02:29:57Z
The hasOverloads needs to be there for it to work right, as if there is a cast it should select the correct overload.