Hi,
In the detailed design section of SE-0346 - Lightweight same-type requirements for primary associated types, it demonstrates a function which returns an opaque Collection of opaque Equatable elements:
Constrained protocols in opaque result types
- A constrained protocol may appear in an opaque result type specified by the
some
keyword. In this case, the syntax actually allows you to express something that was previously not possible to write, since we do not allowwhere
clauses on opaque result types:func transformElements<S : Sequence<E>, E>(_ lines: S) -> some Sequence<E>
This example also demonstrates that the argument can itself depend on generic parameters from the outer scope. The SE-0328 Structural Opaque Result Types pitch allows multiple occurrences of
some
in a return type. This generalizes to constrained protocol types, whose constraint can be another opaque result type:func transform(_: some Sequence<some Equatable>) -> some Sequence<some Equatable>
Note that in the above, the opaque result type
some Sequence<some Equatable>
is unrelated to the opaque parameter typesome Sequence<some Equatable>
. The parameter type is provided by the caller. The opaque result type is a (possibly different) homogeneous sequence of elements, where the element type is known to conform tosome Equatable
but is otherwise opaque to the caller.
This second function doesn't compile. In fact I've found that opaque return types in general don't support other opaque types as primary associated types:
// Both errors
// 'some' types are only permitted in properties, subscripts, and functions
func foo() -> some Collection<some Equatable> {
[1]
}
var x: some Collection<some Equatable> {
[1]
}
It's weird because using opaque types in this way (as constraints) works if the outer type is concrete:
// Works
func foo() -> Array<some Equatable> {
[1]
}
var x: Array<some Equatable> {
[1]
}
The one place this construct does seem to be allowed is in parameter position, as a shorthand for generics (this example is also from SE-0346):
// Works! But nowhere else :S
func sort(elements: inout some Collection<some Equatable>) {}
Is this gap known about? The way it is described in the proposal, it seems like the intention was for this to support opaque return types. Are there implementation issues blocking it, or could it be an oversight?