mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Custom global executor is not landing in 6.2, so we skip the test by just gating it behind the platform check.
224 lines
4.5 KiB
Swift
224 lines
4.5 KiB
Swift
// RUN: %target-run-simple-swift(-target %target-swift-5.1-abi-triple) | %FileCheck %s
|
|
|
|
// REQUIRES: executable_test
|
|
// REQUIRES: concurrency
|
|
// REQUIRES: concurrency_runtime
|
|
// UNSUPPORTED: back_deployment_runtime
|
|
|
|
protocol P {
|
|
func f()
|
|
}
|
|
|
|
protocol Q {
|
|
func g()
|
|
}
|
|
|
|
protocol R: Sendable {
|
|
func h()
|
|
}
|
|
|
|
nonisolated class MyClass: @MainActor P {
|
|
func f() {
|
|
print("MyClass.f()")
|
|
|
|
// Make sure we're on the main actor.
|
|
MainActor.assumeIsolated { }
|
|
}
|
|
}
|
|
|
|
actor SomeActor { }
|
|
|
|
@globalActor
|
|
struct SomeGlobalActor {
|
|
static let shared = SomeActor()
|
|
}
|
|
|
|
extension MyClass: @SomeGlobalActor Q {
|
|
@SomeGlobalActor func g() {
|
|
print("MyClass.g()")
|
|
|
|
// Make sure we're on this actor.
|
|
SomeGlobalActor.shared.assumeIsolated { _ in }
|
|
}
|
|
}
|
|
|
|
extension MyClass: nonisolated R {
|
|
nonisolated func h() {
|
|
print("MyClass.h()")
|
|
}
|
|
}
|
|
|
|
struct Wrapper<T> {
|
|
var wrapped: T
|
|
}
|
|
|
|
extension Wrapper: P where T: P {
|
|
func f() {
|
|
print("Wrapper for ", terminator: "")
|
|
wrapped.f()
|
|
}
|
|
}
|
|
|
|
extension Wrapper: Q where T: Q {
|
|
func g() {
|
|
print("Wrapper for ", terminator: "")
|
|
wrapped.g()
|
|
}
|
|
}
|
|
|
|
extension Wrapper: R where T: R {
|
|
func h() {
|
|
print("Wrapper for ", terminator: "")
|
|
wrapped.h()
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 5.9, *)
|
|
struct WrapMany<each T> {
|
|
var wrapped: (repeat each T)
|
|
}
|
|
|
|
@available(SwiftStdlib 5.9, *)
|
|
extension WrapMany: P where repeat each T: P {
|
|
func f() {
|
|
print("Wrapper for many")
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 5.9, *)
|
|
extension WrapMany: Q where repeat each T: Q {
|
|
func g() {
|
|
print("Wrapper for many")
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 5.9, *)
|
|
extension WrapMany: R where repeat each T: R {
|
|
func h() {
|
|
print("Wrapper for many")
|
|
}
|
|
}
|
|
|
|
extension Int: P, Q, R {
|
|
func f() { }
|
|
func g() { }
|
|
func h() { }
|
|
}
|
|
|
|
extension String: P, Q, R {
|
|
func f() { }
|
|
func g() { }
|
|
func h() { }
|
|
}
|
|
|
|
func tryCastToP(_ value: any Sendable) -> Bool {
|
|
if let p = value as? any P {
|
|
p.f()
|
|
return true
|
|
}
|
|
|
|
print("Conformance did not match")
|
|
return false
|
|
}
|
|
|
|
func tryCastToPAndR(_ value: any Sendable) -> Bool {
|
|
if let p = value as? any P & R {
|
|
p.f()
|
|
return true
|
|
}
|
|
|
|
print("Conformance did not match")
|
|
return false
|
|
}
|
|
|
|
func tryCastToQ(_ value: any Sendable) -> Bool {
|
|
if let q = value as? any Q {
|
|
q.g()
|
|
return true
|
|
}
|
|
|
|
print("Conformance did not match")
|
|
return false
|
|
}
|
|
|
|
// CHECK: Testing on the main actor
|
|
// CHECK-NEXT: MyClass.f()
|
|
// CHECK-NEXT: Wrapper for MyClass.f()
|
|
print("Testing on the main actor")
|
|
nonisolated let mc = MyClass()
|
|
nonisolated let wrappedMC = Wrapper(wrapped: mc)
|
|
precondition(tryCastToP(mc))
|
|
precondition(tryCastToP(wrappedMC))
|
|
|
|
if #available(SwiftStdlib 5.9, *) {
|
|
let wrappedMany = WrapMany(wrapped: (17, mc, "Pack"))
|
|
precondition(tryCastToP(wrappedMany))
|
|
}
|
|
|
|
// CHECK: Testing a separate task on the main actor
|
|
// CHECK-NEXT: MyClass.f()
|
|
// CHECK-NEXT: Wrapper for MyClass.f()
|
|
print("Testing a separate task on the main actor")
|
|
await Task.detached { @MainActor in
|
|
precondition(tryCastToP(mc))
|
|
precondition(tryCastToP(wrappedMC))
|
|
|
|
// Cannot cast to P & R because the conformance to P is isolated, but R
|
|
// is Sendable.
|
|
precondition(!tryCastToPAndR(mc))
|
|
precondition(!tryCastToPAndR(wrappedMC))
|
|
|
|
if #available(SwiftStdlib 5.9, *) {
|
|
let wrappedMany = WrapMany(wrapped: (17, mc, "Pack"))
|
|
precondition(tryCastToP(wrappedMany))
|
|
}
|
|
|
|
}.value
|
|
|
|
// CHECK: Testing a separate task on a different global actor
|
|
// CHECK-NEXT: MyClass.g()
|
|
// CHECK-NEXT: Wrapper for MyClass.g()
|
|
print("Testing a separate task on a different global actor")
|
|
await Task.detached { @SomeGlobalActor in
|
|
precondition(tryCastToQ(mc))
|
|
precondition(tryCastToQ(wrappedMC))
|
|
|
|
// Cannot cast to P & R because the conformance to P is isolated, but R
|
|
// is Sendable.
|
|
precondition(!tryCastToPAndR(mc))
|
|
precondition(!tryCastToPAndR(wrappedMC))
|
|
|
|
if #available(SwiftStdlib 5.9, *) {
|
|
let wrappedMany = WrapMany(wrapped: (17, mc, "Pack"))
|
|
precondition(tryCastToQ(wrappedMany))
|
|
}
|
|
|
|
// Not on the main actor any more.
|
|
precondition(!tryCastToP(mc))
|
|
precondition(!tryCastToP(wrappedMC))
|
|
}.value
|
|
|
|
// CHECK: Testing a separate task off the main actor
|
|
print("Testing a separate task off the main actor")
|
|
#if !os(WASI)
|
|
await Task.detached {
|
|
if #available(SwiftStdlib 6.2, *) {
|
|
|
|
precondition(!tryCastToP(mc))
|
|
precondition(!tryCastToP(wrappedMC))
|
|
|
|
precondition(!tryCastToQ(mc))
|
|
precondition(!tryCastToQ(wrappedMC))
|
|
|
|
let wrappedMany = WrapMany(wrapped: (17, mc, "Pack"))
|
|
precondition(!tryCastToP(wrappedMany))
|
|
} else {
|
|
print("Cast succeeds, but shouldn't")
|
|
}
|
|
}.value
|
|
#endif
|
|
|
|
|
|
// Ensure that we access mc later
|
|
print(mc)
|