diff --git a/lib/ClangImporter/ClangAdapter.cpp b/lib/ClangImporter/ClangAdapter.cpp index 04daaf81ee9e1..bcbf2c8427b29 100644 --- a/lib/ClangImporter/ClangAdapter.cpp +++ b/lib/ClangImporter/ClangAdapter.cpp @@ -221,6 +221,7 @@ OmissionTypeName importer::getClangTypeNameForOmission(clang::ASTContext &ctx, // For id or NSObject, retrieve the name of "Proto". if (objcObjectPtr->getNumProtocols() == 1 && + !isNSObjectProtocol(*objcObjectPtr->qual_begin()) && (!objcClass || objcClass->getName() == "NSObject")) return (*objcObjectPtr->qual_begin())->getName(); diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index 9ad1e8c944618..55f393b6b75f7 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -6714,6 +6714,8 @@ void SwiftDeclConverter::importObjCProtocols( for (auto cp = clangProtocols.begin(), cpEnd = clangProtocols.end(); cp != cpEnd; ++cp) { + if (isNSObjectProtocol(*cp)) continue; + if (auto proto = castIgnoringCompatibilityAlias( Impl.importDecl(*cp, getActiveSwiftVersion()))) { addProtocols(proto, protocols, knownProtocols); @@ -6797,6 +6799,8 @@ Optional SwiftDeclConverter::importObjCGenericParams( inherited.push_back(TypeLoc::withoutLoc(superclassType)); } for (clang::ObjCProtocolDecl *clangProto : clangBound->quals()) { + if (isNSObjectProtocol(clangProto)) continue; + ProtocolDecl *proto = castIgnoringCompatibilityAlias( Impl.importDecl(clangProto, getActiveSwiftVersion())); if (!proto) { @@ -8555,6 +8559,14 @@ void ClangImporter::Implementation::collectMembersToAdd( members); } + // For NSObject, add the otherwise-hidden NSObject protocol. This is only + // used to import mirrored members. + // FIXME: Check for any class that conforms to the NSObject protocol? + if (clangClass->getName() == "NSObject") { + if (auto nsObjectProto = getNSObjectProtocolType()) { + protos.push_back(nsObjectProto->castTo()->getDecl()); + } + } } else if (auto clangProto = dyn_cast(objcContainer)) { objcContainer = clangProto->getDefinition(); diff --git a/lib/ClangImporter/ImportName.cpp b/lib/ClangImporter/ImportName.cpp index 845f2b77c6001..f46a328f1550a 100644 --- a/lib/ClangImporter/ImportName.cpp +++ b/lib/ClangImporter/ImportName.cpp @@ -612,6 +612,9 @@ findSwiftNameAttr(const clang::Decl *decl, ImportNameVersion version) { if (version == ImportNameVersion::raw()) return nullptr; + // HACK: Don't rename the NSObject protocol. + if (isNSObjectProtocol(decl)) return nullptr; + // Handle versioned API notes for Swift 3 and later. This is the common case. if (version > ImportNameVersion::swift2()) { const auto *activeAttr = decl->getAttr(); @@ -1021,6 +1024,10 @@ static bool shouldBeSwiftPrivate(NameImporter &nameImporter, } } + // The NSObject protocol is SwiftPrivate. + // FIXME: Move this into the API notes for the ObjectiveC module. + if (isNSObjectProtocol(decl)) return true; + return false; } diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp index 00c7b69c4212f..46c186a023d61 100644 --- a/lib/ClangImporter/ImportType.cpp +++ b/lib/ClangImporter/ImportType.cpp @@ -926,17 +926,6 @@ namespace { SmallVector protocols{ type->qual_begin(), type->qual_end() }; - auto *nsObjectProto = - Impl.getNSObjectProtocolType()->getAnyNominal(); - if (!nsObjectProto) { - // Input is malformed - return {}; - } - auto *clangProto = - cast(nsObjectProto->getClangDecl()); - protocols.push_back( - const_cast(clangProto)); - clang::ASTContext &clangCtx = Impl.getClangASTContext(); clang::QualType protosOnlyType = clangCtx.getObjCObjectType(clangCtx.ObjCBuiltinIdTy, @@ -1037,8 +1026,15 @@ namespace { if (!importedType->isAnyObject()) members.push_back(importedType); + bool hasNSObjectProtocol = false; for (auto cp = type->qual_begin(), cpEnd = type->qual_end(); cp != cpEnd; ++cp) { + // Never import the NSObject protocol in a type. + if (isNSObjectProtocol(*cp)) { + hasNSObjectProtocol = true; + continue; + } + auto proto = castIgnoringCompatibilityAlias( Impl.importDecl(*cp, Impl.CurrentVersion)); if (!proto) @@ -1049,7 +1045,7 @@ namespace { importedType = ProtocolCompositionType::get(Impl.SwiftContext, members, - /*HasExplicitAnyObject=*/false); + /*HasExplicitAnyObject=*/hasNSObjectProtocol); } // Class or Class

maps to an existential metatype. @@ -2473,3 +2469,10 @@ Type ClangImporter::Implementation::getNSCopyingType() { Type ClangImporter::Implementation::getNSObjectProtocolType() { return getNamedProtocolType(*this, "NSObject"); } + +bool swift::importer::isNSObjectProtocol(const clang::Decl *decl) { + if (auto objcProto = dyn_cast_or_null(decl)) + return objcProto->getName() == "NSObject"; + return false; +} + diff --git a/lib/ClangImporter/ImporterImpl.h b/lib/ClangImporter/ImporterImpl.h index 7f61ab8db27e2..7fc5a2877069a 100644 --- a/lib/ClangImporter/ImporterImpl.h +++ b/lib/ClangImporter/ImporterImpl.h @@ -1409,6 +1409,8 @@ static T *castIgnoringCompatibilityAlias(Decl *D) { return cast_or_null(D); } +bool isNSObjectProtocol(const clang::Decl *decl); + class SwiftNameLookupExtension : public clang::ModuleFileExtension { std::unique_ptr &pchLookupTable; LookupTableMap &lookupTables; diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index 74d21f4b51593..fed77a48989e7 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -286,6 +286,18 @@ void TypeChecker::resolveInheritanceClause( } } +/// Determine whether this type refers to the deprecated NSObjectProtocol +/// type alias. +static bool isDeprecatedNSObjectProtocol(Type type) { + if (auto typeAlias = dyn_cast(type.getPointer())) { + if (typeAlias->getDecl()->getAttrs().getDeprecated(type->getASTContext()) && + typeAlias->getDecl()->getName().str() == "NSObjectProtocol") + return true; + } + + return false; +} + /// check the inheritance clause of a type declaration or extension thereof. /// /// This routine validates all of the types in the parsed inheritance clause, @@ -518,8 +530,9 @@ void TypeChecker::checkInheritanceClause(Decl *decl, } // Swift 3 compatibility -- a class inheriting from AnyObject is a no-op. - if (Context.LangOpts.isSwiftVersion3() && isa(decl) && - inheritedTy->isAnyObject()) { + if (isa(decl) && inheritedTy->isAnyObject() && + (Context.LangOpts.isSwiftVersion3() || + isDeprecatedNSObjectProtocol(inheritedTy))) { auto classDecl = cast(decl); auto removeRange = getRemovalRange(i); diagnose(inherited.getSourceRange().Start, diff --git a/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift b/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift index dbf43f11c8882..08933d324940f 100644 --- a/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift +++ b/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift @@ -196,7 +196,10 @@ public var NO: ObjCBool { // NSObject implements Equatable's == as -[NSObject isEqual:] // NSObject implements Hashable's hashValue() as -[NSObject hash] -// FIXME: what about NSObjectProtocol? + +@available(*, deprecated, renamed: "AnyObject", + message: "all classes implicitly conform to the 'NSObject' protocol") +public typealias NSObjectProtocol = AnyObject extension NSObject : Equatable, Hashable { /// The hash value. diff --git a/test/ClangImporter/Dispatch_test.swift b/test/ClangImporter/Dispatch_test.swift index 53f4736702afa..de8f3a19e95e2 100644 --- a/test/ClangImporter/Dispatch_test.swift +++ b/test/ClangImporter/Dispatch_test.swift @@ -7,14 +7,14 @@ import Foundation func test1(_ queue: dispatch_queue_t) {} // expected-error {{'dispatch_queue_t' is unavailable}} func test2(_ queue: DispatchQueue) { - let base: NSObjectProtocol = queue + let base: AnyObject = queue let _: DispatchObject = queue let _ = base as? DispatchQueue // Make sure the dispatch types are actually distinct types! let _ = queue as DispatchSource // expected-error {{cannot convert value of type 'DispatchQueue' to type 'DispatchSource' in coercion}} - let _ = base as DispatchSource // expected-error {{'NSObjectProtocol' is not convertible to 'DispatchSource'; did you mean to use 'as!' to force downcast?}} + let _ = base as DispatchSource // expected-error {{'AnyObject' is not convertible to 'DispatchSource'; did you mean to use 'as!' to force downcast?}} } extension dispatch_queue_t {} // expected-error {{'dispatch_queue_t' is unavailable}} diff --git a/test/ClangImporter/MixedSource/mixed-target-using-header.swift b/test/ClangImporter/MixedSource/mixed-target-using-header.swift index cd506d6ec04c1..32902b9ca91a3 100644 --- a/test/ClangImporter/MixedSource/mixed-target-using-header.swift +++ b/test/ClangImporter/MixedSource/mixed-target-using-header.swift @@ -12,7 +12,7 @@ func test(_ foo : FooProto) { @objc class ForwardClass : NSObject { } -@objc protocol ForwardProto : NSObjectProtocol { +@objc protocol ForwardProto : AnyObject { } @objc class ForwardProtoAdopter : NSObject, ForwardProto { } diff --git a/test/ClangImporter/MixedSource/mixed-target-using-module.swift b/test/ClangImporter/MixedSource/mixed-target-using-module.swift index d1661865adf48..20336a8cf9cc7 100644 --- a/test/ClangImporter/MixedSource/mixed-target-using-module.swift +++ b/test/ClangImporter/MixedSource/mixed-target-using-module.swift @@ -12,7 +12,7 @@ @objc class ForwardClass : NSObject { } -@objc protocol ForwardProto : NSObjectProtocol { +@objc protocol ForwardProto : AnyObject { } @objc class ForwardProtoAdopter : NSObject, ForwardProto { } diff --git a/test/ClangImporter/availability.swift b/test/ClangImporter/availability.swift index 97a8f05e272db..4e3313bbc9273 100644 --- a/test/ClangImporter/availability.swift +++ b/test/ClangImporter/availability.swift @@ -13,10 +13,6 @@ func test_unavailable_instance_method(_ x : NSObject) -> Bool { return x.allowsWeakReference() // expected-error {{'allowsWeakReference()' is unavailable}} } -func test_unavailable_method_in_protocol(_ x : NSObjectProtocol) { - // expected-warning @+1 {{expression of type 'NSObjectProtocol' is unused}} - x.retain() // expected-error {{'retain()' is unavailable}} -} func test_unavailable_method_in_protocol_use_class_instance(_ x : NSObject) { x.retain() // expected-error {{'retain()' is unavailable}} expected-warning {{result of call to 'retain()' is unused}} } diff --git a/test/ClangImporter/objc_parse.swift b/test/ClangImporter/objc_parse.swift index 554dde0863451..46824ed481dd5 100644 --- a/test/ClangImporter/objc_parse.swift +++ b/test/ClangImporter/objc_parse.swift @@ -57,7 +57,7 @@ func instanceMethods(_ b: B) { // Instance methods with keyword components var obj = NSObject() - var prot = NSObjectProtocol.self + var prot = NSCoding.self b.`protocol`(prot, hasThing:obj) b.doThing(obj, protocol: prot) } @@ -311,10 +311,10 @@ func ivars(_ hive: Hive) { hive.queen.description() // expected-error{{value of type 'Hive' has no member 'queen'}} } -class NSObjectable : NSObjectProtocol { - @objc var description : String { return "" } - @objc(conformsToProtocol:) func conforms(to _: Protocol) -> Bool { return false } - @objc(isKindOfClass:) func isKind(of aClass: AnyClass) -> Bool { return false } +class NSObjectable : NSObject { + @objc override var description : String { return "" } + @objc(conformsToProtocol:) override func conforms(to _: Protocol) -> Bool { return false } + @objc(isKindOfClass:) override func isKind(of aClass: AnyClass) -> Bool { return false } } @@ -553,17 +553,15 @@ func testStrangeSelectors(obj: StrangeSelectors) { func testProtocolQualified(_ obj: CopyableNSObject, cell: CopyableSomeCell, plainObj: NSObject, plainCell: SomeCell) { - _ = obj as NSObject // expected-error {{'CopyableNSObject' (aka 'NSCopying & NSObjectProtocol') is not convertible to 'NSObject'; did you mean to use 'as!' to force downcast?}} {{11-13=as!}} - _ = obj as NSObjectProtocol + _ = obj as NSObject // expected-error {{'CopyableNSObject' (aka 'NSCopying') is not convertible to 'NSObject'; did you mean to use 'as!' to force downcast?}} {{11-13=as!}} _ = obj as NSCopying - _ = obj as SomeCell // expected-error {{'CopyableNSObject' (aka 'NSCopying & NSObjectProtocol') is not convertible to 'SomeCell'; did you mean to use 'as!' to force downcast?}} {{11-13=as!}} + _ = obj as SomeCell // expected-error {{'CopyableNSObject' (aka 'NSCopying') is not convertible to 'SomeCell'; did you mean to use 'as!' to force downcast?}} {{11-13=as!}} _ = cell as NSObject - _ = cell as NSObjectProtocol _ = cell as NSCopying // expected-error {{'CopyableSomeCell' (aka 'SomeCell') is not convertible to 'NSCopying'; did you mean to use 'as!' to force downcast?}} {{12-14=as!}} _ = cell as SomeCell - _ = plainObj as CopyableNSObject // expected-error {{'NSObject' is not convertible to 'CopyableNSObject' (aka 'NSCopying & NSObjectProtocol'); did you mean to use 'as!' to force downcast?}} {{16-18=as!}} + _ = plainObj as CopyableNSObject // expected-error {{'NSObject' is not convertible to 'CopyableNSObject' (aka 'NSCopying'); did you mean to use 'as!' to force downcast?}} {{16-18=as!}} _ = plainCell as CopyableSomeCell // FIXME: This is not really typesafe. } diff --git a/test/Compatibility/nsobjectprotocol.swift b/test/Compatibility/nsobjectprotocol.swift new file mode 100644 index 0000000000000..769c63ec212c5 --- /dev/null +++ b/test/Compatibility/nsobjectprotocol.swift @@ -0,0 +1,17 @@ +// RUN: %target-typecheck-verify-swift -swift-version 3 +// RUN: %target-typecheck-verify-swift -swift-version 4 +// REQUIRES: objc_interop + +import ObjectiveC +import Foundation + +class X: NSObjectProtocol { } // expected-warning{{'NSObjectProtocol' is deprecated: all classes implicitly conform to the 'NSObject' protocol}} +// expected-note@-1{{use 'AnyObject' instead}} +// expected-warning@-2{{conformance of class 'X' to 'AnyObject' is redundant}} + +protocol P: NSObjectProtocol { } // expected-warning{{'NSObjectProtocol' is deprecated: all classes implicitly conform to the 'NSObject' protocol}} +// expected-note@-1{{use 'AnyObject' instead}} + +func composition(_: NSCoding & NSObjectProtocol) { } // expected-warning{{'NSObjectProtocol' is deprecated: all classes implicitly conform to the 'NSObject' protocol}} +// expected-note@-1{{use 'AnyObject' instead}} + diff --git a/test/IDE/dump_swift_lookup_tables_objc.swift b/test/IDE/dump_swift_lookup_tables_objc.swift index cff7a367cffa9..ae4a4f5bf14a7 100644 --- a/test/IDE/dump_swift_lookup_tables_objc.swift +++ b/test/IDE/dump_swift_lookup_tables_objc.swift @@ -14,11 +14,12 @@ // CHECK-NOT: lookup table // CHECK: NSObject: // CHECK-NEXT: TU: NSObject -// CHECK-NEXT: NSObjectProtocol: +// CHECK: __NSObjectProtocol: // CHECK-NEXT: TU: NSObject // CHECK: responds: // CHECK-NEXT: -[NSObject respondsToSelector:] + // CHECK-LABEL: <> // CHECK-NEXT: Base name -> entry mappings: // CHECK-NEXT: CCItem: diff --git a/test/IDE/importProtocols.swift b/test/IDE/importProtocols.swift index d5bcdcc621c78..7f43066d85d0c 100644 --- a/test/IDE/importProtocols.swift +++ b/test/IDE/importProtocols.swift @@ -3,7 +3,7 @@ // REQUIRES: objc_interop -// CHECK: protocol ImportedProtocolBase : NSObjectProtocol { +// CHECK: protocol ImportedProtocolBase { // CHECK: } // CHECK: typealias ImportedProtocolBase_t = ImportedProtocolBase // CHECK: protocol IPSub : ImportedProtocolBase { diff --git a/test/IDE/print_clang_ObjectiveC.swift b/test/IDE/print_clang_ObjectiveC.swift index a903207110ce1..8b1d95918dbf5 100644 --- a/test/IDE/print_clang_ObjectiveC.swift +++ b/test/IDE/print_clang_ObjectiveC.swift @@ -13,13 +13,13 @@ // NEGATIVE-WITHOUT-FORWARD-DECLS-NOT: var description // NEGATIVE-NOT: NSCoder -// CHECK-LABEL: protocol NSObjectProtocol { +// CHECK-LABEL: protocol __NSObjectProtocol { // CHECK-DAG: var superclass: AnyClass? { get } // CHECK-DAG: func zone() -> NSZone // CHECK-WITH-FORWARD-DECLS-DAG: var description: String { get } // CHECK: {{^[}]$}} -// CHECK-LABEL: class NSObject : NSObjectProtocol { +// CHECK-LABEL: class NSObject { // CHECK-DAG: func copy() -> Any // CHECK-DAG: class func hash() -> Int // CHECK-WITH-FORWARD-DECLS-DAG: class func description() -> String diff --git a/test/IDE/print_omit_needless_words.swift b/test/IDE/print_omit_needless_words.swift index 9cf56bbf168f9..7aefa158b2ed2 100644 --- a/test/IDE/print_omit_needless_words.swift +++ b/test/IDE/print_omit_needless_words.swift @@ -140,7 +140,7 @@ // CHECK-FOUNDATION: func doSomething(with: NSCopying) // Note: NSObject treated as "Proto". -// CHECK-FOUNDATION: func doSomethingElse(with: NSCopying & NSObjectProtocol) +// CHECK-FOUNDATION: func doSomethingElse(with: NSCopying) // Note: Function type -> "Function". // CHECK-FOUNDATION: func sort(_: @escaping @convention(c) (Any, Any) -> Int) diff --git a/test/Inputs/clang-importer-sdk/swift-modules-without-ns/ObjectiveC.swift b/test/Inputs/clang-importer-sdk/swift-modules-without-ns/ObjectiveC.swift index f849669af88d7..7dd6e0d8ae984 100644 --- a/test/Inputs/clang-importer-sdk/swift-modules-without-ns/ObjectiveC.swift +++ b/test/Inputs/clang-importer-sdk/swift-modules-without-ns/ObjectiveC.swift @@ -82,3 +82,7 @@ extension NSObject : Equatable, Hashable { public func == (lhs: NSObject, rhs: NSObject) -> Bool { return lhs.isEqual(rhs) } + +@available(*, deprecated, renamed: "AnyObject", + message: "all classes implicitly conform to the 'NSObject' protocol") +public typealias NSObjectProtocol = AnyObject diff --git a/test/Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift b/test/Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift index 11338a687b0d9..11e0f093011f0 100644 --- a/test/Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift +++ b/test/Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift @@ -96,3 +96,7 @@ extension NSObject : Equatable, Hashable { public func == (lhs: NSObject, rhs: NSObject) -> Bool { return lhs.isEqual(rhs) } + +@available(*, deprecated, renamed: "AnyObject", + message: "all classes implicitly conform to the 'NSObject' protocol") +public typealias NSObjectProtocol = AnyObject diff --git a/test/PrintAsObjC/classes.swift b/test/PrintAsObjC/classes.swift index 9f3b0eb59607c..0387e3a24bbd8 100644 --- a/test/PrintAsObjC/classes.swift +++ b/test/PrintAsObjC/classes.swift @@ -89,13 +89,13 @@ class ClassWithCustomName2 {} class ClassWithCustomNameSub : ClassWithCustomName {} -// CHECK-LABEL: @interface ClassWithNSObjectProtocol +// CHECK-LABEL: @interface ClassWithNSObjectProtocol // CHECK-NEXT: @property (nonatomic, readonly, copy) NSString * _Nonnull description; // CHECK-NEXT: - (BOOL)conformsToProtocol:(Protocol * _Nonnull)_ SWIFT_WARN_UNUSED_RESULT; // CHECK-NEXT: - (BOOL)isKindOfClass:(Class _Nonnull)aClass SWIFT_WARN_UNUSED_RESULT; // CHECK-NEXT: - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER; // CHECK-NEXT: @end -@objc class ClassWithNSObjectProtocol : NSObjectProtocol { +@objc class ClassWithNSObjectProtocol { @objc var description: String { return "me" } @objc(conformsToProtocol:) func conforms(to _: Protocol) -> Bool { return false } @@ -355,9 +355,9 @@ typealias AliasForNSRect = NSRect // NEGATIVE-NOT: @interface NSObject class MyObject : NSObject {} -// CHECK-LABEL: @protocol MyProtocol +// CHECK-LABEL: @protocol MyProtocol // CHECK-NEXT: @end -@objc protocol MyProtocol : NSObjectProtocol {} +@objc protocol MyProtocol {} // CHECK-LABEL: @protocol MyProtocolMetaOnly; // CHECK-LABEL: @interface MyProtocolMetaCheck @@ -521,7 +521,6 @@ public class NonObjCClass { } // CHECK-NEXT: @property (nonatomic, copy) IBOutletCollection(Properties) NSArray * _Null_unspecified outletCollection; // CHECK-NEXT: @property (nonatomic, copy) IBOutletCollection(CustomName) NSArray * _Nullable outletCollectionOptional; // CHECK-NEXT: @property (nonatomic, copy) IBOutletCollection(id) NSArray * _Nullable outletCollectionAnyObject; -// CHECK-NEXT: @property (nonatomic, copy) IBOutletCollection(id) NSArray> * _Nullable outletCollectionProto; // CHECK-NEXT: SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly) NSInteger staticInt;) // CHECK-NEXT: + (NSInteger)staticInt SWIFT_WARN_UNUSED_RESULT; // CHECK-NEXT: SWIFT_CLASS_PROPERTY(@property (nonatomic, class, copy) NSString * _Nonnull staticString;) @@ -614,7 +613,6 @@ public class NonObjCClass { } @IBOutlet var outletCollection: [Properties]! @IBOutlet var outletCollectionOptional: [ClassWithCustomName]? = [] @IBOutlet var outletCollectionAnyObject: [AnyObject]? - @IBOutlet var outletCollectionProto: [NSObjectProtocol]? @objc static let staticInt = 2 @objc static var staticString = "Hello" diff --git a/test/stdlib/RuntimeObjC.swift b/test/stdlib/RuntimeObjC.swift index f30371186d792..e56ee6ccfc827 100644 --- a/test/stdlib/RuntimeObjC.swift +++ b/test/stdlib/RuntimeObjC.swift @@ -695,8 +695,8 @@ Reflection.test("MetatypeMirror") { dump(compositionConcreteMetatype, to: &output) expectEqual(expectedComposition, output) - let objcDefinedProtoType = NSObjectProtocol.self - expectEqual(String(describing: objcDefinedProtoType), "NSObject") + let objcDefinedProtoType = NSCoding.self + expectEqual(String(describing: objcDefinedProtoType), "NSCoding") } }