swiftlang / swift

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

Undefined symbols mixing `@MainActor`, `open`, subclassing Objective-C (Swift 6 Regression) #75119

Open KeithBauerANZ opened 2 months ago

KeithBauerANZ commented 2 months ago

Description

I have a package with two types:

open class MyButton: UIButton {

    public typealias ActionHandler = @MainActor () -> Void

    open var actionHandler: ActionHandler?

}

public final class MyOtherButton: MyButton {}

This is using swift tools version 5.10, and enables the upcoming feature "strict concurrency".

I have an app consuming it, also using swift 5, but not using strict concurrency yet:

func concurrencyUnaware() {
    let x = MyOtherButton()
    x.actionHandler?()
}

This results in undefined symbols:

Undefined symbols for architecture arm64:
  "LocalPackage.MyButton.actionHandler.getter : (@Swift.MainActor () -> ())?", referenced from:
      full type metadata for LocalPackage.MyOtherButton in LocalPackage.o
ld: symbol(s) not found for architecture arm64

It seems there's two getters from the actionHandler, one @MainActor and one not (only one of which is defined for some reason), which makes me suspect SE-0423 @hborla @xedin

Explicitly adding @MainActor to the button types resolves the issue (but requires the app's caller to be updated too).

Reproduction

Full Xcode project attached:

OpenMainActor.zip

Expected behavior

This compiles and links when using Xcode 15, but breaks with the Xcode 16 betas.

Environment

🌸 xcodebuild -version Xcode 16.0 Build version 16A5202i 🌸 swift --version
swift-driver version: 1.111.2 Apple Swift version 6.0 (swiftlang-6.0.0.5.15 clang-1600.0.22.6)

Additional information

No response

hborla commented 2 months ago

@KeithBauerANZ does explicitly writing @preconcurrency on var actionHandler work around the issue?

@preconcurrency open var actionHandler: ActionHandler?
KeithBauerANZ commented 1 month ago

Yep, that also works around the problem.