Yes, that's correct.
Mostly yes, it's fine from a performance point of view. It's a little complicated because it's mixed in with other topics, such as whether the type has a resilient ABI (in a framework "built for library evolution") and other things like inlinability, cross-module optimization.
Basically, if the compiler has visibility into the function returning the type, then it knows what it is even if you don't, and it can optimize accordingly. So for example if you use an opaque result type in your own source code, then the compiler can see the function implementation and so knows the real returned type. If you use one returned from an ABI-stable library (like the standard library) then it depends on whether the function has been marked inlinable, allowing the caller's compiler to see what type it is. This is the fairly standard burden on ABI-stable library authors to decide how much flexibility to trade off. If the function is inlinable, this means the author cannot, later, return a different type. If it isn't inlinable, then the type is entirely opaque and has to be manipulated via the witness tables. But this is standard for ABI-stable libraries and goes along other things like whether the type is @frozen
, whether other methods are inlinable etc.
For the most part, the standard library tends to mark most stuff frozen and inlinable ("fragile") because performance is critical. But higher-level frameworks tend to skew more in favor of resilience.
It is definitely possible when aligned with a Swift 6 language mode. The ABI consequences can be worked around with various techniques. Whether the source break is worth it should be discussed as part of a future pitch.
I think so, yes! A pitch of this very idea is being worked on now. Such a concept when combined with opening of existentials should indeed render AnyCollection<Int>
unnecessary (though since it's ABI, we'll never actually get to delete the 2,500 lines found in ExistentialCollections.swift alas).