Any insight about this compiler crash? Workarounds?

I filed an issue for this crash, but I also want to post it here because for these types of things I often get some interesting insights into what’s really going wrong and/or workarounds when I post them to the forums (usually from @Slava_Pestov).

Here’s the crashing setup:

protocol A {
    associatedtype B: A
    associatedtype C: D<Self>
}

protocol D<E> {
    associatedtype E: A
    func f(g: some G<E>) throws
}

protocol G<H> {
    associatedtype H: A
}

extension Optional: A where Wrapped: A {
    typealias B = Optional<Wrapped.B>
    struct C: D {
        typealias E = Optional<Wrapped>
        func f(g: some G<E>) throws {}
    }
}

Sorry about that. This needs a better diagnostic with a source location. In fact your example is the first one I've seen where we hit this error in that particular code path.

To see what's going on, you can boil your example down to this, which you can see produces a diagnostic:

protocol A {
    associatedtype B: A
}

protocol G {
    associatedtype H: A
}

extension Optional: A where Wrapped: A {
    typealias B = Optional<Wrapped.B>
}

func f<T: A, U: G>(_: T, _: U) where U.H == Optional<T> {}

In the generic signature of f(), we have U.H == Optional<T>, U.H.B == Optional<T.B>, U.H.B.B == Optional<T.B.B>, and so on. This cannot be represented today, because only a finite subset of type parameters can be fixed to concrete types inside a generic signature.

3 Likes

out of curiosity – is there a way this could be represented?

Yeah, probably. I never figured out a good way to model concrete same-type and superclass requirements, so we just sort of enumerate everything upfront in that case.