None of the following integer literals trigger an ambiguous autocast error:
class A
@x : Int8 | UInt8 = 1
@y : Int8 | UInt8
def initialize
@y = 2
z : Int8 | UInt8 = 3
w = uninitialized Int8 | UInt8
w = 4
end
end
A.new
def foo(x : Int8 | UInt8 = 5)
end
foo
On the other hand foo(5) triggers the error. Similar (lack of) errors can be done with enum types. This happens only since 0.35.0; previous versions will report can't restrict Int32 to Int8 | UInt8 or type must be (Int8 | UInt8), not (Int32 | Int8 | UInt8). This might be due to #9366.
In these cases the compiler chooses the first variant type of the normalized union, i.e. the type whose name comes first alphabetically, which would be Int8 in the above cases. For enums we have:
enum Foo
X
end
enum Foe
X
end
enum Fox
X
end
a : Foo | Foe = :x # "Foo" > "Foe"
a.class # => Foe
b : Foo | Fox = :x # "Foo" < "Fox"
b.class # => Foo
This is certainly unexpected, so assignments like these should trigger an error unless that union already contains an exact match (e.g. Symbol for enums). The question is whether such a fix would constitute a post-1.0 breaking change.
None of the following integer literals trigger an ambiguous autocast error:
On the other hand
foo(5)
triggers the error. Similar (lack of) errors can be done with enum types. This happens only since 0.35.0; previous versions will reportcan't restrict Int32 to Int8 | UInt8
ortype must be (Int8 | UInt8), not (Int32 | Int8 | UInt8)
. This might be due to #9366.In these cases the compiler chooses the first variant type of the normalized union, i.e. the type whose name comes first alphabetically, which would be
Int8
in the above cases. For enums we have:This is certainly unexpected, so assignments like these should trigger an error unless that union already contains an exact match (e.g.
Symbol
for enums). The question is whether such a fix would constitute a post-1.0 breaking change.