Search code examples
swiftgenericstype-constraintsassociated-types

Swift Self as associated type bound in protocol


I want to force an associated type to be Self, but the compiler is having none of it.
Here's what I want to get to compile:

protocol Protocol {
    // Error: Inheritance from non-protocol, non-class type 'Self'
    associatedtype Type: Self
}

You might ask, why not just use Self instead of an associated type? Simply because I cannot: the associated type is inherited from a parent protocol. And it doesn't make sense to change that in the parent protocol.
Here's something similar to what I'm trying to do:

protocol Factory {
    associatedtype Type

    func new() -> Type
}

protocol SelfFactory: Factory {
    associatedtype Type: Self // Same Error
}

Edit:
matt's answer is almost what I'm looking for. It behaves like I want it to at runtime, but is not restrictive enough at compile time.
I want this to be impossible:

protocol Factory {
    associatedtype MyType
    static func new() -> MyType
}

protocol SelfFactory: Factory {
    static func new() -> Self
}

final class Class: SelfFactory {

    // Implement SelfFactory:
    static func new() -> Class {
        return Class()
    }

    // But make the Factory implementation diverge:
    typealias MyType = Int

    static func new() -> Int {
        return 0
    }
}

I'd like the typealias in Class to trigger a redeclaration error or similar.


Solution

  • Are you trying to say this?

    protocol Factory {
        associatedtype MyType
        func new() -> MyType
    }
    
    protocol SelfFactory: Factory {
        func new() -> Self
    }