-
Notifications
You must be signed in to change notification settings - Fork 10.5k
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
TypeResolution: Abolish TypeResolutionStage::Contextual #39652
Conversation
@swift-ci please smoke test macOS |
d2c0632
to
65aeb64
Compare
@swift-ci please smoke test macOS |
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 looks pretty reasonable, just a few comments I'd like to hear your thoughts on before we merge this.
lib/Sema/TypeCheckType.h
Outdated
SourceLoc loc, | ||
ArrayRef<Type> genericArgs) const; | ||
static Type | ||
applyUnboundGenericArguments(GenericTypeDecl *decl, Type parentTy, |
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.
Would it be cleaner if it was an instance member?
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.
Perhaps. The fact that we have to consider passing function objects for opening placeholders and unbound generics just to call applyUnboundGenericArguments
, even though it never needs them, was a bit of an eyesore. On the other hand, it interacts with a lot of TypeResolution state, and it is a lot easier to manage on-demand use of the generic environment with an instance member.
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.
On second thought, I have to object here. It does appear to be visually cleaner the instance member way, but the fact that we sometimes pass a contextual parent type to applyUnboundGenericArguments
just doesn't play well together with a type resolution stage, now that it cannot be "contextual". It seems to be more about whether we want to check requirements or not, rather than which stage we're on. Looking forward to further thoughts.
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.
@slavapestov Just in case – I'm happy to set this discussion aside.
@@ -3976,9 +3976,13 @@ class ConstraintSystem { | |||
/// parent type by introducing fresh type variables for generic parameters | |||
/// and constructing a bound generic type from these type variables. | |||
/// | |||
/// \param useArchetypes When \p decl has no parent, indicates whether to use | |||
/// archetypes for generic parameters of its parent context. |
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.
Even if there is a parent type, it might be nested inside of another non-type generic context, eg
func foo<T>() {
struct Outer {
struct Inner {
typealias A = Array<T>
}
}
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.
IIRC we don't support type declarations nested inside generic (or contextually generic) functions, so it's alright for now.
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've changed the flag name to "isTypeResolution" to be more explicit.
12880d4
to
311f321
Compare
@swift-ci please smoke test macOS |
@swift-ci please test source compatibility release |
311f321
to
bde02fa
Compare
@swift-ci please smoke test macOS |
@swift-ci please test source compatibility release |
bde02fa
to
e52be42
Compare
@swift-ci please smoke test macOS |
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.
Only one remaining question.
lib/Sema/TypeChecker.h
Outdated
/// \returns \c true on success. | ||
bool checkContextualRequirements( | ||
GenericTypeDecl *decl, Type parentTy, SourceLoc loc, ModuleDecl *module, | ||
llvm::function_ref<const GenericEnvironment *()> getGenericEnvironment); |
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.
Instead, can you pass a GenericSignature and call getGenericEnvironment() on it when needed?
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, great suggestion!
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.
Passing a GenericSignature instead of a function ref results in one more duplicate circularity error in compiler_crashers_2_fixed/0161-sr6569.swift. Do you reckon that sounds fine? All this fuss around checkContextualRequirements() is really only to make sure that is works correctly with SIL code, where we explicitly pass a generic environment to type resolution, because it cannot be derived from context.
8e3d7ff
to
0593c29
Compare
@swift-ci please smoke test |
1c606e6
to
e223e52
Compare
@swift-ci please smoke test |
…ment when specified
…ad of mapping into context in place
…akes a generic environment
… in 'openUnboundGenericType'
…ning opened archetypes
e223e52
to
f0264de
Compare
@swift-ci please smoke test |
@swift-ci please test source compatibility |
@swift-ci please smoke test macOS |
@swift-ci please smoke test |
The correctness issue that lead to this refactoring is an inconsistency in how generic metatypes are resolved in properties that are referenced and declared under a certain kind of same-type constraint:
This is a source-breaking change, since these generic metatypes would no longer resolve to existential metatypes when a same-type constraint binds the 'instance type' type parameter to an existential type, be it a protocol requirement or other member.
Extracted from #39492