Skip to content

Release Note 4.2

Soutaro Matsumoto edited this page Aug 18, 2026 · 1 revision

Some of the highlights in RBS 4.2 are:

  • Non-ASCII identifiers (#3082)
  • Correct type parameter alignment across declarations (#3067, #3068)
  • Parser and AST support for ... forwarding parameters, disabled by default (#3042, #3087)
  • Parser byte-range and CRLF location fixes (#3083, #3085, #3069)

You can install it with $ gem install rbs --pre or using Bundler.

gem 'rbs', '~> 4.2.0'

Read the CHANGELOG for the details.

Non-ASCII identifiers

PR: #3082

RBS now accepts non-ASCII characters in identifiers, following Ruby's identifier rules more closely.

Method and variable names can start with non-ASCII characters. Non-ASCII characters can also appear after the first character of class names, module names, interface names, type aliases, and type parameters.

class ServicioÚltimaVez
  MI_CONSTANTE_Ñ: Integer

  def 日本語: () -> void
  def con_parametros: (Integer 引数, キーワード: String) -> void

  @@クラス変数: Integer

  attr_reader nombre_único: String
end

Names whose first character determines the kind of name must still start with an ASCII character. This applies to class and module names, interface names, type alias names, and type parameters.

class Foo日本語
end

class 日本語 # Syntax error
end

The Unicode tables used by the C lexer have also been updated from Prism 1.9.0.

Type parameter alignment across declarations

PRs: #3067, #3068

When a class or module has multiple declarations, the declarations can use different names for compatible type parameters.

interface _Reader[T]
  def read: () -> T
end

module M[A] : _Reader[A]
end

module M[B] : _Reader[B]
end

RBS now consistently aligns references from the other declarations with the type parameter names of the primary declaration. In this example, both self types are treated as _Reader[A].

The alignment also applies to superclass validation and to references from type parameter bounds and default types. This prevents free type variables and false SuperclassMismatchError or GenericParameterMismatchError errors when compatible declarations use different parameter names.

Parser fixes

Byte-range validation

PRs: #3083, #3085

RBS::Parser now rejects a byte_range whose starting position is inside a multibyte character or past the end of the buffer.

RBS::Parser.parse_type('"🐕🐈"', byte_range: 2...)
# => ArgumentError: position range starts inside a character: 2...10

RBS::Parser.parse_type("Integer", byte_range: 20...30)
# => ArgumentError: position range starts past the end of the buffer: 20...30, buffer is 7 bytes

Starting past the end of the buffer previously caused the lexer to loop indefinitely. CRuby and JRuby now report the same errors for these invalid positions.

Comment locations in CRLF files

PR: #3069

Comment tokens in CRLF files no longer include the \r from the line ending. This fixes an off-by-one Location#end_line, which could cause incorrect diagnostics in tools built on RBS::Parser.lex.

A bare \r without a following \n remains part of the comment, preserving the existing behavior.

Forwarding parameter syntax

PRs: #3042, #3087

Warning

Forwarding parameter syntax is defined by the parser and represented in the AST, but is not yet supported by the layers built on top of the parser. It is disabled by default in RBS 4.2 and is not enabled by the public RBS::Parser API, so it cannot be used in regular RBS signatures yet.

The parser and AST now support Ruby-style ... forwarding parameters in method types.

def request: (...) -> Response
def logged_request: (String message, ...) -> Response

When using the C parser directly, enable the syntax with rbs_parser_options_t and pass the options to rbs_parser_new_with_options.

rbs_parser_options_t options = {
    .enable_forwarding_params = true,
};

rbs_parser_t *parser = rbs_parser_new_with_options(
    string,
    encoding,
    start_pos,
    end_pos,
    options
);

Zero-initialized options leave the syntax disabled, as does rbs_parser_new.

Clone this wiki locally