Parameter pack that returns a tuple is producing an error: "Failed to produce diagnostics..."

Here's my code:

extension Sequence {
	/// Filters the sequence, returning a tuple of arrays, where each array contains elements
	/// castable to one of the specified types.
	///
	/// - Parameter types: A variadic list of metatypes (e.g., `Keypad.self, Sensor.self`).
	/// - Returns: A tuple where each component is an array of elements successfully cast
	///   to the corresponding type in the `types` parameter pack.
	///
	/// Example:
	/// ```
	/// let (keypads, sensors) = items.compactMap(of: Keypad.self, Sensor.self)
	/// // keypads will be [Keypad]
	/// // sensors will be [Sensor]
	/// ```
	func compactMap<each T>(of types: repeat (each T).Type) -> (repeat [each T]) {
		return (repeat self.compactMap { $0 as? (each T) })
	}
}

But I'm getting an error:

Is there something I'm doing wrong? I'm brand new to parameter packs and I'm just playing around with it. Would be cool if I could get this to work. Just seemed like a nice syntax to be able to write:

let (keypads, sensors) = allDevices.compactMap(of: Keypad.self, Sensor.self)
1 Like

I don't think so. Parameter packs are very hard to not break. Sometimes there are workarounds:

func cast<Uncast, Cast>(_ uncast: Uncast) -> Cast? {
  uncast as? Cast
}

extension Sequence {
  func compactCast<each T>(to _: repeat (each T).Type) -> (repeat [each T]) {
    compactCast()
  }

  func compactCast<each T>() -> (repeat [each T]) {
    (repeat { _ in compactMap(cast) } ((each T).self))
  }
}
let uncast: [Any] = [1, true, 2, false, 3]
let cast = ([1, 2, 3], [true, false])
#expect(uncast.compactCast() == cast)
#expect(uncast.compactCast(to: Int.self, Bool.self) == cast)
2 Likes

So they're just fragile right now? Is that due to missing compiler support?

Also, thanks for your workaround. Going to try that out.

1 Like