Skip to content

Commit 3e10622

Browse files
authored
Merge pull request #72673 from DougGregor/async-sequence-fixes
AsyncSequence conformance fixes
2 parents f5c3775 + fb584f8 commit 3e10622

File tree

5 files changed

+69
-8
lines changed

5 files changed

+69
-8
lines changed

lib/Sema/AssociatedTypeInference.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2426,13 +2426,17 @@ AssociatedTypeInference::computeFailureTypeWitness(
24262426
for (const auto &witness : valueWitnesses) {
24272427
if (isAsyncIteratorProtocolNext(witness.first)) {
24282428
if (auto witnessFunc = dyn_cast<AbstractFunctionDecl>(witness.second)) {
2429+
auto thrownError = witnessFunc->getEffectiveThrownErrorType();
2430+
24292431
// If it doesn't throw, Failure == Never.
2430-
if (!witnessFunc->hasThrows())
2432+
if (!thrownError)
24312433
return AbstractTypeWitness(assocType, ctx.getNeverType());
24322434

2433-
// If it isn't 'rethrows', Failure == any Error.
2434-
if (!witnessFunc->getAttrs().hasAttribute<RethrowsAttr>())
2435-
return AbstractTypeWitness(assocType, ctx.getErrorExistentialType());
2435+
// If it isn't 'rethrows', use the thrown error type;.
2436+
if (!witnessFunc->getAttrs().hasAttribute<RethrowsAttr>()) {
2437+
return AbstractTypeWitness(assocType,
2438+
dc->mapTypeIntoContext(*thrownError));
2439+
}
24362440

24372441
for (auto req : witnessFunc->getGenericSignature().getRequirements()) {
24382442
if (req.getKind() == RequirementKind::Conformance) {

stdlib/public/Concurrency/AsyncIteratorProtocol.swift

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,9 @@ public protocol AsyncIteratorProtocol<Element, Failure> {
111111

112112
@available(SwiftStdlib 5.1, *)
113113
extension AsyncIteratorProtocol {
114-
/// Default implementation of `next()` in terms of `next()`, which is
115-
/// required to maintain backward compatibility with existing async iterators.
114+
/// Default implementation of `next(isolation:)` in terms of `next()`, which
115+
/// is required to maintain backward compatibility with existing async
116+
/// iterators.
116117
@available(SwiftStdlib 6.0, *)
117118
@inlinable
118119
public mutating func next(isolation actor: isolated (any Actor)?) async throws(Failure) -> Element? {
@@ -123,3 +124,15 @@ extension AsyncIteratorProtocol {
123124
}
124125
}
125126
}
127+
128+
@available(SwiftStdlib 5.1, *)
129+
extension AsyncIteratorProtocol {
130+
/// Default implementation of `next()` in terms of `next(isolation:)`, which
131+
/// is required to maintain backward compatibility with existing async
132+
/// iterators.
133+
@available(SwiftStdlib 6.0, *)
134+
@inlinable
135+
public mutating func next() async throws(Failure) -> Element? {
136+
return try await next(isolation: nil)
137+
}
138+
}

test/Concurrency/async_sequence_rethrows.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,37 @@ extension InheritsAsyncSequence {
5151
try await self.reduce(into: [Element]()) { $0.append($1) }
5252
}
5353
}
54+
55+
// Ensure that we can get the thrown error type from next().
56+
struct Data { }
57+
58+
struct ErrorSequence<Element, Failure: Error>: AsyncSequence, AsyncIteratorProtocol {
59+
let throwError : Failure
60+
61+
func makeAsyncIterator() -> ErrorSequence<Element, Failure> {
62+
self
63+
}
64+
65+
mutating func next() async throws(Failure) -> Element? {
66+
throw throwError
67+
}
68+
}
69+
70+
enum MyError: Error {
71+
case foo
72+
}
73+
74+
75+
func getASequence() -> any AsyncSequence<Data, MyError> {
76+
return ErrorSequence<Data, _>(throwError: MyError.foo) // ERROR: Cannot convert return expression of type 'any Error' to return type 'MyError'
77+
}
78+
79+
// Test the default implementation of next() in terms of next(isolation:).
80+
struct AsyncIteratorWithOnlyNextIsolation: AsyncIteratorProtocol {
81+
public mutating func next(isolation: (any Actor)?) throws(MyError) -> Int? { 0 }
82+
}
83+
84+
// Test the default implementation of next(isolation:) in terms of next().
85+
struct AsyncIteratorWithOnlyNext: AsyncIteratorProtocol {
86+
public mutating func next() throws(MyError) -> Int? { 0 }
87+
}

test/abi/macOS/arm64/concurrency.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,11 @@ Added: _$ss26withTaskExecutorPreference_9isolation9operationxSch_pSg_ScA_pSgYixy
276276
// async function pointer to Swift.withTaskExecutorPreference<A, B where B: Swift.Error>(_: Swift.TaskExecutor?, isolation: isolated Swift.Actor?, operation: () async throws(B) -> A) async throws(B) -> A
277277
Added: _$ss26withTaskExecutorPreference_9isolation9operationxSch_pSg_ScA_pSgYixyYaq_YKXEtYaq_YKs5ErrorR_r0_lFTu
278278

279+
280+
// next() default implementation in terms of next(isolation:)
281+
Added: _$sScIsE4next7ElementQzSgyYa7FailureQzYKF
282+
Added: _$sScIsE4next7ElementQzSgyYa7FailureQzYKFTu
283+
279284
// === SerialExecutor.checkIsolated()
280285
Added: _swift_task_checkIsolated
281286
Added: _swift_task_checkIsolated_hook
@@ -284,4 +289,4 @@ Added: _$sScfsE13checkIsolatedyyF
284289
// dispatch thunk of Swift.SerialExecutor.checkIsolated() -> ()
285290
Added: _$sScf13checkIsolatedyyFTj
286291
// method descriptor for Swift.SerialExecutor.checkIsolated() -> ()
287-
Added: _$sScf13checkIsolatedyyFTq
292+
Added: _$sScf13checkIsolatedyyFTq

test/abi/macOS/x86_64/concurrency.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,11 @@ Added: _$ss26withTaskExecutorPreference_9isolation9operationxSch_pSg_ScA_pSgYixy
276276
// async function pointer to Swift.withTaskExecutorPreference<A, B where B: Swift.Error>(_: Swift.TaskExecutor?, isolation: isolated Swift.Actor?, operation: () async throws(B) -> A) async throws(B) -> A
277277
Added: _$ss26withTaskExecutorPreference_9isolation9operationxSch_pSg_ScA_pSgYixyYaq_YKXEtYaq_YKs5ErrorR_r0_lFTu
278278

279+
280+
// next() default implementation in terms of next(isolation:)
281+
Added: _$sScIsE4next7ElementQzSgyYa7FailureQzYKF
282+
Added: _$sScIsE4next7ElementQzSgyYa7FailureQzYKFTu
283+
279284
// === SerialExecutor.checkIsolated()
280285
Added: _swift_task_checkIsolated
281286
Added: _swift_task_checkIsolated_hook
@@ -284,4 +289,4 @@ Added: _$sScfsE13checkIsolatedyyF
284289
// dispatch thunk of Swift.SerialExecutor.checkIsolated() -> ()
285290
Added: _$sScf13checkIsolatedyyFTj
286291
// method descriptor for Swift.SerialExecutor.checkIsolated() -> ()
287-
Added: _$sScf13checkIsolatedyyFTq
292+
Added: _$sScf13checkIsolatedyyFTq

0 commit comments

Comments
 (0)