This one should fall out naturally from the parser change; I don't think it needs special consideration.
Supporting some P.Type would be a different change than we're discussing here, since it doesn't involve optionals. Ifsome P.Type was supported in the future, then some P.Type? would fall out naturally from that due to the parser change.
I'd like to avoid feature creep here, so if it doesn't involve optional sugar, I don't want to include it in this proposal.
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.