> On Oct 9, 2016, at 1:10 PM, Erica Sadun via swift-evolution 
> <[email protected]> wrote:
> 
> Normally in guard and if condition lists, you look up a value in a dictionary 
> and conditionally cast:
> 
>     if let value = dict[key] as? T, ...
> 
> The "as?" operator passes the Any? type through, and the lhs result is T, not 
> T?.
> 
> * dict[key] returns Any?
> * Any? as T returns T?, not T??
> * the conditional binding binds T? to T
> * PROFIT!
> 
> However, this (somewhat illogical) "sugar" doesn't happen when you 
> conditionally cast T? to U, for example, when a dictionary is [AnyHashable: 
> String]:
> 
> guard let value = dict["Key"] as? NSString
>     else { fatalError() }
> 
> (see http://i.imgur.com/SkXkk6o.jpg <http://i.imgur.com/SkXkk6o.jpg>)
> 
> * dict[key] returns String?
> * String? as T is guaranteed to fail
> 
> In this case, the compiler asserts that a cast from String? to an unrelated 
> type NSString always fails. You can mitigate this by sticking an "Any" cast 
> in the middle:
> 
> guard let value = dict["Key"] as Any as? NSString
>     else { fatalError() }
> 
> If that's not "magic", I don't know what is.  (You can also cast the 
> dictionary to [AnyHashable: NSString], etc.)

This is a bug. 'String as NSString' works, and you can cast through Optionals 
'T? as? U', so transitively this also works, despite the misleading warning. 
Please file a bug report if you haven't yet.

-Joe

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to