Protocol extension with Self requirement doesn't compile

59 views Asked by At

I'm trying to build a type-safe matching framework, and for this I defined a protocol and a conformer that matches any value (more conformers to come later).

protocol Matcher<Value> {
    associatedtype Value

    func matches(_ other: Value) -> Bool
}

struct AnyMatcher<T>: Matcher {
    func matches(_ other: T) -> Bool { true }
}

Next, I wanted to make it easy to use the matchers, and to provider factory methods in the protocol extensions, similar to how SwiftUI does for some of the styling methods. So, I wrote something along the lines of

extension Matcher where Self == AnyMatcher<Value> {
    static var any: AnyMatcher<Value> { AnyMatcher() }
}

, which should've enabled a neat syntax like

let matcher: any Matcher<String> = .any

However, to my surprise, the compiler gave the following error on the protocol extension:

Same-type constraint 'Self' == 'AnyMatcher<Self.Value>' is recursive

The problem seems to be related to the fact that AnyMatcher is generic, as if I do the same drill but with a non-generic struct, it compiles:

struct AnyMatcher2: Matcher {
    typealias Value = Int

    func matches(_ other: Int) -> Bool { true }
}

extension Matcher where Self == AnyMatcher2 {
    static var any2: AnyMatcher2 { AnyMatcher2() }
}

, though if I try to use it (e.g. let matcher2: any Matcher<Int> = .any2), the compiler crashes without any useful message

Command SwiftCompile failed with a nonzero exit code

Is this a limitation of the Swift language, or am I doing something wrong? Is there any way to make it work?

I'm using Swift 5.9.

0

There are 0 answers