Automatic conversion of literal numbers?


def test(v : Float64)
v + 42

p! test(123_i32)

x = 123_i32
p! test(x)

gives the following output

Showing last frame. Use --error-trace for full trace.

error in line 8
Error: no overload matches ‘test’ with type Int32

Overloads are:

  • test(v : Float64)

Please, could somebody explain me why test(123_i32) succeeds while test(x) fails ?

I feel like this is a bug related to autocasting. However @asterite could confirm.

Last Crystal version to catch the error in line 5 is 0.24.2 !

Not a bug. I think it should work like that.

There’s a proposal for that:

I implemented it but other core team members had their doubt so I decided to close it

Do you mean that line 5 of your code (p! test(123_i32)) should cause a compilation error because you’re passing an Int32 literal into a method that only takes a Float64 argument?

I’m asking because it seems like people think you mean that line 5 (above) is working correctly and line 8 (p! test(x)) should also work. Clarifying what you expect to happen would help us help you.

Yes, I actually mean line 5 should throw a compilation error, like line 8 does.
(or, at least, both syntax should have same behavior, I think)
Another example of oddity :

class Test
def initialize(@v : Float64)

compiles, but

class Test
getter v : Float64
def initialize(@v)

throws an error.

1 Like

I don’t think it’s documented but it’s a language feature. Literals can be automatically casted to an argument with a type restriction as long as the value fits in the target type. Only if there’s a type restriction.