Skip to content

Commit bffce66

Browse files
committed
SourceKit: Don't call subst() with generic parameters that don't exist in the SubstitutionMap
Hack around this instead by using the two-function form of subst(), and checking if the generic parameter is valid in the signature. This comes up because we're using the generic signature of the nominal type to get a SubstitutionMap, and then applying this map to the types in the generic requirements of a member. If the member introduces its own generic parameters, some of those requirements might not be valid types in the outer generic signature. This can probably use SubstitutionMap::combineSubstitutionMaps() instead, but it would require more refactoring than I'm willing to undertake for now.
1 parent 07f889f commit bffce66

File tree

2 files changed

+40
-8
lines changed

2 files changed

+40
-8
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,17 +1588,34 @@ void PrintAST::printSingleDepthOfGenericSignature(
15881588
bool swapSelfAndDependentMemberType =
15891589
(flags & SwapSelfAndDependentMemberType);
15901590

1591+
unsigned typeContextDepth = 0;
15911592
SubstitutionMap subMap;
1593+
ModuleDecl *M = nullptr;
15921594
if (CurrentType && Current) {
15931595
if (!CurrentType->isExistentialType()) {
15941596
auto *DC = Current->getInnermostDeclContext()->getInnermostTypeContext();
1595-
auto *M = DC->getParentModule();
1597+
M = DC->getParentModule();
15961598
subMap = CurrentType->getContextSubstitutionMap(M, DC);
1599+
if (!subMap.empty()) {
1600+
typeContextDepth = subMap.getGenericSignature()
1601+
.getGenericParams().back()->getDepth() + 1;
1602+
}
15971603
}
15981604
}
15991605

16001606
auto substParam = [&](Type param) -> Type {
1601-
return param.subst(subMap);
1607+
if (subMap.empty())
1608+
return param;
1609+
1610+
return param.subst(
1611+
[&](SubstitutableType *type) -> Type {
1612+
if (cast<GenericTypeParamType>(type)->getDepth() < typeContextDepth)
1613+
return Type(type).subst(subMap);
1614+
return type;
1615+
},
1616+
[&](CanType depType, Type substType, ProtocolDecl *proto) {
1617+
return M->lookupConformance(substType, proto);
1618+
});
16021619
};
16031620

16041621
if (printParams) {
@@ -1608,10 +1625,7 @@ void PrintAST::printSingleDepthOfGenericSignature(
16081625
genericParams,
16091626
[&](GenericTypeParamType *param) {
16101627
if (!subMap.empty()) {
1611-
if (auto argTy = substParam(param))
1612-
printType(argTy);
1613-
else
1614-
printType(param);
1628+
printType(substParam(param));
16151629
} else if (auto *GP = param->getDecl()) {
16161630
Printer.callPrintStructurePre(PrintStructureKind::GenericParameter,
16171631
GP);

tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,9 @@ static void initDocGenericParams(const Decl *D, DocEntityInfo &Info,
269269
// synthesized extention itself rather than a member, into its extended
270270
// nominal (the extension's own requirements shouldn't be considered in the
271271
// substitution).
272+
unsigned TypeContextDepth = 0;
272273
SubstitutionMap SubMap;
274+
ModuleDecl *M = nullptr;
273275
Type BaseType;
274276
if (SynthesizedTarget) {
275277
BaseType = SynthesizedTarget.getBaseNominal()->getDeclaredInterfaceType();
@@ -279,13 +281,29 @@ static void initDocGenericParams(const Decl *D, DocEntityInfo &Info,
279281
DC = cast<ExtensionDecl>(D)->getExtendedNominal();
280282
else
281283
DC = D->getInnermostDeclContext()->getInnermostTypeContext();
282-
auto *M = DC->getParentModule();
284+
M = DC->getParentModule();
283285
SubMap = BaseType->getContextSubstitutionMap(M, DC);
286+
if (!SubMap.empty()) {
287+
TypeContextDepth = SubMap.getGenericSignature()
288+
.getGenericParams().back()->getDepth() + 1;
289+
}
284290
}
285291
}
286292

287293
auto SubstTypes = [&](Type Ty) {
288-
return Ty.subst(SubMap, SubstFlags::DesugarMemberTypes);
294+
if (SubMap.empty())
295+
return Ty;
296+
297+
return Ty.subst(
298+
[&](SubstitutableType *type) -> Type {
299+
if (cast<GenericTypeParamType>(type)->getDepth() < TypeContextDepth)
300+
return Type(type).subst(SubMap);
301+
return type;
302+
},
303+
[&](CanType depType, Type substType, ProtocolDecl *proto) {
304+
return M->lookupConformance(substType, proto);
305+
},
306+
SubstFlags::DesugarMemberTypes);
289307
};
290308

291309
// FIXME: Not right for extensions of nested generic types

0 commit comments

Comments
 (0)