Questions about autocasting and method signature

Hello folks,

When I was writing some code that needs Int64 as part of the initialization, found that automatic casting of Int32 args to Int64 on a method only works if the method has the variable type in the signature.

Not working:

class Foo
  getter id : Int64

  def initialize(@id)
  end
end

pp Foo.new(1) # Error: instance variable '@id' of Foo must be Int64, not Int32

Even that @id has been defined with the right type, is not automatically casted.

However, when re-adding it to the method, it works:

class Foo
  getter id : Int64

  def initialize(@id : Int64)
  end
end

f = Foo.new(1)    # OK, no error
puts typeof(f.id) # => Int64

I normally duplicate the types of the instances in the method signature, but was wondering if this is intentional or I might be missing something.

Thank you!

Update: found in the Crystal Book the reference to autocasting:

Autocasting at the moment works only in two scenarios: at function calls, as shown so far, and at class/instance variable initialization.

I think that the first snippet is a consequence of how ivar assignments are expanded.

def m(@ivar) is expanded as def m(ivar); @ivar = ivar.

As such the method has no type restrictions the auto-cast can relay on.

Maybe we can propagate the type of the ivar as type restrictions in those methods so the auto-casting will work and even the typing errors could improve since they will report the call instead of the (implicit) assignment.

I’d really like that to happen. It would actually change the AST so that the type will also show up in docs. I think I thought about this in the past. Now that we are more than one thinking about this, it’s probably a good idea to do it.

That could be awesome! It would definitely reduce some wait, what? mental scenarios :sweat_smile:

:heart: :heart: :heart:

I just sent a proof of concept: Experimental: restriction augmenter by asterite · Pull Request #12103 · crystal-lang/crystal · GitHub