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

[SR-9035] Bridging of Unmanaged CF types to ObjC doesn't work for throwing functions #51538

Closed
swift-ci opened this issue Oct 18, 2018 · 4 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself good first issue Good for newcomers

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-9035
Radar None
Original Reporter stephengroom (JIRA User)
Type Bug
Status Resolved
Resolution Done
Environment

Apple Swift version 4.2 (swiftlang-1000.11.37.1 clang-1000.11.45.1)

Target: x86_64-apple-darwin17.7.0

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, StarterBug
Assignee @theblixguy
Priority Medium

md5: a75bc65432adfa13920e0584ecf94a27

Issue Description:

If you define the following protocol in Swift it causes an error:

@objc protocol TestProtocol {
    func throwingMethod() throws -> Unmanaged<CFArray>
}

Throwing method cannot be a member of an @objc protocol because it returns a value of type 'Unmanaged<CFArray>'; return 'Void' or a type that bridges to an Objective-C class

The error is wrong as Unmanaged<CFArray> does bridge to an Objective-C class.
eg. if you define the following in Swift

 
@objc protocol TestProtocolWhichBridges { 
    func method() -> Unmanaged<CFArray>
    func optionalMethod() -> Unmanaged<CFArray>? 
}

the following appears in Module-Swift.h (albeit albeit with a warning) and can be used

@protocol TestProtocolWhichBridges
- (CFArrayRef _Nonnull __unsafe_unretained)method SWIFT_WARN_UNUSED_RESULT;
- (CFArrayRef _Nullable __unsafe_unretained)optionalMethod SWIFT_WARN_UNUSED_RESULT;
@end

//'objc_ownership' only applies to Objective-C object or block pointer types; type here is 'CFArrayRef' (aka 'const struct __CFArray *')

If you define a protocol in Objective-C which matches the signature of TestProtocol and view the file's generated interface it looks as you'd expect:

@protocol TestProtocol
- (CFArrayRef)throwingMethodWithError:(NSError **)error;
@end

It is imported into Swift as

public protocol TestProtocol {
    public func throwingMethod() throws -> Unmanaged<CFArray>
}

but the protocol can't be implemented because of the error:

Throwing method cannot be an implementation of an @objc requirement because it returns a value of type 'Unmanaged<CFArray>'; return 'Void' or a type that bridges to an Objective-C class

@belkadan
Copy link
Contributor

Nice catch. I think this is simple enough to do as a StarterBug, but I need to scope it out a little more first.

@belkadan
Copy link
Contributor

Okay, tagging as StarterBug. The fix is in swift::isRepresentableInObjC in TypeCheckDeclObjC.cpp, where it assigns kind = ForeignErrorConvention::NilResult when the helper function isBridgedToObjectiveCClass returns true for the result type. It should also be true when the type is Unmanaged specifically, something available from ASTContext::getUnmanagedDecl(). I'd suggest changing isBridgedToObjectiveCClass to account for this explicitly and renaming it to something like isValidObjectiveCErrorResultType.

One nice thing is that we don't have to worry about the Unmanaged type being unrepresentable in Objective-C for other reasons (like being Unmanaged of a Swift-only type), because that will still be checked separately from whether it's a valid throwing result type. It's worth having a test for that too.

@theblixguy
Copy link
Collaborator

PR: #24135

@theblixguy
Copy link
Collaborator

Fixed on master & also cherry-picked to the swift 5.1 branch.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
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. compiler The Swift compiler in itself good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

3 participants