Files
swift-mirror/test/Concurrency/sendable_checking.swift
Michael Gottesman 97c3bf3b99 [rbi] Remove code that caused us to misidentify certain captured parameters as sending.
Specifically, this code was added because otherwise we would in swift 5 +
strict-concurrency mode emit two warnings, one at the AST level and one at the
SIL level. Once we are in swift-6 mode, this does not happen since we stop
compiling at the AST level since we will emit the AST level diagnostic as an
error.

To do this, we tried to pattern match what the AST was erroring upon and treat
the parameter as disconnected instead of being isolated. Sadly, this resulted in
us treating certain closure cases incorrectly and not emit a diagnostic
(creating a concurrency hole).

Given that this behavior results in a bad diagnostic only to avoid emitting two
diagnostics in a mode which is not going to last forever... it really doesn't
make sense to keep it. We really need a better way to handle these sorts of
issues. Perhaps a special semantic parameter put on the function that squelches
certain errors. But that is something for another day. The specific case it
messes up is:

```
class NonSendable {
    func action() async {}
}

@MainActor
final class Foo {
    let value = NonSendable()

    func perform() {
        Task { [value] in
            await value.action() // Should emit error but do not.
        }
    }
}
```

In this case, we think that value is sending... when it isnt and we should emit
an error.

rdar://146378329
2025-10-14 14:00:29 -07:00

582 lines
24 KiB
Swift

