Skip to content

Resolve rbs type aliases and interfaces from their definitions#79

Open
tompng wants to merge 2 commits into
mainfrom
interface_type
Open

Resolve rbs type aliases and interfaces from their definitions#79
tompng wants to merge 2 commits into
mainfrom
interface_type

Conversation

@tompng

@tompng tompng commented Jul 17, 2026

Copy link
Copy Markdown
Member

Fixes the nightly CI failure of test-rbs-versions (latest): rbs HEAD now uses builtin type aliases (range[int], array[U], etc.) in core method signatures where concrete classes and interfaces used to appear (failure example).

Introduce InterfaceType for rbs interface and type alias resolution

  • Type aliases are now expanded from their definitions with DefinitionBuilder#expand_alias2 (available since rbs 2.7.0) instead of mapping known alias names to hardcoded types, so future alias migrations in rbs core signatures keep working, and user-defined aliases resolve too.
  • rbs interfaces become Types::InterfaceType instead of falling back to Object. Completion candidates come from the interface definition, type variables are bound through named_params (_ToAry[Integer]#to_aryArray[Integer]), and overload scoring matches arguments by duck typing ([1][0.5]. completes as Integer because Float#to_int satisfies _ToInt), generalizing the previous ad-hoc to_str/to_int/to_ary checks.
  • Also fixes RBS::Types::Bases::Class conversion which discarded the transform result and referenced an undefined variable.

Limit type alias and interface expansion depth

Recursive aliases guarded by a type constructor (e.g. type json = Integer | Array[json]) are valid RBS — rbs validate only rejects unguarded recursion, and that check does not run on environment load. Eager expansion caused SystemStackError on recursive aliases, and alias chains like type c = b | [b]; type b = a | [a] can expand exponentially even without recursion (which a visited set would not bound). Expansion nesting is limited to 3, falling back to Object at the cutoff, with the count threaded as an argument to stay stateless. The limit also covers the interface case of _match_free_variable, which could recurse infinitely on cyclic generic interfaces.

Testing

  • bundle exec rake test passes with rbs 2.7.0, 3.0, 3.3, 3.4, 3.6, 3.8, 3.10, 4.0 and HEAD (108 tests)
  • Completion on a method whose rbs return type is a recursive json alias: previously SystemStackError (no candidates), now resolves in ~0.4ms including element access like info["a"][0].

🤖 Generated with Claude Code

tompng and others added 2 commits July 18, 2026 02:37
rbs HEAD uses type aliases (range[T], array[U], etc.) in core method
signatures where concrete classes and interfaces used to appear, which
broke completion. Resolve type aliases from their definitions with
expand_alias2 instead of mapping known alias names, and represent rbs
interfaces as InterfaceType instead of falling back to Object. Interface
types provide completion candidates from the interface definition, bind
type variables through named_params, and match argument types by duck
typing in overload scoring.

Also fix RBS::Types::Bases::Class conversion that discarded the transform
result and referenced an undefined variable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Recursive type aliases are valid RBS when guarded by a type constructor
(e.g. `type json = Integer | Array[json]`); only unguarded recursion is
rejected, and only by `rbs validate` which does not run on environment
load. Eager alias expansion caused SystemStackError on recursive aliases,
and nested alias chains can expand exponentially even without recursion,
so a visited set is not enough; limit expansion nesting instead, falling
back to Object at the cutoff.

The nesting count is threaded as an argument: from_rbs_type only recurses
into itself, so each function carries its own counter and resetting at
the method_return_type boundary is safe. The limit also applies to the
interface case of _match_free_variable, which could recurse infinitely on
cyclic generic interfaces regardless of aliases.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant