swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.3k stars 10.33k forks source link

Pattern that the region based isolation checker does not understand how to check #75439

Open yonihemi opened 1 month ago

yonihemi commented 1 month ago

Description

This is a more concise reproducible than others I've seen. Calling an isolated method on an actor from a MainActor-isolated class fails to build if done in the same call with a function result, but succeeds if I break it down to 2 separate calls. cc @gottesmm

FWIW this built in Xcode 16 b2, fails in Xcode 16 b3 and b4. Also builds with latest release/6.0 toolchain 600202407211a, not sure if that means already fixed but not yet shipped in Xcode.

Reproduction

actor SomeActor {
    func doSomething() { }
}

@MainActor
final class SomeIsolatedClass {
    func someActor() -> SomeActor { .init() }

    func doWithSomeActor() async {
        /// This builds:
        let act = someActor()
        await act.doSomething()

        /// This fails:
        await someActor().doSomething()
    }
}
swiftc isolationissue.swift -swift-version 6

Expected behavior

Builds successfully.

Environment

# Xcode 16 beta 4 (fails)
$ swift --version
swift-driver version: 1.112.3 Apple Swift version 6.0 (swiftlang-6.0.0.6.8 clang-1600.0.23.1)
Target: arm64-apple-macosx14.0
$ swiftc isolationissue.swift -swift-version 6
isolationissue.swift:15:21: error: pattern that the region based isolation checker does not understand how to check. Please file a bug
13 |
14 |        /// This fails:
15 |        await someActor().doSomething()
   |                     `- error: pattern that the region based isolation checker does not understand how to check. Please file a bug
16 |    }
17 | }

# release/6.0 July 21, 2024 (builds)
$ xcrun --toolchain org.swift.600202407211a swift --version
Apple Swift version 6.0-dev (LLVM ec7116ccf9bd8a8, Swift e6aae024fab0927)
Target: arm64-apple-macosx14.0
$ xcrun --toolchain org.swift.600202407211a swiftc isolationissue.swift -swift-version 6
$

Additional information

No response

samsonjs commented 1 month ago

I've run into a similar situation when awaiting an async var:

// ✅
// Breaking this up into 2 lines works around a Swift bug with region-based isolation checking
let staleTasks = await service.allTasks
try removeStaleBackgroundTasks(tasks: staleTasks)

// ❌
try await removeStaleBackgroundTasks(tasks: service.allTasks)
alpaycli commented 1 month ago

I've run into same issue in a bit different situation.

actor NotificationManagerr {
    func scheduleTimeIntervalNotification() async throws {
        // ❌ Pattern that the region based isolation checker does not understand how to check. Please file a bug
        try await scheduleNotification()

        // ✅
        try await scheduleNotification(sound: .default)
    }

    private func scheduleNotification(
        sound: UNNotificationSound = .default
    ) async throws {}
}
stephencelis commented 1 month ago

Another example:


actor S {
  init(
    // Comment this line out and it builds:
    isolation: isolated (any Actor)? = #isolation
  ) {
    fatalError()
  }

  func f() -> S {
    fatalError()
  }
}

func f() async {
  _ = await S().f()
}