<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">On Jun 2, 2016, at 9:08 AM, John McCall via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><div><blockquote type="cite" class=""><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="">The official way to build a literal of a specific type is to write the literal in an explicitly-typed context, like so:<div class=""><font face="Andale Mono" class="">&nbsp; &nbsp; let x: UInt16 = 7</font></div><div class="">or</div><div class=""><font face="Andale Mono" class="">&nbsp; &nbsp; let x = 7 as UInt16</font></div><div class=""><br class=""></div><div class="">Nonetheless, programmers often try the following:</div><div class=""><font face="Andale Mono" class="">&nbsp; &nbsp; UInt16(7)</font></div><div class=""><br class=""></div><div class="">Unfortunately, this does <i class="">not</i> attempt to construct the value using the appropriate literal protocol; it instead performs overload resolution using the standard rules, i.e. considering only single-argument unlabelled initializers of a type which conforms to IntegerLiteralConvertible. &nbsp;Often this leads to static ambiguities or, worse, causes the literal to be built using a default type (such as Int); this may have semantically very different results which are only caught at runtime.</div><div class=""><br class=""></div><div class="">In my opinion, using this initializer-call syntax to build an explicitly-typed literal is an obvious and natural choice with several advantages over the "as" syntax.</div></div></div></blockquote><div><br class=""></div><div>I completely agree that this is a problem that we need to solve. &nbsp;In addition to the trap of using [U]Int64 values on 32-bit targets, it is embarrassing that we reject (on all targets):</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space: pre;">        </span>let x =&nbsp;UInt64(0x8000_0000_0000_0000)</div><div><br class=""></div><div>and require people to use the less obvious syntax:</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>let x =&nbsp;0x1000_0000_0000_0000 as UInt64</div><div><br class=""></div><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Therefore, I propose that we adopt the following typing rule:</div></div></blockquote><div><br class=""></div><div>I’m sorry of this has already been covered down-thread (just getting caught up now, and haven’t read it all), but this seems like a LOT of magic in the type checker to solve this problem.</div><div><br class=""></div><div>Can’t we just require that literal convertibles implement an initializer that the type checker will already consider to be more specific than any of the other overloads? &nbsp;This would eliminate the need for magic like this in the type checker. &nbsp;Right now, we have this:</div><div><br class=""></div><div>public protocol IntegerLiteralConvertible {<br class="">&nbsp;&nbsp;associatedtype IntegerLiteralType : _BuiltinIntegerLiteralConvertible<br class="">&nbsp;&nbsp;init(integerLiteral value: IntegerLiteralType)<br class="">}<br class=""><br class=""></div><div>Change it to be an unlabeled requirement like this probably isn’t enough to make it privileged in the case of ambiguity:</div><div><br class=""></div><div>public protocol IntegerLiteralConvertible {<br class="">&nbsp;&nbsp;associatedtype IntegerLiteralType : _BuiltinIntegerLiteralConvertible<br class="">&nbsp;&nbsp;init(_ value: IntegerLiteralType)<br class="">}<br class=""><br class=""></div><div>but perhaps we could have:</div><div><br class=""></div><div>public protocol IntegerLiteralConvertible {<br class="">&nbsp;&nbsp;associatedtype IntegerLiteralType : _BuiltinIntegerLiteralConvertible<br class="">&nbsp;&nbsp;init(integerLiteral&nbsp;value: IntegerLiteralType)<br class="">&nbsp;&nbsp;init&lt;T : IntegerLiteralConvertible&gt;(_ value: T)<br class="">}<br class=""></div><div><br class=""></div><div>and get the type checker to consider the later one to be a“more specific” match than the other overloads, when confronted with a literal?</div><div><br class=""></div><div>-Chris</div><div><br class=""></div></div></body></html>