swiftexistential-type

When do you need to write `any` when using a protocol as a type in Swift 5.7


I found that this piece of code generates no errors

protocol Foo{
    func foo()
}

let x: Foo? = nil

While the following starts complaining Use of protocol 'Foo' as a type must be written 'any Foo'

protocol Foo: ObservableObject{
    func foo()
}

let x: Foo? = nil      //Use of protocol 'Foo' as a type must be written 'any Foo'

Since ObservableObject inherits AnyObject so I tried

protocol Foo: AnyObject{
    func foo()
}

let x: Foo? = nil

Which again gives no errors.

What exactly is the condition in which writing any when using protocol as type is necessary?


Solution

  • According to the proposal that introduced any - SE-0335,

    SE-0309 Unlock existentials for all protocols enables more code to be written using existential types. To minimize the amount of new code written that will become invalid in Swift 6, I propose requiring any immediately for protocols with Self and associated type requirements. This introduces an inconsistency for protocols under the Swift 5 language mode, but this inconsistency already exists today (because you cannot use certain protocols as existential types at all)

    So it is required for writing existential types of "protocols with Self and associated type requirements" since Swift 5.6. ObservableObject is such a protocol, with an ObjectWillChangePublisher associated type.

    Note that in Swift 6 and above, or in the Swift 6 language mode, existential types of all protocols need any.