Implicitly unwrapped optionals in tuples

I can use implicitly unwrapped optionals in structs and enums but not tuples:

struct A { var x: Int!, y: Float! } // ✅
enum B { case x(Int!), y(Float!) }  // ✅
typealias C = (x: Int!, y: Float!)  // 🛑 Using '!' is not allowed here; perhaps '?' was intended?

Is this a bug or a feature?

Implicitly unwrapped optionals don't actually exist as a type. It used to exist under the name ImplicitlyUnwrappedOptional<Wrapped> but it was removed to simplify the compiler. Therefore they cannot be used in generic type arguments:

Array<Int?> // allowed
Array<Int!> // not allowed

If you think of a tuple as a builtin variadic generic type you can see why this is not allowed. So I wouldn't say this is either a bug or a feature, but rather a consequence of how implicitly unwrapped optionals work.

2 Likes

Yeah, it perhaps makes sense to think of "implicitly unwrapped" as a property of the declaration to which the type annotation is attached rather than an actual property of the type. It's like if we had, say, an @implicitlyUnwrapped attribute which could be attached to T?-typed variables and would allow the automatic insertion of force-unwrap operators to convert usages of that variable in T-typed contexts, but the type of the variable would still be T? when following the context-less type propagation rules.

3 Likes