mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
162 lines
4.8 KiB
Swift
162 lines
4.8 KiB
Swift
// RUN: %empty-directory(%t)
|
|
// RUN: %target-build-swift -target %target-swift-5.1-abi-triple -parse-as-library %s -o %t/a.out
|
|
// RUN: %target-codesign %t/a.out
|
|
// RUN: %env-SWIFT_IS_CURRENT_EXECUTOR_LEGACY_MODE_OVERRIDE=legacy %target-run %t/a.out
|
|
|
|
// REQUIRES: executable_test
|
|
// REQUIRES: concurrency
|
|
// REQUIRES: concurrency_runtime
|
|
|
|
// TODO: The actual reason is that we do these %env- tricks, which e.g. Windows is confused about
|
|
// REQUIRES: libdispatch
|
|
|
|
// UNSUPPORTED: back_deploy_concurrency
|
|
// UNSUPPORTED: use_os_stdlib
|
|
// UNSUPPORTED: freestanding
|
|
|
|
import StdlibUnittest
|
|
|
|
func checkAssumeMainActor(echo: MainActorEcho) /* synchronous! */ {
|
|
// Echo.get("any") // error: MainActor isolated, cannot perform async call here
|
|
MainActor.assumeIsolated {
|
|
let input = "example"
|
|
let got = echo.get(input)
|
|
precondition(got == "example", "Expected echo to match \(input)")
|
|
}
|
|
}
|
|
|
|
@MainActor
|
|
func mainActorCallCheck(echo: MainActorEcho) {
|
|
checkAssumeMainActor(echo: echo)
|
|
}
|
|
|
|
actor MainFriend {
|
|
nonisolated var unownedExecutor: UnownedSerialExecutor {
|
|
MainActor.sharedUnownedExecutor
|
|
}
|
|
|
|
func callCheck(echo: MainActorEcho) {
|
|
checkAssumeMainActor(echo: echo)
|
|
}
|
|
}
|
|
|
|
func checkAssumeSomeone(someone: SomeoneOnDefaultExecutor) /* synchronous */ {
|
|
// someone.something // can't access, would need a hop but we can't
|
|
someone.assumeIsolated { someone in
|
|
let something = someone.something
|
|
let expected = "isolated something"
|
|
precondition(something == expected, "expected '\(expected)', got: \(something)")
|
|
}
|
|
}
|
|
|
|
actor SomeoneOnDefaultExecutor {
|
|
func callCheckMainActor(echo: MainActorEcho) {
|
|
checkAssumeMainActor(echo: echo)
|
|
}
|
|
|
|
func callCheckSomeone() {
|
|
checkAssumeSomeone(someone: self)
|
|
}
|
|
|
|
var something: String {
|
|
"isolated something"
|
|
}
|
|
}
|
|
|
|
actor SomeonesFriend {
|
|
let someone: SomeoneOnDefaultExecutor
|
|
nonisolated var unownedExecutor: UnownedSerialExecutor {
|
|
self.someone.unownedExecutor
|
|
}
|
|
|
|
init(someone: SomeoneOnDefaultExecutor) {
|
|
self.someone = someone
|
|
}
|
|
|
|
func callCheckSomeone() {
|
|
checkAssumeSomeone(someone: someone)
|
|
}
|
|
}
|
|
|
|
actor CompleteStranger {
|
|
let someone: SomeoneOnDefaultExecutor
|
|
init(someone: SomeoneOnDefaultExecutor) {
|
|
self.someone = someone
|
|
}
|
|
|
|
func callCheckSomeone() {
|
|
checkAssumeSomeone(someone: someone)
|
|
}
|
|
}
|
|
|
|
@MainActor
|
|
final class MainActorEcho {
|
|
func get(_ key: String) -> String {
|
|
key
|
|
}
|
|
}
|
|
|
|
@main struct Main {
|
|
static func main() async {
|
|
let tests = TestSuite("AssumeActorExecutor")
|
|
|
|
let echo = MainActorEcho()
|
|
|
|
if #available(SwiftStdlib 5.1, *) {
|
|
// === MainActor --------------------------------------------------------
|
|
|
|
tests.test("MainActor.assumeIsolated: assume the main executor, from 'main() async'") {
|
|
await checkAssumeMainActor(echo: echo)
|
|
}
|
|
|
|
tests.test("MainActor.assumeIsolated: assume the main executor, from MainActor method") {
|
|
await mainActorCallCheck(echo: echo)
|
|
}
|
|
|
|
tests.test("MainActor.assumeIsolated: assume the main executor, from actor on MainActor executor") {
|
|
await MainFriend().callCheck(echo: echo)
|
|
}
|
|
|
|
#if !os(WASI)
|
|
tests.test("MainActor.assumeIsolated: wrongly assume the main executor, from actor on other executor") {
|
|
expectCrashLater(withMessage: "Incorrect actor executor assumption; Expected 'MainActor' executor.")
|
|
await SomeoneOnDefaultExecutor().callCheckMainActor(echo: echo)
|
|
}
|
|
#endif
|
|
|
|
// === some Actor -------------------------------------------------------
|
|
|
|
let someone = SomeoneOnDefaultExecutor()
|
|
#if !os(WASI)
|
|
tests.test("assumeOnActorExecutor: wrongly assume someone's executor, from 'main() async'") {
|
|
expectCrashLater(withMessage: "Incorrect actor executor assumption; Expected same executor as a.SomeoneOnDefaultExecutor.")
|
|
checkAssumeSomeone(someone: someone)
|
|
}
|
|
|
|
tests.test("assumeOnActorExecutor: wrongly assume someone's executor, from MainActor method") {
|
|
expectCrashLater(withMessage: "Incorrect actor executor assumption; Expected same executor as a.SomeoneOnDefaultExecutor.")
|
|
checkAssumeSomeone(someone: someone)
|
|
}
|
|
#endif
|
|
|
|
tests.test("assumeOnActorExecutor: assume someone's executor, from SomeoneOnDefaultExecutor") {
|
|
await someone.callCheckSomeone()
|
|
}
|
|
|
|
tests.test("assumeOnActorExecutor: assume someone's executor, from actor on the SomeoneOnDefaultExecutor.unownedExecutor") {
|
|
await SomeonesFriend(someone: someone).callCheckSomeone()
|
|
}
|
|
|
|
#if !os(WASI)
|
|
tests.test("assumeOnActorExecutor: wrongly assume the main executor, from actor on other executor") {
|
|
expectCrashLater(withMessage: "Incorrect actor executor assumption; Expected same executor as a.SomeoneOnDefaultExecutor.")
|
|
await CompleteStranger(someone: someone).callCheckSomeone()
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
await runAllTestsAsync()
|
|
}
|
|
}
|