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. 
tera
5
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.
tera
7
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