The following fails to compile with Error: undefined method 'f' for A (compile-time type is A+)
# snippet 1
class A; end
class B < A
def f; 5; end
end
def g(x : A)
x.f
end
a : A = B.new.as(A)
g(a)
On the other hand, turning A into a module leads to an error-free compilation:
# snippet 2
module A; end
class B; include A
def f; 5; end
end
def g(x : A)
x.f
end
a : A = B.new.as(A)
g(a)
I'd argue the two should behave in the same way - either way we pick - and mark this as a bug.
What are your thoughts?
Type parameters complicate things a bit. The following prints true
# snippet 3
module A
end
class B; include A
def f
5
end
end
a : A = B.new.as(A)
puts a.responds_to?(:f) # prints true
whereas the following prints false
# snippet 4
module A(T)
end
class B(T); include A(T)
def f
5
end
end
a : A(Nil) = B(Nil).new.as(A(Nil))
puts a.responds_to?(:f)
I'm compiling with crystal 0.31.1.
So:
A, which you can instantiate, doesn't define an f method.A is a module and can't be instantiated, and all of the types that include A (in this case just B) define f, so this is finetrue)Makes sense. Shall I close this issue and open a tiny one for the compiler bug?
We can use this issue. Thank you!