<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="">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. &nbsp;However, even if you disagree, it's clear that programmers are going to continue to independently try to use it, so it's really unfortunate for it to be subtly wrong.</div><div class=""><br class=""></div><div class="">Therefore, I propose that we adopt the following typing rule:</div><div class=""><br class=""></div><div class="">&nbsp; Given a function call expression of the form A(B) (that is, an <i class="">expr-call</i>&nbsp;with a single, unlabelled argument)&nbsp;where B is an&nbsp;<i class="">expr-literal</i>&nbsp;or <i class="">expr-collection</i>, if A has type T.Type for some type T and there is a declared conformance of T to an appropriate literal protocol for B, then the expression is always resolves as a literal construction of type T (as if the expression were written "B as A") rather than as a general initializer call.</div><div class=""><br class=""></div><div class="">Formally, this would be a special form of the argument conversion constraint, since the type of the expression A may not be immediately known.</div><div class=""><br class=""></div><div class="">Note that, as specified, it is possible to suppress this typing rule by wrapping the literal in parentheses. &nbsp;This might seem distasteful; it would be easy enough to allow the form of B to include extra parentheses. &nbsp;It's potentially useful to have a way to suppress this rule and get a normal construction, but there are several other ways of getting that effect, such as explicitly typing the literal argument (e.g. writing "A(Int(B))").</div><div class=""><br class=""></div><div class="">A conditional conformance counts as a declared conformance even if the generic arguments are known to not satisfy the conditional conformance. &nbsp;This permits the applicability of the rule to be decided without having to first decide the type arguments, which greatly simplifies the type-checking problem (and may be necessary for soundness; I didn't explore this in depth, but it certainly feels like a very nasty sort of dependence). &nbsp;We could potentially weaken this for cases where A is a direct type reference with bound parameters, e.g. Foo&lt;Int&gt;([]) or the same with a typealias, but I think there's some benefit from having a simpler specification, both for the implementation and for the explicability of the model.</div><div class=""><br class=""></div><div class="">John.</div></body></html>