Tuple label conversion breaks for member functions

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?

Change to:

typealias T = (Int, String)

works. Tuple labels are part of its type. No label is compatible to any tuple of the same element types, regardless of what their labels.

1 Like

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 seems (Int, Just<String>.Output) and (a: Int, b: String) should be equivalent. It's odd remove the labels from T works.

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.

Reported: [SR-15723] Tuple conversion fails in the context of a type · Issue #58000 · apple/swift · GitHub

1 Like