Bug? `@objc` async method has `_Nonnull` completion handler parameter instead of `_Nullable`

SE-0297 says that

@objc func perform(operation: String) async -> Int { ... }

will be translated into

- (void)performWithOperation:(NSString * _Nonnull)operation
           completionHandler:(void (^ _Nullable)(NSInteger))completionHandler;

However, when I tried it, the completion handler is _Nonnull, resulting in the following error when I try to pass nil:

Null passed to a callee that requires a non-null argument

Does the implementation have a bug or does SE-0297 need to be updated?

(CC @Douglas_Gregor who authored SE-0297)

This Swift compiler code seems to suggest that the synthesized wrapper method does handle nil completion handlers. So it seems like a bug in the code that generates the Objective-C interface?

Oh actually, there is a completionIsOptional variable whose value is determined here. Unfortunately, I can’t understand what this code is saying. :sweat_smile:

Created `@objc` async method has `_Nonnull` completion handler parameter instead of `_Nullable` · Issue #64870 · apple/swift · GitHub since it seems likely this is a bug. But let me know if this is actually intended behavior!

Is that a warning or an error? I'm getting a warning, but I'm not on the latest Xcode.

It's not unseen that the final implementation doesn't follow proposal document 100%.

However in this case it looks like @discardableResult attribute should be taken into account when converting from swift to obj-c, symmetrically to what it does when going from obj-c to swift.

Oops, sorry for the imprecision. Yes, it’s a warning.

Oh do you mean if I add @discardableResult to the Swift method, the Objective-C translated method’s completion handler should be nullable? I tried it but still got the same warning.

Yes, I mean it should take @discardableResult into account, but it doesn't. So it does look like a bug (a minor one – it's just a warning after all).

Hmm it also crashes at runtime (even with @discardableResult), so I guess the warning is correct but the behavior seems unexpected.

1 Like