SwiftQARandom

What are opaque return types (some) and why were they introduced?

The problem opaque types solve

Before Swift 5.1 (SE-0244), if you wanted a function to return “something conforming to protocol P” without committing to a concrete return type, your only option was returning the protocol type itself as an existential. This breaks down in two important cases:

1. Protocols with associated types (or Self requirements) can’t be used this way at all

protocol Container {
    associatedtype Item
    var items: [Item] { get }
}
func makeContainer() -> Container { ... } // ❌ compile error

2. Even when it compiles, returning the protocol type erases useful information — and costs performance

Every caller only knows “this is some Shape” — type identity is lost (can’t compare two Shape existentials even if both concrete types are the same and comparable), and existentials require witness tables and possibly heap-boxing.

The some solution: opaque types

func makeShape() -> some Shape {
    return Circle()
}
  • The compiler knows the concrete type at the definition site — compiles down the generics path, direct calls, no witness-table indirection.
  • The caller does not know the concrete type, but relies on it consistently.
  • Type identity is preserved across calls to the same function — two calls to makeShape() always return the same underlying concrete type.
  • It unlocks associated-type protocols as return types — some Container works even though -> Container doesn’t.

Concrete motivating example — SwiftUI

var body: some View {
    VStack {
        Text("Hello")
        Image(systemName: "star")
    }
}

View has an associated type (Body), so -> View isn’t even expressible as an existential in general.

Comparison table

-> Shape (existential) -> some Shape (opaque)
Concrete type known to compiler? No (erased) Yes, at definition site
Concrete type known to caller? No No
Same type guaranteed across calls? No Yes
Works with associated-type protocols? Often no Yes
Performance Witness table, possible heap box Same as concrete type
Can compare with Equatable? No (unless same concrete type provably) Yes

One-liner if pressed: “Opaque types (some) let a function hide its concrete return type from callers while still giving the compiler full knowledge of it internally — you get the abstraction of a protocol return type without the existential’s cost or its associated-type limitations, because the compiler treats it like specialized generic code rather than a boxed existential.”