tupl-tufts / rdl

Types, type checking, and contracts for Ruby
BSD 3-Clause "New" or "Revised" License
602 stars 38 forks source link

Structural types + class methods? #60

Open rmosolgo opened 7 years ago

rmosolgo commented 7 years ago

Hi! I tried out structural typing, but I found that a class with a class method did not pass the structural type check.

Should it pass that check? Here's an example:

# rdl_test.rb
require "rdl"
extend RDL::Annotate

class T
  def m
    1
  end

  def self.m
    2
  end
end

type("([m: () -> Integer]) -> Integer")
def m2(x)
  x.m
end

puts m2(T.new)
puts m2(T)

Outputs:

$ ruby rdl_test.rb
1
/Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rdl-2.1.0/lib/rdl/types/method.rb:245:in `block in check_arg_types': Object#m2: Argument type error. (RDL::Type::TypeError)
Method type:
        ([ m: () -> Integer ]) -> Integer
Actual argument type:
        (Class)
Actual argument values (one per line):
        T
    from /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rdl-2.1.0/lib/rdl/switch.rb:13:in `off'
    from /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rdl-2.1.0/lib/rdl/types/method.rb:237:in `check_arg_types'
    from /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rdl-2.1.0/lib/rdl/wrap.rb:62:in `block in m2'
    from /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rdl-2.1.0/lib/rdl/switch.rb:13:in `off'
    from /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rdl-2.1.0/lib/rdl/wrap.rb:48:in `m2'
    from _rdl_test.rb:20:in `<main>'

So, the instance (T.new) with its instance method passed (seen by the 1 in the output), but the class T with its class method did not pass.

If it should pass, I'm happy to take a look somewhere :)