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.