Extensions and Variadic Generic Types

This example seems like something that shouldn't compile or run, but it does:

% swiftc --version
swift-driver version: 1.87.3 Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5)
Target: x86_64-apple-macosx14.0
% cat > test.swift
struct S<each T> {
  typealias Storage = (repeat each T)
  let elements: (repeat each T)
  
  init(_ element: repeat each T) {
    self.elements = (repeat each element)
  }
}

extension S<Bool, Int> {
  func foo() { print("Hmm:", type(of: self), "...") }
}

func testS() {
  let e = UInt8(123)
  let s = S(e, e, e)
  print(type(of: s))
  s.foo() // Works, even though S<UInt8, UInt8, UInt8> != S<Bool, Int>
}

testS()
^C
% swiftc test.swift && ./test
S<Pack{UInt8, UInt8, UInt8}>
Hmm: S<Pack{UInt8, UInt8, UInt8}> ...

How are extensions of types with type parameter packs intended to work?

2 Likes

Heh, that extension is being compiled as extension S. Same type requirements for parameter packs is not quite fully implemented yet, so this code snippet should definitely cause a compiler error. Please file an issue for this at Issues · apple/swift · GitHub :smile: cc: @Slava_Pestov @hborla @simanerush

4 Likes

Same-element requirements (a generic requirement that states that all pack elements are equivalent to some specific concrete type) are what's not currently supported in the implementation, which is not the same thing as this code. Regardless, I agree that this is a compiler bug.

4 Likes
3 Likes

Thanks for the bug report. There's some implementation work that remains before concrete same-type requirements involving packs can work; nothing terribly difficult, we just haven't got around to it yet. I knew that the long form syntax was currently rejected:

extension S where (repeat each T) == (Int, Float) {}

but it didn't occur to me that SE-0361 introduced a back door to spelling this without new syntax. This introduces the same-type requirement correctly, but we ignore it when instantiating a pack archetype because as I said a few things are unimplemented. Nice catch!

2 Likes