Home > Net >  Generic where clause in class: 'Failure' is not a member type of type 'Self'
Generic where clause in class: 'Failure' is not a member type of type 'Self'

Time:11-07

Why does Self.Failure result in an error when AddIndexPublisher is defined as a class, but shows no error when defined as a struct?

Consider the following: (compile errors shown in comments above the corresponding line)

class AddIndexPublisher<InputP: Publisher>: Publisher {
    typealias Output = (InputP.Output, Int)
    typealias Failure = InputP.Failure

    let ip: InputP

    init(ip: InputP) {
        self.ip = ip
    }

    func receive<S>(subscriber: S)
    // 'Failure' is not a member type of type 'Self'
    // 'Output' is not a member type of type 'Self'
    where S : Subscriber, Self.Failure == S.Failure, Self.Output == S.Input
    {
        let sub = AddIndexSubscription<
                        // 'Failure' is not a member type of type 'Self'
                        S, InputP, Self, InputP.Output, Self.Failure
                    >(sub: subscriber, ipub: ip, opub: self)
        subscriber.receive(subscription: sub)
    }
}

Removing Self. lets the compile errors disappear too when using class. However, I'm curious why there is a difference between struct and class producing these errors. Is there a section in the spec which explains some background for that?

Thanks.

CodePudding user response:

My base idea is on 2 points:

  1. Has to do with inheritance, since structs can't inherit from other structs. This also connects to point 2.

  2. Self.Failure is using Self, which is a type (in this case, of the current same object type). Also Output and Failure are associated types of the Publisher protocol. Using Self of associated types doesn't make sense due to inheritance of classes( what types really are these Failure and Output ?). Removing Self. tells the compiler to use the typealias defined in this object.

It's a nice question anyway, thanks for this :)

  • Related