Skip to content

Unsubstituted generic type argument can leak in generic subclass #10834

Open
@HertzDevil

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.

Metadata

Assignees

No one assigned

    Labels

    kind:bugA bug in the code. Does not apply to documentation, specs, etc.topic:compiler:semantic

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions