Using Self in generics

I was wondering why this piece of code works

import SwiftUI
import Combine
import Foundation

class Game: BindableObject {
    let didChange = PassthroughSubject<Game, Never>()
}

But replacing Game with Self runs into a segmentation fault on compile

import SwiftUI
import Combine
import Foundation

class Game: BindableObject {
    let didChange = PassthroughSubject<Self, Never>()
}

It certainly shouldn't segfault (please file a bug at https://bugs.swift.org!) but the problem here is that any subclasses of Game would have a different type. That is, it's not obvious that a PassthroughSubject<CardGame, Never> is a kind of PassthroughSubject<Game, Never>, even though CardGame is a kind of Game. This feature is called "covariant generic parameters" and would be non-trivial to add to Swift.

1 Like

Thanks for the explanation. Wasn't obvious what was wrong with my implementation. I filed a bug SR-10969 with a smaller test case and one that doesn't rely on any dependencies.

Additionally, would using Self in this case from a struct be possible since they can't be subclassed?

2 Likes

Yes, using Self in a struct should be identical to spelling out the type. It could also work with final classes, but I don't know if that was implemented.

1 Like

In the cases I have worked with Self has worked identical to structs when in a final class.

1 Like