-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
[red-knot] fix non-callable reporting for unions #16387
Merged
Merged
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back 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.
I think this is now wrong but in different ways then before?
If I understand this correctly, it will now return
not_callable
if one variant is not callable and the other has binding errors. What I think we want is to only returnnot_callable
if all errors are not_callable.So the fix might be to keep initializing the variable to
true
but change the error case tonot_callable &= error.is_not_callable()
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 don't think that behavior would be correct. A union with at least one not-callable element is not callable.
In general for any type it is always true that some inhabitants of the type may permit some behavior that the overall type does not permit. The definition of a type supporting an operation is that all inhabitants support it.
I would like us to offer more detailed diagnostics for not-callable unions, where we would clarify which member(s) are not callable. In that world, I do think we might want to return
CallError::Union
in more cases. But with the behavior today, whereCallError::Union
only reports one of its errors, I think it would be wrong if we ignored a not-callable error from one element and just reported a binding error from some other type in the union. So I think we need to return NotCallable if any element is not callable.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 suspect that this will lead to worse diagnostics overall because we then end up saying that the type isn't callable instead of saying which variant isn't callable.
I can't argue on what this means on the type inference level but your original implementation only returned
NotCallable
if all variants weren't callable, unless I'm misreading the implementation:ruff/crates/red_knot_python_semantic/src/types/call.rs
Lines 240 to 282 in 792f9e3
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.
Both branches in the linked original implementation return
NotCallableError
, whether some or all elements are not callable. The only difference is whether we return a "simple"NotCallableError
(because if all elements are not callable, we don't really need to give more details) or a "union"NotCallableError
(because we want to clarify which elements are not callable.)I agree. The core problem here is the current handling of
CallError::Union
only reporting one of its errors. This means that in a case where we have one binding error and one not-callable in a union, might decide to just report the binding error and ignore the not-callable error. That's the wrong result I aimed to avoid with this change. In that case I would much rather see a not-callable error on the entire union, than a wrong-arguments error for the one callable element.We can go ahead and return
CallError::Union
for that case. It will just increase the priority of better diagnostics forCallError::Union
.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'd prefer keeping returning
Union
because it already forces the right handling in all upstream code.Fixing the diagnostic is an issue on its own where we may want to be more clever about how we handle different errors (I don't think rendering all errors is a good idea but we could sort the errors and e.g. report not callable first)