Referencing self on default associated type

I've been trying to reference an associated type with itself:

struct Composite<Foo> { }

protocol Chain {
  associatedtype Next: Chain
  associatedtype Foo = Composite<Next.Foo> // Associated type `Foo` references itself.
}

Is this too eager of a check? Since I can still technically break a chain:

enum EndChain: Chain {
  typealias Next = Self
  typealias Foo = Double
}
enum A: Chain {
  typealias Next = EndChain
  typealias Foo = Composite<Next.Foo> // Ok
}
enum B: Chain {
  typealias Next = A
  typealias Foo = Composite<Next.Foo> // Ok
}
...

And I want to reduce the amount of Foo I need to type.

Most important part is that I can match the "Chain" size with the Composite count:

"FullChain<A>".Foo = Composite<Double>
"FullChain<A, B>".Foo = Composite<Composite<Double>>
"FullChain<A, B, C>".Foo = Composite<Composite<Composite<Double>>>

and I'm not too fixated on the syntax of "FullChain". Any suggestion is appreciated.

I think I found a solution let me know if it works. Since the compiler apparently has a problem with Foo referencing itself in its definition you could use, a 'proxy' type -if you will - which will require just Next to be used, since referencing Next in Foo's definition is allowed. An example would be:

struct Composite<Foo> { }
typealias CompositeWithoutFoo<Value> = Composite<Value.Foo> 
    where Value: Chain

protocol Chain {
    associatedtype Next: Chain
    associatedtype Foo = CompositeWithoutFoo<Next> // ✅ 
}
1 Like

Hmm, that works. Makes me think that this restriction is indeed a little too tight.

Thanks!

I agree, the restriction is a bit too tight. Should this maybe be reported as a bug?

https://bugs.swift.org/browse/SR-12943