0

I got this code:

protocol Protocol {
    var id: Int { get }
}

extension Array where Element: Protocol {
    func contains(_protocol: Protocol) -> Bool {
        return contains(where: { $0.id == _protocol.id })
    }
}

class Class {
    func method<T: Protocol>(_protocol: T) {
        var arr = [Protocol]()

        // Does compile
        let contains = arr.contains(where: { $0.id == _protocol.id })

        // Doens't compile
        arr.contains(_protocol: _protocol)
    }
}

Why doesn't the line of code compile where I commented 'Doens't compile'? This is the error:

Incorrect argument label in call (have '_protocol:', expected 'where:')

When I change the method name in the extension to something else, like containz (and ofcourse change the name of the method that calls it to containz), I get this error when I try to call it:

Using 'Protocol' as a concrete type conforming to protocol 'Protocol' is not supported

But why doesn't it work when I try to call it through an extension, but it does work when I create the function in the extension directly? There isn't really any difference that I can see.

J. Doe
  • 12,159
  • 9
  • 60
  • 114
  • 1
    Ultimately a probable duplicate of https://stackoverflow.com/questions/33112559/protocol-doesnt-conform-to-itself – matt Nov 18 '18 at 21:55

1 Answers1

1

I agree with matt that the underlying answer is Protocol doesn't conform to itself?, but it's probably worth answering anyway, since in this case the answer is very simple. First, read the linked question about why [Protocol] doesn't work the way you think it does (especially Hamish's answer, which is much more extensive than the accepted answer that I wrote). [Protocol] does not match the where Element: Protocol clause because Protocol is not a concrete type that conforms to Protocol (because it's not a concrete type).

But you don't need [Protocol] here. You have T: Protocol, so you can (and should) just use that:

var arr = [T]()

With that change, the rest should work as you expect because T is a concrete type that conforms to Protocol.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610