Generics type parameter Inherite?

#1

I wrote following code:

class Klass1(T, U); end
class Klass2(U) < Klass1(Nil, U)
  def map(&block : T -> V) forall T, V
    p T
  end
end

Klass2.new.map {|x| x} # => get Nil

Why does T become Nil?
I expected T to become free type parameter.

#2

I don’t think free variables can be determined from block arguments. Seems like it falls back to using the generic argument T from the parent type, which is obviously not intended in this case. This looks like a bug.
The code should probably result in a compile error that T can’t be resolved, like with this code:

def foo(&block : T -> _) forall T # undefined constant T
  p T
end

foo{|x| x}

The exact error message could certainly be improved and tailored to this specific case, but I think that’s the direction.

1 Like
#3

Ok, I understand.
Thank you for your answer.

#4

I opened an issue for the more general case: https://github.com/crystal-lang/crystal/issues/7737