i have a protocol HTTP.ServerLoop that has some requirements and provides a method runServer()
public protocol ServerLoop
{
func allow(origin:IP) -> Bool
func x()
func y()
}
extension HTTP.ServerLoop
{
func runServer()
}
there is an actor SharedServer that provides all the witnesses except for allow(origin:), and lives in a module called CoreServer. the idea is that a downstream module will extend SharedServer with the necessary allow(origin:) requirement and declare the ServerLoop conformance.
there are two such modules, a public module with a stub implementation, and a private module that provides a proprietary implementation.
public module:
import CoreServer
extension SharedServer:HTTP.ServerLoop
{
public
func allow(origin:IP) -> Bool
{
// Allow everything.
return true
}
}
proprietary module:
import CoreServer
extension SharedServer:HTTP.ServerLoop
{
public
func allow(origin:IP) -> Bool
{
// Enforce firewall rules
...
}
}
now, i would like to write some extension in the CoreServer module that assumes a conformance that does not yet exist at this level.
extension SharedServer where Self:HTTP.ServerLoop
{
public
func run() async throws
{
// calls `runServer()`
}
}
but it seems this is not allowed.
trailing 'where' clause for extension of non-generic type 'Unidoc.ServerLoop'
this run() method accesses a lot of private implementation details of SharedServer. so it is not a good candidate for refactoring into some SharedServerProtocol. are there any other ways to assume a conformance that is expected to be declared in a client module?
dnadoba
(David Nadoba)
2
You can flip the requirements:
extension HTTP.ServerLoop where Self: SharedServer {}
I recently run into this as well. I wish both spelling would be accepted.
3 Likes
ah, it has to be spelled with a colon! i had tried writing this
extension HTTP.ServerLoop where Self == TheServerLoop
and encountered the no type for 'Self' can satisfy both 'Self == TheServerLoop' and 'Self : HTTP.ServerLoop' error so i assumed this was not allowed.
it’s not quite the same, as the protocol extension cannot access any private members, but that is acceptable to me.
(the error perplexes me, TheServerLoop is an actor which cannot possibly have subclasses. so i do not understand why there is a difference between : and ==.)
1 Like