![]()
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.
![]()
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.