Skip to content

Add rewriter option for erasing generics #924

@amomchilov

Description

@amomchilov

Motivation

Sorbet runtime can't type-check generics at runtime:

Example error not being detected at runtime
#!/usr/bin/ruby

require "sorbet-runtime"

class Box
  extend T::Generic
  
  Value = type_member
  
  def initialize(value)
    @value = value
  end
end

extend T::Sig

sig { returns(Box[Integer]) }
def box_of_int = Box[String].new("Not an integer!")

box_of_int() # no runtime error.

If we're using the Spoom rewriter for the sole purpose of reifying RBS sigs to enable type-checking in CI, then there's no benefit for us to keep the generic types around.

E.g. there's no reason to extend T::Generic, if we don't need the [] method.

Proposed solution

Add a new setting like erase_generic_types: bool to RBSCommentsToSorbetSigs.

For this example input:

#: [E]
class Box
  #: -> void
  def initialize
    @elems = [] #: T::Array[E]
  end
end

#: -> Box[Integer]
def box_of_int = Box.new(123) #: Box[Integer]

When enabled, the rewritten output would erase generics, like so:

 class Box
- extend T::Generic
- 
- E = type_member
  
  sig { void }
  def initialize
    @elems = [] #: T::Array[E]
  end
 end
 
-sig { returns(Box[Integer]) }
+sig { returns(Box) }
 def box_of_int = Box.new(123) #: Box[Integer]

This would also involved changing how method signatures are translated, so we'd need to add them same setting to RBI::RBS::MethodTypeTranslator in the rbi gem first.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions