New concurrency api not available in latest toolchain

You add them under "Other Swift Flags".

It appears runAsyncAndBlock has been removed as of the 4/16 toolchain, making it a bit difficult to create async contexts. You can get it back by replication the signature:

@_silgen_name("swift_task_runAndBlockThread")
public func runAsyncAndBlock(_ asyncFun: @escaping () async -> ())

But I'd like to know what the official equivalent might be since we still don't have a root async context?

I suppose you can do:

@main
struct S {
  static func main() async { ... }
}

if you're using runAsyncAndBlock for top-level code. I suppose you can also use detach { ... } + continuations.

2 Likes

Thanks. Looks like you also need to rename your main.swift file to something else for @main to work at all.

We also intend for await to be allowed at the top level in 'script mode", but that's taking a little more work.

5 Likes

Is there any current solution for XCTests? It seems detach + expectations might work, but I'm not sure of the right way to capture values out of the detach closure.

1 Like

Try this:

swiftSettings: [
  .unsafeFlags(["-Xfrontend", "-enable-experimental-concurrency"]),
  .unsafeFlags(["-Xfrontend", "-disable-availability-checking"])
]
1 Like

Not working. I think I've tried every possible combination of Package.swift config :(

Weird, works for me :(

Wow. Now it suddenly worked, after God knows how many cleanups... Thanks for the tip!

Xcode is very special with reevaluating a Package file :face_with_monocle:

1 Like

If you use Swift 5.5 or main development snapshot tool chain, the detach keyword in macOS App Target using AppKit or SwiftUI (not Command Line Executable Target) will always fail with the run time error:

EXC_BAD_ACCESS, in libswiftCore.dylibswift::ResolveAsSymbolicReference::operator()`

1 Like

Don't use 5.5 for concurrency, use nightly main builds, everything seems to be working there.

did you try it to build a macOS app using detach ?

It worked on Apr 20 snapshot of 5.5, currently downloading Apr 26 main snapshot, will also check there.

Test snippet is

@main
struct Main {
    static func main() async throws {
        await detach {
            print("it works")
        }.get()
    }
}

I mean macOS app using AppKit or SwiftUI, not executable.

Well then, my snippet is still a macOS app :) But no, I'm not really into GUI apps.

Solution 1:
disable Hardened runtime
or
allow Hardened runtime with disable library validation

Solution 2:
Put the GUI app fully into a Swift Package resolved the macOS detach problem.
Notes: source code files must put into the right ./Sources/MyApp folder, and it also needs to include an empty main.swift.

import PackageDescription

let package = Package(
    name: "MyApp",
    platforms: [
        .macOS(.v11)
    ],
    products: [
        // Products define the executables and libraries a package produces, and make them visible to other packages.
        .executable(
            name: "MyApp",
            targets: ["MyApp"]
        ),
    ],
    dependencies: [
        .package(name: "MyAppCore", path: "./../MyAppCore"),
    ],
    targets: [
        // Targets are the basic building blocks of a package. A target can define a module or a test suite.
        // Targets can depend on other targets in this package, and on products in packages this package depends on.
        .target(
            name: "MyApp",
            dependencies: [
                "MyAppCore"
            ],
            swiftSettings: [
                .unsafeFlags(["-parse-as-library"]), // @main at top level
                .unsafeFlags([
                    "-Xfrontend", "-disable-availability-checking",
                    "-Xfrontend", "-enable-experimental-concurrency",
                ])
            ]
        )
    ]