I'm a bit at a loss to pin-point the exact point of failure in the following scenario:
typealias T = (a: Int, b: String)
func f<P: Publisher>(_ t: P) where P.Output == T {}
f( Just(0).combineLatest(Just("")) ) // Global function 'f' requires the types '(Int, Just<String>.Output)' and 'T' (aka '(a: Int, b: String)') be equivalent
The following very similar use cases appear to compile just fine:
f( Just(0).combineLatest(Just("")).map { $0 as T } )
f( Just((0, "")) )
I'm unsure what exactly about combineLatest is causing the tuple label conversion/inference to fail. Thoughts?
Changing T is kind of beside the point of the issue, which is to determine why Publishers.CombineLatest<Int, String>.Output (which should be (Int, String)) doesn't transparently convert into (a: Int, b: String); especially when Just<(Int, String)>.Output and Publishers.Map<_, (Int, String)>.Output does transparently convert. This inconsistency appears to indicate a compiler bug.
It appears that tuple conversion is broken by the function's enclosing type:
typealias T = (a: Int, b: String)
protocol P {
func f<PT: Publisher>(_ t: PT) where PT.Output == T
}
func f<PT: Publisher>(_ t: PT) where PT.Output == T {}
let p: P!
f(Just((0, ""))) // Fine.
p.f(Just((0, ""))) // Instance method 'f' requires the types '(Int, String)' and 'T' (aka '(a: Int, b: String)') be equivalent
Presumably, the reason tuple conversion fails in the OP case is that the conversion is taking place at the level of CombineLatest.Output, whereas the other examples convert the tuple at the function argument level.