Skip to content

Commit 97a59c1

Browse files
committed
TypeCheckType: Do not form protocol type with generic parent in resolveTypeInContext
1 parent 8b941e6 commit 97a59c1

File tree

4 files changed

+18
-4
lines changed

4 files changed

+18
-4
lines changed

include/swift/AST/DeclContext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,10 @@ class alignas(1 << DeclContextAlignInBits) DeclContext
586586
/// context.
587587
bool isInSpecializeExtensionContext() const;
588588

589+
/// Returns whether this declaration context is a protocol in an unsupported
590+
/// context.
591+
bool isUnsupportedNestedProtocol() const;
592+
589593
/// Get the most optimal resilience expansion for code in this context.
590594
/// If the body is able to be inlined into functions in other resilience
591595
/// domains, this ensures that only sufficiently-conservative access patterns

lib/AST/Decl.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5162,10 +5162,8 @@ static Type computeNominalType(NominalTypeDecl *decl, DeclTypeKind kind) {
51625162
// If `decl` is a nested type, find the parent type.
51635163
Type ParentTy;
51645164
DeclContext *dc = decl->getDeclContext();
5165-
bool isUnsupportedNestedProtocol =
5166-
isa<ProtocolDecl>(decl) && decl->getParent()->isGenericContext();
51675165

5168-
if (!isUnsupportedNestedProtocol && dc->isTypeContext()) {
5166+
if (!decl->isUnsupportedNestedProtocol() && dc->isTypeContext()) {
51695167
switch (kind) {
51705168
case DeclTypeKind::DeclaredType: {
51715169
if (auto *nominal = dc->getSelfNominalTypeDecl())

lib/AST/DeclContext.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ DeclContext *DeclContext::getParentForLookup() const {
306306
// outer types.
307307
return getModuleScopeContext();
308308
}
309-
if (isa<ProtocolDecl>(this) && getParent()->isGenericContext()) {
309+
if (isUnsupportedNestedProtocol()) {
310310
// Protocols in generic contexts must not look in to their parents,
311311
// as the parents may contain types with inferred implicit
312312
// generic parameters not present in the protocol's generic signature.
@@ -1532,6 +1532,10 @@ bool DeclContext::isInSpecializeExtensionContext() const {
15321532
return isSpecializeExtensionContext(this);
15331533
}
15341534

1535+
bool DeclContext::isUnsupportedNestedProtocol() const {
1536+
return isa<ProtocolDecl>(this) && getParent()->isGenericContext();
1537+
}
1538+
15351539
bool DeclContext::isAlwaysAvailableConformanceContext() const {
15361540
auto *ext = dyn_cast<ExtensionDecl>(this);
15371541
if (ext == nullptr)

lib/Sema/TypeCheckType.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,14 @@ Type TypeResolution::resolveTypeInContext(TypeDecl *typeDecl,
531531

532532
assert(foundDC);
533533

534+
// Protocols cannot be nested in generic contexts. Use the declared interface
535+
// type, which won't have a parent.
536+
if (auto *proto = dyn_cast<ProtocolDecl>(typeDecl)) {
537+
if (proto->isUnsupportedNestedProtocol()) {
538+
return typeDecl->getDeclaredInterfaceType();
539+
}
540+
}
541+
534542
// selfType is the self type of the context, unless the
535543
// context is a protocol type, in which case we might have
536544
// to use the existential type or superclass bound as a

0 commit comments

Comments
 (0)