From d1b3cca1d93524c30743a0a1328fe640a602a4b7 Mon Sep 17 00:00:00 2001 From: Mykola Pokhylets Date: Tue, 18 Feb 2025 13:09:29 +0100 Subject: [PATCH 1/3] Added Hashable conformance to Async(Throwing)Stream.Continuation --- stdlib/public/Concurrency/AsyncStream.swift | 10 ++++++++++ .../Concurrency/AsyncThrowingStream.swift | 10 ++++++++++ test/Concurrency/Runtime/async_stream.swift | 18 ++++++++++++++++++ .../Inputs/macOS/arm64/concurrency/baseline | 12 ++++++++++++ .../macOS/arm64/concurrency/baseline-asserts | 12 ++++++++++++ .../Inputs/macOS/x86_64/concurrency/baseline | 12 ++++++++++++ .../macOS/x86_64/concurrency/baseline-asserts | 12 ++++++++++++ 7 files changed, 86 insertions(+) diff --git a/stdlib/public/Concurrency/AsyncStream.swift b/stdlib/public/Concurrency/AsyncStream.swift index d678246efc7e7..fbc3e96790640 100644 --- a/stdlib/public/Concurrency/AsyncStream.swift +++ b/stdlib/public/Concurrency/AsyncStream.swift @@ -475,6 +475,16 @@ extension AsyncStream: @unchecked Sendable where Element: Sendable { } @available(SwiftStdlib 5.1, *) extension AsyncStream.Continuation.YieldResult: Sendable where Element: Sendable { } +@available(SwiftStdlib 9999, *) +extension AsyncStream.Continuation: Hashable { + public func hash(into hasher: inout Hasher) { + return hasher.combine(ObjectIdentifier(storage)) + } + public static func == (lhs: Self, rhs: Self) -> Bool { + return lhs.storage === rhs.storage + } +} + #else @available(SwiftStdlib 5.1, *) @available(*, unavailable, message: "Unavailable in task-to-thread concurrency model") diff --git a/stdlib/public/Concurrency/AsyncThrowingStream.swift b/stdlib/public/Concurrency/AsyncThrowingStream.swift index 488ff9760f38d..f1d342d351c4f 100644 --- a/stdlib/public/Concurrency/AsyncThrowingStream.swift +++ b/stdlib/public/Concurrency/AsyncThrowingStream.swift @@ -521,6 +521,16 @@ extension AsyncThrowingStream: @unchecked Sendable where Element: Sendable { } @available(SwiftStdlib 5.1, *) extension AsyncThrowingStream.Continuation.YieldResult: Sendable where Element: Sendable { } +@available(SwiftStdlib 9999, *) +extension AsyncThrowingStream.Continuation: Hashable { + public func hash(into hasher: inout Hasher) { + return hasher.combine(ObjectIdentifier(storage)) + } + public static func == (lhs: Self, rhs: Self) -> Bool { + return lhs.storage === rhs.storage + } +} + #else @available(SwiftStdlib 5.1, *) @available(*, unavailable, message: "Unavailable in task-to-thread concurrency model") diff --git a/test/Concurrency/Runtime/async_stream.swift b/test/Concurrency/Runtime/async_stream.swift index 7f54de2165632..553d4d736bbd8 100644 --- a/test/Concurrency/Runtime/async_stream.swift +++ b/test/Concurrency/Runtime/async_stream.swift @@ -435,6 +435,24 @@ class NotSendable {} expectTrue(expectation.fulfilled) } + tests.test("continuation equality") { + let (_, continuation1) = AsyncStream.makeStream() + let (_, continuation2) = AsyncStream.makeStream() + expectTrue(continuation1 == continuation1) + expectTrue(continuation1 != continuation2) + expectTrue(continuation1.hashValue == continuation1.hashValue) + expectTrue(continuation1.hashValue != continuation2.hashValue) + } + + tests.test("throwing continuation equality") { + let (_, continuation1) = AsyncThrowingStream.makeStream() + let (_, continuation2) = AsyncThrowingStream.makeStream() + expectTrue(continuation1 == continuation1) + expectTrue(continuation1 != continuation2) + expectTrue(continuation1.hashValue == continuation1.hashValue) + expectTrue(continuation1.hashValue != continuation2.hashValue) + } + // MARK: - Multiple consumers tests.test("finish behavior with multiple consumers") { diff --git a/test/abi/Inputs/macOS/arm64/concurrency/baseline b/test/abi/Inputs/macOS/arm64/concurrency/baseline index b6ed4a9a6bc9a..8aa55b3098c58 100644 --- a/test/abi/Inputs/macOS/arm64/concurrency/baseline +++ b/test/abi/Inputs/macOS/arm64/concurrency/baseline @@ -164,12 +164,18 @@ _$sScS12ContinuationV15BufferingPolicyO15bufferingOldestyADyx__GSicAFmlFWC _$sScS12ContinuationV15BufferingPolicyO9unboundedyADyx__GAFmlFWC _$sScS12ContinuationV15BufferingPolicyOMa _$sScS12ContinuationV15BufferingPolicyOMn +_$sScS12ContinuationV2eeoiySbAByx_G_ADtFZ +_$sScS12ContinuationV4hash4intoys6HasherVz_tF _$sScS12ContinuationV5yield4withAB11YieldResultOyx__Gs0E0Oyxs5NeverOG_tF _$sScS12ContinuationV5yieldAB11YieldResultOyyt__GyytRszlF _$sScS12ContinuationV5yieldyAB11YieldResultOyx__GxnF _$sScS12ContinuationV6finishyyF +_$sScS12ContinuationV9hashValueSivg +_$sScS12ContinuationV9hashValueSivpMV _$sScS12ContinuationVMa _$sScS12ContinuationVMn +_$sScS12ContinuationVyx_GSHsMc +_$sScS12ContinuationVyx_GSQsMc _$sScS17makeAsyncIteratorScS0C0Vyx_GyF _$sScS8IteratorV4nextxSgyYaF _$sScS8IteratorV4nextxSgyYaFTu @@ -359,12 +365,18 @@ _$sScs12ContinuationV15BufferingPolicyO15bufferingOldestyADyxq___GSicAFms5ErrorR _$sScs12ContinuationV15BufferingPolicyO9unboundedyADyxq___GAFms5ErrorR_r0_lFWC _$sScs12ContinuationV15BufferingPolicyOMa _$sScs12ContinuationV15BufferingPolicyOMn +_$sScs12ContinuationV2eeoiySbAByxq__G_ADtFZ +_$sScs12ContinuationV4hash4intoys6HasherVz_tF _$sScs12ContinuationV5yield4withAB11YieldResultOyxs5Error_p__Gs0E0OyxsAG_pG_tsAG_pRs_rlF _$sScs12ContinuationV5yieldAB11YieldResultOyytq___GyytRszrlF _$sScs12ContinuationV5yieldyAB11YieldResultOyxq___GxnF _$sScs12ContinuationV6finish8throwingyq_Sgn_tF +_$sScs12ContinuationV9hashValueSivg +_$sScs12ContinuationV9hashValueSivpMV _$sScs12ContinuationVMa _$sScs12ContinuationVMn +_$sScs12ContinuationVyxq__GSHsMc +_$sScs12ContinuationVyxq__GSQsMc _$sScs17makeAsyncIteratorScs0C0Vyxq__GyF _$sScs8IteratorV4nextxSgyYaKF _$sScs8IteratorV4nextxSgyYaKFTu diff --git a/test/abi/Inputs/macOS/arm64/concurrency/baseline-asserts b/test/abi/Inputs/macOS/arm64/concurrency/baseline-asserts index b6ed4a9a6bc9a..8aa55b3098c58 100644 --- a/test/abi/Inputs/macOS/arm64/concurrency/baseline-asserts +++ b/test/abi/Inputs/macOS/arm64/concurrency/baseline-asserts @@ -164,12 +164,18 @@ _$sScS12ContinuationV15BufferingPolicyO15bufferingOldestyADyx__GSicAFmlFWC _$sScS12ContinuationV15BufferingPolicyO9unboundedyADyx__GAFmlFWC _$sScS12ContinuationV15BufferingPolicyOMa _$sScS12ContinuationV15BufferingPolicyOMn +_$sScS12ContinuationV2eeoiySbAByx_G_ADtFZ +_$sScS12ContinuationV4hash4intoys6HasherVz_tF _$sScS12ContinuationV5yield4withAB11YieldResultOyx__Gs0E0Oyxs5NeverOG_tF _$sScS12ContinuationV5yieldAB11YieldResultOyyt__GyytRszlF _$sScS12ContinuationV5yieldyAB11YieldResultOyx__GxnF _$sScS12ContinuationV6finishyyF +_$sScS12ContinuationV9hashValueSivg +_$sScS12ContinuationV9hashValueSivpMV _$sScS12ContinuationVMa _$sScS12ContinuationVMn +_$sScS12ContinuationVyx_GSHsMc +_$sScS12ContinuationVyx_GSQsMc _$sScS17makeAsyncIteratorScS0C0Vyx_GyF _$sScS8IteratorV4nextxSgyYaF _$sScS8IteratorV4nextxSgyYaFTu @@ -359,12 +365,18 @@ _$sScs12ContinuationV15BufferingPolicyO15bufferingOldestyADyxq___GSicAFms5ErrorR _$sScs12ContinuationV15BufferingPolicyO9unboundedyADyxq___GAFms5ErrorR_r0_lFWC _$sScs12ContinuationV15BufferingPolicyOMa _$sScs12ContinuationV15BufferingPolicyOMn +_$sScs12ContinuationV2eeoiySbAByxq__G_ADtFZ +_$sScs12ContinuationV4hash4intoys6HasherVz_tF _$sScs12ContinuationV5yield4withAB11YieldResultOyxs5Error_p__Gs0E0OyxsAG_pG_tsAG_pRs_rlF _$sScs12ContinuationV5yieldAB11YieldResultOyytq___GyytRszrlF _$sScs12ContinuationV5yieldyAB11YieldResultOyxq___GxnF _$sScs12ContinuationV6finish8throwingyq_Sgn_tF +_$sScs12ContinuationV9hashValueSivg +_$sScs12ContinuationV9hashValueSivpMV _$sScs12ContinuationVMa _$sScs12ContinuationVMn +_$sScs12ContinuationVyxq__GSHsMc +_$sScs12ContinuationVyxq__GSQsMc _$sScs17makeAsyncIteratorScs0C0Vyxq__GyF _$sScs8IteratorV4nextxSgyYaKF _$sScs8IteratorV4nextxSgyYaKFTu diff --git a/test/abi/Inputs/macOS/x86_64/concurrency/baseline b/test/abi/Inputs/macOS/x86_64/concurrency/baseline index b6ed4a9a6bc9a..8aa55b3098c58 100644 --- a/test/abi/Inputs/macOS/x86_64/concurrency/baseline +++ b/test/abi/Inputs/macOS/x86_64/concurrency/baseline @@ -164,12 +164,18 @@ _$sScS12ContinuationV15BufferingPolicyO15bufferingOldestyADyx__GSicAFmlFWC _$sScS12ContinuationV15BufferingPolicyO9unboundedyADyx__GAFmlFWC _$sScS12ContinuationV15BufferingPolicyOMa _$sScS12ContinuationV15BufferingPolicyOMn +_$sScS12ContinuationV2eeoiySbAByx_G_ADtFZ +_$sScS12ContinuationV4hash4intoys6HasherVz_tF _$sScS12ContinuationV5yield4withAB11YieldResultOyx__Gs0E0Oyxs5NeverOG_tF _$sScS12ContinuationV5yieldAB11YieldResultOyyt__GyytRszlF _$sScS12ContinuationV5yieldyAB11YieldResultOyx__GxnF _$sScS12ContinuationV6finishyyF +_$sScS12ContinuationV9hashValueSivg +_$sScS12ContinuationV9hashValueSivpMV _$sScS12ContinuationVMa _$sScS12ContinuationVMn +_$sScS12ContinuationVyx_GSHsMc +_$sScS12ContinuationVyx_GSQsMc _$sScS17makeAsyncIteratorScS0C0Vyx_GyF _$sScS8IteratorV4nextxSgyYaF _$sScS8IteratorV4nextxSgyYaFTu @@ -359,12 +365,18 @@ _$sScs12ContinuationV15BufferingPolicyO15bufferingOldestyADyxq___GSicAFms5ErrorR _$sScs12ContinuationV15BufferingPolicyO9unboundedyADyxq___GAFms5ErrorR_r0_lFWC _$sScs12ContinuationV15BufferingPolicyOMa _$sScs12ContinuationV15BufferingPolicyOMn +_$sScs12ContinuationV2eeoiySbAByxq__G_ADtFZ +_$sScs12ContinuationV4hash4intoys6HasherVz_tF _$sScs12ContinuationV5yield4withAB11YieldResultOyxs5Error_p__Gs0E0OyxsAG_pG_tsAG_pRs_rlF _$sScs12ContinuationV5yieldAB11YieldResultOyytq___GyytRszrlF _$sScs12ContinuationV5yieldyAB11YieldResultOyxq___GxnF _$sScs12ContinuationV6finish8throwingyq_Sgn_tF +_$sScs12ContinuationV9hashValueSivg +_$sScs12ContinuationV9hashValueSivpMV _$sScs12ContinuationVMa _$sScs12ContinuationVMn +_$sScs12ContinuationVyxq__GSHsMc +_$sScs12ContinuationVyxq__GSQsMc _$sScs17makeAsyncIteratorScs0C0Vyxq__GyF _$sScs8IteratorV4nextxSgyYaKF _$sScs8IteratorV4nextxSgyYaKFTu diff --git a/test/abi/Inputs/macOS/x86_64/concurrency/baseline-asserts b/test/abi/Inputs/macOS/x86_64/concurrency/baseline-asserts index b6ed4a9a6bc9a..8aa55b3098c58 100644 --- a/test/abi/Inputs/macOS/x86_64/concurrency/baseline-asserts +++ b/test/abi/Inputs/macOS/x86_64/concurrency/baseline-asserts @@ -164,12 +164,18 @@ _$sScS12ContinuationV15BufferingPolicyO15bufferingOldestyADyx__GSicAFmlFWC _$sScS12ContinuationV15BufferingPolicyO9unboundedyADyx__GAFmlFWC _$sScS12ContinuationV15BufferingPolicyOMa _$sScS12ContinuationV15BufferingPolicyOMn +_$sScS12ContinuationV2eeoiySbAByx_G_ADtFZ +_$sScS12ContinuationV4hash4intoys6HasherVz_tF _$sScS12ContinuationV5yield4withAB11YieldResultOyx__Gs0E0Oyxs5NeverOG_tF _$sScS12ContinuationV5yieldAB11YieldResultOyyt__GyytRszlF _$sScS12ContinuationV5yieldyAB11YieldResultOyx__GxnF _$sScS12ContinuationV6finishyyF +_$sScS12ContinuationV9hashValueSivg +_$sScS12ContinuationV9hashValueSivpMV _$sScS12ContinuationVMa _$sScS12ContinuationVMn +_$sScS12ContinuationVyx_GSHsMc +_$sScS12ContinuationVyx_GSQsMc _$sScS17makeAsyncIteratorScS0C0Vyx_GyF _$sScS8IteratorV4nextxSgyYaF _$sScS8IteratorV4nextxSgyYaFTu @@ -359,12 +365,18 @@ _$sScs12ContinuationV15BufferingPolicyO15bufferingOldestyADyxq___GSicAFms5ErrorR _$sScs12ContinuationV15BufferingPolicyO9unboundedyADyxq___GAFms5ErrorR_r0_lFWC _$sScs12ContinuationV15BufferingPolicyOMa _$sScs12ContinuationV15BufferingPolicyOMn +_$sScs12ContinuationV2eeoiySbAByxq__G_ADtFZ +_$sScs12ContinuationV4hash4intoys6HasherVz_tF _$sScs12ContinuationV5yield4withAB11YieldResultOyxs5Error_p__Gs0E0OyxsAG_pG_tsAG_pRs_rlF _$sScs12ContinuationV5yieldAB11YieldResultOyytq___GyytRszrlF _$sScs12ContinuationV5yieldyAB11YieldResultOyxq___GxnF _$sScs12ContinuationV6finish8throwingyq_Sgn_tF +_$sScs12ContinuationV9hashValueSivg +_$sScs12ContinuationV9hashValueSivpMV _$sScs12ContinuationVMa _$sScs12ContinuationVMn +_$sScs12ContinuationVyxq__GSHsMc +_$sScs12ContinuationVyxq__GSQsMc _$sScs17makeAsyncIteratorScs0C0Vyxq__GyF _$sScs8IteratorV4nextxSgyYaKF _$sScs8IteratorV4nextxSgyYaKFTu From ee2e86c7fc01431babc14737741dc1d51aa81c07 Mon Sep 17 00:00:00 2001 From: Mykola Pokhylets Date: Sun, 13 Apr 2025 13:23:56 +0200 Subject: [PATCH 2/3] Added explicit availability attribute for each protocol requirement To fix failing test/api-digester/stability-concurrency-abi.test --- stdlib/public/Concurrency/AsyncStream.swift | 6 ++++++ stdlib/public/Concurrency/AsyncThrowingStream.swift | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/stdlib/public/Concurrency/AsyncStream.swift b/stdlib/public/Concurrency/AsyncStream.swift index fbc3e96790640..a47946723d723 100644 --- a/stdlib/public/Concurrency/AsyncStream.swift +++ b/stdlib/public/Concurrency/AsyncStream.swift @@ -477,9 +477,15 @@ extension AsyncStream.Continuation.YieldResult: Sendable where Element: Sendable @available(SwiftStdlib 9999, *) extension AsyncStream.Continuation: Hashable { + @available(SwiftStdlib 9999, *) public func hash(into hasher: inout Hasher) { return hasher.combine(ObjectIdentifier(storage)) } + @available(SwiftStdlib 9999, *) + public var hashValue: Int { + return _hashValue(for: self) + } + @available(SwiftStdlib 9999, *) public static func == (lhs: Self, rhs: Self) -> Bool { return lhs.storage === rhs.storage } diff --git a/stdlib/public/Concurrency/AsyncThrowingStream.swift b/stdlib/public/Concurrency/AsyncThrowingStream.swift index f1d342d351c4f..b4d136cb5e502 100644 --- a/stdlib/public/Concurrency/AsyncThrowingStream.swift +++ b/stdlib/public/Concurrency/AsyncThrowingStream.swift @@ -523,9 +523,15 @@ extension AsyncThrowingStream.Continuation.YieldResult: Sendable where Element: @available(SwiftStdlib 9999, *) extension AsyncThrowingStream.Continuation: Hashable { + @available(SwiftStdlib 9999, *) public func hash(into hasher: inout Hasher) { return hasher.combine(ObjectIdentifier(storage)) } + @available(SwiftStdlib 9999, *) + public var hashValue: Int { + return _hashValue(for: self) + } + @available(SwiftStdlib 9999, *) public static func == (lhs: Self, rhs: Self) -> Bool { return lhs.storage === rhs.storage } From 3fdcb49fb2078d70f1693a8e03b2ca35ef444650 Mon Sep 17 00:00:00 2001 From: Mykola Pokhylets Date: Mon, 14 Apr 2025 16:58:43 +0200 Subject: [PATCH 3/3] Use concrete SwiftStdlib version --- stdlib/public/Concurrency/AsyncStream.swift | 8 ++++---- stdlib/public/Concurrency/AsyncThrowingStream.swift | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/stdlib/public/Concurrency/AsyncStream.swift b/stdlib/public/Concurrency/AsyncStream.swift index a47946723d723..ca6eb979695c1 100644 --- a/stdlib/public/Concurrency/AsyncStream.swift +++ b/stdlib/public/Concurrency/AsyncStream.swift @@ -475,17 +475,17 @@ extension AsyncStream: @unchecked Sendable where Element: Sendable { } @available(SwiftStdlib 5.1, *) extension AsyncStream.Continuation.YieldResult: Sendable where Element: Sendable { } -@available(SwiftStdlib 9999, *) +@available(SwiftStdlib 6.2, *) extension AsyncStream.Continuation: Hashable { - @available(SwiftStdlib 9999, *) + @available(SwiftStdlib 6.2, *) public func hash(into hasher: inout Hasher) { return hasher.combine(ObjectIdentifier(storage)) } - @available(SwiftStdlib 9999, *) + @available(SwiftStdlib 6.2, *) public var hashValue: Int { return _hashValue(for: self) } - @available(SwiftStdlib 9999, *) + @available(SwiftStdlib 6.2, *) public static func == (lhs: Self, rhs: Self) -> Bool { return lhs.storage === rhs.storage } diff --git a/stdlib/public/Concurrency/AsyncThrowingStream.swift b/stdlib/public/Concurrency/AsyncThrowingStream.swift index b4d136cb5e502..3cdc5d0077bf0 100644 --- a/stdlib/public/Concurrency/AsyncThrowingStream.swift +++ b/stdlib/public/Concurrency/AsyncThrowingStream.swift @@ -521,17 +521,17 @@ extension AsyncThrowingStream: @unchecked Sendable where Element: Sendable { } @available(SwiftStdlib 5.1, *) extension AsyncThrowingStream.Continuation.YieldResult: Sendable where Element: Sendable { } -@available(SwiftStdlib 9999, *) +@available(SwiftStdlib 6.2, *) extension AsyncThrowingStream.Continuation: Hashable { - @available(SwiftStdlib 9999, *) + @available(SwiftStdlib 6.2, *) public func hash(into hasher: inout Hasher) { return hasher.combine(ObjectIdentifier(storage)) } - @available(SwiftStdlib 9999, *) + @available(SwiftStdlib 6.2, *) public var hashValue: Int { return _hashValue(for: self) } - @available(SwiftStdlib 9999, *) + @available(SwiftStdlib 6.2, *) public static func == (lhs: Self, rhs: Self) -> Bool { return lhs.storage === rhs.storage }