[Pitch] Allow `some P?` and `any P?` (removing the need for parentheses)

:speaking_head:
I'm in favor of this feature in principle, but let me talk about "what-if" as a thought experiment:

"What if Swift would accept intersection types more generally in the future?"


Status Quo

Current Swift allows intersection types only for protocol-constrained types.
That means each intersection type in current Swift must be composed of one or more protocols and zero or one class:

protocol P1 {}
protocol P2 {}
class C {}

let _: any P1 & P2 & C // ✅ Allowed

func f<T>(_: T) {
  let _: any P1 & T // ⛔️ Not Allowed
  // error: non-protocol, non-class type 'T' cannot be used within a protocol-constrained type
}

What-if World

Imagine that future Swift would allow any P1 & T. In other words, each intersection type could be composed of one or more protocols and zero or one non-protocol type in Future Swift.
(Side note: You may ask "Would it be useful?"; My answer is "It would be". See my comment on another thread for more detail.)

Here is an (arbitrary) example in such world:

protocol MyWrappedValueProtocol {}

protocol MyOptionalProtocol<Wrapped> where Wrapped: MyWrappedValueProtocol {
  associatedtype Wrapped
}
extension Optional: MyOptionalProtocol where Wrapped: MyWrappedValueProtocol {}

protocol MyOptionalHolderProtocol<Wrapped> where Wrapped: MyWrappedValueProtocol {
  associatedtype Wrapped
  var optional: Wrapped? { get }
}

struct MyOptionalHolder<Wrapped> {
  let optional: Wrapped?
}
extension MyOptionalHolder: MyOptionalHolderProtocol where Wrapped: MyWrappedValueProtocol {}

extension MyOptionalHolder {
  func doSomthing() {
    // This `if case ...` syntax is allowed even in current Swift:
    if case let specialSelf as any MyOptionalHolderProtocol<Wrapped> = self {
      // In this scope,
      //   - `specialSelf.optional` is just `Wrapped?` in current Swift.
      //   - `specialSelf.optional` could be expressed with type annotation like below in Future Swift:
      let myOptional: any MyOptionalProtocol & Wrapped? = specialSelf.optional
      // :
      // :
    }
  }
}

In Future Swift, any MyOptionalProtocol & Wrapped? here should be parsed as any MyOptionalProtocol & Optional<Wrapped> rather than (any MyOptionalProtocol & Wrapped)?.
On top of that, any Wrapped? & MyOptionalProtocol could be parsed successfully in Future Swift.


:thought_balloon:
This is just a thought experiment and the example above is very arbitrary, but we'd remember that parsing any P & Q? as (any (P & Q))? would be a hindrance when we want to make Swift's intersection types more general.

1 Like