Need help understanding opaque types

I'm trying to understand why let notWorking: () -> some View = { EmptyView() } doesn't compile.

In the following example, I'm passing a closure to a function argument with the same annotation as notWorking, ie: () -> some View, and it works. So why can't I assign the closure with explicit typing?

import SwiftUI

// Able to assign EmptyView to some View
let working: some View = EmptyView()

// Function that accepts a closure returning some View
func throwAway(closure: () -> some View) -> some View {
    closure()
}

// Passing a closure that returns some View, works as expected
print(throwAway { EmptyView() })

// However, this line causes a compiler error
// error: cannot convert value of type 'EmptyView' to closure result type 'some View'
let notWorking: () -> some View = { EmptyView() }

Edit:
The same error occurred with a different example, and no imports were involved. (not sure if this changes things, I want to emphasize this is not a SwiftUI first question)

protocol View { }

struct EmptyView: View { }

let working: some View = EmptyView()

func throwAway(closure: () -> some View) -> some View {
    closure()
}

print(throwAway { EmptyView() })

let notWorking: () -> some View = { EmptyView() }

This is supposed to work, as part of swift-evolution/proposals/0328-structural-opaque-result-types.md at main · apple/swift-evolution · GitHub. Do you mind filing a bug? Issues · apple/swift · GitHub.

As a workaround you can use your func throwAway, or do something like this:

protocol View {}
struct EmptyView: View {}

let fn = { EmptyView() }
let fn2: () -> some View = fn
3 Likes

Thank you for replying and for showing me a workaround.

Do you mind filing a bug?

Sure, I have filed one here. Expected assignment to opaque type fails · Issue #73789 · apple/swift · GitHub

2 Likes