I'm pretty sure it's a recursive error, it's Cannot build rewrite system for generic signature; rule length limit exceeded
, and it occurs because of this bits of my code.
extension GenericBuilder where T == SomeUseCase<T.AssociatedEntity> { // <- Error here on this line.
// Do thing, no errors here
}
struct SomeUseCase<T: Entity>: Model {
typealias AssociatedEntity = T
// Do thing, no errors here
}
protocol Entity: Model {
// Do thing, no errors here
}
protocol Model: Equatable, Hashable, Codable {
/// The entity associated with that specific model.
associatedtype AssociatedEntity: Entity
// Do thing, no errors here
}
I'm not really sure how to approach this, I want the GenericBuilder to have a function only when it's associatedType T
is of type SomeUseCase
regardless of the associated entity. I don't want to list out an extension for the GenericBuilder
for every possible entity that could be used. I was hoping that by adding an AssociatedEntity
to the Model, I could just pass the type in, but now it blows up.
If I switch to using a protocol for type T
in the GenericBuilder
, it tells me that any SomeProtocol
doesn't conform to Codable
, Hashable
, or Equatable
, which it doesn't, specific implementations do, but I want it to work for every version of this.
Any advice?
Instead of writing the constraint in the extension declaration, you can write the constraint in each of methods that you are going to write in the extension. This way, you can introduce another type parameter U
, which resolves this recursive constraint problem.
Assuming GenericBuilder
is:
protocol GenericBuilder {
associatedtype T: Model
}
You can write the extension like this:
extension GenericBuilder {
func foo<U: Entity>() where
T == SomeUseCase<U>,
U.AssociatedEntity == T.AssociatedEntity {
}
}
This won't work for properties, but properties can be easily rewritten as a getter (and setter) function, unless you need to get KeyPath
s from those properties.