@@ -91,7 +91,12 @@ func TestSwiftObjectNSObjectAssertNoErrors()
9191// Verify that Obj-C isEqual: provides same answer as Swift ==
9292func TestEquatableEquals<T: Equatable & AnyObject>(_ e1: T, _ e2: T) {
9393 if e1 == e2 {
94+ #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
95+ // Legacy behavior: Equatable Swift does not imply == in ObjC
96+ TestSwiftObjectNSObjectNotEquals(e1, e2)
97+ #else
9498 TestSwiftObjectNSObjectEquals(e1, e2)
99+ #endif
95100 } else {
96101 TestSwiftObjectNSObjectNotEquals(e1, e2)
97102 }
@@ -104,14 +109,26 @@ func TestNonEquatableEquals(_ e1: AnyObject, _ e2: AnyObject) {
104109// Verify that Obj-C hashValue matches Swift hashValue for Hashable types
105110func TestHashable(_ h: H)
106111{
112+ #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
113+ // Legacy behavior: Hash value is identity in ObjC
114+ TestSwiftObjectNSObjectDefaultHashValue(h)
115+ #else
116+ // New behavior: Hashable in Swift, same hash value in ObjC
107117 TestSwiftObjectNSObjectHashValue(h, h.hashValue)
118+ #endif
108119}
109120
110121// Test Obj-C hashValue for Swift types that are Equatable but not Hashable
111122func TestEquatableHash(_ e: AnyObject)
112123{
113- // These should have a constant hash value
124+ #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
125+ // Legacy behavior: Equatable in Swift => ObjC hashes with identity
126+ TestSwiftObjectNSObjectDefaultHashValue(e)
127+ fakeEquatableWarning(e)
128+ #else
129+ // New behavior: These should have a constant hash value
114130 TestSwiftObjectNSObjectHashValue(e, 1)
131+ #endif
115132}
116133
117134func TestNonEquatableHash(_ e: AnyObject)
@@ -125,11 +142,19 @@ func TestNonEquatableHash(_ e: AnyObject)
125142// CHECK-NEXT: d ##SwiftObjectNSObject.D##
126143// CHECK-NEXT: S ##{{.*}}SwiftObject##
127144
128- // Full message is longer, but this is the essential part ...
145+ // Verify that the runtime emits the warning that we expected ...
129146// CHECK-NEXT: Obj-C `-hash` {{.*}} type `SwiftObjectNSObject.E` {{.*}} Equatable but not Hashable
130147// CHECK-NEXT: Obj-C `-hash` {{.*}} type `SwiftObjectNSObject.E1` {{.*}} Equatable but not Hashable
131148// CHECK-NEXT: Obj-C `-hash` {{.*}} type `SwiftObjectNSObject.E2` {{.*}} Equatable but not Hashable
132149
150+ // If we're checking legacy behavior or unsupported platform, then
151+ // the warning above won't be emitted. This function emits a fake
152+ // message that will satisfy the checks above in such cases.
153+ func fakeEquatableWarning(_ e: AnyObject) {
154+ let msg = " Obj- C `-hash` ... type `SwiftObjectNSObject.\(type(of: e) ) ` ... Equatable but not Hashable\n"
155+ fputs(msg, stderr)
156+ }
157+
133158// Temporarily disable this test on older OSes until we have time to
134159// look into why it's failing there. rdar://problem/47870743
135160if #available(OSX 10.12, iOS 10.0, *) {
@@ -195,7 +220,7 @@ if #available(OSX 10.12, iOS 10.0, *) {
195220 fputs( " c ##SwiftObjectNSObject. C##\n" , stderr)
196221 fputs ( " d ##SwiftObjectNSObject.D## \n " , stderr)
197222 fputs ( " S ##Swift._SwiftObject## \n " , stderr)
198- fputs ( " Obj-C `-hash` ... type `SwiftObjectNSObject.E` ... Equatable but not Hashable " , stderr )
199- fputs ( " Obj-C `-hash` ... type `SwiftObjectNSObject.E1` ... Equatable but not Hashable " , stderr )
200- fputs ( " Obj-C `-hash` ... type `SwiftObjectNSObject.E2` ... Equatable but not Hashable " , stderr )
223+ fakeEquatableWarning ( E ( i : 1 ) )
224+ fakeEquatableWarning ( E1 ( i : 1 ) )
225+ fakeEquatableWarning ( E2 ( i : 1 ) )
201226}
0 commit comments