Can a generic Protocol adopt/extend another generic protocol

I'm using the ANTLR parser generator, but the generated classes aren't close to idiomatic swift. Lots of subclasses are used when protocols should. The problem is that lots of the clases are generic. For instance:

open class ParseTreeVisitor {
    open func visit(_ tree: ParseTree) -> T? {
        fatalError(#function + " must be overridden")
    }
}
public protocol ParseTree: SyntaxTree, CustomStringConvertible, CustomDebugStringConvertible {
    func accept(_ visitor: ParseTreeVisitor) -> T?
}

Seems to me ParseTreeVisitor should be a protocol instead of a class calling fatalError. I can convert this to a protocol with an associatedtype, but that leads to the following.

public protocol ParseTreeVisitor {
	associatedtype T

	// generates error: Protocol 'ParseTree' can only be used as a generic constraint because it has Self or associated type requirements
    func visit(_ tree: ParseTree) -> T?
}

ParseTree.accept also gets the error Cannot specialize non-generic type 'ParseTreeVisitor'.

Is it possible to have a protocol extend another protocol with an associatedtype? Any other ideas?

You need to make both visit and accept generic:

public protocol ParseTreeVisitor {
    associatedtype T

    func visit<Tree: ParseTree>(_ tree: Tree) -> T?
}

public protocol ParseTree {
    associatedtype T

    func accept<Visitor: ParseTreeVisitor>(_ visitor: Visitor) -> T?
}
2 Likes