Skip to content

Commit 4cadee4

Browse files
committed
Handle nested generic extensions in TypeBase::gatherAllSubstitutions().
The code in TypeBase::gatherAllSubstitutions() walks a declaration context and type to form a complete set of substitutions for a (nested) type. When provided with a context for a nested extension---e.g., "extension OuterGeneric.InnerGeneric", it would skip over OuterGeneric due to the lexical nesting of DeclContexts not matching the semantic nesting. Teach this function to determine the type parameters without walking DeclContexts.
1 parent ba06709 commit 4cadee4

File tree

1 file changed

+9
-10
lines changed

1 file changed

+9
-10
lines changed

lib/AST/Module.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -586,28 +586,24 @@ TypeBase::gatherAllSubstitutions(Module *module,
586586
// The type itself contains substitutions up to the innermost
587587
// non-type context.
588588
CanType parent(canon);
589-
auto *parentDC = gpContext;
589+
ArrayRef<GenericTypeParamType *> genericParams =
590+
genericSig->getGenericParams();
591+
unsigned lastGenericIndex = genericParams.size();
590592
while (parent) {
591593
if (auto boundGeneric = dyn_cast<BoundGenericType>(parent)) {
592-
auto genericSig = parentDC->getGenericSignatureOfContext();
593-
unsigned index = 0;
594-
595-
assert(boundGeneric->getGenericArgs().size() ==
596-
genericSig->getInnermostGenericParams().size());
597-
594+
unsigned index = lastGenericIndex - boundGeneric->getGenericArgs().size();
598595
for (Type arg : boundGeneric->getGenericArgs()) {
599-
auto paramTy = genericSig->getInnermostGenericParams()[index++];
596+
auto paramTy = genericParams[index++];
600597
substitutions[paramTy->getCanonicalType().getPointer()] = arg;
601598
}
599+
lastGenericIndex -= boundGeneric->getGenericArgs().size();
602600

603601
parent = CanType(boundGeneric->getParent());
604-
parentDC = parentDC->getParent();
605602
continue;
606603
}
607604

608605
if (auto nominal = dyn_cast<NominalType>(parent)) {
609606
parent = CanType(nominal->getParent());
610-
parentDC = parentDC->getParent();
611607
continue;
612608
}
613609

@@ -616,6 +612,9 @@ TypeBase::gatherAllSubstitutions(Module *module,
616612

617613
// Add forwarding substitutions from the outer context if we have
618614
// a type nested inside a generic function.
615+
auto *parentDC = gpContext;
616+
while (parentDC->isTypeContext())
617+
parentDC = parentDC->getParent();
619618
if (auto *outerEnv = parentDC->getGenericEnvironmentOfContext())
620619
for (auto pair : outerEnv->getInterfaceToArchetypeMap()) {
621620
auto result = substitutions.insert(pair);

0 commit comments

Comments
 (0)