The Crystal Programming Language Forum

How to get generic Parent's annotation from Child

I’m able to reach a parent’s annotation from within the child. The following works as expected:

annotation Ann
end

@[Ann]
class Parent
  {% puts "#{@type}: #{@type.annotation(Ann)}" %}
end

class Child < Parent
  {% puts "#{@type.superclass}: #{@type.superclass.annotation(Ann)}" %}
end

OUTPUT: https://play.crystal-lang.org/#/r/72gq

# Parent: @[Ann]
# Parent: @[Ann]

The problem arises when the parent is a generic. For instance:

annotation Ann
end

@[Ann]
class Parent(T)
  {% puts "#{@type}: #{@type.annotation(Ann)}" %}
end

class Child < Parent(Int32)
  {% puts "#{@type.superclass}: #{@type.superclass.annotation(Ann)}" %}
end

OUTPUT: https://play.crystal-lang.org/#/r/72gr

# Parent(T): @[Ann]
# Parent(Int32): nil

I expected the following:

# Parent(T): @[Ann]
# Parent(Int32): @[Ann]

That’s because I expected Parent(Int32) to inherit Parent(T)'s annotations.

What is the relationship between Parent(T) and Parent(Int32)?

How do I get Parent(T)'s annotation from within Child < Parent(Int32)?

Thanks for your help already.

This is a bug. Please report it. Thank you!

Another way to look at this: the way annotations work was never formalized. Should annotations be inherited? Should there be a way to ask for annotations and inherit the ones from supertypes? It’s not clear. There’s it a lot missing regarding processing (and defining) annotations so for now my advice is to avoid using them.

I thought so. I will.

Bug report filed here »