Reputation: 1498
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???
Upvotes: 5
Views: 390
Reputation: 2661
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.
Upvotes: 1