The following Swift code yields this error on the last line: Type 'E' does not inherit from 'C<Self>'
. Not sure what's going on here. Any clues would be appreciated.
class C<T> {}
protocol P {
typealias E : C<Self>
}
class A : P {
typealias E = C<A>
}
class S<U : P> {}
class C2<T> : S<A> {}
Update: I simplified the broken example. The old version (to which milos' answer refers) can be found in this question's edit history.
I have renamed your identifiers so I can think about them:
This should eventually, and very nearly does, work out. In effect, what you want is:
However, on the marked line, where you are defining
class S
you are asking the compiler to check the type ofU : P
and then passB
as the concrete type to check. Unfortunately, at this pointB
's conformance toP
is still unresolved (i.e. it is itself defined in terms ofC2 : S : C
, which is where you are going withU : P
). Removing: P
inU : P
removes the error, though this may not be what you want. Then again, depending on what you want, there may be any number of solutions :)EDIT
The following is in response to @igul222's much simplified code example. I still, think, however, that the compiler is simply returning a less then helpful error message, which is really caused by the recursive type definition. Consider, for example, if you define an
enum
in terms of itself:Now, this is probably also the problem with the following:
... neither does this work (a version of your gist):
... or this:
What the compiler seems to be saying is that
Self
inC<Self>
is not yetA
, i.e. thatA
is not yet itSelf
since to beA
it must conform toP
which is in turn pendingC<Self>
checking out... But the following works becauseA
no longer defines an associated type in terms of itself:Some patterns of functional programming require recursively defined types, so it might be nice to have that in Swift. At present, however, I am not sure one can usefully conform to a protocol with an associated type of the form
T<Self>
, even though the compiler allows its definition... otherwise, this should all just work at runtime.EDIT 2
I have just upgraded to Xcode 6.1 GM Seed and things have changed! The following snippet, that would not have compiled before, now compiles and appears to run fine!
This improvement, however, does not extend to recursively defined associated types.