Open
Description
This was discovered while writing #3649 (comment). Consider:
class Foo(T1)
def foo
{T1}
end
end
class Bar(T2) < Foo(T2)
def bar
{T1, T2}
end
end
x = Bar(Int32).new
x.foo # => {Int32}
x.bar # => {T2, Int32}
This T2
on the last line corresponds to the formal argument in Bar(T2)
's superclass, i.e. it is a Crystal::TypeParameter
, formed by substituting T1
. The same also happens if that argument is a nested generic like Array(T2)
or a splat like *T2
(in that case the type is a Crystal::TypeSplat
instead).
This means those type parameters must be substituted repeatedly until no formal parameters appear in the type.