Reputation: 439
I am trying to overload a function by its return type. The return type is source from the type constraint on another generic function.
I thought the protocol constraint would allow all cases (Int, String) to be catered for. Here is a small test case that can be run in a playground.
protocol Gettable {}
extension Int: Gettable {}
extension String: Gettable {}
struct Test {
static func get() -> Int {
return 1
}
static func get() -> String {
return "1"
}
}
func getOne<T: Gettable>(_: T.Type) {
let value: T = Test.get()
}
getOne(Int.self)
getOne(String.self)
This produces the following error
error: test.playground:11:23: error: no 'get' candidates produce the expected contextual result type 'T'
let value: T = Test.get()
^
test.playground:11:23: note: overloads for 'get' exist with these result types: Int, String
let value: T = Test.get()
^
Isn't there enough information for the compiler to infer which candidate function should be used?
Upvotes: 1
Views: 115
Reputation: 138051
The problem is that the compiler doesn't know that you've addressed every case of Gettable
with your overloads.
The type of analysis that the compiler would need here is impossible to perform. Swift is capable of laying out new types at runtime, which is notably used for generics. This means that even with internal and private protocols, positively testing for the exhaustiveness of conformances at compile-time is impossible.
In other words, it's not possible to make a constraint that could verify that you have one overload returning the correct type for every type that conforms to some protocol.
Upvotes: 1