-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Make type error messages more consistent #5092
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
7f843b2
to
f9757e7
Compare
Thanks for working on this, I don't think this would need an RFC as it's only what error message is being displayed. I do think we probably should standardize user and internal error messages and go with the user formatted one because it makes more sense to me to indicate the Argument position. Some of the custom ZPP ones may be a bit hard to standardize but most probably should be able to follow a similar pattern. For ValueError and normal Error I think doing like TypeError and indicating the argument position seems like a sensible change. |
It makes sense to standardize on one format, but it doesn't necessarily have to match any of the existing ones :) I don't like the userland one because it is currently quite special cased, partly for historic reasons. I'd prefer something that does |
Agree. Standardizing them on a best effort basis is perfect for me.
Agree. Prior to submitting the PR I did a small research, and collected type error messages from some of the most popular languages. Unfortunately, I didn't find any that I particularly liked, but I'll include them here just in case, maybe someone gets some inspiration from them :) Java
Go
Rust
I can also relate, but wasn't sure where to put it exactly, and whether it really helps in practice. I'll have a shot on doing so myself, but I'll probably need suggestions about the format. +1: Nikita, you mentioned |
Yeah, I'm not really sure on this. There doesn't seem to be a really nice way to provide both the name and the number, and maybe it's not particularly useful in the first place.
I'm using the "of type T" form for union type errors in Line 678 in 3c72105
|
f9757e7
to
fc3ac80
Compare
Do you miss anything? I'll continue to fix the tests in |
One more thing came to my mind. Instead of the current message format (e.g.
Would you think these versions make the message any more clear? |
Is maybe a bit better but the first one is kinda confusing for me, especially if you have a class: |
Thanks, George, for the feedback. It's interesting for me to hear the opinion of native English speakers. ^^ Somehow I'd either expect some kind of quotation after the |
Inspiring it from Rust but we could maybe do something along the lines: |
For reference, some typed properties error messages:
With this PR, the messages for arguments/returns are:
The property errors put the given type first and expected type later. Two possibilities using this order:
We also have the option to go for the zpp style message rather than the userland one:
|
Thanks for the analysis, Nikita! Do you guys have a strong preference? Do you think a quick poll on the ML or at least on Twitter would be useful? Speaking about my preference, I think I still lean towards |
It's already quite visible that people on twiter prefer the ZPP-style message rather than the user-land one: https://twitter.com/kocsismate90/status/1220430708562448385?s=19 Plus, it turned out that PHPStan also displays the parameter name:
|
ead7f04
to
c0f12b6
Compare
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 changed the wording according to the result of the vote.
7404acf
to
c777019
Compare
c777019
to
aa79a6e
Compare
@nikic Could you please have a look at this whenever you can allocate some time slot? |
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.
So... just to make sure we're really sure here (:P) a few more variations on the message:
%s() expects argument %d to be of type %s, %s given
%s() expects argument %d of type %s, %s given
%s() expects argument %d to be %s, %s given
It seems to be like the current "to be of type" is redundant and we can drop either the "to be" or the "of type".
Also, the Twitter thread has a suggestion for including the argument, which in this format would look something like this I guess?
%s() expects argument #%d ($%s) to be of type %s, %s given
@kocsismate I think the
If we want to adopt this as a more general format, of course... |
Yeah, it's better to reiterate now :) The "to be of type" version seems a bit verbose indeed, but I still like it because it makes clear that it's a type issue, not something else (in case of objects, it might not be obvious). Moreover, if we want to apply a similar format for other errors as well then IMO it would be advantageous to distinguish the different categories in order to avoid possible confusion. Although I am not a great fan of including the parameter name, I could live with it. I can imagine that the parameter name is helpful for people. That said, I'll try to update the PR with this variant. |
aa79a6e
to
982cb28
Compare
@nikic I implemented the last variant. There will be still dozens of failures though... And there were some places (in the VM I think) from where I couldn't add the param name. |
6fde695
to
fcba027
Compare
fcba027
to
3391a4a
Compare
I've implemented some suggested improvements, and managed to fix all the tests except for Additionally, there are 4 error messages ( If it is possible, I'd prefer not to split this PR into a userland and an internal part, unless it's really needed (e.g. for making code review possible). |
@kocsismate Those errors refer to the first arg of call_user_func/call_user_func_array, so you can insert whatever the parameter name is for those. |
3391a4a
to
fc82c65
Compare
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.
You have a bunch of places here checking for the arg name not be available. Is that case hit anywhere in practice?
Maybe with variadic arguments? Those are not included in the argument count, so get_func_arg_name() would return NULL for them as-is. I'm not quite sure what we should be printing for variadic args. I think your current userland code will print the name of the variadic arg, while the internal code will skip the arg name.
@nikic I've just wrote a test for variadic userland function arguments, and it really prints the name well. Unfortunately, I couldn't try it out with internal ones - as far as I saw custom ZPP checks are needed in case of a var arg. However, the main reason that there's so many |
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.
Let's land this is-as, we can clean up implementation details afterwards... Note that there is one failing test.
fc82c65
to
a33cf89
Compare
Right now it's still allowed to not have arg_info in internal functions, so the argument name isn't guaranteed. I plan to make this required soon though, and we can probably drop the checks at that point. |
a33cf89
to
3cad30b
Compare
3cad30b
to
3077e6e
Compare
This PR is the second part of #5066
Currently, type errors can be of many forms (see https://3v4l.org/IRXq6 for example code):
%s() expects parameter 1 to be int, array given
When only one parameter is given, it must be an array
Array expected as options when using translate or scale
Expects string, null, long or boolelan value for PostgreSQL '%s' (%s)
Argument 1 passed to foo() must be of the type string, array given
I think it would make sense to settle on a single format - in the worst case, on a minimum number of similar formats. In the sense of this, my patch changes the error message structure of internal functions with "custom" ZPP to the one used by user-land functions, but I am open to any discussion about what kind of format to use.
However, I think we could (and should) go further, in which case these questions arise: