// -- Test with resilience enabled // RUN: %empty-directory(%t) // RUN: %target-build-swift -whole-module-optimization -enable-library-evolution -module-name KeyPathMultiModule_b -c -o %t/KeyPathMultiModule_b.o -emit-module-path %t/KeyPathMultiModule_b.swiftmodule -parse-as-library %S/Inputs/KeyPathMultiModule_b.swift // RUN: %target-build-swift -g %t/KeyPathMultiModule_b.o -I %t %s -o %t/a.out.resilient // RUN: %target-codesign %t/a.out.resilient // RUN: %target-run %t/a.out.resilient // -- Test again with resilience disabled, which changes the circumstances under // which we emit and use property descriptors // RUN: %empty-directory(%t) // RUN: %target-build-swift -whole-module-optimization -module-name KeyPathMultiModule_b -c -o %t/KeyPathMultiModule_b.o -emit-module-path %t/KeyPathMultiModule_b.swiftmodule -parse-as-library %S/Inputs/KeyPathMultiModule_b.swift // RUN: %target-build-swift %t/KeyPathMultiModule_b.o -I %t %s -o %t/a.out.fragile // RUN: %target-codesign %t/a.out.fragile // RUN: %target-run %t/a.out.fragile // REQUIRES: executable_test // Freestanding stdlib is built with -experimental-hermetic-seal-at-link which doesn't allow -enable-library-evolution // UNSUPPORTED: freestanding import KeyPathMultiModule_b import StdlibUnittest var keyPathMultiModule = TestSuite("key paths across multiple modules") func expectEqualWithHashes(_ x: T, _ y: T, file: String = #file, line: UInt = #line) { expectEqual(x, y, file: file, line: line) expectEqual(x.hashValue, y.hashValue, file: file, line: line) } class LocalSub: ResilientSub { override var virtual: String { get { return "bas" } set { } } final var storedD: String = "zim" final var storedE: String = "zang" var localSubA: String { get { return "zung" } } var localSubB: String { get { return "zipiti" } } } keyPathMultiModule.test("identity across multiple modules") { // Do this twice, to ensure that fully constant key paths remain stable // after one-time instantiation of the object for _ in 1...2 { expectEqualWithHashes(A_x_keypath(), \A.x) expectEqualWithHashes(A_y_keypath(), \A.y) expectEqualWithHashes(A_z_keypath(), \A.z) expectEqualWithHashes(A_w_keypath(), \A.w) expectEqualWithHashes(A_v_keypath(), \A.v) expectEqualWithHashes(A_immutable_keypath(), \A.immutable) expectEqualWithHashes(A_subscript_withGeneric_keypath(index: 0), \A.[withGeneric: 0]) expectEqualWithHashes(A_subscript_withGeneric_keypath(index: "butt"), \A.[withGeneric: "butt"]) expectEqualWithHashes(A_subscript_withGeneric_butt_keypath(), \A.[withGeneric: "pomeranian's big butt"]) expectEqualWithHashes(A_subscript_withGenericSettable_keypath(index: 0), \A.[withGenericSettable: 0]) expectEqualWithHashes(A_subscript_withGenericSettable_keypath(index: "butt"), \A.[withGenericSettable: "butt"]) expectEqualWithHashes(A_subscript_withGenericPrivateSet_keypath(index: 0), \A.[withGenericPrivateSet: 0]) expectEqualWithHashes(A_subscript_withGenericPrivateSet_keypath(index: "butt"), \A.[withGenericPrivateSet: "butt"]) do { let lifetimeTracker = LifetimeTracked(679) expectEqualWithHashes(A_subscript_withGeneric_keypath(index: lifetimeTracker), \A.[withGeneric: lifetimeTracker]) expectEqualWithHashes(A_subscript_withGenericSettable_keypath(index: lifetimeTracker), \A.[withGenericSettable: lifetimeTracker]) expectEqualWithHashes(A_subscript_withGenericPrivateSet_keypath(index: lifetimeTracker), \A.[withGenericPrivateSet: lifetimeTracker]) expectEqualWithHashes(\A.[withGeneric: lifetimeTracker].appendTest, (\A.[withGeneric: lifetimeTracker]) .appending(path: \LifetimeTracked.appendTest)) expectEqualWithHashes(\A.[withGenericSettable: lifetimeTracker].appendTest, (\A.[withGenericSettable: lifetimeTracker]) .appending(path: \LifetimeTracked.appendTest)) expectEqualWithHashes(\A.[withGenericPrivateSet: lifetimeTracker].appendTest, (\A.[withGenericPrivateSet: lifetimeTracker]) .appending(path: \LifetimeTracked.appendTest)) } expectEqualWithHashes(B_x_keypath(Double.self), \B.x) expectEqualWithHashes(B_Int_x_keypath(), \B.x) expectEqualWithHashes(B_y_keypath(Double.self), \B.y) expectEqualWithHashes(B_Int_y_keypath(), \B.y) expectEqualWithHashes(B_z_keypath(Double.self), \B.z) expectEqualWithHashes(B_Int_z_keypath(), \B.z) expectEqualWithHashes(B_subscript_withInt_keypath(Double.self, index: 1738), \B.[withInt: 1738]) expectEqualWithHashes(B_subscript_withInt_keypath(Double.self, index: 679), \B.[withInt: 679]) expectEqualWithHashes(B_Double_subscript_withInt_0_keypath(), \B.[withInt: 0]) expectEqualWithHashes(B_subscript_withGeneric_keypath(Double.self, index: "buttt"), \B.[withGeneric: "buttt"]) expectEqualWithHashes(B_Double_subscript_withGeneric_butt_keypath(), \B.[withGeneric: "Never is the universal butt type"]) expectEqualWithHashes(A_storedA_keypath(), \A.storedA) expectEqualWithHashes(A_storedA_storedB_keypath(), \A.storedA.storedB) expectEqualWithHashes(A_storedB_keypath(), \A.storedB) expectEqualWithHashes(B_storedA_keypath(Double.self), \B.storedA) expectEqualWithHashes(B_storedB_keypath(Double.self), \B.storedB) expectEqualWithHashes(B_Int_storedA_keypath(), \B.storedA) expectEqualWithHashes(B_Int_storedB_keypath(), \B.storedB) func testInGenericContext(x: X, y: Y, appending: KeyPath) { expectEqualWithHashes(A_subscript_withGeneric_keypath(index: y), \A.[withGeneric: y]) expectEqualWithHashes(A_subscript_withGenericSettable_keypath(index: y), \A.[withGenericSettable: y]) expectEqualWithHashes(A_subscript_withGenericPrivateSet_keypath(index: y), \A.[withGenericPrivateSet: y]) _ = (\A.[withGeneric: y]).appending(path: appending) _ = (\A.[withGenericSettable: y]).appending(path: appending) _ = (\A.[withGenericPrivateSet: y]).appending(path: appending) expectEqualWithHashes(B_x_keypath(X.self), \B.x) expectEqualWithHashes(B_y_keypath(X.self), \B.y) expectEqualWithHashes(B_z_keypath(X.self), \B.z) expectEqualWithHashes(B_subscript_withInt_keypath(X.self, index: 0), \B.[withInt: 0]) expectEqualWithHashes(B_subscript_withGeneric_keypath(X.self, index: y), \B.[withGeneric: y]) expectEqualWithHashes(B_subscript_withGenericSettable_keypath(X.self, index: y), \B.[withGenericSettable: y]) expectEqualWithHashes(B_subscript_withGenericPrivateSet_keypath(X.self, index: y), \B.[withGenericPrivateSet: y]) _ = (\B.[withGeneric: y]).appending(path: appending) _ = (\B.[withGenericSettable: y]).appending(path: appending) _ = (\B.[withGenericPrivateSet: y]).appending(path: appending) expectEqualWithHashes(B_storedA_keypath(X.self), \B.storedA) expectEqualWithHashes(B_storedB_keypath(X.self), \B.storedB) } testInGenericContext(x: 0.0, y: 42, appending: \Int.appendTest) testInGenericContext(x: "pomeranian", y: "big butt", appending: \String.appendTest) testInGenericContext(x: LifetimeTracked(17), y: LifetimeTracked(38), appending: \LifetimeTracked.appendTest) expectEqualWithHashes(ResilientRoot_storedA_keypath(), \ResilientRoot.storedA) expectEqualWithHashes(ResilientRoot_storedB_keypath(), \ResilientRoot.storedB) expectEqualWithHashes(ResilientRoot_storedLet_keypath(), \ResilientRoot.storedLet) expectEqualWithHashes(ResilientRoot_virtual_keypath(), \ResilientRoot.virtual) expectEqualWithHashes(ResilientRoot_virtualRO_keypath(), \ResilientRoot.virtualRO) expectEqualWithHashes(ResilientRoot_final_keypath(), \ResilientRoot.final) expectEqualWithHashes(ResilientSub_storedA_keypath(), \ResilientSub.storedA) expectEqualWithHashes(ResilientSub_storedB_keypath(), \ResilientSub.storedB) expectEqualWithHashes(ResilientSub_storedC_keypath(), \ResilientSub.storedC) expectEqualWithHashes(ResilientSub_virtual_keypath(), \ResilientSub.virtual) expectEqualWithHashes(ResilientSub_virtualRO_keypath(), \ResilientSub.virtualRO) expectEqualWithHashes(ResilientSub_final_keypath(), \ResilientSub.final) expectEqualWithHashes(ResilientSub_sub_keypath(), \ResilientSub.sub) expectEqualWithHashes(ResilientSub_subRO_keypath(), \ResilientSub.subRO) // Ensure that we can instantiate key paths on a local subclass of a // resilient class, and that they have distinct values. let kps: [PartialKeyPath] = [ \LocalSub.storedA, \LocalSub.storedB, \LocalSub.storedC, \LocalSub.storedD, \LocalSub.storedE, \LocalSub.virtual, \LocalSub.sub, \LocalSub.localSubA, \LocalSub.localSubB, ] for i in kps.indices { for j in kps.indices { if i == j { continue } expectNotEqual(kps[i], kps[j]) } } func testInGenericContext2(_: W.Type) { expectEqualWithHashes(ResilientRootProto_root_keypath(W.self), \W.root) expectEqualWithHashes(ResilientSubProto_sub_keypath(W.self), \W.sub) } testInGenericContext2(Int.self) } } runAllTests()