Skip to content

Conversation

@hborla
Copy link
Member

@hborla hborla commented Apr 5, 2024

  • Explanation: The actor isolation checker allows erasing global actor isolation in function conversions when the conversion happens in the same isolation domain and the destination type is not Sendable under the assumption that the function value will never cross an isolation boundary. This is an important rule, because it allows calling synchronous higher order function APIs with global actor isolated function values as long as you're calling from a global actor isolated context. However, the actor isolation checker was allowing the conversion in cases where the function value crosses an isolation boundary:

    func crossIsolationBoundary(_ closure: () -> Void) async { closure() }
    
    @MainActor func test() async {
      let closure = { @MainActor @Sendable in
        MainActor.assertIsolated()
      }
    
      await crossIsolationBoundary(closure)
    }

    This PR diagnoses the function conversion that loses actor isolation if the function conversion is an argument to a call that crosses an isolation boundary.

    We still need to fix this case under region isolation:

    func crossIsolationBoundary(_ closure: () -> Void) async { closure() }
    
    @MainActor func test() async {
      let closure = { @MainActor @Sendable in
        MainActor.assertIsolated()
      }
    
      let erased: () -> Void = closure
    
      await crossIsolationBoundary(erased)
    }

    Currently, the above code is "fine" because the function conversion itself isn't crossing an isolation boundary, and from the perspective of region analysis, erased is in a disconnected region. I think the way to solve this is to merge erased to the main actor region due to the function conversion that erases main actor isolation.

  • Scope: Only impacts isolated-to-non-Sendable function conversions that cross isolation boundaries.

  • Risk: Low due to narrow scope.

  • Testing: Add a test case.

  • Reviewer: @xedin

  • Main branch PR: [Concurrency] Don't allow erasing global actor isolation when the function value crosses an isolation boundary. #72607

…ction

value crosses an isolation boundary.

(cherry picked from commit 6154823)
@hborla hborla requested a review from a team as a code owner April 5, 2024 05:24
@hborla
Copy link
Member Author

hborla commented Apr 5, 2024

@swift-ci please test

@hborla hborla merged commit bb339b8 into swiftlang:release/6.0 Apr 5, 2024
@hborla hborla deleted the 6.0-unsafe-isolation-erasure branch April 5, 2024 16:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants