Skip to content

Commit 452e1b1

Browse files
committed
[Runtime] Check for @objc existentials conforming to @objc protocols.
When checking conformance requirements against an @objc protocol, also check for an @objc existential using protocol_conformsToProtocol(). Fixes rdar://problem/45685649.
1 parent 3e2e81d commit 452e1b1

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

stdlib/public/runtime/Casting.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,24 @@ bool swift::_conformsToProtocol(const OpaqueValue *value,
362362
#endif
363363

364364

365-
case MetadataKind::Existential: // FIXME
366-
case MetadataKind::ExistentialMetatype: // FIXME
365+
case MetadataKind::Existential: {
366+
#if SWIFT_OBJC_INTEROP
367+
// If all protocols are @objc and at least one of them conforms to the
368+
// protocol, succeed.
369+
auto existential = cast<ExistentialTypeMetadata>(type);
370+
if (!existential->isObjC())
371+
return false;
372+
for (auto existentialProto : existential->getProtocols()) {
373+
if (protocol_conformsToProtocol(existentialProto.getObjCProtocol(),
374+
protocol.getObjCProtocol()))
375+
return true;
376+
}
377+
#endif
378+
379+
return false;
380+
}
381+
382+
case MetadataKind::ExistentialMetatype:
367383
default:
368384
return false;
369385
}

test/Runtime/demangleToMetadataObjC.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ let DemangleToMetadataTests = TestSuite("DemangleToMetadataObjC")
1414
@objc enum E: Int { case a }
1515
@objc protocol P1 { }
1616
protocol P2 { }
17+
@objc protocol P3: P1 { }
1718

1819
DemangleToMetadataTests.test("@objc classes") {
1920
expectEqual(type(of: C()), _typeByMangledName("4main1CC")!)
@@ -96,5 +97,11 @@ DemangleToMetadataTests.test("runtime conformance lookup via foreign superclasse
9697
_typeByMangledName("ShySo18CFMutableStringRefaG")!)
9798
}
9899

100+
class F<T: P1> { }
101+
102+
DemangleToMetadataTests.test("runtime conformance check for @objc protocol inheritance") {
103+
expectEqual(F<P3>.self, _typeByMangledName("4main1FCyAA2P3PG")!)
104+
}
105+
99106
runAllTests()
100107

0 commit comments

Comments
 (0)