-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Type checker] Reduce/isolate reuse of parent generic environments #6086
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
[Type checker] Reduce/isolate reuse of parent generic environments #6086
Conversation
@swift-ci please smoke test and merge |
@@ -6820,6 +6833,25 @@ void TypeChecker::checkDeclCircularity(NominalTypeDecl *decl) { | |||
} | |||
} | |||
|
|||
/// Determine whether the given variable is the implicit 'self' parameter for | |||
/// a function, and return that function if so. | |||
static AbstractFunctionDecl *isImplicitSelfParam(VarDecl *var){ |
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.
We already have VarDecl::isSelfParameter()...
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.
Ugh! I was looking for that on ParamDecl
. Thank you
@@ -357,6 +357,12 @@ AbstractFunctionDecl *DeclContext::getInnermostMethodContext() { | |||
} | |||
} | |||
|
|||
bool DeclContext::isTypeContext() const { | |||
return (getContextKind() == DeclContextKind::GenericTypeDecl && |
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.
maybe just isa<NominalTypeDecl>(this)
then...
@@ -103,7 +103,7 @@ void IterativeTypeChecker::processResolveInheritedClauseEntry( | |||
|
|||
// Validate the type of this inherited clause entry. | |||
// FIXME: Recursion into existing type checker. | |||
PartialGenericTypeToArchetypeResolver resolver; | |||
GenericTypeToArchetypeResolver resolver(dc->getGenericEnvironmentOfContext()); |
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.
There's a constructor that takes a dc too, it's nicer
if (TC.validateType(typeAliasDecl->getUnderlyingTypeLoc(), | ||
typeAliasDecl->getDeclContext(), | ||
options, nullptr, &unsatisfiedDependency)) { | ||
options, &resolver, &unsatisfiedDependency)) { |
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.
If the parameter is always non-null, it could be a reference
@@ -151,4 +151,4 @@ struct S4<Q>: P4 { | |||
init(_: Q) { } | |||
} | |||
|
|||
extension S4 where T : P5 {} // expected-error{{type 'T' in conformance requirement does not refer to a generic parameter or associated type}} | |||
extension S4 where T : P5 {} |
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.
Heh
checkGenericParamList(&builder, genericParams, parentSig, parentEnv, | ||
nullptr); |
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.
reference instead of pointer maybe?
We cannot properly determine the context type of any parameter (including 'self') until after we have determined the generic environment for the enclosing function.
DeclContext's nomenclature around "type contexts" is confusing, because it essentially means "nominal type contexts", e.g., struct/class/enum/protocol and extensions thereof. This implies the presence of a 'Self' type, the ability to have members, etc. However, typealiases are also currently classified as "type contexts", despite not having a reasonable 'Self' type, which breaks in various places. Stop classifying typealiases as "type contexts".
Typealiases were getting type-checked in their parent's context, not their own context. For non-generic typealiases this is fine, because the generic environment is inherited. Generic typealiases, on the other hand, have their own generic environment that should be used. Do so.
This method gets the GenericTypeDecl for a typealias, nominal type, or extension thereof. While the result is typed as GenericTypeDecl, it's not always generic, so rename it accordingly. An audit of the callers illustrated that they should be using different entrypoints anyway, so fix all of the callers and make this function private.
…solver. PartialGenericTypeToArchetypeResolver is (eventually) going away. Isolate it's use to those places where we still rely on its odd behavior.
Stop using PartialGenericTypeToArchetypeResolver in extensions. It means Yet Another ArchetypeBuilder pass (for now).
The GenericTypeOrArchetypeResolver changes are effectively porting some existing hacks from the now-dead PartialGenericTypeOrArchetypeResolver, which dodges some regressions in the compiler-crashers suite and fixes 11 new crashers. There is undoubtedly a more principled approach to fix these problems, most of which now step from recursively looking for a generic environment that isn't there, but doing so requires improvements to our name lookup.
…vironment. This routine was passing a 'null' generic environment when it should, in fact, provide the generic environment for its context. Fixes a code-completion regression introduced by the removal of PartialGenericTypeToArchetypeResolver.
592d9a6
to
553216a
Compare
@swift-ci please smoke test |
1 similar comment
@swift-ci please smoke test |
Linux build failed with something unrelated in LLVM: buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/llvm/lib/Target/PowerPC/PPCMCInstLower.cpp:40:22: error: no member named 'Mang' in 'llvm::AsmPrinter' macOS build failed with an exception |
@swift-ci please smoke test |
@swift-ci please smoke test macOS |
@swift-ci please smoke test Linux |
The type checker is still reusing the archetypes from parent contexts in nested generic contexts, which is is both a mess (semantically) and means that we cannot add any new requirements to those archetypes, a source of numerous bugs. Take a few more concrete steps toward eliminating this reuse of parent archetypes:
self
parameter late, after we've had a change to create the generic environment for a functiontypealias
declarations with thetypealias
as the context, so we're in the right generic environment for generictypealias
declarationsPartialGenericTypeToArchetypeResolver
, which handled the weird case of pulling archetypes from an outer context rather than the current context. Instead, be explicit about the places where we reuse archetypes by explicitly telling the archetype builder to reuse the parent archetypes.