-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[SR-12689] Diagnose arg mismatch with exact same fixes across multiple solutions #31359
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
[SR-12689] Diagnose arg mismatch with exact same fixes across multiple solutions #31359
Conversation
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 great, thank you!
@LucianoPAlmeida Why special case this instead of letting it be diagnosed as |
bfed10e
to
f0a7adf
Compare
humm, in this case, there is no ambiguous overload, there is only one overload on the solutionDiff that had the exact same fixes recorded for all the solutions. |
@LucianoPAlmeida |
I think the problem here is that we are ranking overloads although in presence of fixes we shouldn't be doing that because it's not apples to apples comparison. I want to adjust that and only rank on score instead. |
Humm, so the strategy would be not ranking if any overload solution has at least one fix? |
Not ranking based on declarations yes, let it be ambiguous different overloads have the same "fix" weight. |
f0a7adf
to
33d07bd
Compare
Right, func foo(_ u: Int) -> String { "" }
func foo(_ u: String) -> String { "" }
func bar(_ u: Int) {}
bar(foo(1 as Double)) These situations produce exactly the same situation where for each solution the solver will produce two sets of fixes where each solution has two fixes (one argument mismatches for So my question is if the better approach would be to:
Also this also happens with other mismatches e.g. coercion, I didn't investigate yet but probably a similar situation... foo(1 as Double) as Int // type of expression is ambiguous without more context So let me know what you think @xedin @hborla :) Edit: Actually the first option is not viable because in cases where the return types are different the argument mismatches wouldn't be the same... func foo(_ u: Int) -> String { "" }
func foo(_ u: String) -> Double { 0 }
func bar(_ u: Int) {}
bar(foo(1 as Double)) |
dcd4fa9
to
f658324
Compare
Just changed to WIP because although this fixes the problem, there are still 2 diagnostic regressions I still don't know how to solve them :( |
27afb42
to
4d2c82c
Compare
d3cc464
to
e1fc42d
Compare
@LucianoPAlmeida It seems like #2 is what we should be working towards with a tweak that it should diagnose all of the fixes in common and not just one so in that example it should diagnose ambiguity + result mismatch with what is expected by |
Hey @xedin :) func foo(_ u: Int) -> String { "" }
func foo(_ u: String) -> Double { 0 }
func bar(_ u: Int) {}
bar(foo(1 as Double)) There is 2 solutions each with 2 fixes. So for the set of aggregated fixes in |
That's exactly what I'm currently pondering on. I think in this case we should just diagnose two invalid conversions... Current plan is to (once again) change the way we do stuff in It seems to me (and @hborla agrees) that this whole problem boils down to us needing to find an intersection of solutions based on fixes and their locations. For each distinct fix/location pair we need to figure out whether it's included in all solutions, if all of the solutions match exactly on this criteria I think it's reasonable to diagnose as if there was just one solution because this means that the problems are universal e.g. contextual type mismatch + r-value type on left-hand side of I think this covers case you mentioned without requiring any special handling because all of the fixes are going to be shared across solutions. |
Hm, it actually might be kind of weird to diagnose conversions here, I think we should add a criteria that checks whether each distinct fix is related directly to multiple distinct overload choices and diagnose that appropriately... |
Thank you @xedin I'll work on that :) One question ...
The actual aggregate fix logic takes into account the fix kind, this should be the case here too? |
I think so, that's what I mean why |
e1fc42d
to
4b158f8
Compare
…on fixes in all solutions first and try diagnose if not fall back to common anchor diagnostic
4b158f8
to
2b861fc
Compare
2b861fc
to
38306a9
Compare
@LucianoPAlmeida overall this is exactly what I imagined this supposed to work, thank you! I just wanted to check why stop after after diagnosing non-overload related ambiguities here - https://github.com/apple/swift/pull/31359/files#diff-27038c7aac8e7016c5ab7bceb4a03651R3015 why not diagnose everything? |
On the side note I think we can simplify |
Hey @xedin :) |
Are there any other examples of that? What I'm worried about is that we are not going to show all the relevant errors and developers would end up fixing one error just to get to the other similar to climbing a ladder where in contrast if they have seen all of the errors it might be more obvious what to do... |
No, I think there were only two "regressions" initially this and another one that I think was related to other changes I made halfway progress Edit: The other case is in fact related We endup producing an extra But these are the only cases I've seen :) |
I'll address this, just finishing to adjust to diagnose another case that I found that is not handled ... :( |
@xedin One thing is that if I understand it correctly this will make us iterate over all the fixes and solutions for each (fix + location) entry? Also, I think that diagnose single aggregate will require some extra logic for cases where for |
Yes, that's right. First build a set of all unique kind/location parts, then use each to find whether its include into all of the solutions. My intuition is that fixes which are local to some solutions are most likely a result of ambiguities that manifest differently based on overload choice. |
I'm currently working on moving |
No problem! Let me know when you have your changes set :) |
Ahh also, @xedin when possible can you take a look at ff121353c19b3d751e8ea23cf0c690d0fa9939a6? that's another case and this was the best I could come up with and I think is fine ... but maybe you have some other option suggestion :) |
It seems like we should differentiate when reference is applied and when it's not because |
Yeah, you right that makes total sense :) |
…nd overloaded ref expression argument
ff12135
to
bcde8b5
Compare
@xedin, I just adjust this last case |
Thank you! |
I was looking through some JIRA SRs and found this SR-12705 which I think is going to benefit from the improvements being done on func bindToInt(
_ base: UnsafeMutableRawPointer,
at offset: Int
) -> UnsafeMutablePointer<Int> {
let result = (base + offset).bindMemory(to: Int.self, count: 1) // cannot convert value of type 'UnsafeMutableRawPointer' to expected argument type 'Int'
// value of type 'Int' has no member 'bindMemory'
return result
} |
Superseded by #31713 |
In this case, there are multiple solutions that record the same exact argument mismatch fix.
So this makes sure if all the fixes are the exact same arg and param types across solutions, we just diagnose.
cc @xedin @hborla :)
Resolves SR-12689.