Skip to content

Add erase_generic_types option to RBS translators#611

Draft
dejmedus wants to merge 2 commits into
mainfrom
jb-erase-generic-types
Draft

Add erase_generic_types option to RBS translators#611
dejmedus wants to merge 2 commits into
mainfrom
jb-erase-generic-types

Conversation

@dejmedus

@dejmedus dejmedus commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

WIP, implementation will change

dejmedus added 2 commits June 8, 2026 17:05
Previously, `RBS::TypeTranslator` and
`RBS::MethodTypeTranslator` always translated generic
types like `Foo[Bar]`. However, `sorbet-runtime` is
unable to enforce them, so they are superfluous in
runtime contexts

This commit adds a default `false` `erase_generic_types`
kwarg to both translators. When set to `true`
generic types are dropped and the simple type is
returned (`Foo[Bar]` to `Foo`)
Comment on lines -10 to -12
#: (Method, ::RBS::MethodType) -> Sig
def translate(method, type)
translator = new(method)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is just a shim for backwards-compatibility, so there's no need to also add this option here.

Users who want the new API can just switch to .new.

Comment on lines 24 to +25
@result = Sig.new #: Sig
@type_translator = TypeTranslator.new #: TypeTranslator
@erase_generic_types = erase_generic_types

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style nit, keep the ivars initialized from the params first and in-order

Suggested change
@result = Sig.new #: Sig
@type_translator = TypeTranslator.new #: TypeTranslator
@erase_generic_types = erase_generic_types
@erase_generic_types = erase_generic_types
@result = Sig.new #: Sig
@type_translator = TypeTranslator.new #: TypeTranslator

Type.proc.params(arg0: Type.untyped).returns(Type.untyped)
when ::RBS::Types::Variable
Type.type_parameter(type.name)
@erase_generic_types ? Type.untyped : Type.type_parameter(type.name)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rewrite into T.anything rather than T.untyped. It conveys a more specific specific intent.

Suggested change
@erase_generic_types ? Type.untyped : Type.type_parameter(type.name)
@erase_generic_types ? Type.anything : Type.type_parameter(type.name)

assert_equal(
[
SigParam.new("array", Type.simple("Array")),
SigParam.new("item", Type.untyped),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will need to update the tests to match, e.g.

Suggested change
SigParam.new("item", Type.untyped),
SigParam.new("item", Type.anything),

Comment on lines +105 to +108
def test_translate_variable
assert_equal(Type.type_parameter(:T), translate_variable(:T))
assert_equal(Type.type_parameter(:E), translate_variable(:E))
end

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh interesting, I guess this wasn't covered directly before, but indirectly via test/rbi/rbs/method_type_translator_test.rb

Comment on lines +123 to +127
assert_equal(Type.class_of(Type.simple("Foo")), translate("singleton(Foo)", erase_generic_types: true))
assert_equal(
Type.class_of(Type.simple("Foo")),
translate("singleton(Foo)[Bar]", erase_generic_types: true),
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notably, the expected value is the same in both cases. You can emphasize that by extracting the variable in common:

Suggested change
assert_equal(Type.class_of(Type.simple("Foo")), translate("singleton(Foo)", erase_generic_types: true))
assert_equal(
Type.class_of(Type.simple("Foo")),
translate("singleton(Foo)[Bar]", erase_generic_types: true),
)
expected = Type.class_of(Type.simple("Foo"))
assert_equal(expected, translate("singleton(Foo)", erase_generic_types: true))
assert_equal(
expected,
translate("singleton(Foo)[Bar]", erase_generic_types: true),
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants