"Unavailable instance method... used to satisfy a requirement of protocol"

I am updating from Xcode 8 to Xcode 9, still using Swift 3.

In my project I am getting warnings of the pattern:

Unavailable instance method ‘compareQueryResult(_:toQueryResult:)’ was used to satisfy a requirement of protocol ‘ResultComparable’.

My project uses an Obj-C++ framework to wrap C++ and expose it in Obj-C.

The instance method in question is declared and implemented in a number of Obj-C classes in this framework.

@interface DocumentQuery: Query {
   - (ComparisonResult)compareQueryResult:(DocumentResult *)result1 toQueryResult:(DocumentResult *)result2;
}
@end

@interface GroupQuery: Query {
   - (ComparisonResult)compareQueryResult:(GroupResult *)result1 toQueryResult:(GroupResult *)result2;
}
@end

Another framework imports the Obj-C++ framework. In this framework the protocol is defined in Swift with an associated type:

public protocol ResultComparable
{
    associatedtype ResultType
    func compareQueryResult(_ r1: ResultType, toQueryResult r2: ResultType) -> ComparisonResult
}

And conformance is declared:

extension DocumentQuery: ResultComparable {}
extension GroupQuery: ResultComparable {}

This compiled without warnings in Xcode 8 / Swift 3, but they appear in Xcode 9 / Swift 3. Any help in understanding the issue and how to fix it would be greatly appreciated.

James

Hi, James. The trick here is that the name you’ll get in Swift for these methods is probably 'compareQuery(_:toQuery:)', because the Swift compiler detects that the “result” is redundant with the type name. In Xcode 8 the compiler didn’t check if you were using the “old" name to satisfy a protocol, but Xcode 9 now does (for unrelated reasons).

Since this is a source-breaking change, can you file an issue at https://bugs.swift.org <Issues · apple/swift · GitHub; ? At the very least we should make the diagnostic better.

You can always tell the Swift compiler you know better by using the NS_SWIFT_NAME annotation to provide an alternate name, using Swift function name syntax.

Jordan

···

On Sep 15, 2017, at 12:45, James Dempsey via swift-users <swift-users@swift.org> wrote:

I am updating from Xcode 8 to Xcode 9, still using Swift 3.

In my project I am getting warnings of the pattern:

Unavailable instance method ‘compareQueryResult(_:toQueryResult:)’ was used to satisfy a requirement of protocol ‘ResultComparable’.

My project uses an Obj-C++ framework to wrap C++ and expose it in Obj-C.

The instance method in question is declared and implemented in a number of Obj-C classes in this framework.

@interface DocumentQuery: Query {
   - (ComparisonResult)compareQueryResult:(DocumentResult *)result1 toQueryResult:(DocumentResult *)result2;
}
@end

@interface GroupQuery: Query {
   - (ComparisonResult)compareQueryResult:(GroupResult *)result1 toQueryResult:(GroupResult *)result2;
}
@end

Another framework imports the Obj-C++ framework. In this framework the protocol is defined in Swift with an associated type:

public protocol ResultComparable
{
    associatedtype ResultType
    func compareQueryResult(_ r1: ResultType, toQueryResult r2: ResultType) -> ComparisonResult
}

And conformance is declared:

extension DocumentQuery: ResultComparable {}
extension GroupQuery: ResultComparable {}

This compiled without warnings in Xcode 8 / Swift 3, but they appear in Xcode 9 / Swift 3. Any help in understanding the issue and how to fix it would be greatly appreciated.

James

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Thanks Jordan!

I can definitely file an issue.

A better diagnostic would definitely help.

James

···

On Sep 15, 2017, at 2:03 PM, Jordan Rose <jordan_rose@apple.com> wrote:

Hi, James. The trick here is that the name you’ll get in Swift for these methods is probably 'compareQuery(_:toQuery:)', because the Swift compiler detects that the “result” is redundant with the type name. In Xcode 8 the compiler didn’t check if you were using the “old" name to satisfy a protocol, but Xcode 9 now does (for unrelated reasons).

Since this is a source-breaking change, can you file an issue at https://bugs.swift.org <Issues · apple/swift · GitHub; ? At the very least we should make the diagnostic better.

You can always tell the Swift compiler you know better by using the NS_SWIFT_NAME annotation to provide an alternate name, using Swift function name syntax.

Jordan

On Sep 15, 2017, at 12:45, James Dempsey via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

I am updating from Xcode 8 to Xcode 9, still using Swift 3.

In my project I am getting warnings of the pattern:

Unavailable instance method ‘compareQueryResult(_:toQueryResult:)’ was used to satisfy a requirement of protocol ‘ResultComparable’.

My project uses an Obj-C++ framework to wrap C++ and expose it in Obj-C.

The instance method in question is declared and implemented in a number of Obj-C classes in this framework.

@interface DocumentQuery: Query {
   - (ComparisonResult)compareQueryResult:(DocumentResult *)result1 toQueryResult:(DocumentResult *)result2;
}
@end

@interface GroupQuery: Query {
   - (ComparisonResult)compareQueryResult:(GroupResult *)result1 toQueryResult:(GroupResult *)result2;
}
@end

Another framework imports the Obj-C++ framework. In this framework the protocol is defined in Swift with an associated type:

public protocol ResultComparable
{
    associatedtype ResultType
    func compareQueryResult(_ r1: ResultType, toQueryResult r2: ResultType) -> ComparisonResult
}

And conformance is declared:

extension DocumentQuery: ResultComparable {}
extension GroupQuery: ResultComparable {}

This compiled without warnings in Xcode 8 / Swift 3, but they appear in Xcode 9 / Swift 3. Any help in understanding the issue and how to fix it would be greatly appreciated.

James

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users