Skip to content

Commit 473faf1

Browse files
committed
AST: Update TypeBase::getSuperclassForDecl() for subclass existentials
This function takes a member of a class and a base type, and returns the correct 'self' type to substitute into the member's type. When accessing a member of a subclass existential, if the member was found via the superclass constraint, we have to erase the existential down to the class type to calculate the member's substituted type. We already had special logic to handle class-constrained archetypes in the callers of getSuperclassForDecl(); move this check into the method, and add a similar check for subclass existentials, which now support the getSuperclass() method.
1 parent 30cd0a9 commit 473faf1

File tree

2 files changed

+12
-14
lines changed

2 files changed

+12
-14
lines changed

lib/AST/Type.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3105,10 +3105,19 @@ Type TypeBase::getSuperclassForDecl(const ClassDecl *baseClass,
31053105
LazyResolver *resolver) {
31063106
Type t(this);
31073107
while (t) {
3108-
auto *derivedClass = dyn_cast_or_null<ClassDecl>(t->getAnyNominal());
3109-
assert(derivedClass && "expected a class here");
3108+
// If we have a class-constrained archetype or class-constrained
3109+
// existential, get the underlying superclass constraint.
3110+
auto *nominalDecl = t->getAnyNominal();
3111+
if (!nominalDecl) {
3112+
assert(t->is<ArchetypeType>() || t->isExistentialType() &&
3113+
"expected a class, archetype or existentiall");
3114+
t = t->getSuperclass(resolver);
3115+
assert(t && "archetype or existential is not class constrained");
3116+
continue;
3117+
}
3118+
assert(isa<ClassDecl>(nominalDecl) && "expected a class here");
31103119

3111-
if (derivedClass == baseClass)
3120+
if (nominalDecl == baseClass)
31123121
return t;
31133122

31143123
t = t->getSuperclass(resolver);
@@ -3139,19 +3148,10 @@ TypeBase::getContextSubstitutions(const DeclContext *dc,
31393148
return substitutions;
31403149
}
31413150

3142-
// If we found a member of a concrete type from a protocol extension,
3143-
// get the superclass out of the archetype.
3144-
if (auto *archetypeTy = baseTy->getAs<ArchetypeType>())
3145-
baseTy = archetypeTy->getSuperclass();
3146-
31473151
// Extract the lazy resolver.
31483152
LazyResolver *resolver = dc->getASTContext().getLazyResolver();
31493153

31503154
// Find the superclass type with the context matching that of the member.
3151-
//
3152-
// FIXME: Do this in the caller?
3153-
assert(baseTy->getAnyNominal());
3154-
31553155
auto *ownerNominal = dc->getAsNominalTypeOrNominalTypeExtensionContext();
31563156
if (auto *ownerClass = dyn_cast<ClassDecl>(ownerNominal))
31573157
baseTy = baseTy->getSuperclassForDecl(ownerClass, resolver);

lib/Sema/TypeCheckType.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3030,8 +3030,6 @@ Type TypeChecker::substMemberTypeWithBase(ModuleDecl *module,
30303030
// derived class as the parent type.
30313031
if (auto *ownerClass = member->getDeclContext()
30323032
->getAsClassOrClassExtensionContext()) {
3033-
if (auto *archetypeTy = baseTy->getAs<ArchetypeType>())
3034-
baseTy = archetypeTy->getSuperclass();
30353033
baseTy = baseTy->getSuperclassForDecl(ownerClass, this);
30363034
}
30373035

0 commit comments

Comments
 (0)