Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Swift 5.9] Using shorthand syntax to reference @MainActor isolated method from non isolated context raises error #68117

Closed
kokluch opened this issue Aug 24, 2023 · 5 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels

Comments

@kokluch
Copy link

kokluch commented Aug 24, 2023

Description

Accessing the init method of a @mainactor isolated object to store as a closure raises an isolation error since Swift 5.9.

Steps to reproduce

@MainActor
struct Component {
    init() {}
}

struct Builder<T> {
    private let builder: @MainActor () -> T
    
    init(
        builder: @MainActor @escaping () -> T
    ) {
        self.builder = builder
    }
    
    @MainActor
    func build() -> T {
        builder()
    }
}

let _ = Builder { Component() } // OK
let _ = Builder(builder: Component.init) // KO: Call to main actor-isolated initializer 'init()' in a synchronous nonisolated context

Expected behavior

I would expect the last line to compile successfully as it used to prior to Swift 5.9

Environment

  • Swift compiler version info
    swift-driver version: 1.87.1 Apple Swift version 5.9 (swiftlang-5.9.0.128.106 clang-1500.0.40.1)
    Target: arm64-apple-macosx13.0
  • Xcode version info
    Xcode 15.0
    Build version 15A5229h
  • Deployment target:
    iOS 15.0
@kokluch kokluch added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels labels Aug 24, 2023
@skorulis
Copy link

skorulis commented Nov 3, 2023

A related issue to this is that it's possible to completely bypass the @MainActor isolation.

@MainActor
struct Component {
    init() {}
}

final class ClosureContainer {
    var foo: (() -> Component)?
    var bar: (() -> Component)?
    
    init() {
        // Store closure in a MainActor context
        Task { @MainActor in
            self.foo = { Component() }
            self.bar = Component.init
        }
    }
    
    // Calling @MainActor isolated initializers in a non isolated context
    func run() {
        _ = foo?()
        _ = bar?()
    }
}

Expected behavior

It should be a compiler error to store a @MainActor closure without the closure being marked @MainActor.

** Environment**
Swift compiler version info
swift-driver version: Swift 5.9.2 (5.9.2.2.51)
Target: arm64-apple-macosx13.0
Xcode version info
Xcode 15.1 beta 2
Build version 15C5042i
Deployment target:
iOS 17.2

@skorulis
Copy link

skorulis commented Nov 3, 2023

I can replicate the original issue in XCode 15.1 beta 2.

@loganblevins
Copy link

Bumping this issue. Having to find workarounds

@dfed
Copy link

dfed commented Apr 6, 2024

I think this is a duplicate of #67581

@hborla
Copy link
Member

hborla commented Apr 27, 2024

Duplicate of #67581

@hborla hborla marked this as a duplicate of #67581 Apr 27, 2024
@hborla hborla closed this as completed Apr 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels
Projects
None yet
Development

No branches or pull requests

5 participants