# Cannot use \`?\` with async?

**URL:** <https://forums.swift.org/t/cannot-use-with-async/69963>\
**Category:** Using Swift\
**Tags:** optionals, asyncawait\
**Created:** [February 11, 2024, 12:12am UTC](https://forums.swift.org/t/cannot-use-with-async/69963 "2024-02-11T00:12:27Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![wadetregaskis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/wadetregaskis/32/8494_2.png) [@wadetregaskis](https://forums.swift.org/u/wadetregaskis)\
**Post date:** [February 11, 2024, 12:12am UTC](https://forums.swift.org/t/cannot-use-with-async/69963/1 "2024-02-11T00:12:27Z")

</div>

```swift
let nonAsyncLocalVariable: [Int]? = []

func throwingAsyncFunc() async throws -> [Int] {
    []
}

let x = try await nonAsyncLocalVariable ?? throwingAsyncFunc()

```

> ```swift
> wot.swift:7:44: error: 'async' call in an autoclosure that does not support concurrency
> let x = try await nonAsyncLocalVariable ?? throwingAsyncFunc()
> ^
> wot.swift:7:13: warning: no 'async' operations occur within 'await' expression
> let x = try await nonAsyncLocalVariable ?? throwingAsyncFunc()
> ^
> error: fatalError
> 
> ```

…but if I _do_ move the `await` like it insists:

> ```swift
> wot2.swift:7:38: error: 'await' cannot appear to the right of a non-assignment operator
> let x = try nonAsyncLocalVariable ?? await throwingAsyncFunc()
> ^
> 
> ```

# 😢

It seems like `??` doesn't have an async-compatible overload? And it behaves differently to other binary operators? Presumably because it uses an `@autoclosure`'d parameter?

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [February 11, 2024, 12:39am UTC](https://forums.swift.org/t/cannot-use-with-async/69963/2 "2024-02-11T00:39:36Z")

</div>

Yep. This is how it'd look like without autoclosed parameter:

```swift
let x = try await nonAsyncLocalVariable ?? throwingAsyncFunc()

```

and this with autoclosed async parameter:

```swift
let y = try await nonAsyncLocalVariable ?? (await throwingAsyncFunc())

```

Not ideal as you'd have to put extra `await` (but not extra `try` 🤔).

> **test code**
>
> ```swift
> let x = try await nonAsyncLocalVariable ??? throwingAsyncFunc()
> let y = try await nonAsyncLocalVariable ???? (await throwingAsyncFunc())
> 
> let nonAsyncLocalVariable: [Int]? = []
> func throwingAsyncFunc() async throws -> [Int] { [] }
> 
> infix operator ???
> func ??? <T>(optional: T?, defaultValue: T) -> T {
> switch optional {
> case .some(let value): value
> case .none: defaultValue
> }
> }
> 
> infix operator ????
> func ???? <T>(optional: T?, defaultValue: @autoclosure () async throws -> T) async rethrows -> T {
> switch optional {
> case .some(let value): value
> case .none: try await defaultValue()
> }
> }
> 
> ```

> [@wadetregaskis](#):
>
> And it behaves differently to other binary operators?

Same happens with short-circuiting bool ops:

```swift
let one = true
func two() async throws -> Bool { true }
try await one || two() // 🛑

```

* * *

And the same happens with other functions that take autoclosed parameters, example:

```swift
precondition(try await two()) // 🛑 'async' call in an autoclosure that does not support concurrency
preCondition{try await two()} // ✅
func preCondition(_ execute: () async throws -> Bool) {...}

```

* * *

Another example, same issue:

```swift
func foo() async -> Int {0}
var dict = [0:0]
dict[0, default: await foo()] // 🛑

```

---

<div class="post-metadata">

**Author:** ![momo](https://avatars.discourse-cdn.com/v4/letter/m/f4b2a3/32.png) [@momo](https://forums.swift.org/u/momo)\
**Post date:** [February 15, 2026, 3:05pm UTC](https://forums.swift.org/t/cannot-use-with-async/69963/3 "2026-02-15T15:05:17Z")

</div>

I have struggled with this myself. Has anyone found a solution?
