AnyObject used in a Generic fails to identify the conformances to AnyObject. Only Generics fail

So, can someone possibly explain why the Generic here fails? It doesn't make sense why it should, since the generic conformance should enforce this as a class.

Error occurs on Swift 5.7

protocol VirtualSimulatorDataSource: AnyObject {
    func data(forCommand: any BLEReadCommand) -> Data
}

final class WeakVirtualSimulatorDataSourceRef {
    weak var value: VirtualSimulatorDataSource?
    init(value: any VirtualSimulatorDataSource) {
        self.value = value
    }
}

final class WeakRef<T: AnyObject> {
    weak var value: T?
    init(value: T) {
        self.value = value
    }
}


// WORKS
private var dataSources: [DeviceType: WeakVirtualSimulatorDataSourceRef] = [:]

// FAILS
private var dataSources: [DeviceType: WeakRef<VirtualSimulatorDataSource>] = [:]

VirtualSimulatorDataSource is not a class; it is a protocol. When used as a type, VirtualSimulatorDataSource (aka any VirtualSimulatorDataSource) is known as an existential type.

An existential type (with limited exceptions not applicable here) does not conform to any protocol, not even itself. In other words, any VirtualSimulatorDataSource does not conform to VirtualSimulatorDataSource or AnyObject.

Why don't existential types express their conformance in generics, however they can express it when used as concrete definitions.

ie.

If I alter the concrete definition like this it still works.

final class WeakVirtualSimulatorDataSourceRef {
    weak var value: (any VirtualSimulatorDataSource)?
    init(value: any VirtualSimulatorDataSource) {
        self.value = value
    }
}

Weak can only be expressed as a class type.

What this means is there's no way to enforce a weak generic as a protocol constraint.

Unless you can suggest an alternative.

In some ways, I always liked the C++ stye pure interfaces better, as they support this kind of magic.

Generally speaking, in Swift, I find myself fighting with the language more than the problem I'm trying to solve. It's a shame, Swift had such great potential.

…unless it’s declared @objc. You said there are exceptions but I think this specific one is worth highlighting, as it’s tripped me up in the past.

1 Like