<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Oct 10, 2016, at 11:08 AM, Joe Groff &lt;<a href="mailto:jgroff@apple.com" class="">jgroff@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Oct 9, 2016, at 1:10 PM, Erica Sadun via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Normally in guard and if condition lists, you look up a value in a dictionary and conditionally cast:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; if let value = dict[key] as? T, ...</div><div class=""><br class=""></div><div class="">The "as?" operator passes the Any? type through, and the lhs result is T, not T?.</div><div class=""><br class=""></div><div class="">* dict[key] returns Any?</div><div class="">* Any? as T returns T?, not T??</div><div class="">* the conditional binding binds T? to T</div><div class="">* PROFIT!</div><div class=""><br class=""></div><div class="">However, this (somewhat illogical) "sugar" doesn't happen when you conditionally cast T? to U, for example, when a dictionary is [AnyHashable: String]:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 16px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">guard</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> value = </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">dict</span><span style="font-variant-ligatures: no-common-ligatures" class="">[</span><span style="font-variant-ligatures: no-common-ligatures; color: #d12f1b" class="">"Key"</span><span style="font-variant-ligatures: no-common-ligatures" class="">] </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">as</span><span style="font-variant-ligatures: no-common-ligatures" class="">? </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">NSString</span></div><div style="margin: 0px; font-size: 16px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">else</span><span style="font-variant-ligatures: no-common-ligatures" class=""> { </span><span style="font-variant-ligatures: no-common-ligatures; color: #3e1e81" class="">fatalError</span><span style="font-variant-ligatures: no-common-ligatures" class="">() }</span></div></div><div class=""><br class=""></div><div class="">(see&nbsp;<a href="http://i.imgur.com/SkXkk6o.jpg" class="">http://i.imgur.com/SkXkk6o.jpg</a>)</div><div class=""><br class=""></div><div class=""><div class="">* dict[key] returns String?</div><div class="">* String? as T is guaranteed to fail</div><div class=""><br class=""></div></div><div class="">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:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 16px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">guard</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> value = </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">dict</span><span style="font-variant-ligatures: no-common-ligatures" class="">[</span><span style="font-variant-ligatures: no-common-ligatures; color: #d12f1b" class="">"Key"</span><span style="font-variant-ligatures: no-common-ligatures" class="">] </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">as</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">Any</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">as</span><span style="font-variant-ligatures: no-common-ligatures" class="">? </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">NSString</span></div><div style="margin: 0px; font-size: 16px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">else</span><span style="font-variant-ligatures: no-common-ligatures" class=""> { </span><span style="font-variant-ligatures: no-common-ligatures; color: #3e1e81" class="">fatalError</span><span style="font-variant-ligatures: no-common-ligatures" class="">() }</span></div></div><div class=""><br class=""></div><div class="">If that's not "magic", I don't know what is. &nbsp;(You can also cast the dictionary to [AnyHashable: NSString], etc.)</div></div></div></blockquote><div class=""><br class=""></div>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.</div><div class=""><br class=""></div><div class="">-Joe</div><div class=""><br class=""></div></div></div></blockquote></div><br class=""><div class=""><a href="https://bugs.swift.org/browse/SR-2911" class="">https://bugs.swift.org/browse/SR-2911</a></div><div class=""><br class=""></div><div class="">(changed lists to reply on Swift-Users)</div><div class=""><br class=""></div><div class="">-- E</div><div class=""><br class=""></div></body></html>