The folllowing program compiles (in Swift 5.2 / Xcode 11.4 and earlier), but should it?
protocol P {
associatedtype A
typealias B = Int
}
extension P where A == Bool {
typealias B = Float // I mean, isn't this an invalid redeclaration of B?
}
If it is meant to compile, then why does this program print Int rather than Bool?
protocol P {
associatedtype A
typealias B = Int
}
extension P where A == Bool {
typealias B = Float
static func printB() { print(B.self) }
}
struct S<A> : P {}
S<Bool>.printB() // Prints "Int"
This one is different. Should have been a redeclaration (we are not supposed to support this kind of conditional type member overloading, not that it's completely senseless to do so).
struct Foo<T> {
typealias B = Int
}
extension Foo where T == Bool {
typealias B = Float // Invalid redeclaration of 'B'
}
Interesting. I think the behavior is expected, especially since you can use coercion to disambiguate (there is nothing we could do to similarly disambiguate type members in the general case, because a type member is simply a name). @xedin Am I right here?
On the other hand, the amount of bugs in this area shows that an agreement on how all these edge-case ambiguities with conditional conformances and extensions should work is yet to be settled (and implemented).
struct S<A> {
static var foo: Int { 123 }
}
extension S {
static var foo: Bool { true } // Redeclaration of 'foo' is deprecated and will be an error in Swift 5
}
I only see the error in 5.3 (master) ...which brings some doubt to what I said earlier about a similar example being expected behavior. But I do not see a reason to ban this either.