Why is it not possible to reference nested type in generic signature?

Suppose you want to define a class like this:

class Some<A, B, M> where M == Either<A, Self.U> {
    enum U { case a(A), b(B) }
}
enum Either<A, B>{ case a(A), b(B) }

Why does compiler throws an error about that it is not possible to reference the nested type?

1 Like

That cyclical referencing looks very scary, I think you can better express that requirement as:

class Some<A, B> {
  enum U { case a(A), b(B) }
  typealias M = Either<A, U>
}

You need to fully specify the generic placeholders to identify nested types. So you need M (and A, B) to define U, then you need U to constrain M. I'm not even sure how that's suppose to work.

1 Like

I tried that, but it shows the same issue.

My initial intuition was that it is a process with two steps, first of which is an inference of A and B and second is a reference to Self.U, that is gonna be parametrized.
Would like to know whose flaw it is: mine or the language's.

Thing is, it is Some<A, B, M>.U, not U<A, B>. You need to know M before considering U even if M doesn't appear inside U. Like in this example:

struct Foo<Value> {
    enum A { }
}

Foo<Int>.A.self == Foo<Int>.A.self // true
Foo<Int>.A.self == Foo<String>.A.self // false

Foo.Value is considered part of A. I don't think it's a flaw, just that your expectation of U doesn't match that of the language's.

Alright, thank you for feedback.
ps. It is interesting that even though the nested type signature does not dependent on a parent type signature, it is still treated as contravariant. Is that a correct behaviour?

They're actually invariant. And I believe that that'd be the expected behaviour if we're to treat the unused generic as significant.