overload set printing

<moving to cfe-dev>

With tweaks (and hacking around the "system header note issue"),

I guess it's time to really fix the "continuation error messages" problem, then.

You're right, done. :slight_smile:

What do you think?

GCC does that, and it's reasonably helpful. One ends up spending a bit of time comparing the argument list to each of the candidates, but it's better than not having that information.

I think it is really important to provide a basic level of decency.

Another alternative would be to say what went wrong with each candidate, e.g.,

  "cannot convert argument of type 'short*' to parameter of type 'long long x' for candidate function:"

with the caret pointing at the appropriate parameter (i.e., the first failure). It's more work, but that would let us say very specific things like, "cannot bind a non-const reference of type 'blah' to a temporary".

Yes yes yes, this would be very very helpful.

In addition to that, in the case when there is exactly one member of the overload set, we should hone in on the exact problem. For example, in:

struct foo {
   void bar();
   void bar(int);
};

void test(const foo *P) { P->bar(); }

GCC produces:
t.cpp:7: error: passing ‘const foo’ as ‘this’ argument of ‘void foo::bar()’ discards qualifiers

Which is acceptable but ugly (it should explicitly say 'cannot call non-const method on const object' or something), we say:

t.cpp:7:27: error: no matching member function for call to 'bar'; candidates are:
void test(const foo *P) { P->bar(); }
                           ^~~~~~
t.cpp:3:8: note: candidate function
   void bar();
        ^
t.cpp:4:8: note: candidate function
   void bar(int);
        ^

lame :frowning:

I also filed PR3600 with a more broken case.

-Chris

<moving to cfe-dev>

With tweaks (and hacking around the "system header note issue"),

I guess it's time to really fix the "continuation error messages" problem, then.

You're right, done. :slight_smile:

Thanks!

What do you think?

GCC does that, and it's reasonably helpful. One ends up spending a bit of time comparing the argument list to each of the candidates, but it's better than not having that information.

I think it is really important to provide a basic level of decency.

Agreed.

Another alternative would be to say what went wrong with each candidate, e.g.,

  "cannot convert argument of type 'short*' to parameter of type 'long long x' for candidate function:"

with the caret pointing at the appropriate parameter (i.e., the first failure). It's more work, but that would let us say very specific things like, "cannot bind a non-const reference of type 'blah' to a temporary".

Yes yes yes, this would be very very helpful.

In addition to that, in the case when there is exactly one member of the overload set, we should hone in on the exact problem. For example, in:

struct foo {
void bar();
void bar(int);
};

void test(const foo *P) { P->bar(); }

GCC produces:
t.cpp:7: error: passing ‘const foo’ as ‘this’ argument of ‘void foo::bar()’ discards qualifiers

Which is acceptable but ugly (it should explicitly say 'cannot call non-const method on const object' or something), we say:

t.cpp:7:27: error: no matching member function for call to 'bar'; candidates are:
void test(const foo *P) { P->bar(); }
                         ^~~~~~
t.cpp:3:8: note: candidate function
void bar();
      ^
t.cpp:4:8: note: candidate function
void bar(int);
      ^

lame :frowning:

Well, there are two candidates here, but the first one is "clearly" better than the other. There are at least two parts to the solution: the first is to classify what went wrong in each of the candidates (which means annotating failed ImplicitConversionSequences) and the second is to sort and filter the candidate set based on this annotations.

   - Doug