Skip to content

Commit c8fbfb7

Browse files
authored
Merge pull request #4029 from aleksgapp/bugfix/SR-1894
[SR-1894] Consider protocol metatypes as not @objc compatible.
2 parents cc0c2bf + 9a87f8d commit c8fbfb7

File tree

3 files changed

+47
-2
lines changed

3 files changed

+47
-2
lines changed

lib/AST/ASTDumper.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2477,7 +2477,13 @@ class PrintTypeRepr : public TypeReprVisitor<PrintTypeRepr> {
24772477
printRec(T->getBase());
24782478
OS << ')';
24792479
}
2480-
2480+
2481+
void visitProtocolTypeRepr(ProtocolTypeRepr *T) {
2482+
printCommon(T, "type_protocol") << '\n';
2483+
printRec(T->getBase());
2484+
OS << ')';
2485+
}
2486+
24812487
void visitInOutTypeRepr(InOutTypeRepr *T) {
24822488
printCommon(T, "type_inout") << '\n';
24832489
printRec(T->getBase());

lib/AST/Type.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2027,9 +2027,15 @@ static ForeignRepresentableKind
20272027
getObjCObjectRepresentable(Type type, const DeclContext *dc) {
20282028
// @objc metatypes are representable when their instance type is.
20292029
if (auto metatype = type->getAs<AnyMetatypeType>()) {
2030+
auto instanceType = metatype->getInstanceType();
2031+
2032+
// Consider metatype of any existential type as not Objective-C
2033+
// representable.
2034+
if (metatype->is<MetatypeType>() && instanceType->isAnyExistentialType())
2035+
return ForeignRepresentableKind::None;
2036+
20302037
// If the instance type is not representable verbatim, the metatype is not
20312038
// representable.
2032-
auto instanceType = metatype->getInstanceType();
20332039
if (getObjCObjectRepresentable(instanceType, dc)
20342040
!= ForeignRepresentableKind::Object)
20352041
return ForeignRepresentableKind::None;

test/attr/attr_objc.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,13 +314,46 @@ class ConcreteContext2 {
314314
}
315315

316316
class ConcreteContext3 {
317+
317318
func dynamicSelf1() -> Self { return self }
318319

319320
@objc func dynamicSelf1_() -> Self { return self }
320321
// expected-error@-1{{method cannot be marked @objc because its result type cannot be represented in Objective-C}}
321322

322323
@objc func genericParams<T: NSObject>() -> [T] { return [] }
323324
// expected-error@-1{{method cannot be marked @objc because it has generic parameters}}
325+
326+
@objc func returnObjCProtocolMetatype() -> NSCoding.Protocol { return NSCoding.self }
327+
// expected-error@-1{{method cannot be marked @objc because its result type cannot be represented in Objective-C}}
328+
329+
typealias AnotherNSCoding = NSCoding
330+
typealias MetaNSCoding1 = NSCoding.Protocol
331+
typealias MetaNSCoding2 = AnotherNSCoding.Protocol
332+
333+
@objc func returnObjCAliasProtocolMetatype1() -> AnotherNSCoding.Protocol { return NSCoding.self }
334+
// expected-error@-1{{method cannot be marked @objc because its result type cannot be represented in Objective-C}}
335+
336+
@objc func returnObjCAliasProtocolMetatype2() -> MetaNSCoding1 { return NSCoding.self }
337+
// expected-error@-1{{method cannot be marked @objc because its result type cannot be represented in Objective-C}}
338+
339+
@objc func returnObjCAliasProtocolMetatype3() -> MetaNSCoding2 { return NSCoding.self }
340+
// expected-error@-1{{method cannot be marked @objc because its result type cannot be represented in Objective-C}}
341+
342+
typealias Composition = NSCopying & NSCoding
343+
344+
@objc func returnCompositionMetatype1() -> Composition.Protocol { return Composition.self }
345+
// expected-error@-1{{method cannot be marked @objc because its result type cannot be represented in Objective-C}}
346+
347+
@objc func returnCompositionMetatype2() -> (NSCopying & NSCoding).Protocol { return (NSCopying & NSCoding).self }
348+
// expected-error@-1{{method cannot be marked @objc because its result type cannot be represented in Objective-C}}
349+
350+
typealias NSCodingExistential = NSCoding.Type
351+
352+
@objc func metatypeOfExistentialMetatypePram1(a: NSCodingExistential.Protocol) {}
353+
// expected-error@-1{{method cannot be marked @objc because the type of the parameter cannot be represented in Objective-C}}
354+
355+
@objc func metatypeOfExistentialMetatypePram2(a: NSCoding.Type.Protocol) {}
356+
// expected-error@-1{{method cannot be marked @objc because the type of the parameter cannot be represented in Objective-C}}
324357
}
325358

326359
func genericContext1<T>(_: T) {

0 commit comments

Comments
 (0)