This is related to the new Swift 5.2 feature:
A method override can no longer have a generic signature with requirements not imposed by the base method. For example, the below code produces an error. (23626260) (FB5382462)
Unfortunately I inherited a project that is greatly impacted by this change. I'm aware of the bad code for a longer time but the refactor is scheduled to be addressed no sooner than in Q3/20. I'm now looking for some workaround that would allow me to move to Swift 5.2 before the great refactor. And I hit something that I'm now not sure if I'm thinking wrong or violating some principle or it is just not implemented yet this way.
What I'm expecting is ability to implement a protocol requirement adopted by superclass.
protocol Fooable {
associatedtype BarType
func foo(_ value: BarType)
}
class Bar {}
class SubBar: Bar {}
class Base: Fooable {
func foo(_ value: Bar) {
print("I'm Base accepting Bar but actually I'm \(type(of: self)) and received \(type(of: value))")
}
}
class SubBase: Base {
func foo(_ value: SubBar) {
print("hmm...")
super.foo(value)
}
}
func baz<T>(_ value: T, argument: T.BarType) where T: Fooable {
value.foo(argument)
}
When I call baz(SubBase(), argument: SubBar())
there is no "hmm..." in the console but only "I'm Base accepting Bar but actually I'm SubBase and received SubBar".
- So protocol conformance isn't actually inherited but forbidden? Is this why initializer requirement in protocol imposes required initializer for classes?