I've been playing around with AsyncSequence
which has now been updated to have a Failure
associatedtype, with availability restricted to the latest platform versions. But I encountered something curious. The flatMap
operator looks like this:
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
extension AsyncSequence {
...
@preconcurrency @inlinable public func flatMap<SegmentOfResult>(_ transform: @escaping @Sendable (Self.Element) async -> SegmentOfResult) -> AsyncFlatMapSequence<Self, SegmentOfResult> where SegmentOfResult : AsyncSequence, Self.Failure == SegmentOfResult.Failure
}
Notice there is no restriction to latest platform versions (it's only restricted to versions that support concurrency), but it does make use of Failure
, which if I follow to its definition, is restricted to the latest platform versions.
I discovered this after I upgraded Xcode (I can't remember if the problem surfaced before or after changing the language version to 6), in a library where I wrote a flatten
operator (i.e. flatMap { $0 }
). The compiler complained that there were no matching overloads, and that the correct one isn't a candidate because it requires the constraint on Failure
. So I added that constraint, and got an error that Failure
isn't available on the target platform version. I eventually had to change the return type to AsyncThrowingFlatMapSequence
, and write another version of flatten
that is restricted to latest platform versions.
It was possible previously for it to return AsyncFlatMapSequence
because AsyncSequence
was @rethrows
, but now this seems to not be possible anymore, which means it's a breaking change.
How is it possible that this extension is written so that it is available on older platforms but uses Failure
? Is that a magic capability available only to the standard or "core" modules like _Concurrency
?
Xcode let slip while showing possible overloads that the function is actually marked with @_alwaysEmitIntoClient
, so I thought maybe that is why it works (that it would defer the restriction up to whoever imports the module), but I tried adding that and it didn't get rid of the error.