# SE-0335: Introduce existential \`any\`

**URL:** <https://forums.swift.org/t/se-0335-introduce-existential-any/53934>\
**Category:** Proposal Reviews\
**Created:** [December 8, 2021, 9:30pm UTC](https://forums.swift.org/t/se-0335-introduce-existential-any/53934 "2021-12-08T21:30:23Z")\
**Posts on this page:** 19\
**Page:** 7

<div class="post-metadata">

**Author:** ![Nickolas\_Pohilets](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nickolas_pohilets/32/10659_2.png) [@Nickolas\_Pohilets](https://forums.swift.org/u/Nickolas_Pohilets)\
**Post date:** [December 19, 2021, 2:04pm UTC](https://forums.swift.org/t/se-0335-introduce-existential-any/53934/124 "2021-12-19T14:04:10Z")

</div>

> [@Douglas\_Gregor](#):
>
> I can provide the background here. We ended up doing this when implementing `Sendable` in the standard library, because it depends on the feature being in the compiler as well, like this:
> 
> ```swift
> #if <some check for marker protocols>
> @_marker protocol Sendable { }
> #else
> typealias Sendable = Any
> #endif
> 
> ```
> 
> It allowed downstream clients to use `Sendable` as a generic constraint and also write conformances to `Sendable` , even with older compilers that couldn't handle the definition.

Is this still relevant? Reading the [source code](https://github.com/apple/swift/blob/main/stdlib/public/core/Sendable.swift#L15), that's not what I see. Am I looking in the wrong place?

---

<div class="post-metadata">

**Author:** ![benrimmington](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/benrimmington/32/695_2.png) [@benrimmington](https://forums.swift.org/u/benrimmington)\
**Post date:** [December 19, 2021, 7:59pm UTC](https://forums.swift.org/t/se-0335-introduce-existential-any/53934/125 "2021-12-19T19:59:50Z")

</div>

Another recent example:

> <https://github.com/apple/swift/blob/3ec0413aa79248bc73852081f9ac7bf5e8fcecbf/stdlib/public/core/Pointer.swift#L13-L17>

---

<div class="post-metadata">

**Author:** ![hborla](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/hborla/32/27563_2.png) [@hborla](https://forums.swift.org/u/hborla)\
**Post date:** [December 20, 2021, 3:42pm UTC](https://forums.swift.org/t/se-0335-introduce-existential-any/53934/126 "2021-12-20T15:42:58Z")

</div>

> [@100mango](#):
>
> Would You mind telling me the relationship between SE-0335 and Generalized existential?  
> If we have the support with Generalized existential, do we need SE-0335 ?

This proposal is orthogonal to generalized existentials. This proposal adds an explicit keyword for writing existential types, but it does not allow you to express additional constraints on existential types. Similarly, generalized existentials would not give us an explicit, searchable keyword for writing existential types.

---

<div class="post-metadata">

**Author:** ![Douglas\_Gregor](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/douglas_gregor/32/1362_2.png) [@Douglas\_Gregor](https://forums.swift.org/u/Douglas_Gregor)\
**Post date:** [December 21, 2021, 7:17pm UTC](https://forums.swift.org/t/se-0335-introduce-existential-any/53934/127 "2021-12-21T19:17:06Z")

</div>

> [@Nickolas\_Pohilets](#):
>
> Is this still relevant? Reading the [source code](https://github.com/apple/swift/blob/main/stdlib/public/core/Sendable.swift#L15), that's not what I see. Am I looking in the wrong place?

The _technique_ remains relevant, even if the compatibility window for needing this for the specific marker protocol `Sendable` has passed.

Doug

---

<div class="post-metadata">

**Author:** ![Nickolas\_Pohilets](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nickolas_pohilets/32/10659_2.png) [@Nickolas\_Pohilets](https://forums.swift.org/u/Nickolas_Pohilets)\
**Post date:** [December 22, 2021, 5:46pm UTC](https://forums.swift.org/t/se-0335-introduce-existential-any/53934/128 "2021-12-22T17:46:19Z")

</div>

Moved to a separate thread - [Introduce existential `any` - avoiding inconsistency around `Any` and `AnyObject`](https://forums.swift.org/t/introduce-existential-any-avoiding-inconsistency-around-any-and-anyobject/54231)

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [December 22, 2021, 6:14pm UTC](https://forums.swift.org/t/se-0335-introduce-existential-any/53934/129 "2021-12-22T18:14:39Z")

</div>

As John mentioned above, this is a proposal review; can we split this off to a separate discussion thread?

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [December 28, 2021, 8:21pm UTC](https://forums.swift.org/t/se-0335-introduce-existential-any/53934/130 "2021-12-28T20:21:08Z")

</div>

> [@hborla](#):
>
> The reason why `any` is not required on `Any` is because it's redundant, not because `any` is inherently meaningless for unconstrained existential types.

> [@hborla](#):
>
> > [@1-877-547-7272](#):
> >
> > If you have a type alias to `Any` or `AnyObject` , do you have to use the `any` keyword to declare an existential?
> 
> I think the answer should be no, because that would lead to really weird inconsistencies with associated type inference.

If I read this correctly, does that mean we can only declare `typealias Foo = Any`, and that declare `Foo` as both constraint and existential type? Particularly, can I do this?

```swift
typealias Foo = Any

protocol P1: Foo { ... }
func bar(foo: Foo)

```

I think the more important part about `typealias` is that it now separates existential aliasing from constraint aliasing. Breaking that property would make refactoring non-trivial. If for example we original used `typealias Foo = any` and use them as both constraint and existential, such as the code above, then changing `Foo` to anything else, e.g., `Foo = Codable` or `Foo = any Codable` would break the codebase.

That why I think the important part is that we can immediately tell from `typealias` whether it is aliasing types, constraints, or existential. Maybe we can instead disallow `any Any` only outside of typealias?

On that note, I think the `Any` and `AnyObject` interaction with `typealias` could be better clarified in the proposal.

* * *

For motivation, I think we should focus more on the capability differences between generic and existential. I don't think people are bitten as much about performance (nor are they particularly concerned). It's more important that generic can

- use static members,
- conform to the itself, or anything really,
- access associated type, and
- convert to existential,

while existential can only support different member types at run time\* at the cost of everything above. So most likely one would use generic when they mean to use _unspecified type conforming to certain constraints_. The proposal did include the `associatetype` portion, so we can expand a bit more on that.

\* Theoretically, we can add `openExistential` to convert existential to _generic types_, but then you're still more likely to prefer to use generic type directly for performance reasons.

* * *

Overall, I doubt a mere keyword would make it _obvious_ all the nuance between different choices (existential vs generic vs opaque), but I find the separation between constraint and existential invaluable. Especially since existential behaves much more like concrete types and generics than protocol constraints.

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [January 4, 2022, 6:35pm UTC](https://forums.swift.org/t/se-0335-introduce-existential-any/53934/131 "2022-01-04T18:35:15Z")

</div>

I think the proposal should clarify that, like their base types, `Any.Type` and `AnyObject.Type` will also get special behavior to be treated as existential.

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [January 5, 2022, 7:18pm UTC](https://forums.swift.org/t/se-0335-introduce-existential-any/53934/133 "2022-01-05T19:18:18Z")

</div>

Sorry to be pinging this, but could someone clarify this part?

> [@Lantua](#):
>
> Particularly, can I do this?
> 
> ```swift
> typealias Foo = Any
> 
> protocol P1: Foo { ... }
> func bar(foo: Foo)
> 
> ```

---

<div class="post-metadata">

**Author:** ![hborla](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/hborla/32/27563_2.png) [@hborla](https://forums.swift.org/u/hborla)\
**Post date:** [January 5, 2022, 8:03pm UTC](https://forums.swift.org/t/se-0335-introduce-existential-any/53934/134 "2022-01-05T20:03:16Z")

</div>

Thanks for the ping!

I thought about the use case for typealiasing `Any` a bit more and I think this example should be the same as other type aliases that can be used as generic constraints:

```swift
typealias Foo = Any

protocol P1: Foo { ... }
func bar(foo: any Foo)

```

Otherwise, when the type alias switches from `Any` to e.g. `Sendable`, the code would break (under a language mode where `any` is required). The implementation already knows how to infer `any` specifically for associated type inference, and we _could_ keep that behavior around for `Any` and `AnyObject` under the language mode where `any` becomes more strict, but this would leave a couple weird inconsistencies:

```swift
protocol P {
  associatedtype A
}

struct S: P {
  // this is a type witness, so it has to be existential
  typealias A = Any

  func generic<T: P>() -> T.A: A { ... } // error, `A` is really `any Any` which isn't a valid conformance requirement
}

```

This inconsistency is only an issue if the type witness is explicitly written with a typealias. We can fix this by always requiring `any` for explicit type witnesses, even for `Any` and `AnyObject`, like you suggest. This also means getting rid of the `any Any` warning, which I'm very indifferent about anyway, and it seems like some folks in this thread would prefer to write `any Any` for consistency. And FWIW, this example is super contrived and I don't imagine that using `Any` or `AnyObject` as a type witness is particularly common.

> [@Lantua](#):
>
> I think the more important part about `typealias` is that it now separates existential aliasing from constraint aliasing. Breaking that property would make refactoring non-trivial.

In the vast majority of cases where a typealias is used as both an existential and a conformance constraint, the refactoring amounts to adding `any` in front of the type alias name where used as an existential. It's only in the case where a type alias is used for both _and_ it satisfies an associated type requirement that the type alias must be split into two different ones (once `any` is required) because a protocol is not a valid type witness. This case seems pretty rare, and the transformation still seems straightforward enough to be performed by a migrator.

> [@Lantua](#):
>
> On that note, I think the `Any` and `AnyObject` interaction with `typealias` could be better clarified in the proposal.

I agree. I'll clarify this behavior in the proposal.

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [January 5, 2022, 8:38pm UTC](https://forums.swift.org/t/se-0335-introduce-existential-any/53934/135 "2022-01-05T20:38:49Z")

</div>

Thanks for clarification, it's much clearer now.

In this case, since we're treating `typealias Foo = Any` as protocol, we lose the ability to directly make an alias to its existential `typealias Bar = any Any`. The workaround is simple, though; we can just do

```swift
typealias Foo = Any
typealias Bar = any Foo

```

so it's not particularly a problem whether we reject direct `Any` existential in type alias or specifically allow `any Any` in there.

However, since we might be allowing/requiring `any Any` in associated types. It might be better to make the rule instead that, _`any` is required for all (existential) type aliases, even for `Any`_. That might be an easier rule to work with.

* * *

> [@hborla](#):
>
> I don't imagine that using `Any` or `AnyObject` as a type witness is particularly common.

Agreed. This should be a pretty rare occurrence. I don't have a strong opinion either.

> [@hborla](#):
>
> It's only in the case where a type alias is used for both _and_ it satisfies an associated type requirement that the type alias must be split into two different ones (once `any` is required) because a protocol is not a valid type witness.

I agreed that it seems automatically migratable.

I was thinking about the special case for `Any` after `any` is required, which I assumed that its type alias would remain as both existential and protocol. Since that's not the case, please kindly ignore it.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [January 6, 2022, 12:56am UTC](https://forums.swift.org/t/se-0335-introduce-existential-any/53934/136 "2022-01-06T00:56:21Z")

</div>

> [@hborla](#):
>
> I thought about the use case for typealiasing `Any` a bit more and I think this example should be the same as other type aliases that can be used as generic constraints:
> 
> ```swift
> typealias Foo = Any
> 
> protocol P1: Foo { ... }
> func bar(foo: any Foo)
> 
> ```
> 
> Otherwise, when the type alias switches from `Any` to e.g. `Sendable` , the code would break (under a language mode where `any` is required).

I would urge you to maintain the rule that a typealias to `Any` can continue to serve as both protocol constraint and existential type without warning. As @Lantua points out, otherwise a user cannot typealias existential type `Any` without jumping through hoops since you also propose to disallow the spelling `any Any`.

> [@hborla](#):
>
> This also means getting rid of the `any Any` warning, which I'm very indifferent about anyway, and it seems like some folks in this thread would prefer to write `any Any` for consistency.

That definitely suffices as an alternative resolution to the problem though :)

---

<div class="post-metadata">

**Author:** ![gwendal.roue](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/gwendal.roue/32/13992_2.png) [@gwendal.roue](https://forums.swift.org/u/gwendal.roue)\
**Post date:** [January 6, 2022, 1:58pm UTC](https://forums.swift.org/t/se-0335-introduce-existential-any/53934/138 "2022-01-06T13:58:42Z")

</div>

> [@xwu](#):
>
> I would urge you to maintain the rule that a typealias to `Any` can continue to serve as both protocol constraint and existential type without warning.

And let's make sure, at the same time, that we support the technique described [here](https://github.com/swift-server/guides/blob/main/docs/concurrency-adoption-guidelines.md#backwards-compatibility-of-declarations-and-checked-swift-concurrency), by not emitting any warning for `any Foo` even if `Foo` is an alias to `Any`:

```swift
#if swift(>=5.5) && canImport(_Concurrency)
public typealias Foo = Swift.Sendable
#else 
public typealias Foo = Any
#endif

```

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [January 6, 2022, 3:19pm UTC](https://forums.swift.org/t/se-0335-introduce-existential-any/53934/139 "2022-01-06T15:19:30Z")

</div>

By the way, when discussing changes to `Any`, there is one secret/magical use-case that I hope is maintained:

```swift
typealias IsRandomAccessCollectionOfIntegers<T> = T where T: RandomAccessCollection, T.Element == Int

func doSomething<Source>(
  _ source: Source
) where IsRandomAccessCollectionOfIntegers<Source>: Any {
// ^^^^^ - this is where the magic happens :)
  let _: Int? = source.first // ✅
}

func useDoSomething() {
  doSomething([1, 2, 3]) // ✅
  doSomething(["one", "two", "three"]) // ❌ Cannot convert value of type 'String' to expected element type 'Int'
}

```

Basically, it allows you to write "constraint aliases" and simplify repeated, verbose generic constraints.

I suspect this is an implementation accident, and I wouldn't be surprised if it isn't tested either in the compiler's test suite or the source-compact suite, but it's awesome and I hope it doesn't get broken unless it is being replaced by true constraint aliases (which would be a good thing to add as part of the overall work to make generics more approachable, IMO).

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [January 6, 2022, 3:38pm UTC](https://forums.swift.org/t/se-0335-introduce-existential-any/53934/140 "2022-01-06T15:38:32Z")

</div>

This is completely inscrutable and super neat!

---

<div class="post-metadata">

**Author:** ![hborla](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/hborla/32/27563_2.png) [@hborla](https://forums.swift.org/u/hborla)\
**Post date:** [January 6, 2022, 5:29pm UTC](https://forums.swift.org/t/se-0335-introduce-existential-any/53934/141 "2022-01-06T17:29:28Z")

</div>

> [@gwendal.roue](#):
>
> And let's make sure, at the same time, that we support the technique described [here](https://github.com/swift-server/guides/blob/main/docs/concurrency-adoption-guidelines.md#backwards-compatibility-of-declarations-and-checked-swift-concurrency), by not emitting any warning for `any Foo` even if `Foo` is an alias to `Any`

I agree:

> [@hborla](#):
>
> I thought about the use case for typealiasing `Any` a bit more and I think this example should be the same as other type aliases that can be used as generic constraints:
> 
> ```swift
> typealias Foo = Any
> 
> protocol P1: Foo { ... }
> func bar(foo: any Foo)
> 
> ```
> 
> Otherwise, when the type alias switches from `Any` to e.g. `Sendable` , the code would break (under a language mode where `any` is required).

> [@Karl](#):
>
> Basically, it allows you to write "constraint aliases" and simplify repeated, verbose generic constraints.
> 
> I suspect this is an implementation accident, and I wouldn't be surprised if it isn't tested either in the compiler's test suite or the source-compact suite, but it's awesome and I hope it doesn't get broken unless it is being replaced by true constraint aliases

This feature is called requirement inference. You could achieve the same thing using a same-type constraint `IsRandomAccessCollectionOfIntegers<Source> == Source` if you only want to write the type alias in the `where` clause (except the compiler currently warns that this same-type constraint is redundant even though it adds requirements via inference). In any case, I'm not proposing to remove the ability to write an unconstrained constraint. There would also be no replacement for `some Any`, which could be useful for some of the future directions around using opaque types in parameter position.

---

<div class="post-metadata">

**Author:** ![Douglas\_Gregor](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/douglas_gregor/32/1362_2.png) [@Douglas\_Gregor](https://forums.swift.org/u/Douglas_Gregor)\
**Post date:** [January 7, 2022, 7:15pm UTC](https://forums.swift.org/t/se-0335-introduce-existential-any/53934/142 "2022-01-07T19:15:22Z")

</div>

Hey all,

Thanks for the fantastic discussion. The Core Team has discussed this proposal and accepted it with modifications. The review result is [here](https://forums.swift.org/t/accepted-with-modifications-se-0335-introduce-existential-any/54504).

Doug

---

<div class="post-metadata">

**Author:** ![ebg](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ebg/32/23208_2.png) [@ebg](https://forums.swift.org/u/ebg)\
**Post date:** [March 28, 2022, 2:24pm UTC](https://forums.swift.org/t/se-0335-introduce-existential-any/53934/143 "2022-03-28T14:24:41Z")

</div>

Which compiler flag will enable this warning in Swift 5.6?

---

<div class="post-metadata">

**Author:** ![davdroman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/davdroman/32/46501_2.png) [@davdroman](https://forums.swift.org/u/davdroman)\
**Post date:** [March 29, 2022, 4:02pm UTC](https://forums.swift.org/t/se-0335-introduce-existential-any/53934/144 "2022-03-29T16:02:25Z")

</div>

> [@ebg](#):
>
> Which compiler flag will enable this warning in Swift 5.6?

There are none (by design):

> [@Finding existentials for \`any\`](https://forums.swift.org/t/finding-existentials-for-any/55956/3):
>
> There isn't currently a way to turn on warnings for missing anys in your code. That's intentional; we're working on a lot of generics ergonomics features right now that may change the way programmers update their current use of existential types. A lot of Swift code today uses existential types where it doesn't need to because existential types were the more natural thing to write. With [opaque parameters](https://github.com/apple/swift-evolution/blob/main/proposals/0341-opaque-parameters.md) and [existential opening for function arguments](https://forums.swift.org/t/pitch-implicitly-opening-existentials/55412) that's being worked on right now, a lot of c…

[Previous page](https://forums.swift.org/t/se-0335-introduce-existential-any/53934.md?page=6)
