Serialization: Fix latent bug with extensions of nested generic types

ExtensionDecls for nested generic types have multiple generic parameter
lists, one for each level of nested generic context.

We only serialized the outermost list, though. This didn't cause any
problems as far as I can see because most of the time we seem to use
the GenericSignature instead, which has the correct generic parameters.

However since we still have usages of getGenericParamsOfContext() on
deserialized DeclContexts, better safe than sorry.

I added a test; the test used to pass on master, but with the new
assertion I added, it would fail without the other changes in this
patch.
This commit is contained in:
Slava Pestov
2017-03-13 19:30:53 -07:00
parent e95acebc24
commit 18fbfd46c5
4 changed files with 57 additions and 4 deletions

View File

@@ -3428,9 +3428,12 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
extension->setEarlyAttrValidation();
declOrOffset = extension;
// Generic parameters.
GenericParamList *genericParams = maybeReadGenericParams(DC);
extension->setGenericParams(genericParams);
// Generic parameter lists are written from outermost to innermost.
// Keep reading until we run out of generic parameter lists.
GenericParamList *outerParams = nullptr;
while (auto *genericParams = maybeReadGenericParams(DC, outerParams))
outerParams = genericParams;
extension->setGenericParams(outerParams);
configureGenericEnvironment(extension, genericEnvID);
@@ -3458,6 +3461,19 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
nominal->addExtension(extension);
#ifndef NDEBUG
if (outerParams) {
unsigned paramCount = 0;
for (auto *paramList = outerParams;
paramList != nullptr;
paramList = paramList->getOuterParameters()) {
paramCount += paramList->size();
}
assert(paramCount ==
extension->getGenericSignature()->getGenericParams().size());
}
#endif
break;
}