swiftlang / swift

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

NS_SWIFT_UI_ACTOR is ignored on block typedefs #76099

Open xavierjurado opened 3 weeks ago

xavierjurado commented 3 weeks ago

Description

NS_SWIFT_UI_ACTOR is not properly recognized on Objective-C block typedefs. This should be possible according to #58150 and #70693, but as far as I can tell it's not working on Xcode 15.4 or the latest Xcode 16 toolchain. Interestingly enough, NS_SWIFT_SENDABLE seems to be working as intended.

Reproduction

typedef void (^MainActorCompletionHandler)(void) NS_SWIFT_UI_ACTOR;
typedef void (^SendableCompletionHandler)(void) NS_SWIFT_SENDABLE;

Is translated as:

@MainActor public typealias MainActorCompletionHandler = () -> Void
public typealias SendableCompletionHandler = @Sendable () -> Void

Notice how the main actor closure has the @MainActor applied before the typedef, which is not valid and seems to be ignored by Swift. The sendable closure, instead, is correctly annotated.

Expected behavior

public typealias MainActorCompletionHandler = @MainActor () -> Void

Environment

swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)

Additional information

For what is worth, I've tried placing the NS_SWIFT_UI_ACTOR annotation on pretty much every position inside the typedef without any success 😅

NS_SWIFT_UI_ACTOR typedef NS_SWIFT_UI_ACTOR void NS_SWIFT_UI_ACTOR (^ NS_SWIFT_UI_ACTOR MainActorCompletionHandler)(void) NS_SWIFT_UI_ACTOR;
xavierjurado commented 1 week ago

The issue is no longer reproducible in the latest version of Xcode 16 (RC). Closing.

drodriguez commented 1 week ago

There might be something missing in the open source toolchain. With changes like https://github.com/drodriguez/swift/commit/a3c4428ea7c46d1e212de2bd8a335800b27a814a (or even moving the MAIN_ACTOR to just after the block ^) I get the error in that commit message.

xedin commented 1 week ago

I think that might be an issue with how attributes on a typedef declaration are interpreted by the importer, if you move MAIN_ACTOR in the type position (inside of (^)), does that work?

drodriguez commented 1 week ago

@xedin I tested both and got the same results in both cases. I uploaded the second version in https://github.com/drodriguez/swift/commit/7a1032f446a2359b0b4a079b2d45e06adf7b668a and when I use check-swift-validation I get those three tests failing with the same error message:

.../test-macosx-arm64/Concurrency/Output/sendable_objc_attr_in_type_context_swift5.swift.tmp/src/main.swift:36:29: error: unexpected error produced: cannot convert value of type '@MainActor () -> Void' to expected argument type 'MainActorCompletionHandler' (aka '(@escaping @Sendable () -> ()) -> ()')
  test.withMainActorHandler(mainFn)