Opaque result types

As @Douglas_Gregor already knows, I'm a big fan of this feature: LGTM!

A few minor points:

I'm a little concerned about overloading “_” in the way proposed; everywhere else it means a kind of nothingness (no label, no pattern constraint, no name) but here it's being used to refer to a specific thing. It's hard to see that on a continuum with its other uses.

I'm also concerned about the arguable overloading of “->” and lack of symmetry in this example:

To me something like this would be more logical:

extension BidirectionalCollection {
  public func reversed()
      -> opaque BidirectionalCollection where _.Element == Element,
      -> opaque RandomAccessCollection where Self : RandomAccessCollection,
      -> opaque MutableCollection where Self : MutableCollection 
  {
    return ReversedCollection<Self>(...)
  }
}

I know what you mean, but I don't think subscript has an “element type” does it? Can we just say “return type” since a subscript always has a getter? The next sentence doesn't sound like a “however” to me; it's just a restatement, so “however” is confusing.

It's not clear what you mean here. If I read it literally it seems to be saying that this proposal introduces contextual named types to the language by allowing them in opaque result type constraints. If so, IMO you should say so more directly. If not, maybe you could clarify.

Is it possible to work around that with something like this as long as you were willing to return a nominal type instead of a tuple?

protocol SameElement {
    associatedtype C0 : Collection
    associatedtype C1 : Collection where C1.Element == C0.Element
    var c0: C0 { get }
    var c1: C1 { get }
}
func g() -> opaque SameElement { }
1 Like