protocol Destinationable: Hashable {
associatedtype D: Hashable
var destination: D { get }
}
protocol Graph {
associatedtype Edge: Destinationable
subscript(node: D) -> Set<Edge>! { get set }
}
extension Graph {
typealias D = Edge.D
}
struct UndirectedGraph<Edge: Destinationable>: Graph {
typealias D = Edge.D // Why should we again declare this typealias!?
private var storage: [D: Set<Edge>]
subscript(node: D) -> Set<Edge>! {
get { storage[node] }
set { storage[node] = newValue }
}
}
This works. But if I remove redeclaration of typealias D = Edge.D
in the struct I get an compilation error, related to the subscript:
Unsupported recursion for reference to type alias 'D' of type 'UndirectedGraph'
Why is it happening? What recursion???
I'm not sure what recursion, but you should avoid declaring typealiases in protocol extensions and use same-type constaints instead:
protocol Destinationable: Hashable {
associatedtype D: Hashable
var destination: D { get }
}
protocol Graph {
associatedtype D
associatedtype Edge: Destinationable where D == Edge.D
subscript(node: D) -> Set<Edge>! { get set }
}
struct UndirectedGraph<Edge: Destinationable>: Graph {
private var storage: [D: Set<Edge>]
subscript(node: Edge.D) -> Set<Edge>! {
get { storage[node] }
set { storage[node] = newValue }
}
}
compiles just fine but in your case:
protocol Destinationable: Hashable {
associatedtype D: Hashable
var destination: D { get }
}
protocol Graph {
associatedtype Edge: Destinationable
subscript(node: Edge.D) -> Set<Edge>! { get set }
}
struct UndirectedGraph<Edge: Destinationable>: Graph {
private var storage: [Edge.D: Set<Edge>]
subscript(node: Edge.D) -> Set<Edge>! {
get { storage[node] }
set { storage[node] = newValue }
}
}
might be enough.