-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[GSB] Eliminate concrete potential archetypes by early substitution #14965
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
/cc @DougGregor could you please take a look? Spent some time working on this over the weekend to remove the hack for It seems like it can detect more situations where protocol P {
typealias A = Int
}
func foo<T: P, U>(_ a: T, _ b: U) where T.A == U {} is going to produce func foo<U>(_ a: U) where U == Int {} |
bfa046a
to
a1fb120
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.
This is looking really promising! I'd like us to think about that loop over the "other" declarations found with the same name (in maybeResolvedEquivalenceClass
), and will comment on the new error separately.
lib/AST/GenericSignatureBuilder.cpp
Outdated
if (!concreteDecl->hasInterfaceType()) | ||
builder.getLazyResolver()->resolveDeclSignature(concreteDecl); | ||
|
||
if (concreteDecl->hasInterfaceType()) { |
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.
Nit: I suggest doing an early return if !concreteDecl->hasInterfaceType()
to de-nest the main code path.
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.
Sure! I confess that I have a habit of moving the code around without really refactoring it all the way...
lib/AST/GenericSignatureBuilder.cpp
Outdated
static Type substituteConcreteType(GenericSignatureBuilder &builder, | ||
PotentialArchetype *basePA, | ||
TypeDecl *concreteDecl) { | ||
if (!concreteDecl) |
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.
Will we ever call it with a null concreteDecl
? It seems like this should be an assert.
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, makes sense!
// introduce various same-type constraints. | ||
for (auto concreteDecl : concreteDecls) { | ||
(void)basePA->updateNestedTypeForConformance(*this, concreteDecl, | ||
resolutionKind); |
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.
Huh. I'm surprised we can get rid of this. It's supposed to establish equivalences between same-named nested types.
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.
To be honest I'm just not sure what it's going to do now because we substitute early which means that we'd end up with new potential archetype that has associated type so we don't really need to add new same-type requirement like before where we had potential archetype with concrete decl and substituted typealias type. But I might be totally missing something here, could you please provide an example?
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.
Huh. I had convinced myself that this mattered due to #14974, but my change there didn't fix the problem at all. Maybe this is indeed dead code!
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 the deletion of this loop is the cause of the regression in ./validation-test/compiler_crashers_2_fixed/0075-rdar30248571.swift
.
lib/AST/GenericSignatureBuilder.cpp
Outdated
target->getParent() && | ||
sourceDepMemTy->getAssocType() && | ||
sourceDepMemTy->getAssocType() == target->getResolvedAssociatedType()){ | ||
target->getParent() && sourceDepMemTy->getAssocType() && |
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.
Oh, I don't think you need to check for a null sourceDepMemTy->getAssocType()
, because the "subject" of any constraint should (now) always be a well-formed type. I bet there are other places where we have such null checks that could go away with your PR!
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.
Right, good catch! Thanks!
That |
Here's an assertion I have lying around that I think we can introduce into your PR, which would ensure that unresolved dependent types never slip into a generic function type. It's worth a shot!
|
a1fb120
to
2be67ef
Compare
@DougGregor You've already added |
2be67ef
to
d0c533f
Compare
@swift-ci please smoke test |
@DougGregor Could you please take a look at the failures - especially new error message in |
@DougGregor Thanks! I'll take a look, maybe I should get it back and substitute all of them the same way as typealiases, will try that later today. |
@swift-ci please smoke test macOS platform |
@DougGregor looks like your changes for nested typealiases have fixed validation test, I am going to fix up code completion one and run source compatibility suite. |
d0c533f
to
76fc9f7
Compare
To make generic signature builder more robust it's imperative to eliminate possibility of out-of-order typealias substitution. These changes try to make it so potential archetypes could only be constructed with associated types by doing early concrete type (typealias) subsitution while trying to resolve equivalence class.
76fc9f7
to
4b05449
Compare
@swift-ci please smoke test |
@swift-ci please test source compatibility |
@swift-ci please test |
@DougGregor Looks like everything is green, going to merge in the morning. |
Fantastic! |
|
||
// Make sure that there are no unresolved | ||
// dependent types in the generic signature. | ||
assert(func->getInterfaceType()->hasError() || |
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.
Very excited that this assertion is here now!
To make generic signature builder more robust it's imperative to
eliminate possibility of out-of-order typealias substitution.
These changes try to make it so potential archetypes could only be
constructed with associated types by doing early concrete type (typealias)
subsitution while trying to resolve equivalence class.