Search code examples
rubysorbet

How do I include Enumerable in a project using sorbet?


If I define an enumerable class like

# typed: strict

class MyEnumerable
  extend T::Generic
  extend T::Sig
  include Enumerable

  Elem = type_member

  sig {override.params(blk: T.proc.params(arg: Elem).returns(BasicObject)).returns(NilClass)}
  def each(&blk)
  end
end

This type checks with srb tc just fine, but if I try to run srb rbi update, I get an error. Checking the reflection.json.err

reflection.rbi:15619: Type variable `Elem` needs to be declared as `= type_member(SOMETHING)` https://srb.help/5018
       15619 |  Elem = ::T.let(nil, ::T.untyped)
                ^^^^

Changing the Elem declaration to (i.e. how it is defined in the Enumerable rbi)

    Elem = type_member(:out)

now srb tc gives me the error

Classes can only have invariant type members https://srb.help/5016
     9 |    Elem = type_member(:out)
            ^^^^^^^^^^^^^^^^^^^^^^^^
Errors: 1

changing the Elem declaration to

    Elem = type_member(:invariant)

now srb tc gives me the error

Invalid variance kind, only :out and :in are supported https://srb.help/4011
     9 |    Elem = type_member(:invariant)
                               ^^^^^^^^^^
Errors: 1

How can I implement an Enumerable class in a project using sorbet such that it both type checks and doesn't error when running srb rbi update?


Solution

  • This looks like a bug in Sorbet. I don't know of a workaround. Please file an issue at https://github.com/sorbet/sorbet. Unfortunately we have limited resources and so will have to make a decision about how to prioritize this.