// RUN: %target-swift-frontend -target %target-swift-5.0-abi-triple -verify -verify-ignore-unrelated -verify-additional-prefix targeted-and-ni- -strict-concurrency=targeted -verify-additional-prefix targeted- -emit-sil -o /dev/null %s
// RUN: %target-swift-frontend -target %target-swift-5.0-abi-triple -verify -verify-ignore-unrelated -strict-concurrency=complete -verify-additional-prefix tns-ni- -verify-additional-prefix tns- -emit-sil -o /dev/null %s -swift-version 5 -verify-additional-prefix targeted-and-ni-
// RUN: %target-swift-frontend -target %target-swift-5.0-abi-triple -verify -verify-ignore-unrelated -strict-concurrency=complete -verify-additional-prefix tns-ni-ns- -verify-additional-prefix tns- -emit-sil -o /dev/null %s -enable-upcoming-feature NonisolatedNonsendingByDefault -swift-version 5 -DNONISOLATEDNONSENDING
// REQUIRES: concurrency
// REQUIRES: asserts
// REQUIRES: OS=macosx
// REQUIRES: swift_feature_NonisolatedNonsendingByDefault
@available(SwiftStdlib 5.1, *)
struct NS1 { }
@available(SwiftStdlib 5.1, *)
@available(*, unavailable)
extension NS1: Sendable { }
// expected-note@-1 4{{conformance of 'NS1' to 'Sendable' has been explicitly marked unavailable here}}
@available(SwiftStdlib 5.1, *)
struct NS2 { // expected-note {{consider making struct 'NS2' conform to the 'Sendable' protocol}}
// expected-tns-note @-1 {{consider making struct 'NS2' conform to the 'Sendable' protocol}}
var ns1: NS1
}
@available(SwiftStdlib 5.1, *)
struct NS3 { }
@available(SwiftStdlib 5.3, *)
extension NS3: Sendable { }
@available(SwiftStdlib 5.1, *)
class NS4 { } // expected-note {{class 'NS4' does not conform to the 'Sendable' protocol}}
// expected-tns-note @-1 {{class 'NS4' does not conform to the 'Sendable' protocol}}
@available(SwiftStdlib 5.1, *)
func acceptCV<T: Sendable>(_: T) { }
func acceptSendableFn(_: @Sendable @escaping () -> Void) { }
@available(SwiftStdlib 5.1, *)
func testCV(
ns1: NS1, ns1array: [NS1], ns2: NS2, ns3: NS3, ns4: NS4,
fn: @escaping () -> Void
// expected-note @-1 {{parameter 'fn' is implicitly non-Sendable}}
) {
acceptCV(ns1) // expected-warning {{conformance of 'NS1' to 'Sendable' is unavailable}}
acceptCV(ns1array) // expected-warning {{conformance of 'NS1' to 'Sendable' is unavailable}}
acceptCV(ns2) // expected-tns-warning {{type 'NS2' does not conform to the 'Sendable' protocol}}
acceptCV(ns3) // expected-warning {{conformance of 'NS3' to 'Sendable' is only available in macOS 11.0 or newer}}
// expected-note @-1 {{add 'if #available' version check}}
acceptCV(ns4) // expected-tns-warning {{type 'NS4' does not conform to the 'Sendable' protocol}}
acceptCV(fn) // expected-tns-warning {{type '() -> Void' does not conform to the 'Sendable' protocol}}
// expected-tns-note @-1 {{a function type must be marked '@Sendable' to conform to 'Sendable'}}
acceptSendableFn(fn) // expected-warning{{passing non-Sendable parameter 'fn' to function expecting a '@Sendable' closure}}
}
@available(SwiftStdlib 5.1, *)
func testCV(
ns1: NS1, ns1array: [NS1], ns2: NS2, ns3: NS3, ns4: NS4,
fn: @escaping () -> Void
// expected-note@-1{{parameter 'fn' is implicitly non-Sendable}}
) async {
acceptCV(ns1) // expected-warning{{conformance of 'NS1' to 'Sendable' is unavailable}}
acceptCV(ns1array) // expected-warning{{conformance of 'NS1' to 'Sendable' is unavailable}}
acceptCV(ns2) // expected-warning{{type 'NS2' does not conform to the 'Sendable' protocol}}
acceptCV(ns3) // expected-warning{{conformance of 'NS3' to 'Sendable' is only available in macOS 11.0 or newer}}
// expected-note@-1{{add 'if #available' version check}}
acceptCV(ns4) // expected-warning{{type 'NS4' does not conform to the 'Sendable' protocol}}
acceptCV(fn) // expected-warning{{type '() -> Void' does not conform to the 'Sendable' protocol}}
// expected-note@-1{{a function type must be marked '@Sendable' to conform to 'Sendable'}}
acceptSendableFn(fn) // expected-warning{{passing non-Sendable parameter 'fn' to function expecting a '@Sendable' closure}}
}
// rdar://83942484 - spurious Sendable diagnostics
@available(SwiftStdlib 5.1, *)
public protocol MyProto {
func foo<F>(aFoo: F) async where F: Sendable
}
@available(SwiftStdlib 5.1, *)
func nonisolatedAsyncFunc1(_: NS1) async { }
@available(SwiftStdlib 5.1, *)
func nonisolatedAsyncFunc2() async -> NS1 { NS1() }
@available(SwiftStdlib 5.1, *)
public actor MyActor: MyProto {
public func foo<F>(aFoo: F) async where F: Sendable { }
public func bar<B>(aBar: B) async where B: Sendable { }
func g(ns1: NS1) async {
await nonisolatedAsyncFunc1(ns1)
// expected-tns-ni-warning @-1 {{sending 'ns1' risks causing data races}}
// expected-tns-ni-note @-2 {{sending 'self'-isolated 'ns1' to nonisolated global function 'nonisolatedAsyncFunc1' risks causing data races between nonisolated and 'self'-isolated uses}}
_ = await nonisolatedAsyncFunc2()
}
}
// Make sure the generic signature doesn't minimize away Sendable requirements.
class NSClass { }
@available(*, unavailable)
extension NSClass: @unchecked Sendable {} // expected-note {{conformance of 'NSClass' to 'Sendable' has been explicitly marked unavailable here}}
struct WrapClass<T: NSClass> {
var t: T
}
extension WrapClass: Sendable where T: Sendable { }
// expected-warning@+2 {{conformance of 'SendableSubclass' to protocol 'Sendable' is already unavailable}}
// expected-note@+1 {{'SendableSubclass' inherits conformance to protocol 'Sendable' from superclass here}}
class SendableSubclass: NSClass, @unchecked Sendable { }
@available(SwiftStdlib 5.1, *)
func testSubclassing(obj: SendableSubclass) async {
acceptCV(obj) // expected-warning {{conformance of 'NSClass' to 'Sendable' is unavailable; this is an error in the Swift 6 language mode}}
}
@available(SwiftStdlib 5.1, *)
protocol P {
func foo (x : @Sendable () -> ()) async -> ()
func bar(x : () -> ()) async -> ()
// expected-note@-1 {{a function type must be marked '@Sendable' to conform to 'Sendable'}}
func foo2<T : Sendable>(x : T) async -> ()
func bar2<T>(x : T) async -> ()
// expected-note@-1 {{consider making generic parameter 'T' conform to the 'Sendable' protocol}} {{14-14=: Sendable}}
func bar3<T: Equatable>(x : T) async -> ()
// expected-note@-1 {{consider making generic parameter 'T' conform to the 'Sendable' protocol}} {{25-25= & Sendable}}
}
// Make sure conformance to protocols checks sendability of
// requirement parameters not witness parameters
@available(SwiftStdlib 5.1, *)
actor A : P {
func foo(x : () -> ()) -> () {}
func bar(x : () -> ()) -> () {}
// expected-warning@-1 {{non-Sendable parameter type '() -> ()' cannot be sent from caller of protocol requirement 'bar(x:)' into actor-isolated implementation}}
func foo2<T>(x : T) -> () {}
func bar2<T>(x : T) -> () {}
// expected-warning@-1 {{non-Sendable parameter type 'T' cannot be sent from caller of protocol requirement 'bar2(x:)' into actor-isolated implementation}}
func bar3<T: Equatable>(x : T) -> () {}
// expected-warning@-1 {{non-Sendable parameter type 'T' cannot be sent from caller of protocol requirement 'bar3(x:)' into actor-isolated implementation}}
}
@available(SwiftStdlib 5.1, *)
class Super {
@MainActor
func foo (x : @Sendable () -> ()) async {}
@MainActor
func bar (x : () -> ()) async {}
// expected-targeted-and-ni-note @-1 {{a function type must be marked '@Sendable' to conform to 'Sendable'}}
@MainActor
func foo2<T : Sendable>(x: T) async {}
@MainActor
func bar2<T>(x: T) async {}
// expected-targeted-and-ni-note @-1 {{consider making generic parameter 'T' conform to the 'Sendable' protocol}} {{14-14=: Sendable}}
@MainActor
func bar3<T: Equatable>(x: T) async {}
// expected-targeted-and-ni-note @-1 {{consider making generic parameter 'T' conform to the 'Sendable' protocol}} {{25-25= & Sendable}}
}
// Make sure isolation crossing overrides check sendability
// of superclass parameters not subclass parameters
@available(SwiftStdlib 5.1, *)
class Sub : Super {
override nonisolated func foo(x : () -> ()) async {}
// We do not emit an error for the override with
// NonisolatedNonsendingByDefault since the vtable thunk passes in MainActor
// so we are still in the main actor even though we are nonisolated. In the
// case of that being disabled, we cannot do this since we will hop off the
// actor.
override nonisolated func bar(x : () -> ()) async {}
// expected-targeted-and-ni-warning@-1 {{non-Sendable parameter type '() -> ()' cannot be sent from caller of superclass instance method 'bar(x:)' into nonisolated override}}
override nonisolated func foo2<T>(x: T) async {}
// See comment above about why nonisolated overrides of superclass are allowed
// when is enabled NonisolatedNonsendingByDefault.
override nonisolated func bar2<T>(x: T) async {}
// expected-targeted-and-ni-warning @-1 {{non-Sendable parameter type 'T' cannot be sent from caller of superclass instance method 'bar2(x:)' into nonisolated override}}
// See comment above about why nonisolated overrides of superclass are allowed
// when is enabled NonisolatedNonsendingByDefault.
override nonisolated func bar3<T>(x: T) async {}
// expected-targeted-and-ni-warning @-1 {{non-Sendable parameter type 'T' cannot be sent from caller of superclass instance method 'bar3(x:)' into nonisolated override}}
}
@available(SwiftStdlib 5.1, *)
class SuperWSafeSubscript {
@MainActor
subscript<T : Sendable>(x : T) -> Int {
get async {
return 0
}
}
}
@available(SwiftStdlib 5.1, *)
class SubWSafeSubscript : SuperWSafeSubscript {
override nonisolated subscript<T>(x : T) -> Int {
get async {
return 0
}
}
}
@available(SwiftStdlib 5.1, *)
class SuperWUnsafeSubscript {
@MainActor
subscript<T>(x : T) -> Int {
// expected-targeted-and-ni-note @-1 {{consider making generic parameter 'T' conform to the 'Sendable' protocol}}
// expected-targeted-and-ni-note @-2 {{consider making generic parameter 'T' conform to the 'Sendable' protocol}}
get async {
return 0
}
}
}
@available(SwiftStdlib 5.1, *)
class SubWUnsafeSubscript : SuperWUnsafeSubscript {
// We do not emit an error for the override with
// NonisolatedNonsendingByDefault since the vtable thunk passes in MainActor
// so we are still in the main actor even though we are nonisolated. In the
// case of that being disabled, we cannot do this since we will hop off the
// actor.
override nonisolated subscript<T>(x : T) -> Int {
get async {
// expected-targeted-and-ni-warning@-2{{non-Sendable parameter type 'T' cannot be sent from caller of superclass subscript 'subscript(_:)' into nonisolated override}}
// expected-targeted-and-ni-warning@-2{{non-Sendable parameter type 'T' cannot be sent from caller of superclass getter for subscript 'subscript(_:)' into nonisolated override}}
// there really shouldn't be two warnings produced here, see rdar://110846040 (Sendable diagnostics reported twice for subscript getters)
return 0
}
}
}
// Test implicit conversions getting in the way
@available(SwiftStdlib 5.1, *)
extension MyActor {
func f(_: Any) { }
func g(_: () -> Void) { }
}
@available(SwiftStdlib 5.1, *)
func testConversionsAndSendable(a: MyActor, s: any Sendable, f: @Sendable () -> Void) async {
await a.f(s)
await a.g(f)
}
@available(SwiftStdlib 5.1, *)
actor CustomActorInstance {}
@available(SwiftStdlib 5.1, *)
@globalActor
struct CustomActor {
static let shared = CustomActorInstance()
}
@available(SwiftStdlib 5.1, *)
final class NonSendable {
// expected-note @-1 5 {{class 'NonSendable' does not conform to the 'Sendable' protocol}}
// TransferNonSendable emits 3 fewer errors here.
// expected-tns-note @-3 {{class 'NonSendable' does not conform to the 'Sendable' protocol}}
var value = ""
@MainActor
func update() {
value = "update"
}
func call() async {
await update()
// expected-tns-warning @-1 {{sending 'self' risks causing data races}}
// expected-tns-note @-2 {{sending task-isolated 'self' to main actor-isolated instance method 'update()' risks causing data races between main actor-isolated and task-isolated uses}}
await self.update()
// expected-tns-warning @-1 {{sending 'self' risks causing data races}}
// expected-tns-note @-2 {{sending task-isolated 'self' to main actor-isolated instance method 'update()' risks causing data races between main actor-isolated and task-isolated uses}}
_ = await x
// expected-warning@-1 {{non-Sendable type 'NonSendable' cannot be sent into main actor-isolated context in call to property 'x'}}
_ = await self.x
// expected-warning@-1 {{non-Sendable type 'NonSendable' cannot be sent into main actor-isolated context in call to property 'x'}}
}
@MainActor
var x: Int { 0 }
@CustomActor
var y: Int { 0 }
var z: Int { 0 }
}
// This is not an error since t.update and t.x are both MainActor isolated. We
// still get the returning main actor-isolated property 'x' error though.
@available(SwiftStdlib 5.1, *)
func testNonSendableBaseArg() async {
let t = NonSendable()
await t.update()
// expected-tns-warning @-1 {{sending 't' risks causing data races}}
// expected-tns-note @-2 {{sending 't' to main actor-isolated instance method 'update()' risks causing data races between main actor-isolated and local nonisolated uses}}
_ = await t.x
// expected-warning @-1 {{non-Sendable type 'NonSendable' cannot be sent into main actor-isolated context in call to property 'x'}}
// expected-tns-note @-2 {{access can happen concurrently}}
}
// We get the region isolation error here since t.y is custom actor isolated.
@available(SwiftStdlib 5.1, *)
func testNonSendableBaseArg2() async {
let t = NonSendable()
await t.update()
// expected-tns-warning @-1 {{sending 't' risks causing data races}}
// TODO: Improve the diagnostic so that we say custom actor isolated instead since t.y
// is custom actor isolated.
// expected-tns-note @-4 {{sending 't' to main actor-isolated instance method 'update()' risks causing data races between main actor-isolated and local nonisolated uses}}
_ = await t.y
// expected-warning @-1 {{non-Sendable type 'NonSendable' cannot be sent into global actor 'CustomActor'-isolated context in call to property 'y'}}
// expected-tns-note @-2 {{access can happen concurrently}}
}
// We get the region isolation error here since t.z is not isolated.
@available(SwiftStdlib 5.1, *)
func testNonSendableBaseArg3() async {
let t = NonSendable()
await t.update()
// expected-tns-warning @-1 {{sending 't' risks causing data races}}
// expected-tns-note @-2 {{sending 't' to main actor-isolated instance method 'update()' risks causing data races between main actor-isolated and local nonisolated uses}}
_ = t.z
// expected-tns-note @-1 {{access can happen concurrently}}
}
@available(SwiftStdlib 5.1, *)
@Sendable
func globalSendable(_ ns: NonSendable) async {}
#if !NONISOLATEDNONSENDING
@available(SwiftStdlib 5.1, *)
@MainActor
func callNonisolatedAsyncClosure(
ns: NonSendable,
g: (NonSendable) async -> Void
) async {
await g(ns)
// expected-tns-ni-warning @-1 {{sending 'ns' risks causing data races}}
// expected-tns-ni-note @-2 {{sending main actor-isolated 'ns' to nonisolated callee risks causing data races between nonisolated and main actor-isolated uses}}
let f: (NonSendable) async -> () = globalSendable // okay
await f(ns)
// expected-tns-ni-warning @-1 {{sending 'ns' risks causing data races}}
// expected-tns-ni-note @-2 {{sending main actor-isolated 'ns' to nonisolated callee risks causing data races between nonisolated and main actor-isolated uses}}
}
#endif
@available(SwiftStdlib 5.1, *)
func testLocalCaptures() {
let ns = NonSendable()
@Sendable
func a2() -> NonSendable {
return ns
// expected-tns-warning @-1 {{capture of 'ns' with non-Sendable type 'NonSendable' in a '@Sendable' local function}}
}
}
func testPointersAreNotSendable() {
func testSendable<T: Sendable>(_: T) {}
func testUnsafePointer(ptr: UnsafePointer<Int>,
mutablePtr: UnsafeMutablePointer<String>) {
testSendable(ptr) // expected-warning {{conformance of 'UnsafePointer<Pointee>' to 'Sendable' is unavailable}}
testSendable(mutablePtr) // expected-warning {{conformance of 'UnsafeMutablePointer<Pointee>' to 'Sendable' is unavailable}}
}
func testRawPointer(ptr: UnsafeRawPointer,
mutablePtr: UnsafeMutableRawPointer) {
testSendable(ptr) // expected-warning {{conformance of 'UnsafeRawPointer' to 'Sendable' is unavailable}}
testSendable(mutablePtr) // expected-warning {{conformance of 'UnsafeMutableRawPointer' to 'Sendable' is unavailable}}
}
func testOpaqueAndCPointers(opaquePtr: OpaquePointer, cPtr: CVaListPointer, autoReleasePtr: AutoreleasingUnsafeMutablePointer<Int>) {
testSendable(opaquePtr) // expected-warning {{conformance of 'OpaquePointer' to 'Sendable' is unavailable}}
testSendable(cPtr) // expected-warning {{conformance of 'CVaListPointer' to 'Sendable' is unavailable}}
testSendable(autoReleasePtr) // expected-warning {{conformance of 'AutoreleasingUnsafeMutablePointer<Pointee>' to 'Sendable' is unavailable}}
}
func testBufferPointers(buffer: UnsafeBufferPointer<Int>, mutableBuffer: UnsafeMutableBufferPointer<Int>,
rawBuffer: UnsafeRawBufferPointer, rawMutableBuffer: UnsafeMutableRawBufferPointer) {
testSendable(buffer) // expected-warning {{conformance of 'UnsafeBufferPointer<Element>' to 'Sendable' is unavailable}}
testSendable(mutableBuffer) // expected-warning {{conformance of 'UnsafeMutableBufferPointer<Element>' to 'Sendable' is unavailable}}
testSendable(buffer.makeIterator()) // expected-warning {{conformance of 'UnsafeBufferPointer<Element>.Iterator' to 'Sendable' is unavailable}}
testSendable(rawBuffer) // expected-warning {{conformance of 'UnsafeRawBufferPointer' to 'Sendable' is unavailable}}
testSendable(rawBuffer.makeIterator()) // expected-warning {{conformance of 'UnsafeRawBufferPointer.Iterator' to 'Sendable' is unavailable}}
testSendable(rawMutableBuffer) // expected-warning {{conformance of 'UnsafeMutableRawBufferPointer' to 'Sendable' is unavailable}}
testSendable(rawMutableBuffer.makeIterator()) // expected-warning {{conformance of 'UnsafeRawBufferPointer.Iterator' to 'Sendable' is unavailable}}
}
func testManagedBuffers(buffer1: ManagedBuffer<Int, Int>, buffer2: ManagedBufferPointer<Int, Int>) {
testSendable(buffer1) // expected-warning {{conformance of 'ManagedBuffer<Header, Element>' to 'Sendable' is unavailable}}
testSendable(buffer2) // expected-warning {{conformance of 'ManagedBufferPointer<Header, Element>' to 'Sendable' is unavailable}}
}
}
@available(*, unavailable)
extension SynthesizedConformances.NotSendable: Sendable {}
enum SynthesizedConformances {
struct NotSendable: Equatable {}
// expected-warning@+2 2{{main actor-isolated property 'x' can not be referenced from a nonisolated context}}
// expected-note@+1 2{{in static method '==' for derived conformance to 'Equatable'}}
@MainActor struct Isolated: Equatable {
let x: NotSendable // expected-note 2{{property declared here}}
}
}
@available(SwiftStdlib 5.1, *)
final class UseNonisolatedUnsafe: Sendable {
nonisolated(unsafe) var x1: NonSendable = .init()
nonisolated(unsafe) let x2: NonSendable = .init()
nonisolated(unsafe) var x3: Int = 0
func captureInTask() {
nonisolated(unsafe) var x = NonSendable()
Task {
print(x)
x = NonSendable()
}
}
}
@available(SwiftStdlib 5.1, *)
@preconcurrency
func preconcurrencyContext(_: @escaping @Sendable () -> Void) {}
@available(SwiftStdlib 5.1, *)
@MainActor
struct DowngradeForPreconcurrency {
func capture(completion: @escaping @MainActor () -> Void) {
preconcurrencyContext {
Task { // expected-tns-warning {{passing closure as a 'sending' parameter risks causing data races between code in the current task and concurrent execution of the closure}}
completion() // expected-tns-note {{closure captures 'completion' which is accessible to code in the current task}}
// expected-warning@-1 {{capture of 'completion' with non-Sendable type '@MainActor () -> Void' in a '@Sendable' closure}}
// expected-warning@-2 {{capture of 'completion' with non-Sendable type '@MainActor () -> Void' in an isolated closure}}
// expected-note@-3 2 {{a function type must be marked '@Sendable' to conform to 'Sendable'}}
// expected-warning@-4 {{expression is 'async' but is not marked with 'await'; this is an error in the Swift 6 language mode}}
// expected-note@-5 {{calls to parameter 'completion' from outside of its actor context are implicitly asynchronous}}
// expected-complete-and-tns-warning @-7 {{passing closure as a 'sending' parameter risks causing data races between code in the current task and concurrent execution of the closure}}
// expected-complete-and-tns-note @-7 {{closure captures 'completion' which is accessible to code in the current task}}
}
}
}
var x: NonSendable
func createStream() -> AsyncStream<NonSendable> {
AsyncStream<NonSendable> {
self.x
// expected-warning@-1 {{main actor-isolated property 'x' cannot be accessed from outside of the actor; this is an error in the Swift 6 language mode}} {{7-7=await }}
// expected-warning@-2 {{non-Sendable type 'NonSendable' of property 'x' cannot exit main actor-isolated context; this is an error in the Swift 6 language mode}}
}
}
}
@available(SwiftStdlib 5.1, *)
@MainActor protocol InferMainActor {}
@available(SwiftStdlib 5.1, *)
struct ImplicitSendableViaMain: InferMainActor {}
@available(SwiftStdlib 5.1, *)
extension ImplicitSendableViaMain {
nonisolated func capture() {
Task { @MainActor in
_ = self
}
}
}
@available(SwiftStdlib 5.1, *)
struct TestImplicitSendable: Sendable {
var x: ImplicitSendableViaMain
}
struct UnavailableSendable {}
@available(*, unavailable)
extension UnavailableSendable: Sendable {}
// expected-note@-1 {{conformance of 'UnavailableSendable' to 'Sendable' has been explicitly marked unavailable here}}
@available(SwiftStdlib 5.1, *)
func checkOpaqueType() -> some Sendable {
UnavailableSendable()
// expected-warning@-1 {{conformance of 'UnavailableSendable' to 'Sendable' is unavailable; this is an error in the Swift 6 language mode}}
}
// rdar://129024926
@available(SwiftStdlib 5.1, *)
@MainActor class MainActorSuper<T: Sendable> {}
@available(SwiftStdlib 5.1, *)
class MainActorSub: MainActorSuper<MainActorSub.Nested> {
struct Nested {} // no cycle
}
@available(SwiftStdlib 5.9, *)
struct SendablePack<each Element: Sendable>: Sendable {
let elements: (repeat each Element)
}
@available(SwiftStdlib 5.1, *)
@MainActor
func sendablePacks<each Element: Sendable>(
_ element: repeat each Element
) async {
{ @Sendable in
repeat _ = each element
}()
await sendPack(repeat each element)
}
@available(SwiftStdlib 5.1, *)
func sendPack<each Element>(_: repeat each Element) async {}
// rdar://153083848 - crash in `getConcurrencyFixBehavior` when member comes from a tuple
func test(value: (_: Int, _: () -> Void)) {
func takesSendable(_: @Sendable () -> Void) {}
takesSendable(value.1) // Ok
// expected-warning@-1 {{converting non-Sendable function value to '@Sendable () -> Void' may introduce data races}}
}
// Don't forget about parameter packs -- https://github.com/swiftlang/swift/issues/82614
@available(SwiftStdlib 5.1, *)
protocol PackProto {
func foo<each A: Sendable>(_ a: repeat each A) async
func bar<each A>(_ a: repeat each A) async
// expected-note@-1 {{consider making generic parameter 'each A' conform to the 'Sendable' protocol}}
}
@available(SwiftStdlib 5.1, *)
actor PackActor: PackProto {
func foo<each A: Sendable>(_ a: repeat each A) async {
for b in repeat (each a) {
print(b)
}
}
func bar<each A>(_ a: repeat each A) async {
// expected-warning@-1 {{non-Sendable parameter type 'repeat each A' cannot be sent from caller of protocol requirement 'bar' into actor-isolated implementation; this is an error in the Swift 6 language mode}}
for b in repeat (each a) {
print(b)
}
}
}