-
-
Notifications
You must be signed in to change notification settings - Fork 606
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
Failed template match error now lists candidates. #1197
Conversation
Very nice! I would suggest to make the maximum number configurable somehow, though. I think that might be useful for IDEs. Not sure if a command line option or environment variable is best. |
@alexrp I figured someone might say that. I was tempted to add an opt, but thought that it was too insignificant to clutter the command line with. I know Walter is against adding lots and lots of args (and I agree). I would argue that we should just leave it as is for the moment, and if someone finds a genuine need to control it then we can easily add it later without disruption. I'm thinking this is a simply a case of YAGNI (You Ain't Gonna Need It). FWIW, as far as I can tell, GCC and clang do not provide such an option for C++. |
GCC provides |
Yes, but dmd doesn't even provide that. It's hard coded: if (global.errors >= 20) // moderate blizzard of cascading messages
fatal(); I'm going to call that precedence :-) |
Isn't that just for the lexer? |
Not sure, but I think this is getting off topic. Here's the facts:
Thus, assuming everyone is otherwise happy with this patch, I propose that it is merged, and we can discuss whether the option is needed in a separate forum. |
Added another commit which adds in the template function arguments to the candidate list (and all template function error messages). Before: foo.d(3): Error: template foo.foo does not match any function template declaration. Candidates are:
foo.d(1): foo.foo(T) if (is(T : string))
foo.d(2): foo.foo(T)
foo.d(1): Error: template foo.foo cannot deduce template function from argument types !()(int) After: foo.d(3): Error: template foo.foo does not match any function template declaration. Candidates are:
foo.d(1): foo.foo(T)(T r) if (is(T : string))
foo.d(2): foo.foo(T)(T a, T b)
foo.d(1): Error: template foo.foo cannot deduce template function from argument types !()(int) Notice the addition of the function arguments. This allows you to discern between function template with the same template parameters and constraints, but different function parameters. |
// Too many overloads to sensibly display. | ||
// Just show count of remaining overloads. | ||
int remaining = 0; | ||
while (td = td->overnext) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dmc produces a warning for this expression.
A more complicated example does not end up looking so nice:
Gives:
Or, as my terminal likes to display it,
Maybe this is still a net improvement, but this is going to produce a lot of garbage in a lot of cases. I would expect a much lower number to be reasonable, say 5. The compiler could print the full list when using the |
@yebblies I have reduce the number to 5 and added the option of using -v for all. Last commits should have also fixed the |
That's much better, although it is still nasty for complicated cases like std.conv.to. I'm not sure there's much to be done about them though. @andralex What do you think? Please rebase and squash it down to a single commit. |
I'm having trouble with the |
Given how small the resulting changes are, I'd suggest copy+paste. |
In case you don't know how to »fix« a particular change, you can always do:
This is what I like about Git: even if you don't know what the »proper« way of doing things is, you can always find a sequence of commands with the intended result once you understood the quite simple model behind it. |
Thanks @klickverbot, that appears to have worked. |
Failed template match error now lists candidates.
In an attempt to gradually improve template errors, when a template usage fails to match a template declaration it will now list the candidates, so that the user can see all the overloads in one place. This makes it easier to figure out why the match failed.
Example:
gives
Notice that the location of each overload is shown, too.
If there are over 100 candidates, then it will only show 100 and then end with a line saying "... X more ...", just in case someone has generated some crazy number of overloads.
Next step from here is to offer better diagnostics as to why each instantiation failed.