Circular reference in protocol nesting

Hi there,

I'm excited about Swift 5.10's ability to nest protocol declarations. But I'm facing a challenge with "Circular reference" when trying to move protocols to their appropriate locations:

enum E {}

// Swift 5.9
protocol EP: Sendable {}  // 🆗
extension E: EP {}

// Swift 5.10
extension E {
    protocol P: Sendable {}  // 🆖 Circular reference
}
extension E: E.P {}

What's the correct way to do this?

2 Likes

Thanks for the report. I've identified the issue and have a fix, but I'm also investigating some other, possibly better ways to fix it.

Basically the issue is that when resolving the inheritance list for P, the compiler will look up the name Sendable, which tries to look up the name within P again, which tries to resolve the inheritance list again. So that's where the circularity is. This wasn't an issue previously, because protocols only existed at the top level.

In the mean time, I have a hacky workaround for you:

struct S {
    protocol P: Sendable {}            // Error: circular reference.
    protocol P where Self: Sendable {} // Works.
}
extension S: S.P {}
1 Like

This is now fixed on main and in the 6.0 branch.

4 Likes