[swift-users] Type checker not accepting subclass(protocol conformance) as a valid type inside a closure in a protocol with constraint where Self: MyClass

Jordan Rose jordan_rose at apple.com
Wed Nov 2 19:47:35 CDT 2016


Hi, Henrique. This is a correct error message. Consider this use case:

struct Impl: PersistentModel {
  func doTheThing()
}

func callback(_ objs: [Impl]?, _ error: Error?) -> Void? {
  return objs.first?.doTheThing()
}
find2(withBlock: callback) // direct call for clarity

Clearly here the ‘callback’ function isn’t compatible with the type ‘find2’ expects—it wants to be able to pass an array of SomeModel to the function, but the function only handles Impl instances specifically. Any other conforming type would be a problem.

Hope that helps,
Jordan


> On Nov 1, 2016, at 14:48, Henrique Valcanaia via swift-users <swift-users at swift.org> wrote:
> 
> Hey everyone.
> 
> I’m having some trouble with the following code, more precisely I’m getting the error "Cannot convert value of type '([Self]?, Error?) -> Void?' to expected argument type ‘([SomeModel]?, Error?) -> Void?’” when trying to call “find2(withBlock: ([SomeModel]?, Error?) -> Void?)” inside my extension.
> 
> Here’s a snippet:
> 
> protocol SomeModel { }
> 
> func find2(withBlock block: ([SomeModel]?, Error?) -> Void?) {
>     print(#function)
> }
> 
> protocol PersistentModel {
>     typealias FindBlock = (_ objs: [Self]?, _ error: Error?) -> Void?
>     func find(withBlock block: FindBlock)
> }
> 
> extension PersistentModel where Self: SomeModel {
>     func find(withBlock block: FindBlock) {
>        find2(withBlock: block)
>     }
> }
> 
> Considering I’m constraining my protocol extension to SomeModel, why do I get the error when trying to call “find(withBlock: ([SomeModel]?, Error?) -> Void?)”? It’s seems to me the type checker is not comparing the parameters' type inside the block and its inheritances/protocol conformances.
> 
> Just for testing purposes I created a simple class implementing the protocol and a function with the parameter of the same type, we can see the problem does not occur, being strictly linked to closures.
> 
> class MyClass: SomeModel { }
> 
> func test(a: SomeModel) { }
> test(a: MyClass())
> 
> I’m not sure if I’m doing something wrong or if it is just a compiler/language limitation, any thoughts?
> 
> Thanks
> 
> - Henrique
> 
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20161102/29614776/attachment.html>


More information about the swift-users mailing list