-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[ConstraintSystem] Overhaul ambiguity diagnostics #31713
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
[ConstraintSystem] Overhaul ambiguity diagnostics #31713
Conversation
/cc @LucianoPAlmeida |
This is still a WIP because we need to implement |
auto aggregate = fixes->second; | ||
diagnosed |= ::diagnoseAmbiguity(*this, ambiguity, aggregate, solutions); | ||
|
||
consideredFixes.insert(aggregate.begin(), aggregate.end()); |
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 wonder if In the cases where diagnoseAmbiguity
returns false(if there's any) ... since we are adding them independently it maybe is a problem since they would be dropped from fixes
undiagnosed? If there are such cases, maybe we should let them to attempt diagnose by kind?
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 reason why I did that is related to the fact that it could be a bunch of different fixes all related to the same callee e.g. 1 + ""
would produce one fix for first argument and one for second. Even if we didn't produce ambiguity related to overload in such case keeping them around wouldn't help to diagnose anything later because there is going to be no intersection so it's better to produce "I don't know" diagnostic and figure out case by case what went wrong...
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.
Ah makes sense, I think I actually have seen situations like that too in SR-12689. I was just worried that it may end up discarding useful fixes in some way... but now I see the point :)
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 new approach looks great!
…r fix diagnostics have failed If there are multiple solutions with fixes, let's not try to rank them based on overload choices because doing so would filter out viable candidates.
Refactor `diagnoseAmbiguityWithFixes` as follows: - Aggregate all of the available fixes based on callee locator; - For each ambiguous overload match aggregated fixes and diagnose; - Discard all of the fixes which have been already considered as part of overload diagnostics; - Diagnose remaining (uniqued based on kind + locator) fixes iff they appear in all of the solutions.
…eAmbiguityWithFixes`
…irements If there is a conditional requirement failure associated with member/function reference used in a call let's increase a score of a fix for such failure because it renders member/function unreachable in current context or with a given set of arguments.
…ssion pattern use
…nose ambiguity with fixes
…t specially If aggregate fix (based on callee locator) differs only in picked overload choices, let's diagnose that via `diagnoseForAmbiguity` associated with a particular fix kind all solutions share, that would produce a tailored diagnostic instead of the most general one.
…pe before diagnosing ambiguity Instead of requiring sub-classes of `ContextualMismatch` to implement `diagnoseForAmbiguity` let's implement it directly on `ContextualMismatch` itself and check whether all of the aggregated fixes have same types on both sides and if so, diagnose as-if it was a single fix.
…Ambiguity` For cases like this: ```swift struct X {} struct Y {} func overloaded<T>(_ value: T) -> T { value } func overloaded<T>(_ value: T) -> Int { 0 } func test(x: inout X, y: Y) { x = overloaded(y) } ``` Solver would record a `IgnoreAssignmentDestinationType` fix per overload, `diagnoseForAmbiguity` could be used to properly diagnose ambiguity cases like that.
…with a known foundation type Just like we already do for stdlib types, extend impact of missing conformances on _known_ foundation types because it's unlikely to be a valid suggestion to extend a foundation type with a new conformance.
a01984e
to
82fcee7
Compare
…alid loc) or AST node
…ment positions If parameter has a function type and no argument overload choices match let's diagnose that specifically. Resolves: [SR-12689](https://bugs.swift.org/browse/SR-12689) Resolves: rdar://problem/62481592
This PR is finally ready for review. @LucianoPAlmeida this PR incorporates a fix for SR-12689 which means that it supersedes #31359 |
Awesome @xedin \o/ |
@LucianoPAlmeida I've seen it, thanks! I think it's a different problem those, we'd need to split |
Ahh I see, but that's fine ... thanks for verifying :)) |
@@ -323,12 +323,12 @@ class TestOverloadSets { | |||
self.init(5, 5) // expected-error{{extra argument in call}} | |||
} | |||
|
|||
convenience init(a : Z0) { // expected-note{{candidate has partially matching parameter list (a: Z0)}} | |||
convenience init(a : Z0) { // expected-note{{candidate expects value of type 'Z0' for parameter #1}} |
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.
From what I remember from the other PR, the calls that trigger those have also a relabel fix alongside the argument mismatch. I think this is fine, but do you think to mention that in some way could be valid in those situations?
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 really know, this is something I was thinking about as well. I don't really like partially matching parameter list
note because it's as un-actionable as it gets but I don't know how to also mention a label here. It would be very unfortunate to produce two diagnostics/notes - one for labeling and one for type because that would be confusing...
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.
Yeah, I agree that show two notes wouldn't be ideal. But in the other PR I also thought that partially matching parameter list
was not ideal, but I did choose to show the relabel diagnostic, but to be honest there was no particular reason other than is better than partially matching parameter list
. But in fact neither correct the type or relabel the call would fix the problem by itself because both type and label are wrong in this situation.
I've been thinking about it and also not sure how to mention the label and also don't know how much we are loosing not showing one of them ... probably not much since as you mention both are actionable
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 we could re-visit this once it's possible to produce a fix per label mismatch, that way we could probably coalesce type and label mismatch for each argument and produce a much better note...
…is pattern match
@swift-ci please smoke test |
@swift-ci please smoke test Linux platform |
as part of overload diagnostics;
iff they appear in all of the solutions.
Resolves: SR-12689
Resolves: rdar://problem/62481592