-
Notifications
You must be signed in to change notification settings - Fork 469
Improve function apply error messages #7496
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
Conversation
This function has type (int, int) => unit | ||
It is applied with [1;31m1[0m argument but it requires [1;33m2[0m. No newline at end of file | ||
This function call is incorrect. | ||
The function has type: | ||
(int, int) => unit | ||
|
||
It is called with [1;31m1[0m argument but requires [1;33m2[0m. |
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.
For some reason the new error mechanism does not pick up this specific test. It's an object method call, looks like this:
let f = obj => {
obj["hi"](1, 2)
obj["hi"](1)
}
Couldn't figure out why it wasn't picked up, should've been caught with the too few unlabelled arguments check. Maybe @cristianoc has ideas?
Either way, it's not worse than before, so we can definitely ship this and figure out how to improve it later.
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.
This was resolved right?
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.
No, not yet. But it's not important now, can be investigated as a follow up.
rescript
@rescript/darwin-arm64
@rescript/darwin-x64
@rescript/linux-arm64
@rescript/win32-x64
@rescript/linux-x64
commit: |
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.
great work @zth, this is much better, I'd just differentiate more the wording in Apply_wrong_label between the cases where the argument is unlabelled and where it's an incorrect label.
This function call is incorrect: | ||
- It takes [1;33m1[0m unlabelled argument, but is called with [1;31mjust 0[0m |
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.
wow this is much better!
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.
Yes, except for the "It", which now seems to refer to the function call instead of the function.
- It takes �[1;33m1�[0m unlabelled argument, but is called with �[1;31mjust 0�[0m | |
- The function takes �[1;33m1�[0m unlabelled argument, but is called with �[1;31mjust 0�[0m |
"The function" is repeated below though.
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.
I'll change it to The function
.
It has type: ('a, ~def: int=?) => 'b |
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.
the double negation makes it a bit hard to follow I think, what about:
This function does not take an unlabelled argument at this position. | |
It has type: ('a, ~def: int=?) => 'b | |
The argument at this position should be labelled. | |
This function has type: ('a, ~def: int=?) => 'b |
It has type: (~a: string) => string |
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.
same here
- Missing arguments that must be provided: ~b | ||
|
||
The function has type: | ||
(~a: int, ~b: int) => int |
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.
hell yeah!
- Missing arguments that must be provided: ~d, ~c, ~b | ||
|
||
The function has type: | ||
(int, ~b: int, ~c: 'a, ~d: 'b) => int |
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.
this is really much better!
compiler/ml/typecore.ml
Outdated
let print_label ppf = function | ||
| Noloc.Nolabel -> fprintf ppf "without label" | ||
| l -> fprintf ppf "with label %s" (prefixed_label_name l) | ||
| Noloc.Nolabel -> fprintf ppf "an unlabelled argument at this position" | ||
| l -> fprintf ppf "the argument @{<info>%s@}" (prefixed_label_name l) | ||
in | ||
fprintf ppf | ||
"@[<v>@[<2>The function applied to this argument has type@ %a@]@.This \ | ||
argument cannot be applied %a@]" | ||
type_expr ty print_label l | ||
fprintf ppf "@[<v>@[<2>This function does not take %a.@]@,It has type: %a@]" | ||
print_label l type_expr ty |
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.
I would not use the same text for labelled or unlabelled arguments here, see my comment below.
This function call is incorrect: | ||
- It takes [1;33m1[0m unlabelled argument, but is called with [1;31mjust 0[0m |
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.
Yes, except for the "It", which now seems to refer to the function call instead of the function.
- It takes �[1;33m1�[0m unlabelled argument, but is called with �[1;31mjust 0�[0m | |
- The function takes �[1;33m1�[0m unlabelled argument, but is called with �[1;31mjust 0�[0m |
"The function" is repeated below though.
This function call is incorrect. | ||
The function has type: |
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.
Here the function type is shown at the top, and the explanation of what is wrong is shown below.
In the example further above it is the other way around.
I actually prefer the style here, can we standardize on it?
I.e., always start with
This function call is incorrect.
The function has type:
...
and then the explanation below?
Or maybe even on one line:
This function call is incorrect. The function has type:
...
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.
I adjusted. Please have another look.
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.
Looks good to me now!
The argument at this position should be labelled. | ||
This function has type: ('a, ~def: int=?) => 'b |
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.
We still have different styles here. Other messages have
- function type
- error message
This one has
- error message
- function type
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.
Well, technically I'd say we have this structure:
- "Header"
- Function type
- Error message
For this particular error message I think it makes more sense to have it like this. You're going to see the highlighted position first, then the message that the arg should be labelled, and then the function type. I think that makes sense.
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.
Ok, fine with me, too.
This reworks the function apply error messages some to make them clearer and easier to understand.
Feedback very welcome.
Closes #7055