Fix Issue 15613, 11529: Show parameter mismatch and rvalue/lvalue ref message#7554
Fix Issue 15613, 11529: Show parameter mismatch and rvalue/lvalue ref message#7554dlang-bot merged 10 commits intodlang:masterfrom
Conversation
|
Thanks for your pull request, @ntrel! We are looking forward to reviewing it, and you should be hearing from a maintainer soon. Some tips to help speed things up:
Bear in mind that large or tricky changes may require multiple rounds of review and revision. Please see CONTRIBUTING.md for more information. Bugzilla references
|
5ecde07 to
244000b
Compare
|
Better diagnostics is exactly what D needs right now! Great work! |
src/dmd/func.d
Outdated
| } | ||
| } | ||
|
|
||
| void showArgMismatch(Loc loc, Expressions* fargs, TypeFunction tf, size_t failIndex) |
There was a problem hiding this comment.
Please add Ddoc style function comment.
src/dmd/func.d
Outdated
| auto msg = "cannot pass %sargument `%s` of type `%s` to parameter `%s`"; | ||
| // don't print parameter type if it's already in the parameter string | ||
| if (strcmp(par.type.toChars(), ts[1]) != 0) | ||
| msg ~= " of type `%s`"; |
There was a problem hiding this comment.
This isn't guaranteed to produce a 0 terminated array.
There was a problem hiding this comment.
Just use two different msg strings.
There was a problem hiding this comment.
i.e.:
msg = strcmp() ? "cannot pass ..." : "cannot pass ... of type ...";
There was a problem hiding this comment.
Fixed by adding \0 to 2nd string, hope that's OK?
src/dmd/hdrgen.d
Outdated
| return buf.extractString(); | ||
| } | ||
|
|
||
| extern (C++) const(char)* parameterToChars(Parameter parameter, int varargs) |
There was a problem hiding this comment.
Add Ddoc function comment.
src/dmd/mtype.d
Outdated
| } | ||
| } | ||
|
|
||
| auto u = size_t.max; // used for failedIndex if no match |
There was a problem hiding this comment.
I would prefer having a bool failed and a size_t failedIndex and use failed to determine whether or not failedIndex holds a valid value.
There was a problem hiding this comment.
We can just check the return value against MATCH.nomatch to determine if failedIndex is valid.
src/dmd/hdrgen.d
Outdated
| * parameter = parameter to print. | ||
| * varargs = Kind of varargs, see TypeFunction.varargs. | ||
| * Returns: NT string representing parameter. */ | ||
| extern (C++) const(char)* parameterToChars(Parameter parameter, int varargs) |
There was a problem hiding this comment.
DDoc also needs a summary, and what does "NT" mean? If "null-terminated", spell it out please.
| * parameters = parameters to print, such as TypeFunction.parameters. | ||
| * varargs = Kind of varargs, see TypeFunction.varargs. | ||
| * Returns: NT string representing parameters. */ | ||
| extern (C++) const(char)* parametersTypeToChars(Parameters* parameters, int varargs) |
There was a problem hiding this comment.
DDoc also needs a summary, and what does "NT" mean? If "null-terminated", spell it out please.
There was a problem hiding this comment.
Please don't abbreviate null-terminated.
test/fail_compilation/bug9631.d
Outdated
| TEST_OUTPUT: | ||
| --- | ||
| fail_compilation/bug9631.d(79): Error: function bug9631.arg.f `(int i, S s)` is not callable using argument types `(int, S)` | ||
| fail_compilation/bug9631.d(79): cannot pass argument `y` of type `bug9631.tem!().S` to parameter `S s` of type `bug9631.S` |
There was a problem hiding this comment.
function bug9631.arg.f `(int i, S s)` is not callable using argument types `(int, S)`
- Tick marks should surround the entire function declaration (e.g `bug9631.arg.f (int i, S s)`). That may be a difficult thing to do and I'd be willing to pass on the tick marks for now
- The function accepts
(int, S)but the error message says it's not callable using(int, S). Does this need fully qualified names or something?
There was a problem hiding this comment.
cannot pass argument
yof typebug9631.tem!().Sto parameterS sof typebug9631.S
I suspect this line is supposed the clarify the first, but it's awfully confusing. Can't we have just one line with fully qualified type names?
There was a problem hiding this comment.
bug9631.arg.f `(int i, S s)`
This was introduced by Walter before this PR. I tried to fix it but can't work out why exactly it happens.
test/fail_compilation/bug9631.d
Outdated
| fail_compilation/bug9631.d(80): Error: function literal `__lambda2(S s)` is not callable using argument types `(S)` | ||
| fail_compilation/bug9631.d(80): cannot pass argument `x` of type `bug9631.S` to parameter `S s` of type `bug9631.tem!().S` | ||
| fail_compilation/bug9631.d(86): Error: constructor bug9631.arg.A.this `(S _param_0)` is not callable using argument types `(S)` | ||
| fail_compilation/bug9631.d(86): cannot pass argument `S(0)` of type `bug9631.tem!().S` to parameter `S _param_0` of type `bug9631.S` |
There was a problem hiding this comment.
cannot pass argument `S(0)`
`S(0)` doesn't look like an argument; it looks like a function invocation OK, I get it now, though I'm not sure we're making much progress on clarifying these messages.
to parameter `S _param_0` of type `bug9631.S`
I think this should read "... to parameter `bug9631.S _param_0`" without redundantly specifying one unqualified type name `S` and one qualified type name `bug9631.S`
| fail_compilation/diag8101b.d(18): `diag8101b.S.foo(int _param_0)` | ||
| fail_compilation/diag8101b.d(19): `diag8101b.S.foo(int _param_0, int _param_1)` | ||
| fail_compilation/diag8101b.d(29): Error: function diag8101b.S.bar `(int _param_0)` is not callable using argument types `(double)` | ||
| fail_compilation/diag8101b.d(29): cannot pass argument `1.00000` of type `double` to parameter `int _param_0` |
There was a problem hiding this comment.
Can we shoot for something like:
function
diag8101b.S.bar (int _param_0)is not callable using argument1.00000of typedoubleto parameterint _param_0
You might even be able to make it less verbose with...
function
diag8101b.S.baris not callable using argument1.00000of typedoubleto parameterint _param_0
There was a problem hiding this comment.
I think it's useful to see the full parameter list, so we know which function the compiler means. If we combine both messages I think there's too much information in one sentence.
There was a problem hiding this comment.
I think it's useful to see all the argument types too.
| fail_compilation/diag8101b.d(17): `diag8101b.S.foo(int _param_0)` | ||
| fail_compilation/diag8101b.d(18): `diag8101b.S.foo(int _param_0, int _param_1)` | ||
| fail_compilation/diag8101b.d(33): Error: mutable method `diag8101b.S.bar` is not callable using a const object | ||
| fail_compilation/diag8101b.d(27): Error: none of the overloads of `foo` are callable using argument types `(double)`, candidates are: |
There was a problem hiding this comment.
The term "argument types" seems odd here. What about...
none of the overloads of
fooare callable using parameter list(double), candidates are:
This also removes the plural "types" with the singular parameter type oddity.
There was a problem hiding this comment.
Well, it's talking about arguments so "argument list" would work. But this is not part of the PR, I expect argument types is used elsewhere too.
|
BTW, I also have code to do the same for deduced template function calls (if there are no overloads), but I'll wait until this is merged to submit. |
| parameter.accept(v); | ||
| if (varargs) | ||
| { | ||
| buf.writestring("..."); |
There was a problem hiding this comment.
need test case to cover this new line
There was a problem hiding this comment.
Added test, turns out it was wrong for variadic parameters :-/
src/dmd/hdrgen.d
Outdated
| * parameter = parameter to print. | ||
| * varargs = kind of varargs, see TypeFunction.varargs. | ||
| * fullQual = whether to fully qualify types. | ||
| * Returns: Null-terminated string representing parameters. */ |
There was a problem hiding this comment.
Nit: Please conform to the existing way Ddoc comments are formatted in the front end. To wit:
/****
* blah blah
*/
not:
/** blah blah
* blah blah */
| auto s1 = t1.toChars(); | ||
| auto s2 = t2.toChars(); | ||
| if (strcmp(s1, s2) == 0) | ||
| if (!t1.equals(t2) && strcmp(s1, s2) == 0) |
There was a problem hiding this comment.
when would the type strings be the same but they are different types?
There was a problem hiding this comment.
When the strings aren't the full qualified type, e.g. S vs tem!().S.
There was a problem hiding this comment.
Please add comment to that effect.
src/dmd/hdrgen.d
Outdated
| return buf.extractString(); | ||
| } | ||
|
|
||
| /** Pretty print function parameters. |
There was a problem hiding this comment.
This has the same description and return value as the previous function - what does it do different?
There was a problem hiding this comment.
Typo, should be parameter. Fixed.
src/dmd/expressionsem.d
Outdated
|
|
||
| .error(exp.loc, "`%s%s` is not callable using argument types `%s`", | ||
| exp.e1.toChars(), parametersTypeToChars(tf.parameters, tf.varargs), buf.peekString()); | ||
| showArgMismatch(exp.loc, exp.arguments, tf, failIndex); |
There was a problem hiding this comment.
It'd be nice to have test coverage for the new code.
There was a problem hiding this comment.
BTW, what does TOKvar mean? I'm trying to hit this case.
There was a problem hiding this comment.
TOKvar distinguishes a VarExp from other Expression types.
There was a problem hiding this comment.
I don't know how to test for the case when TOKvar is a function. Function pointers are handled differently.
src/dmd/dtemplate.d
Outdated
| * tiargs initial list of template arguments | ||
| * tthis if !NULL, the 'this' pointer argument | ||
| * fargs arguments to function | ||
| * failedIndex address to store argument index of first type mismatch |
There was a problem hiding this comment.
note that failedIndex can be null
There was a problem hiding this comment.
I've noted this for pMessage (which replaced failedIndex).
There was a problem hiding this comment.
This should be in Ddoc style:
Params:- use
=- then Ddoc can would throw an error about the non-existingfailedIndex
JinShil
left a comment
There was a problem hiding this comment.
Definitely an improvement.
|
Rebased to |
|
@wilzbach Thanks for rebasing. I changed the ddoc comments to use |
Show the first argument that fails to match the function parameters. This is also part of: Issue 9631 - Error message not using fully qualified name when appropriate
Also hide separate parameter type when already shown.
|
Rebased again ;-) |
|
So yesterday I dusted off an old project and tried to compile. Sure thing, I ran out of memory. This project used to take 2, max 3 GBs of memory. Now it runs out of memory after reaching 7 GBs. As a result I started to bisect, which led me to this commit after a bit of gymnastic (having class Bar { this(int) {} }
void main () { scope b = new Bar; }but that was fixed by later refactoring. Second commit (ff99241) doesn't compile because it was blindly rebased after the Now the cherry on the top: this pull request (or more precisely, commit 6) allocates an error message for every matching failure during call resolution. And that memory is allocated with It comes down to commit 6, which eagerly generates error message. @ntrel what was the motivation for it ? |
|
@Geod24 Thanks for finding this. I think the problem is the call to |
When there's only one overload to consider: