Skip to content

Commit 1cd8613

Browse files
committed
Sema: Do a better job with creating generic parameter lists in extension binding
No test case, but it fixes a regression with the next patch.
1 parent a30c32d commit 1cd8613

File tree

1 file changed

+21
-10
lines changed

1 file changed

+21
-10
lines changed

lib/Sema/TypeChecker.cpp

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -331,25 +331,36 @@ static void bindExtensionToNominal(ExtensionDecl *ext,
331331
if (ext->alreadyBoundToNominal())
332332
return;
333333

334+
// Hack to force generic parameter lists of protocols to be created if the
335+
// nominal is an (invalid) nested type of a protocol.
336+
DeclContext *outerDC = nominal;
337+
while (!outerDC->isModuleScopeContext()) {
338+
if (auto *proto = dyn_cast<ProtocolDecl>(outerDC))
339+
proto->createGenericParamsIfMissing();
340+
341+
outerDC = outerDC->getParent();
342+
}
343+
344+
configureOuterGenericParams(nominal);
345+
334346
if (auto proto = dyn_cast<ProtocolDecl>(nominal)) {
335-
// For a protocol extension, build the generic parameter list.
336-
auto genericParams = proto->createGenericParams(ext);
337-
prepareGenericParamList(genericParams);
338-
ext->setGenericParams(genericParams);
347+
// For a protocol extension, build the generic parameter list directly
348+
// since we want it to have an inheritance clause.
349+
ext->setGenericParams(proto->createGenericParams(ext));
339350
} else if (auto genericParams = nominal->getGenericParamsOfContext()) {
340-
// Make sure the generic parameters are set up.
341-
configureOuterGenericParams(nominal);
342-
343351
// Clone the generic parameter list of a generic type.
344-
prepareGenericParamList(genericParams);
345352
ext->setGenericParams(
346353
cloneGenericParams(ext->getASTContext(), ext, genericParams));
347354
}
348355

356+
auto *genericParams = ext->getGenericParams();
357+
if (genericParams)
358+
prepareGenericParamList(genericParams);
359+
349360
// If we have a trailing where clause, deal with it now.
350361
// For now, trailing where clauses are only permitted on protocol extensions.
351362
if (auto trailingWhereClause = ext->getTrailingWhereClause()) {
352-
if (!(nominal->getGenericParamsOfContext() || isa<ProtocolDecl>(nominal))) {
363+
if (!genericParams) {
353364
// Only generic and protocol types are permitted to have
354365
// trailing where clauses.
355366
ext->diagnose(diag::extension_nongeneric_trailing_where,
@@ -361,7 +372,7 @@ static void bindExtensionToNominal(ExtensionDecl *ext,
361372
// FIXME: Long-term, we'd like clients to deal with the trailing where
362373
// clause explicitly, but for now it's far more direct to represent
363374
// the trailing where clause as part of the requirements.
364-
ext->getGenericParams()->addTrailingWhereClause(
375+
genericParams->addTrailingWhereClause(
365376
ext->getASTContext(),
366377
trailingWhereClause->getWhereLoc(),
367378
trailingWhereClause->getRequirements());

0 commit comments

Comments
 (0)