Skip to content

Commit d5e0ca5

Browse files
authored
Merge pull request swiftlang#73360 from hborla/6.0-async-stream-sendable-error
[6.0][Concurrency] Stage in new `Async{Throwing}Stream.init(unfolding:)` errors as warnings.
2 parents 70276e5 + 90ec896 commit d5e0ca5

File tree

5 files changed

+45
-24
lines changed

5 files changed

+45
-24
lines changed

lib/Sema/TypeCheckEffects.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,14 +1183,21 @@ class ApplyClassifier {
11831183
return Classification();
11841184
}
11851185

1186+
bool isContextPreconcurrency() const {
1187+
if (!DC)
1188+
return false;
1189+
1190+
return getActorIsolationOfContext(DC).preconcurrency();
1191+
}
1192+
11861193
/// Whether a missing 'await' error on accessing an async var should be
11871194
/// downgraded to a warning.
11881195
///
11891196
/// Missing 'await' errors are downgraded for synchronous access to isolated
11901197
/// global or static 'let' variables, which was previously accepted in
11911198
/// compiler versions before 5.10, or for declarations marked preconcurrency.
11921199
bool downgradeAsyncAccessToWarning(Decl *decl) {
1193-
if (decl->preconcurrency()) {
1200+
if (decl->preconcurrency() || isContextPreconcurrency()) {
11941201
return true;
11951202
}
11961203

@@ -1339,7 +1346,8 @@ class ApplyClassifier {
13391346

13401347
// Downgrade missing 'await' errors for preconcurrency references.
13411348
result.setDowngradeToWarning(
1342-
result.hasAsync() && fnRef.isPreconcurrency());
1349+
result.hasAsync() &&
1350+
(fnRef.isPreconcurrency() || isContextPreconcurrency()));
13431351

13441352
auto classifyApplyEffect = [&](EffectKind kind) {
13451353
if (!fnType->hasEffect(kind) &&

stdlib/public/Concurrency/AsyncStream.swift

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -330,21 +330,11 @@ public struct AsyncStream<Element> {
330330
/// }
331331
///
332332
///
333-
@_alwaysEmitIntoClient
333+
@_silgen_name("$sScS9unfolding8onCancelScSyxGxSgyYac_yyYbcSgtcfC")
334+
@preconcurrency // Original API had `@Sendable` only on `onCancel`
334335
public init(
335336
unfolding produce: @escaping @Sendable () async -> Element?,
336337
onCancel: (@Sendable () -> Void)? = nil
337-
) {
338-
self.init(
339-
unfolding: produce as () async -> Element?,
340-
onCancel: onCancel
341-
)
342-
}
343-
344-
@usableFromInline
345-
internal init(
346-
unfolding produce: @escaping () async -> Element?,
347-
onCancel: (@Sendable () -> Void)? = nil
348338
) {
349339
let storage: _AsyncStreamCriticalStorage<Optional<() async -> Element?>>
350340
= .create(produce)

stdlib/public/Concurrency/AsyncThrowingStream.swift

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -369,18 +369,9 @@ public struct AsyncThrowingStream<Element, Failure: Error> {
369369
/// print(error)
370370
/// }
371371
///
372-
@_alwaysEmitIntoClient
372+
@preconcurrency
373373
public init(
374374
unfolding produce: @escaping @Sendable () async throws -> Element?
375-
) where Failure == Error {
376-
self.init(
377-
unfolding: produce as () async throws -> Element?
378-
)
379-
}
380-
381-
@usableFromInline
382-
internal init(
383-
unfolding produce: @escaping () async throws -> Element?
384375
) where Failure == Error {
385376
let storage: _AsyncStreamCriticalStorage<Optional<() async throws -> Element?>>
386377
= .create(produce)

test/Concurrency/sendable_checking.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,3 +377,32 @@ final class UseNonisolatedUnsafe: Sendable {
377377
}
378378
}
379379
}
380+
381+
@available(SwiftStdlib 5.1, *)
382+
@preconcurrency
383+
func preconcurrencyContext(_: @escaping @Sendable () -> Void) {}
384+
385+
@available(SwiftStdlib 5.1, *)
386+
@MainActor
387+
struct DowngradeForPreconcurrency {
388+
func capture(completion: @escaping @MainActor () -> Void) {
389+
preconcurrencyContext {
390+
Task {
391+
completion()
392+
// expected-warning@-1 2 {{capture of 'completion' with non-sendable type '@MainActor () -> Void' in a `@Sendable` closure; this is an error in the Swift 6 language mode}}
393+
// expected-note@-2 2 {{a function type must be marked '@Sendable' to conform to 'Sendable'}}
394+
// expected-warning@-3 {{expression is 'async' but is not marked with 'await'; this is an error in the Swift 6 language mode}}
395+
// expected-note@-4 {{calls to parameter 'completion' from outside of its actor context are implicitly asynchronous}}
396+
}
397+
}
398+
}
399+
400+
var x: Int
401+
func createStream() -> AsyncStream<Int> {
402+
AsyncStream<Int> {
403+
self.x
404+
// expected-warning@-1 {{expression is 'async' but is not marked with 'await'; this is an error in the Swift 6 language mode}}
405+
// expected-note@-2 {{property access is 'async'}}
406+
}
407+
}
408+
}

test/api-digester/stability-concurrency-abi.test

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ Func withCheckedThrowingContinuation(function:_:) has parameter 1 type change fr
9191
Func withCheckedContinuation(function:_:) has been renamed to Func withCheckedContinuation(isolation:function:_:)
9292
Func withCheckedContinuation(function:_:) has mangled name changing from '_Concurrency.withCheckedContinuation<A>(function: Swift.String, _: (Swift.CheckedContinuation<A, Swift.Never>) -> ()) async -> A' to '_Concurrency.withCheckedContinuation<A>(isolation: isolated Swift.Optional<Swift.Actor>, function: Swift.String, _: (Swift.CheckedContinuation<A, Swift.Never>) -> ()) async -> A'
9393

94+
// AsyncStream.init(unfolding:onCancel:) uses @_silgen_name to preserve mangling after adding @preconcurrency.
95+
Constructor AsyncStream.init(unfolding:onCancel:) has mangled name changing from 'Swift.AsyncStream.init(unfolding: () async -> Swift.Optional<A>, onCancel: Swift.Optional<@Sendable () -> ()>) -> Swift.AsyncStream<A>' to 'Swift.AsyncStream.init(unfolding: () async -> Swift.Optional<A>, onCancel: Swift.Optional<() -> ()>) -> Swift.AsyncStream<A>'
96+
9497
// SerialExecutor gained `enqueue(_: __owned Job)`, protocol requirements got default implementations
9598
Func SerialExecutor.enqueue(_:) has been added as a protocol requirement
9699

0 commit comments

Comments
 (0)