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.

2 Likes

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.

5 Likes

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.

12 Likes

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

8 Likes