Swift allows generic methods to be overloaded by the constraints placed upon the generic types passed in. If you use this with concrete types, then the type passed in will participate in this overloading and constraints will be inferred from that type.
As soon as a generic method delegates to another with overload resolution, the constraints can no longer be inferred and will instead utilize the constraints already placed on the type from above.
protocol Conformance {}
extension String : Conformance {}
// #1
func baseMethod<T>(_ value: T) {
let isConforming = T.self is Conformance.Type
}
// #2
func baseMethod<T>(_ value: T) where T : Conformance {
let isConforming = T.self is Conformance.Type
}
func delegatingMethod<T>(_ value: T) {
baseMethod(value)
}
func run() {
// Calls #2, isConforming = true
baseMethod(String())
// Calls #1, isConforming = true
delegatingMethod(String())
}
I assume this is there so that you have sufficient type information from the call site about what constraints are applicable no matter where the generic type is used, but it seems to severely and artificially limit the utility of overloading by constraint.
Are there any known workarounds to this oddity? Something that emulates this would be extremely useful.