I've experienced a problem during Swift 3.1 to Swift 4 codebase migration.
The problem arrises when you try to implement a generic protocol method that takes a closure with a generic parameter with a protocol as an 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 in Swift 4 compiler gives me an error about class Foo
not conforming to protocol FooType
with foo(action:)
method implementation missing.
By the way Xcode 9 "fix-it" generates the same implementation I have.
The code compiles if I use BarType
as a parameter type, but it's not good to loose concrete type information.
Turns out that removing the line
typealias BarType = Bar
resolves the issue. Which is fair - type inference does its job.
Nevertheless, it should be a legal code and seems like a bug in compiler.
Reported accordingly.