SE-0353: Constrained Existential Types

We’ve realized that, if we can allow constrained existential types to be stored directly in structs without back-deployment constraints, you can effectively do almost anything you want with them, just with some minor inconvenience. You can’t back-deploy an Array<any Collection<Int>>, but you can back-deploy an Array<MyAnyCollection<Int>>, where that’s simply a struct wrapping any Collection<T>. And you can dynamically cast from an any Collection<T> by converting it to Any first. The only hard restrictions will be that reflection won’t work and dynamic casts to these types won’t work.

We still cannot promise that you’ll be able to do that, however.

11 Likes

Strong +1 on this.

Oh yes. This feature has been highly requested since the earliest days of Swift, and has always been on the "someday we'll get to this" checklist.

It does now that we've worked out the whole story of generics ergonomics, simplifying generics (e.g., with some Collection<String>) and extending support for existentials via SE-0309.

I've been involved with the design of this feature, so I'm not unbiased here.

I do have one request. SE-0309 specifies that we cannot call a member of an existential value if the result type of that member uses any of the associated types in an invariant position. That prevents code like this from working:

extension Collection {
  func doSomething() -> some Collection<Element> { ... }
}

func test(strings: any Collection<String>) {
  let otherStrings = strings.doSomething() // error: result type uses Element in an invariant position
}

We don't have to prevent this, and indeed we want this call to succeed and produce an any Collection<String>. I believe the change is straightforward, allowing same-type requirements on primary associated types and inferring an existential where those primary associated types are bound appropriately. However, I'd prefer that this change be documented as part of this proposal, because I'd like any expansion of the expressivity of existentials to coincide with a change to this rule set out by SE-0309.

Doug

13 Likes

... backing up my comment with a pull request with the requested change: SE-0353: Add "Covariant Erasure with Constrained Existentials" by DougGregor · Pull Request #1649 · apple/swift-evolution · GitHub

Doug

2 Likes

Thanks Doug. The core team has discussed the review up to this point, and we've agreed to extend the review by another week in order to give the community time to review this revision.

The core team has decided to accept this proposal including the above revision.

3 Likes