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-10699] Unhelpful error message: type 'MyClass' cannot conform to protocol 'MyProtocol' because it has requirements that cannot be satisfied #53096

Open
marcomasser opened this issue May 16, 2019 · 4 comments
Labels
compiler The Swift compiler itself improvement

Comments

@marcomasser
Copy link

Previous ID SR-10699
Radar rdar://problem/56834887
Original Reporter @marcomasser
Type Improvement

Attachment: Download

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Improvement, ClangImporter
Assignee None
Priority Medium

md5: 6f4cb02ddc607bea48238689b9e57b8b

Issue Description:

The error message in the following case could be improved:

  • The Objective-C bridging header contains or imports an Objective-C protocol.

  • That protocol uses a class forward declaration.

  • The forward-declared class is not contained or imported in the bridging header.

  • A Swift class tries to declare conformance to the protocol.

Bridging header:

@class MyForwardDeclaredClass;

@protocol MyProtocolUsingForwardDeclaredClass
- (void)doItWith:(MyForwardDeclaredClass *)obj;
@end

Meanwhile, in Swift:

class MySwiftClass: MyProtocolUsingForwardDeclaredClass {}

This leads to the error message:

error: Type 'MySwiftClass' cannot conform to protocol 'MyProtocolUsingForwardDeclaredClass' because it has requirements that cannot be satisfied

If the bridging header imports a lot of files it can be very hard to find out which parameter of which method in the protocol is not being imported. It would be really nice if the error message included the offending type name or method/symbol that cannot be satisfied.

Bonus points for stating that it cannot be satisfied because the type used is a forward declaration.

The attached sample project contains the above code.

Tested with: Xcode 10.2 (10E125) using Swift 5.0, as well as with the current snapshot: swift-DEVELOPMENT-SNAPSHOT-2019-05-12-a-osx.pkg

@belkadan
Copy link
Contributor

belkadan commented Nov 2, 2019

@swift-ci create

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@HeminWon
Copy link

error: type 'DeviceManagerImpl' cannot conform to protocol 'DeviceManagerProtocol' because it has requirements that cannot be satisfied

DeviceManagerProtocol

@objc(TTTDeviceManagerProtocol)
public protocol DeviceManagerProtocol: NSObjectProtocol {
    
    func currentDeviceID() -> String?
    
    @discardableResult func getDeviceList(_ callback: ((_ devIDList: Array<String>) -> Void)?) -> Array<String>
    @discardableResult func getSharedDeviceList(_ callback: ((_ devIDList: Array<String>) -> Void)?) -> Array<String>
    func specifyDevice(_ devID: String, success: ((_ result: Bool) -> Void)?, failure: ((_ error: Error) -> Void)?) -> Void
}

DeviceManagerImpl

@objc(TTTODDeviceManagerImpl)
@objcMembers
public final class DeviceManagerImpl : NSObject, DeviceManagerProtocol {
    public func currentDeviceID() -> String? {
        return "xxx"
    }
    
    public func getDeviceList(_ callback: ((Array<String>) -> Void)?) -> Array<String> {
        let deviceIDList = []
        callback?(deviceIDList)
        return deviceIDList
    }
    
    public func getSharedDeviceList(_ callback: ((Array<String>) -> Void)?) -> Array<String> {
        let deviceIDList = []
        callback?(deviceIDList)
        return deviceIDList
    }
    
    public func specifyDevice(_ devID: String, success: ((Bool) -> Void)?, failure: ((Error) -> Void)?) {
        success?(true)
    }
}

@marcomasser
Copy link
Author

@HeminWon: I’m not sure what the issue here is. The cited error message is identical, but the code you posted doesn’t seem to have this problem. It compiles just fine, at least after changing the two let deviceIDList = [] lines to let deviceIDList: [String] = []. Could you maybe share more details on where you see this compiler error?

@HeminWon
Copy link

error: type 'DeviceManagerImpl' cannot conform to protocol 'DeviceManagerProtocol' because it has requirements that cannot be satisfied

DeviceManagerProtocol

@objc(TTTDeviceManagerProtocol)
public protocol DeviceManagerProtocol: NSObjectProtocol {
    
    func currentDeviceID() -> String?
    
    @discardableResult func getDeviceList(_ callback: ((_ devIDList: Array<String>) -> Void)?) -> Array<String>
    @discardableResult func getSharedDeviceList(_ callback: ((_ devIDList: Array<String>) -> Void)?) -> Array<String>
    func specifyDevice(_ devID: String, success: ((_ result: Bool) -> Void)?, failure: ((_ error: Error) -> Void)?) -> Void
}

DeviceManagerImpl

@objc(TTTODDeviceManagerImpl)
@objcMembers
public final class DeviceManagerImpl : NSObject, DeviceManagerProtocol {
    public func currentDeviceID() -> String? {
        return "xxx"
    }
    
    public func getDeviceList(_ callback: ((Array<String>) -> Void)?) -> Array<String> {
        let deviceIDList = []
        callback?(deviceIDList)
        return deviceIDList
    }
    
    public func getSharedDeviceList(_ callback: ((Array<String>) -> Void)?) -> Array<String> {
        let deviceIDList = []
        callback?(deviceIDList)
        return deviceIDList
    }
    
    public func specifyDevice(_ devID: String, success: ((Bool) -> Void)?, failure: ((Error) -> Void)?) {
        success?(true)
    }
}

use NSError fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler The Swift compiler itself improvement
Projects
None yet
Development

No branches or pull requests

3 participants