Swift 4: Implementing a Generic Protocol with Protocol as a Bound Type

I got a problem while migrating Swift 3.1 code to Swift 4.

The problem arises when you try to implement a generic protocol method that accepts a shared parameter closure with the protocol as its associated type. It's easier than it sounds :)

The following code works fine in Swift 3.1:

protocol FooType {
    associatedtype BarType

    func foo(bar: BarType)
    func foo(action: (BarType) -> Void)
}

protocol Bar {}

class Foo: FooType {
    typealias BarType = Bar

    // Compiles in both 3.1 and 4
    func foo(bar: Bar) {
    }

    // ERROR: Candidate has non-matching type (Bar) -> Void
    func foo(action: (Bar) -> Void) {     
    }
}

      

However, the Swift 4 compiler raises an error related to the class Foo

not conforming to the protocol FooType

with no method implementation foo(action:)

.

By the way, Xcode 9 "fix-it" generates the same implementation as me.

The code compiles if I use it BarType

as a parameter type, but it is not good to lose information about a specific type.

+3


source to share


2 answers


It turns out that deleting a line

typealias BarType = Bar

      

fixes the problem. What kind of inference of a fair type does his job.



However, this should be legal code and seems to be a bug in the compiler.

Reported accordingly.

+3


source


We have to use the generic variable typealias to feed the linkedType of the protocol. I would like to use the typealias variable name in the funtion. This makes sense also legally, but I still don't know why the compiler doesn't know the typealias parameter in the closure.



class Foo: FooType {
    typealias BarType = Bar


    func foo(bar: BarType) {
     /*Code*/
    }


    func foo(action: (BarType) -> Void) {
      /*Code*/
    }
}

      

0


source







All Articles