Any idea why the following code is generating a runtime exception?:

Adding an explicit type declaration solves the problem:

But why? If you Cmd-? over let a you discover that the inferred type in the first example is: [NSObject] not [Any]. It is then, perhaps, a little clearer why the runtime is generating the error:

fatal error: array cannot be bridged from Objective-C

The runtime is throwing up its hands and saying it doesn’t know how to convert from [NSObject] to [Any].

However it feels like this should be picked up by the compiler rather than produce a runtime exception, so I’ve filed a bug report with Apple to that effect: rdar://25799364

Converting Any to [Any]

Different problem, but again Any is involved in causing a runtime exception:

Examining the error message:

Could not cast value of type 'Swift.Array<Swift.Int>' to 'Swift.Array<protocol<>>'

… and noting that Any is defined as:

public typealias Any = protocol<>

… means the error can be translated as:

Could not cast value of type 'Swift.Array<Swift.Int>' to 'Swift.Array<Any>'

This seems counter intuitive - “Surely all types can be converted into Any”. However Airspeed Velocity on stackoverflow nudged my understanding in the right directly with this answer

While every type conforms Any, this is not the same as it being a universal implicit superclass that all types inherit from. . . Since value types are held directly in the array, the ([Any]) array would be a very different shape (to the [Int] array) so under the hood the compiler would have to do the equivalent of this: { $0 as Any }

which allows me to write a conversion from Any to [Any]:

func convertToArray(value: Any) -> [Any] {
    let nsarrayValue = value as! NSArray
    return {$0 as Any}

The code then works:

Hopefully this will help someone (or my future self), not waste so much time with confusing Any related problems.

A playground containing these examples can be downloaded here