-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Sema] Extend callee diagnosis to complex args including generics, e.g. (Void) -> T #1160
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
if (paramType->getKind() != actualArgType->getKind()) | ||
return false; | ||
|
||
// A little walker that just collects direct child types. Can't easily have a |
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.
Take a look at include/swift/AST/TypeMatcher.h, it might be what you need here
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.
Aha! Thank you, that's exactly what I needed. It seemed like something like that must exist, but somehow I missed finding it.
I'm not very familiar with the diagnostics code so I'm still learning too. I noticed a few potential improvements. I won't insist you address all of them in this patch, but take a look and see if any look like low-hanging fruit. The code can always be improved later too. |
I'd like to try the TypeMatcher path and also fix the differing bound generic structs case, and then leave matching with type aliases and other sugared forms for the (hopefully near) future. |
4db95dd
to
7cac541
Compare
Ok! Rewrote this patch to use TypeMatcher, which is a much cleaner way to do it.
The correct solution to do this in general and not by accident is to pre-populate the substitution vectors with any substitutions that have already been made, so this code also does that in findGenericSubstitutions() now, which leads to a few more corrected diagnoses (such as in Generics/function_defs.swift).
All tests pass, new test added, changes to diagnoses for existing tests also cover the new features here. Went ahead and squashed right away because the original commit got entirely changed anyway, so there wasn't anything readable about the diff between the two commits. |
This looks good! I'll merge it once it goes through CI. |
@swift-ci Please test |
Oops. I see I was running just -t instead of -T and a couple of the validation tests failed. Will go back and look at those. |
@swift-ci Please test |
@slavapestov Looks like only people with commit access can request testing. Made a second commit to check for UnresolvedType in the paramType and changed to a better diagnosis in one of the validation tests, and everything now passes for me locally. |
@swift-ci Please test |
@gregomni Requesting tests doesn't always work for me either -- I think it might just be flaky. I'll follow up internally |
@slavapestov I went and found the announcement and it does explicitly say that only committers can kick it off: https://swift.org/blog/swift-ci/. I can understand that, since it's a fairly long-lived process you don't want random people kicking off zillions of tests. |
Huh. There is one failure in a test in IRGen, which I don't see how it could be related to these changes. |
For what it's worth, the next build on that jenkins instance https://ci.swift.org/job/swift-PR-osx/18/, failed with the exact same IRGen error, and it was just doing a build for stdlib changes. So I think that test must be broken by some previous pull. |
I belive the broken test was a commit by @DougGregor that he has since fixed. |
@swift-ci Please test |
@@ -1325,7 +1397,8 @@ void CalleeCandidateInfo::filterList(ArrayRef<CallArgParam> actualArgs) { | |||
// If this isn't a function or isn't valid at this uncurry level, treat it | |||
// as a general mismatch. | |||
if (!inputType) return { CC_GeneralMismatch, {}}; | |||
return evaluateCloseness(inputType, actualArgs); | |||
Decl *decl = candidate.getDecl(); | |||
return evaluateCloseness(decl ? decl->getInnermostDeclContext() : nullptr, inputType, actualArgs); |
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.
Last nitpick before I merge this -- this line is too long, wrap it after the nullptr
…d) -> T Correctly determine callee closeness for func/ops that include generics as part of more complicated parameters, i.e. tuple or closure args containing generics as elements or args/results. Still only handling single archetypes. Also added code to check generic substitutions already made in the callee parameters, which further helps diagnosis.
8407b05
to
6b30695
Compare
Sure thing. Wrapped that line, and squashed. |
[Sema] Extend callee diagnosis to complex args including generics, e.g. (Void) -> T
Cool! |
This is a quick follow-up to <swiftlang#1160>, to replace the becoming deprecated getArchetype() with doing the same thing via calling through to ArchetypeBuilder with a declContext. Uses findGenericSubstitutions() to do so. So this site could take advantage of destructuring of more complex params containing generics. Right now, though, that never happens. For complex params the (unfortunately, worse) diagnosis happens in diagnoseFailureForExpr() on the argument expression before reaching here. I’d like to improve that in future work.
Correctly determine callee closeness for func/ops that include generics as part of more complicated parameters, i.e. tuple or closure args containing generics as elements or args/results. Still only handling single archetypes.
Tests added, all tests pass. The one changed diagnostic in misc_diagnostics is sort of a regression, although both messages are of about equal quality, I think. This commit lets evaluateCloseness find a second partial match for ~= there, but the two partial matches involve different parameter archetypes, so filtering makes the callee argument failure info invalid as a result, thus going back to the generic message as opposed to a specific argument failure message. (In short, the older specific error was actually incorrectly over-specific.)