Skip to content

Add MethodDriftTest to catch method drift between RBS and core - #3221

Open
zonuexe wants to merge 4 commits into
ruby:masterfrom
zonuexe:method-drift-test
Open

zonuexe wants to merge 4 commits into
ruby:masterfrom
zonuexe:method-drift-test

Conversation

@zonuexe

@zonuexe zonuexe commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #3218. Only the last 3 commits are new; the test fails without the singleton methods that #3218 adds. I will rebase this onto master after #3218 is merged.

test/stdlib/method_drift_test.rb works like ConstantDriftTest, but checks methods instead of constants. For a fixed list of platform-invariant core classes (Integer, String, Hash, Binding, ...), it checks both directions:

  • Missing from RBS: methods that Ruby defines are declared in RBS. The test compares singleton_methods(false) with DefinitionBuilder#build_singleton, and public_instance_methods(false) + protected_instance_methods(false) with #build_instance. Only methods implemented in C or <internal:...> count, so methods added by libraries such as pp and json/add are ignored. A method declared on an ancestor counts as declared.
  • Gone from runtime: methods that RBS declares on the class itself are defined at runtime, either public or private. Methods declared with the bot return type are skipped, because RBS uses it for methods that Ruby undefines (e.g. Complex#<).

To check that the test works, I replaced core/hash.rbs with the version from master. The test then reported ::Hash.ruby2_keywords_hash and ::Hash.ruby2_keywords_hash?.

Exceptions in MethodDriftTest::SKIP

Method Reason
Numeric#+, #- Declared on Numeric so that code typed as Numeric can add and subtract (aaf7623). Only the subclasses define them
Struct.members, .keyword_init? Defined only on the classes that Struct.new creates
Enumerable#to_enum, #enum_for TODO: Defined in Kernel. These declarations are no more precise than Kernel#enum_for, so they may be removed
Method#box TODO: Added with the experimental Ruby::Box in Ruby 4.0, which has no signature yet

The first two rows are now documented in a new Q&A item in docs/CONTRIBUTING.md, "Why does RBS declare methods that Ruby does not define on that class?", together with the bot convention.

Other changes

  • Adds Binding#irb: (?show_code: boolish) -> void. It is defined in <internal:prelude> and was not declared anywhere. It has no test, because calling it starts an IRB session.

Ruby development builds

On a development build of Ruby (RUBY_PATCHLEVEL < 0, i.e. ruby-head), the test reports drift with notify instead of failing. New methods appear on head before they can be declared in RBS: the first CI run of this PR found 22 on Ruby 4.1.0dev, such as String#bit_get and Range#clamp. On Ruby 4.0 the test fails as usual. Whether to also run it as a failing nightly job on head can be decided separately.

Add signatures for singleton methods that are defined in Ruby 4.0 but
were missing from core/:

- Hash.ruby2_keywords_hash, Hash.ruby2_keywords_hash?
- Kernel.set_trace_func, Kernel.trap
- Process.last_status, Process.setpgrp
- Process::Status.wait
- Process::Sys.getegid
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