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.
This commit is contained in:
Slava Pestov
2021-08-24 16:22:09 -04:00
parent 07f889f8de
commit bffce661c8
2 changed files with 40 additions and 8 deletions

View File

@@ -269,7 +269,9 @@ static void initDocGenericParams(const Decl *D, DocEntityInfo &Info,
// synthesized extention itself rather than a member, into its extended
// nominal (the extension's own requirements shouldn't be considered in the
// substitution).
unsigned TypeContextDepth = 0;
SubstitutionMap SubMap;
ModuleDecl *M = nullptr;
Type BaseType;
if (SynthesizedTarget) {
BaseType = SynthesizedTarget.getBaseNominal()->getDeclaredInterfaceType();
@@ -279,13 +281,29 @@ static void initDocGenericParams(const Decl *D, DocEntityInfo &Info,
DC = cast<ExtensionDecl>(D)->getExtendedNominal();
else
DC = D->getInnermostDeclContext()->getInnermostTypeContext();
auto *M = DC->getParentModule();
M = DC->getParentModule();
SubMap = BaseType->getContextSubstitutionMap(M, DC);
if (!SubMap.empty()) {
TypeContextDepth = SubMap.getGenericSignature()
.getGenericParams().back()->getDepth() + 1;
}
}
}
auto SubstTypes = [&](Type Ty) {
return Ty.subst(SubMap, SubstFlags::DesugarMemberTypes);
if (SubMap.empty())
return Ty;
return Ty.subst(
[&](SubstitutableType *type) -> Type {
if (cast<GenericTypeParamType>(type)->getDepth() < TypeContextDepth)
return Type(type).subst(SubMap);
return type;
},
[&](CanType depType, Type substType, ProtocolDecl *proto) {
return M->lookupConformance(substType, proto);
},
SubstFlags::DesugarMemberTypes);
};
// FIXME: Not right for extensions of nested generic types