I'm trying to use an opaque PAT:
func opaqueCollection() -> some Collection {
[2]
}
let collection = opaqueCollection()
print(collection[0])
This fails to compile with
error: no exact matches in call to subscript; Candidate expects value of type '(some Collection).Index' for parameter #1
This confuses me for a couple of reasons. SE-0244 says
If the opaque type exposes associated types, those associated types' identities are also maintained. This allows the full API of protocols like the Collection family to be used
This suggests that a) Collection.Index == Int ought to be preserved through the veil, and b) we ought to be able to use "the full API" for Collection, but neither seem really true.
I notice that the codesnippet in SE-0244 (which works) is designed to prove that the type for Element is known at the callsite, but it carefully avoids relying on the type of Index:
c[c.startIndex] = c.first!
Is there something unique about Index here that causes Element to be known but not Index?
Here's a related situation with Combine. The idea here is to have a contract for a useful Publisher, but not its exact type:
import Combine
func publisher() -> some Publisher {
Just(2)
}
publisher().sink(receiveValue: { print($0)})
error: referencing instance method 'sink(receiveValue:)' on 'Publisher' requires the types '(some Publisher).Failure' and 'Never' be equivalent
Of course they are equivalent in this case, but we seem to have forgotten that associatedtype along the way. And without knowledge of that associatedtype, it seems like no opaque Publisher would be useful.
Side note, I'm aware most people solve this by erasing to an AnyCollection/AnyPublisher rather than using opaque types. But paradoxically, the Any wrappers are themselves some particular struct, so if the goal is to erase the return type itself (for example to allow it to change in an ABI-compatible way) returning a wrapper is in a certain sense the opposite.