Skip to content

Commit 2befb08

Browse files
committed
Sema: Fix checkTypeWitness() for Objective-C protocol compositions
I forgot that a protocol composition (C & P) can satisfy a superclass requirement [T : D] in one narrow case implemented in TypeBase::isExactSuperclassOf(): - D is a superclass of C - P is an @objc protocol - C is declared in Objective-C This case was ruled out here because the code assumed the type witness had to be a concrete class or archetype to satisfy a superclass requirement. Fixes rdar://problem/123543200.
1 parent a2a2083 commit 2befb08

File tree

2 files changed

+29
-5
lines changed

2 files changed

+29
-5
lines changed

lib/Sema/AssociatedTypeInference.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -190,12 +190,19 @@ checkTypeWitness(Type type, AssociatedTypeDecl *assocType,
190190
assert(superclassDecl);
191191

192192
// Fish a class declaration out of the type witness.
193-
auto classDecl = type->getClassOrBoundGenericClass();
194-
if (!classDecl) {
195-
if (auto archetype = type->getAs<ArchetypeType>()) {
196-
if (auto superclassType = archetype->getSuperclass())
193+
ClassDecl *classDecl = nullptr;
194+
195+
if (auto archetype = type->getAs<ArchetypeType>()) {
196+
if (auto superclassType = archetype->getSuperclass())
197197
classDecl = superclassType->getClassOrBoundGenericClass();
198-
}
198+
} else if (type->isObjCExistentialType()) {
199+
// For self-conforming Objective-C existentials, the exact check is
200+
// implemented in TypeBase::isExactSuperclassOf(). Here, we just always
201+
// look through into a superclass of a composition.
202+
if (auto superclassType = type->getSuperclass())
203+
classDecl = superclassType->getClassOrBoundGenericClass();
204+
} else {
205+
classDecl = type->getClassOrBoundGenericClass();
199206
}
200207

201208
if (!classDecl || !superclassDecl->isSuperclassOf(classDecl))
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
// REQUIRES: objc_interop
4+
5+
import Foundation
6+
7+
protocol P1 {
8+
associatedtype A: NSObject
9+
}
10+
11+
@objc protocol P2 {}
12+
13+
struct S: P1 {
14+
typealias A = NSObject & P2
15+
}
16+
17+
let x: (any NSObject & P2).Type = S.A.self

0 commit comments

Comments
 (0)