Why can't this class have a related-recursive stored property?

final class MyType<T: Comparable, each U: Comparable, V: Comparable> {
  typealias Data = (T, repeat each U, V)
  typealias NextNode = MyType<repeat each U, V, T>

  //...
}

On the third line, the occurrence of "MyType" is marked with an error:

Generic type 'MyType' specialized with mismatched type parameter pack

I want the next step to be shifted over by 1. What's going on?

The declaration of MyType declares three generic parameters and the second one is a pack:

You're then instantiating MyType with three generic arguments, where the first is a pack:

This doesn't make sense, so the compiler complains.

2 Likes

I expect the compiler to explode U to its separate terms, then have NextNode recalculate its generic parameters. If U is empty, then NextNode.T will be V and NextNode.V will be T. Otherwise, the first term of U will become NextNode.T, T will become NextNode.V and NextNode.U will be the non-first terms of U followed by V.

The problem is that we don't know if the pack is empty or not when we're type checking the function.

struct G<T, each U> {
  typealias A = T
}

func rotate<each T, U>(_: repeat each T, _: U) {
  let a: G<repeat each T, U>.A = ...
}

The compiler has to assign a specific fixed type to a once, without seeing any calls to rotate().

1 Like