Compilation Error (Iterator bug?)

I’m learning about Iterators and getting a compilation error related to a struct’s visibility that doesn’t make sense to me, although I’m a Crystal newbie so perhaps my expectations are off. Consider the following code:

class Thingy
  include Iterator(Int32)

  def initialize()
    @x = 0
    @y = Slice(Int32).new(5)

  def next
    return stop if @x >= 3
    @x += 1

z =
z.each { |i| puts i }

This is a simple iterator that shold print out the numbers


The instance variable @y has no purpose in this example, but it does have an effect: it results in the compiler error


 6 | @y = Slice(Int32).new(5)
Error: wrong number of type vars for Iterator::Slice(I, T, N) (given 1, expected 3)

Apparently the definition of Slice is being overwritten by Iterator. Checking the code, the redefinition is supposed to be private but is nevertheless visible to the body of Thingy. Is this intentional/expected?

(Note that replacing Slice above with ::Slice fixes the problem and leads to the expected output.)

Not exactly. Basically what’s happening is the Iterator module declares a private struct called Slice with its full path being Iterator::Slice. This is a totally different type than the top level Slice. This behavior is somewhat expected in that the type resolution is wanting to use the Iterator::Slice type since that module is included into your type. By using ::Slice, you’re telling it to use the top level Slice type which is the one you’re actually wanting.

In this case however it’s somewhat unfortunate the internal implementation details are kinda leaking out and conflicting with valid code. Easiest solution would be to rename the internal type so it will no longer conflict.

1 Like

Right, I think we should rename the internal type to SliceIterator or something like that.


That would be great. Do you want me to file a bug/issue (and if so, please tell me how to do that)?

1 Like

Naw it’s fine. I took care of it.