Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Improve overload resolution #11271

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft

WIP: Improve overload resolution #11271

wants to merge 1 commit into from

Conversation

kinke
Copy link
Contributor

@kinke kinke commented Jun 14, 2020

Problem

From dlang/phobos#7463 (comment):

float foo(float a, float b);
double foo(double a, double b);
real foo(real a, real b);

alias T = double;
T bar(T x)
{
    pragma(msg, typeof(x * 1));
    return foo(x, 1);
}
double
onlineapp.d(9): Error: `onlineapp.foo` called with argument types `(double, int)` matches both:
onlineapp.d(1):     `onlineapp.foo(float a, float b)`
and:
onlineapp.d(3):     `onlineapp.foo(real a, real b)`

Note that this works for C++.

Approach

The current resolution scheme only takes into account the worst MATCH over all argument->parameter pairs. So in the case above, a single implicit conversion from int to double is just as 'bad' as converting both double and int to a float/real each.

So the approach here is to use counters for each MATCH class, for a more fine-grained resolution.

@UplinkCoder
Copy link
Member

I don't think the phobos code above should compile.
In the case above I would want the user to specify the intended overload via a cast.
C++ is not the best place to look towards for clear and legible overload resolution rules.

@kinke
Copy link
Contributor Author

kinke commented Jun 16, 2020

Do you realize what this would mean when we add proper float/double overloads for all math functions? Ugly and embarrassing stuff like https://github.com/Netflix/vectorflow/pull/33/files.

@UplinkCoder
Copy link
Member

UplinkCoder commented Jun 16, 2020

@kinke literals are real by default?
We should probably deprecate that, and require an llf suffix or something

@kinke
Copy link
Contributor Author

kinke commented Jun 16, 2020

What? The literal above is an int, see the error msg.

@UplinkCoder
Copy link
Member

@kinke in that case the user would have to decide if we wanted to convert it to a double a float or a real.
It depends on the magnitude of the int's value.
Whether conversion to float would remove bits.

@kinke
Copy link
Contributor Author

kinke commented Jun 16, 2020

Taking that into account would IMO be a valid stance too but probably require another MATCH value meaning lossless conversion. Anyway, an int is always losslessly representable as double, so the double overload for the example above should be a no-brainer. [C++ uses the float overload for (float, long long) too.]

@UplinkCoder
Copy link
Member

@kinke c++ does horrible things with implicit conversion.
Like you know this bug when you import a path header.
And it overloads wide_string and string comparison to compare as paths?

"x\\y"w == "x/y" => true

Copy link
Member

@wilzbach wilzbach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fully in favor of this. Thanks!

@UplinkCoder
Copy link
Member

@kinke

So the approach is:
iff there is a single unambiguous match target selected by non-converted parameters.
Do a match convert on the other parameters?

That might be acceptable. ish
I am still weary.

@kinke
Copy link
Contributor Author

kinke commented Jun 16, 2020

C# shows the same C++ behavior in this case:
https://dotnetfiddle.net/Oc7Mlk

So I'd expect regular devs to expect this from D too.

I'm not familiar with the exact C++ overload resolution rules. The approach here is sketched out in the 1st post - an overload requiring a single conversion ((double, int->double)) is to be preferred over one requiring multiple conversions ((double->float, int->float), (double->real, int->real)).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants