Default associated type for a protocol under certain constraints

I have a PAT (protocol with associated types) and I'd like to provide a default associated type in the protocol when certain generic constraints are met. This is not possible today, but will it make sense?

Here's an example:

// Differentiable manifold.
public protocol Differentiable {
    // The tangent space is a real vector space.
    associatedtype TangentVector : VectorNumeric
        where TangentVector.Scalar : FloatingPoint
}

public extension Differentiable where Self : VectorNumeric {
  // When `Self` is a vector space, its default tangent space is itself.
  typealias TangentVector = Self
}

Ok! This compiles. However, when I have methods in the protocol that use TangentVector, the compiler cannot resolve the TangentVector type.

// Differentiable manifold.
public protocol Differentiable {
    // The tangent space is a real vector space.
    associatedtype TangentVector : VectorNumeric
        where TangentVector.Scalar : FloatingPoint
    // Move `self` toward the given tangent vector.
    func moved(toward direction: TangentVector) -> Self
}

public extension Differentiable where Self : VectorNumeric {
    // When `Self` is a vector space, its default tangent space is itself.
    typealias TangentVector = Self
}
test.swift:5:32: error: 'TangentVector' is ambiguous for type lookup in this context
  func moved(toward direction: TangentVector) -> Self
                               ^~~~~~~~~~~~~
test.swift:4:18: note: found this candidate
  associatedtype TangentVector : VectorNumeric
                 ^
test.swift:9:13: note: found this candidate
  typealias TangentVector = Self
            ^

Is this expected? Why is this ambiguous given that TangentVector always maps onto the protocol requirement?

1 Like

This is only a guess, but the typealias in the protocol extension feels to me like some sort of type shadowing instead of a conditionally default for the associated type.

Could be related:

2 Likes