> I was referring to the subtle distinction between creating an Int32 from a > literal (the first one) and creating an Int from a literal and then > coercing it to Int32 (the second one).
I understand the difference and just trying to find out if that behavior(Int32(x) vs x as Int32) could really produce problems at run-time as was stated in initial message for this proposal.
On 03.06.2016 0:57, Tony Allevato wrote:
On Thu, Jun 2, 2016 at 2:38 PM Vladimir.S <sva...@gmail.com <mailto:sva...@gmail.com>> wrote: What is wrong with your examples? var x1: Int32 = 0 var x2 = Int32(0) print(x1.dynamicType, x2.dynamicType) // Int32 Int32 I was referring to the subtle distinction between creating an Int32 from a literal (the first one) and creating an Int from a literal and then coercing it to Int32 (the second one). So, I was pondering whether this was the cause of some complex expressions I've had problems with in the past. However, looking at the specific code, it looks like I had the *opposite* problem. This expression is evaluated quickly in Swift 2.2: let value = Int64((0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) | (0x3b << 28) | (0x56 << 35) | (0x00 << 42) | (0x05 << 49) | (0x26 << 56) | (0x01 << 63)) This one errors out with "expression was too complex to be solved in reasonable time": let value: Int64 = (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) | (0x3b << 28) | (0x56 << 35) | (0x00 << 42) | (0x05 << 49) | (0x26 << 56) | (0x01 << 63) On 03.06.2016 0:17, Tony Allevato via swift-evolution wrote: > +1. As someone who thought "var x: Int32 = 0" and "var x = Int32(0)" were > equivalent, this is very good to know (and very good to fix). > > I'm starting to wonder now if some of the times I've hit "expression was > too complex" errors with large 64-bit multi-term expressions with literals > were caused by coercions happening that I didn't realize. > > > On Thu, Jun 2, 2016 at 9:31 AM John McCall via swift-evolution > <swift-evolution@swift.org <mailto:swift-evolution@swift.org> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>> wrote: > > The official way to build a literal of a specific type is to write the > literal in an explicitly-typed context, like so: > let x: UInt16 = 7 > or > let x = 7 as UInt16 > > Nonetheless, programmers often try the following: > UInt16(7) > > Unfortunately, this does /not/ 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. 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. > > 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. 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. > > Therefore, I propose that we adopt the following typing rule: > > Given a function call expression of the form A(B) (that is, an > /expr-call/ with a single, unlabelled argument) where B is > an /expr-literal/ or /expr-collection/, 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. > > Formally, this would be a special form of the argument conversion > constraint, since the type of the expression A may not be immediately > known. > > Note that, as specified, it is possible to suppress this typing rule by > wrapping the literal in parentheses. This might seem distasteful; it > would be easy enough to allow the form of B to include extra > parentheses. 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))"). > > A conditional conformance counts as a declared conformance even if the > generic arguments are known to not satisfy the conditional > conformance. 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). We could potentially weaken this for > cases where A is a direct type reference with bound parameters, e.g. > Foo<Int>([]) 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. > > John. > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org <mailto:swift-evolution@swift.org> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>> > https://lists.swift.org/mailman/listinfo/swift-evolution > > > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org <mailto:swift-evolution@swift.org> > https://lists.swift.org/mailman/listinfo/swift-evolution >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution