Skip to content

[pull] master from ruby:master - #1284

Merged
pull[bot] merged 30 commits into
turkdevops:masterfrom
ruby:master
Aug 6, 2026
Merged

[pull] master from ruby:master#1284
pull[bot] merged 30 commits into
turkdevops:masterfrom
ruby:master

Conversation

@pull

@pull pull Bot commented Aug 6, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

k0kubun and others added 30 commits August 5, 2026 17:50
tool/mkdepend.rb resolved dependency names against the current working
directory before falling back to the source root.  When configure
re-runs in an already-built build directory nested inside the source
tree (e.g. .ruby under the checkout), leftover generated files such
as builtin_binary.rbbin got emitted as build-dir-relative paths:

    builtin.$(OBJEXT): .ruby/builtin_binary.rbbin

Make satisfies such a prerequisite through VPATH as a plain existing
file, so it never matches the builtin_binary.rbbin rule and the file is
never regenerated.  Linking a stale builtin_binary.rbbin with
up-to-date *.rbinc function tables then makes the built ruby fail to
boot during make install:

    <internal:gc>: builtin function index (8) mismatch (expect _bi454 but _bi464) (ArgumentError)

The same defect also emitted .ruby/probes.h and
.ruby/vm_call_iseq_optimized.inc, and dropped the enc/trans/*.trans
dependencies of the generated transcoder sources.

Convert dependency names against the source root only, never the
current working directory, so that generated files keep the bare names
their Make rules use and the generated dependencies no longer vary with
leftover build artifacts.
There are actually 3 tokens in the Ruby grammar: the newline in a
whitespace insensitive position that is ignored, a newline that is
in a whitespace sensitive position that acts as a statement
terminator, and a newline in a whitespace sensisitive position that
acts as the terminator for an expression. The third one doesn't
exist in our grammar at the moment, but I want to add it, because
it makes working with translating the lex output easier.

ruby/prism@3dbe592a76
JRuby must match the native implementation when captures become empty.

ruby/strscan@535f9b43ba
`integer_at` must read captures from the scanner current string.

ruby/strscan@435095d898
Bumps the github-actions group with 3 updates in the / directory: [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/analyze](https://github.com/github/codeql-action) and [github/codeql-action/upload-sarif](https://github.com/github/codeql-action).


Updates `github/codeql-action/init` from 4.37.4 to 4.37.5
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@f205ea1...d1ba80a)

Updates `github/codeql-action/analyze` from 4.37.4 to 4.37.5
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@f205ea1...d1ba80a)

Updates `github/codeql-action/upload-sarif` from 4.37.4 to 4.37.5
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@f205ea1...d1ba80a)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.37.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.37.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.37.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Darwin 27 answers the retry connect(2) on a refused nonblocking socket
with EISCONN, so the retry idiom in Addrinfo#connect_internal returned
an unconnected socket. SO_ERROR still holds the real error, so consult
it after wait_writable, as wait_connectable() in init.c already does.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Commit bb235bd ("Avoid build-time race condition when
cross-compiling from a source tarball") turned out to be only a partial
fix, we also need to cover the case where git is present but we're not
building from a git checkout.

We can simply check if the `git log` command returned any output, if it
didn't then we're not in a git checkout.
[Bug #22123]

Bundler evaluates gemspecs through TOPLEVEL_BINDING, which always belongs
to the main box, so consuming BUNDLER_SETUP while the root box loads
RubyGems runs Bundler code in the main box before RubyGems has finished
loading there. Skip it in every box once error_highlight, did_you_mean and
syntax_suggest are autoloaded, since nothing loaded here needs the bundle
and RUBYOPT=-rbundler/setup sets Bundler up after the boot sequence.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ruby 4.1 autoloads error_highlight, did_you_mean and syntax_suggest and
deletes BUNDLER_SETUP while loading RubyGems, so the early bundler/setup
is only there for Ruby 3.2 through 4.0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Based on the test in #17323, extended to
cover user boxes and the configuration where the decorator gems are not
autoloaded, which is how Ruby 3.2 through 4.0 behave.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
error_highlight, did_you_mean and syntax_suggest are still loaded eagerly
on Ruby 3.2 through 4.0, where BUNDLER_SETUP is loaded in the main box
rather than skipped everywhere, so derive the expectation from the actual
autoload state.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Add documentation-only deprecation notices to Module#ruby2_keywords,
main.ruby2_keywords, Proc#ruby2_keywords, Hash.ruby2_keywords_hash?,
and Hash.ruby2_keywords_hash, as the first phase of the schedule
proposed at https://bugs.ruby-lang.org/issues/22205.
winnt_stat opened a real file handle (open_special +
GetFileInformationByHandle + GetFileType + get_handle_pathname +
CloseHandle, ~5 syscalls) for every existing file just to stat it.
require does this thousands of times per startup.

Add a fast path that returns size/timestamps/attributes from a single
metadata syscall for regular files and directories:

  - GetFileInformationByName (Windows 11 24H2+): one syscall, also gives
    real FileId and link count -> accurate st_ino/st_nlink. Resolved via
    GetProcAddress; Windows 10 and earlier fall through.
  - GetFileAttributesExW (all supported Windows): one syscall for
    size+times+attrs; st_ino/st_nlink left 0/1 (same compromise as the
    existing stat_by_find fallback).

Reparse points (symlinks, AF_UNIX sockets) and unusual errors fall
through to the original handle-based path unchanged.

Single file, one function, no new dependencies. Measured on Ruby 4.0.5:
require "nokogiri" 224 ms -> 81 ms (2.77x); File.stat of an existing
file 112 us -> 21 us (5.4x).
Query FileStatBasicByNameInfo instead of FileStatByNameInfo for the
128-bit file ID; the 64-bit ID does not match the handle-based result
on ReFS.  Fall back to the handle-based path unless the volume serial
matches the drive of the path, to keep st_dev of files behind
cross-volume junctions and mount points, and also for non-disk
devices and filesystems without file IDs.  Drop the
GetFileAttributesExW path that loses st_ino.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Since `prc.refined(*ms).refined(*ns)` is behaviorally equivalent to
`prc.refined(*ms, *ns)`, the copy of the block is deferred until
the first call and the memo is shared by these behaviorally
equivalent Procs.  A Proc that is never called is no longer copied
at all.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
[Feature #22222]

This allows to efficiently load iseq from mmaped files and other
buffers without having to copy the bytes into a Ruby string an
then invoke `RubyVM::InstructionSequence.load_from_binary`.
Up to `RHASH_AR_TABLE_MAX_SIZE` there's no need to initialize
an `st_table`.
Introduce a streaming source hash API (rb_source_hash_init/update/
finalize) in ruby_parser.c, and use it in the lexer of parse.y to
accumulate a hash of the source as each line is read. The hash is
stored in the AST, and will be used to check whether a file still
contains the same source code when it is re-parsed later.
[Feature #21795]

The hash algorithm (currently FNV-1a) is hidden behind the API as an
implementation detail of the interpreter, so it can be changed freely
between releases.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
After each prism parse, compute a source hash of the parsed source and
keep it in the scope node. The data section after an __END__ marker is
not part of the code, so the hash covers the source only up to the end
of the __END__ line, which matches the range that parse.y hashes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Record the source hash in each ISeq. For prism, the hash computed at
parse time is propagated through the scope nodes; for parse.y, it is
taken from the AST, and copied to child iseqs whose AST wrappers are
created separately. Expose it along with the node id via
RubyVM::InstructionSequence#source_hash and #node_id, include it in
the misc hash of #to_a, and preserve it in ISeq binaries (bumping
IBF_DEVEL_VERSION).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
An alias or a method installed via define_method(UnboundMethod) shares the
original method definition, but the CME's owner and defined_class point at
the site where the copy was installed. Combined with the method name (taken
from the original definition), backtraces reported a "Class#method" pair
that never existed: an alias in a subclass was shown as Child#original
instead of Parent#original, and define_method(Original.instance_method(:m))
was shown as A#m instead of Original#m.

Recover the defining module only for shared definitions (def->aliased),
leaving plain, singleton and class methods untouched. Apply it to both
Location#label and the backtrace string built by location_to_str.

Distinguish the singleton-class cases via the singleton's attached object:
define_method(SomeModule.instance_method(:m)) installed on a singleton class
must report SomeModule#m, while an aliased class method (def self.m), whose
iseq cref holds the lexical class rather than the singleton it lives on,
must keep its owner. Only keep the owner when it is the singleton class of
the cref's class; otherwise the cref names the genuine definition site, so
use it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Backtrace labels need the module where a method body was originally
defined, but alias_method and define_method(UnboundMethod) overwrite the
CME owner with the install site, producing "Class#method" pairs that
never existed. The label code reconstructed the origin from a mix of
owner, defined_class and the iseq cref with several heuristics.

Store it directly instead: a new original_module field on
rb_method_definition_t, set once when a body is created. Because the
definition is reference-counted and shared, every alias/define_method
copy inherits it, so the backtrace reader collapses to a field read.

module_function is the one case that also installs an instance method's
shared definition onto the module's singleton class; that copy is still
labeled by its owner (M.f), detected as the copy whose owner is the
singleton class of the definition module.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This patch adds the following methods to String class:

* String#bit_get(offset, lsb_first: true) -> 1 | 0 | nil
* String#bit_set?(offset, lsb_first: true) -> true | false | nil
* String#bit_set(offset, lsb_first: true) -> self
* String#bit_clear(offset, lsb_first: true) -> self
* String#bit_flip(offset, lsb_first: true) -> self
* String#bit_count -> Integer
* String#bitwise_not -> String
* String#bitwise_not! -> self
* String#bitwise_and(other) -> String
* String#bitwise_and!(other) -> self
* String#bitwise_or(other) -> String
* String#bitwise_or!(other) -> self
* String#bitwise_xor(other) -> String
* String#bitwise_xor!(other) -> self

Other than implementation, tests, specs, and docs are added.

Link: [Feature #22118]

## Note

In `string.c`, I wrote some big macro that create method functions and helper
functions:

* STR_DEFINE_BINARY_BITWISE_METHOD
* STR_DEFINE_UNARY_BITWISE_KERNEL
* STR_DEFINE_BINARY_BITWISE_KERNEL

While using macros like this reduces maintainability, I believe it's acceptable
because there are no plans to extend the `bitwise_*` methods beyond this
proposal, and the logic is stable.

On the other hand, other methods such as `bit_get` and `bit_count` are planned to
have argument extensions in the future.
@pull pull Bot locked and limited conversation to collaborators Aug 6, 2026
@pull pull Bot added the ⤵️ pull label Aug 6, 2026
@pull
pull Bot merged commit 2461cae into turkdevops:master Aug 6, 2026
0 of 2 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.