rbs 4.1.3 → 4.2.0.pre.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +1 -0
  3. data/.github/workflows/bundle-update.yml +2 -2
  4. data/.github/workflows/c-check.yml +2 -2
  5. data/.github/workflows/changelog.yml +121 -0
  6. data/.github/workflows/comments.yml +2 -2
  7. data/.github/workflows/dependabot.yml +1 -1
  8. data/.github/workflows/jruby.yml +3 -3
  9. data/.github/workflows/release-gems.yml +6 -7
  10. data/.github/workflows/ruby.yml +6 -6
  11. data/.github/workflows/rust.yml +12 -12
  12. data/.github/workflows/truffleruby.yml +2 -2
  13. data/.github/workflows/typecheck.yml +2 -2
  14. data/.github/workflows/wasm.yml +3 -3
  15. data/.github/workflows/windows.yml +2 -2
  16. data/CHANGELOG.md +27 -0
  17. data/Rakefile +50 -21
  18. data/config.yml +5 -0
  19. data/docs/CONTRIBUTING.md +1 -1
  20. data/docs/release.md +57 -1
  21. data/docs/stdlib.md +8 -0
  22. data/docs/syntax.md +12 -0
  23. data/ext/rbs_extension/ast_translation.c +15 -0
  24. data/ext/rbs_extension/class_constants.c +2 -0
  25. data/ext/rbs_extension/class_constants.h +1 -0
  26. data/ext/rbs_extension/main.c +55 -19
  27. data/include/rbs/ast.h +21 -13
  28. data/include/rbs/defines.h +2 -2
  29. data/include/rbs/lexer.h +13 -12
  30. data/include/rbs/parser.h +37 -3
  31. data/lib/rbs/ast/declarations.rb +1 -1
  32. data/lib/rbs/ast/type_param.rb +1 -1
  33. data/lib/rbs/definition_builder/ancestor_builder.rb +8 -5
  34. data/lib/rbs/definition_builder/method_builder.rb +4 -4
  35. data/lib/rbs/definition_builder.rb +5 -2
  36. data/lib/rbs/environment/class_entry.rb +12 -0
  37. data/lib/rbs/environment/module_entry.rb +26 -1
  38. data/lib/rbs/parser_aux.rb +2 -2
  39. data/lib/rbs/types.rb +44 -2
  40. data/lib/rbs/version.rb +1 -1
  41. data/lib/rbs/wasm/parser.rb +62 -25
  42. data/lib/rbs/wasm/runtime.rb +19 -4
  43. data/lib/rbs/wasm/serialization_schema.rb +3 -2
  44. data/schema/function.json +12 -1
  45. data/sig/environment/class_entry.rbs +6 -0
  46. data/sig/environment/module_entry.rbs +15 -0
  47. data/sig/parser.rbs +4 -4
  48. data/sig/types.rbs +11 -1
  49. data/src/ast.c +17 -1
  50. data/src/lexer.c +1562 -1560
  51. data/src/lexer.re +50 -18
  52. data/src/lexstate.c +2 -1
  53. data/src/parser.c +130 -70
  54. data/src/serialize.c +20 -13
  55. data/src/util/rbs_encoding.c +195 -49
  56. data/wasm/README.md +20 -4
  57. data/wasm/rbs_wasm.c +93 -37
  58. metadata +3 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f90000891f13d57d27beb58a5176f5ff595e58628c51982dc18d985796bbb90d
4
- data.tar.gz: 7f70e0544fa9c1b1312f1d4f0da5da4fa448bb651ced22f92bc8a6332507d501
3
+ metadata.gz: 2d5559ae50bcf0c82ad2410de2a377281851fd0156e31d305ac42bfcd6c68867
4
+ data.tar.gz: 5e8fd44b4f83cae246ebe0683ecf46a933986bf882a9d14857cc0c0cac2c848a
5
5
  SHA512:
6
- metadata.gz: 5b69502540c88356e2a22e89fe9931fe873421510b64004e7aec332cdb3393a0e75b72cdab2462f020efd9f3bd8b7d5b18b48b53b6ec133c09823c8c518e4536
7
- data.tar.gz: 4598739801a2982e9517e34f11d64ab367a6cf70346866f8937fc44cf7496d4fc099b64510d966fc01c007421e63b07c5de59f17a33fa4140af0f5aa3f0a9193
6
+ metadata.gz: 6a8ee224d637ca355d061d971061c6754165add8dec1e8b0cfd6083fdd030e9b1ff5dbf7bdb35bfc103c9f1cba24b5233a029e102d6996fe1edc0c4bcf49ce54
7
+ data.tar.gz: 2620421db463ab2150517408e6ba6e826ea6408847be33cd2c5b685198b571acddf66abccddd023ac5dcd60dc08b0d8c8936a01760f1979dc9218ac0731ff8db
data/.gitattributes ADDED
@@ -0,0 +1 @@
1
+ src/lexer.c linguist-generated
@@ -11,10 +11,10 @@ jobs:
11
11
 
12
12
  steps:
13
13
  - name: Checkout repository
14
- uses: actions/checkout@v7
14
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
15
15
 
16
16
  - name: Set up Ruby
17
- uses: ruby/setup-ruby@v1
17
+ uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
18
18
  with:
19
19
  ruby-version: '4.0'
20
20
 
@@ -14,8 +14,8 @@ jobs:
14
14
  format-check:
15
15
  runs-on: ubuntu-latest
16
16
  steps:
17
- - uses: actions/checkout@v7
18
- - uses: ruby/setup-ruby@v1
17
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
18
+ - uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
19
19
  with:
20
20
  ruby-version: "4.0"
21
21
  bundler-cache: none
@@ -0,0 +1,121 @@
1
+ name: Changelog
2
+
3
+ # Prints the changelog template for a release, which is otherwise `rake gem:changelog`
4
+ # on a laptop.
5
+ #
6
+ # The task asks GitHub which pull requests the commits came from, and it asks through
7
+ # `gh`. A Claude Code on the web session cannot reach `api.github.com` at all -- the
8
+ # refusal is keyed on the session, so neither installing `gh` nor rewriting the task
9
+ # against REST gets around it -- and a runner has both `gh` and `github.token`. So the
10
+ # same task runs here, and the release is prepared from a session that could not
11
+ # otherwise produce this list.
12
+ #
13
+ # The ref selector picks the branch the changelog is for *and* the copy of the task
14
+ # that computes it, which are the same thing: dispatch it on `aaa-X.Y.x` for a patch
15
+ # release, on `master` otherwise.
16
+ #
17
+ # Nothing is written. The run reads the repository and prints.
18
+
19
+ on:
20
+ workflow_dispatch:
21
+ inputs:
22
+ version:
23
+ description: "Where the changelog starts, if not the RBS::VERSION of the ref (e.g. 4.1.0)"
24
+ required: false
25
+ type: string
26
+ format:
27
+ description: "The changelog template, or the JSON its sections are sorted from"
28
+ required: false
29
+ default: list
30
+ type: choice
31
+ options:
32
+ - list
33
+ - json
34
+
35
+ permissions:
36
+ contents: read
37
+
38
+ jobs:
39
+ changelog:
40
+ name: changelog
41
+ runs-on: ubuntu-latest
42
+ permissions:
43
+ contents: read # the history and the tags
44
+ pull-requests: read # what the commits came from
45
+ env:
46
+ # The inputs are read through the environment rather than interpolated into
47
+ # the script below.
48
+ VERSION: ${{ inputs.version }}
49
+ FORMAT: ${{ inputs.format }}
50
+ GH_TOKEN: ${{ github.token }}
51
+ steps:
52
+ # `changelog_base` resolves the previous release with `git describe`, the task
53
+ # walks the history back to it, and on a release branch it reads the `-x`
54
+ # trailers of the commits it finds -- so the full history and the tags are all
55
+ # needed. `fetch-depth: 0` fetches both.
56
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
57
+ with:
58
+ fetch-depth: 0
59
+
60
+ # Before the gems are installed, since a version that cannot be a version is
61
+ # cheapest to reject here.
62
+ - name: Check the input
63
+ run: |
64
+ version_pattern='^[0-9]+\.[0-9]+\.[0-9]+(\.(pre|dev)\.[0-9]+)?$'
65
+ if [ -n "$VERSION" ] && ! [[ "$VERSION" =~ $version_pattern ]]; then
66
+ echo "::error::\`$VERSION\` is not a version number."
67
+ exit 1
68
+ fi
69
+
70
+ - name: Set up Ruby
71
+ uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
72
+ with:
73
+ ruby-version: ruby
74
+ bundler: none
75
+ - name: Install gems
76
+ run: |
77
+ bundle config set --local without libs:profilers
78
+ bundle install --jobs 4 --retry 3
79
+
80
+ # Only the changelog goes to STDOUT; the task reports what it is doing, and
81
+ # which pull requests it skipped, on STDERR. `tee` keeps both in the log, in
82
+ # order, and puts the changelog on its own where the next step can read it.
83
+ - name: Print the changelog
84
+ run: |
85
+ if [ "$FORMAT" = "json" ]; then
86
+ task="gem:changelog:json"
87
+ else
88
+ task="gem:changelog"
89
+ fi
90
+ if [ -n "$VERSION" ]; then
91
+ task="$task[$VERSION]"
92
+ fi
93
+
94
+ echo "Running \`rake $task\` on $(git rev-parse --abbrev-ref HEAD)"
95
+ bundle exec rake "$task" | tee changelog.out
96
+
97
+ # Uploaded before it is rendered, so that the changelog survives whatever the
98
+ # summary makes of it. This is also what to reach for when the JSON is long
99
+ # enough to be truncated in the log.
100
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
101
+ with:
102
+ name: changelog
103
+ path: changelog.out
104
+
105
+ # The log carries this too, but the summary renders it. A step summary is
106
+ # capped at 1MiB and the step fails if that is exceeded, which a long JSON
107
+ # could manage -- so past a comfortable fraction of it, link the artifact
108
+ # rather than lose the run over formatting.
109
+ - name: Render the changelog
110
+ run: |
111
+ if [ "$(wc -c < changelog.out)" -gt 900000 ]; then
112
+ echo "The changelog is too long to render here. Download the \`changelog\` artifact." \
113
+ >> "$GITHUB_STEP_SUMMARY"
114
+ exit 0
115
+ fi
116
+
117
+ {
118
+ echo '```markdown'
119
+ cat changelog.out
120
+ echo '```'
121
+ } >> "$GITHUB_STEP_SUMMARY"
@@ -13,8 +13,8 @@ jobs:
13
13
  # env:
14
14
  # RUBY_COMMIT: v4.0.0-preview2
15
15
  steps:
16
- - uses: actions/checkout@v7
17
- - uses: ruby/setup-ruby@v1
16
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
17
+ - uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
18
18
  with:
19
19
  ruby-version: "4.0.6"
20
20
  bundler: none
@@ -17,7 +17,7 @@ jobs:
17
17
  uses: dependabot/fetch-metadata@25dd0e34f4fe68f24cc83900b1fe3fe149efef98 # v3.1.0
18
18
  id: metadata
19
19
  - name: Checkout repository
20
- uses: actions/checkout@v7
20
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
21
21
  with:
22
22
  fetch-depth: 0
23
23
  - name: Abort if blocker files are changed
@@ -33,13 +33,13 @@ jobs:
33
33
  name: jruby
34
34
  runs-on: ubuntu-latest
35
35
  steps:
36
- - uses: actions/checkout@v7
36
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
37
37
  - run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
38
38
 
39
39
  # Build the .wasm and fetch the Chicory jars with CRuby + the WASI SDK,
40
40
  # then run RBS itself on JRuby against those artifacts.
41
41
  - name: Set up Ruby (to assemble the WebAssembly runtime)
42
- uses: ruby/setup-ruby@v1
42
+ uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
43
43
  with:
44
44
  ruby-version: ruby
45
45
  bundler: none
@@ -59,7 +59,7 @@ jobs:
59
59
  run: bundle exec rake wasm:jruby_setup
60
60
 
61
61
  - name: Set up JRuby
62
- uses: ruby/setup-ruby@v1
62
+ uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
63
63
  with:
64
64
  ruby-version: jruby
65
65
  bundler: none
@@ -70,7 +70,7 @@ jobs:
70
70
  # The gemspec takes its file list from `git ls-files`, so both gems are built
71
71
  # from the committed state -- of the dispatched commit, since that is what is
72
72
  # checked out. The full history is needed to tell which branches contain it.
73
- - uses: actions/checkout@v7
73
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
74
74
  with:
75
75
  ref: ${{ inputs.commit }}
76
76
  fetch-depth: 0
@@ -113,7 +113,7 @@ jobs:
113
113
  fi
114
114
 
115
115
  - name: Set up Ruby
116
- uses: ruby/setup-ruby@v1
116
+ uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
117
117
  with:
118
118
  ruby-version: ruby
119
119
  bundler: none
@@ -174,7 +174,7 @@ jobs:
174
174
  # from Maven during the install -- and parse something with it, so the
175
175
  # WebAssembly runtime is exercised end to end before anything is published.
176
176
  - name: Set up JRuby
177
- uses: ruby/setup-ruby@v1
177
+ uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
178
178
  with:
179
179
  ruby-version: jruby
180
180
  bundler: none
@@ -190,14 +190,14 @@ jobs:
190
190
  '
191
191
 
192
192
  - name: Switch back to CRuby
193
- uses: ruby/setup-ruby@v1
193
+ uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
194
194
  with:
195
195
  ruby-version: ruby
196
196
  bundler: none
197
197
 
198
198
  # Uploaded before publishing, so a failed push still leaves the gems behind.
199
199
  # This is also where a dry run ends.
200
- - uses: actions/upload-artifact@v7
200
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
201
201
  with:
202
202
  name: gems
203
203
  path: pkg/*.gem
@@ -218,8 +218,7 @@ jobs:
218
218
 
219
219
  - name: Configure RubyGems credentials
220
220
  if: ${{ !inputs.dry_run }}
221
- # No floating major tag on this action, so the exact release is pinned.
222
- uses: rubygems/configure-rubygems-credentials@v2.1.0
221
+ uses: rubygems/configure-rubygems-credentials@dc5a8d8553e6ee01fc26761a49e99e733d17954a # v2.1.0
223
222
 
224
223
  - name: Push the gems
225
224
  if: ${{ !inputs.dry_run }}
@@ -40,8 +40,8 @@ jobs:
40
40
  env:
41
41
  RANDOMIZE_STDLIB_TEST_ORDER: "true"
42
42
  steps:
43
- - uses: actions/checkout@v7
44
- - uses: ruby/setup-ruby@v1
43
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
44
+ - uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
45
45
  with:
46
46
  ruby-version: ${{ matrix.ruby }}
47
47
  bundler: none
@@ -90,11 +90,11 @@ jobs:
90
90
  matrix:
91
91
  ruby: ['4.0', head]
92
92
  steps:
93
- - uses: actions/checkout@v7
93
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
94
94
  - name: Install dependencies
95
95
  run: |
96
96
  brew install ruby-build
97
- - uses: ruby/setup-ruby@v1
97
+ - uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
98
98
  with:
99
99
  ruby-version: ${{ matrix.ruby }}
100
100
  bundler: none
@@ -127,11 +127,11 @@ jobs:
127
127
  matrix:
128
128
  ruby: ['4.0', head]
129
129
  steps:
130
- - uses: actions/checkout@v7
130
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
131
131
  - name: Install dependencies
132
132
  run: |
133
133
  brew install ruby-build
134
- - uses: ruby/setup-ruby@v1
134
+ - uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
135
135
  with:
136
136
  ruby-version: ${{ matrix.ruby }}
137
137
  bundler: none
@@ -26,10 +26,10 @@ jobs:
26
26
  matrix:
27
27
  os: [ubuntu-latest, macos-latest, windows-latest]
28
28
  steps:
29
- - uses: actions/checkout@v7
29
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
30
30
  - run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
31
31
  - name: Set up Ruby
32
- uses: ruby/setup-ruby@v1
32
+ uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
33
33
  with:
34
34
  ruby-version: ruby
35
35
  bundler: none
@@ -45,7 +45,7 @@ jobs:
45
45
  run: |
46
46
  rustup update --no-self-update stable
47
47
  rustup default stable
48
- - uses: actions/cache@v6
48
+ - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
49
49
  with:
50
50
  path: |
51
51
  ~/.cargo/registry
@@ -64,14 +64,14 @@ jobs:
64
64
  runs-on: ubuntu-latest
65
65
  continue-on-error: true
66
66
  steps:
67
- - uses: actions/checkout@v7
67
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
68
68
  - run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
69
69
  - name: Set up git identity
70
70
  run: |
71
71
  git config user.name "GitHub Actions"
72
72
  git config user.email "actions@github.com"
73
73
  - name: Set up Ruby
74
- uses: ruby/setup-ruby@v1
74
+ uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
75
75
  with:
76
76
  ruby-version: ruby
77
77
  bundler: none
@@ -87,7 +87,7 @@ jobs:
87
87
  run: |
88
88
  rustup update --no-self-update stable
89
89
  rustup default stable
90
- - uses: actions/cache@v6
90
+ - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
91
91
  with:
92
92
  path: |
93
93
  ~/.cargo/registry
@@ -106,14 +106,14 @@ jobs:
106
106
  runs-on: ubuntu-latest
107
107
  continue-on-error: true
108
108
  steps:
109
- - uses: actions/checkout@v7
109
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
110
110
  - run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
111
111
  - name: Set up git identity
112
112
  run: |
113
113
  git config user.name "GitHub Actions"
114
114
  git config user.email "actions@github.com"
115
115
  - name: Set up Ruby
116
- uses: ruby/setup-ruby@v1
116
+ uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
117
117
  with:
118
118
  ruby-version: ruby
119
119
  bundler: none
@@ -129,7 +129,7 @@ jobs:
129
129
  run: |
130
130
  rustup update --no-self-update stable
131
131
  rustup default stable
132
- - uses: actions/cache@v6
132
+ - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
133
133
  with:
134
134
  path: |
135
135
  ~/.cargo/registry
@@ -147,10 +147,10 @@ jobs:
147
147
  name: cargo:lint
148
148
  runs-on: ubuntu-latest
149
149
  steps:
150
- - uses: actions/checkout@v7
150
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
151
151
  - run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
152
152
  - name: Set up Ruby
153
- uses: ruby/setup-ruby@v1
153
+ uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
154
154
  with:
155
155
  ruby-version: ruby
156
156
  bundler: none
@@ -167,7 +167,7 @@ jobs:
167
167
  rustup update --no-self-update stable
168
168
  rustup default stable
169
169
  rustup component add --toolchain stable clippy rustfmt
170
- - uses: actions/cache@v6
170
+ - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
171
171
  with:
172
172
  path: |
173
173
  ~/.cargo/registry
@@ -24,8 +24,8 @@ jobs:
24
24
  # TruffleRuby warns and falls back to US-ASCII unless the locale is UTF-8.
25
25
  LANG: "en_US.UTF-8"
26
26
  steps:
27
- - uses: actions/checkout@v7
28
- - uses: ruby/setup-ruby@v1
27
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
28
+ - uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
29
29
  with:
30
30
  ruby-version: ${{ matrix.ruby }}
31
31
  bundler: none
@@ -16,8 +16,8 @@ jobs:
16
16
  strategy:
17
17
  fail-fast: false
18
18
  steps:
19
- - uses: actions/checkout@v7
20
- - uses: ruby/setup-ruby@v1
19
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
20
+ - uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
21
21
  with:
22
22
  ruby-version: "4.0"
23
23
  bundler: none
@@ -28,10 +28,10 @@ jobs:
28
28
  name: wasm:check
29
29
  runs-on: ubuntu-latest
30
30
  steps:
31
- - uses: actions/checkout@v7
31
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
32
32
  - run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
33
33
  - name: Set up Ruby
34
- uses: ruby/setup-ruby@v1
34
+ uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
35
35
  with:
36
36
  ruby-version: ruby
37
37
  bundler: none
@@ -48,7 +48,7 @@ jobs:
48
48
  curl -sSL "$url" | tar xz --strip-components=1 -C "$HOME/wasi-sdk"
49
49
  echo "WASI_SDK_PATH=$HOME/wasi-sdk" >> "$GITHUB_ENV"
50
50
  - name: Install wasmtime
51
- uses: bytecodealliance/actions/wasmtime/setup@v1
51
+ uses: bytecodealliance/actions/wasmtime/setup@9152e710e9f7182e4c29ad218e4f335a7b203613 # v1.1.3
52
52
  with:
53
53
  version: ${{ env.WASMTIME_VERSION }}
54
54
  - name: Build and smoke-test the WebAssembly module
@@ -18,9 +18,9 @@ jobs:
18
18
  matrix:
19
19
  ruby: ['4.0', ucrt, mswin]
20
20
  steps:
21
- - uses: actions/checkout@v7
21
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
22
22
  - name: load ruby
23
- uses: ruby/setup-ruby@v1
23
+ uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
24
24
  with:
25
25
  ruby-version: ${{ matrix.ruby }}
26
26
 
data/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 4.2.0.pre.1 (2026-08-18)
4
+
5
+ ### Language updates
6
+
7
+ * Gate forwarding parameter syntax behind parser option ([#3087](https://github.com/ruby/rbs/pull/3087))
8
+ * Support non-ASCII identifiers ([#3082](https://github.com/ruby/rbs/pull/3082))
9
+ * Support forwarding parameters in method types ([#3042](https://github.com/ruby/rbs/pull/3042))
10
+
11
+ ### Library changes
12
+
13
+ * Stop the lexer reading past the end of a byte_range ([#3040](https://github.com/ruby/rbs/pull/3040))
14
+ * Exclude CR from comment tokens to fix an off-by-one Location#end_line on CRLF files ([#3069](https://github.com/ruby/rbs/pull/3069))
15
+ * Handle the NULL parser in the WebAssembly shim ([#3085](https://github.com/ruby/rbs/pull/3085))
16
+ * Reject a byte position the lexer cannot start on ([#3083](https://github.com/ruby/rbs/pull/3083))
17
+ * Don't use Clang nullability qualifiers in strict ISO C mode ([#3074](https://github.com/ruby/rbs/pull/3074))
18
+ * Avoid eagerly inspecting call traces in type assertions ([#3073](https://github.com/ruby/rbs/pull/3073))
19
+ * Fix TypeParam.rename to substitute variables in bounds and default types ([#3068](https://github.com/ruby/rbs/pull/3068))
20
+ * Extract per-declaration type param alignment into entry-level align_params ([#3070](https://github.com/ruby/rbs/pull/3070))
21
+ * Align type params across declarations in module-self types and superclass validation ([#3067](https://github.com/ruby/rbs/pull/3067))
22
+ * Build the wasm module with -DNDEBUG ([#3066](https://github.com/ruby/rbs/pull/3066))
23
+ * Rename NODISCARD macro to RBS_NODISCARD ([#3065](https://github.com/ruby/rbs/pull/3065))
24
+
25
+ ### Miscellaneous
26
+
27
+ * Skip JSON 2-only tests with JSON 3 ([#3084](https://github.com/ruby/rbs/pull/3084))
28
+ * Pin GitHub Actions to commit hashes ([#3020](https://github.com/ruby/rbs/pull/3020))
29
+
3
30
  ## 4.1.3 (2026-08-10)
4
31
 
5
32
  ### Miscellaneous
data/Rakefile CHANGED
@@ -325,15 +325,11 @@ namespace :generate do
325
325
  class TestTemplateBuilder
326
326
  attr_reader :target, :env
327
327
 
328
- def initialize(target)
328
+ def initialize(target, paths:)
329
329
  @target = target
330
330
 
331
331
  loader = RBS::EnvironmentLoader.new
332
- Dir['stdlib/*'].each do |lib|
333
- next if lib.end_with?('builtin')
334
-
335
- loader.add(library: File.basename(lib))
336
- end
332
+ paths.each { loader.add(path: Pathname(_1)) }
337
333
  @env = RBS::Environment.from_loader(loader).resolve_type_names
338
334
  end
339
335
 
@@ -425,7 +421,7 @@ namespace :generate do
425
421
  end
426
422
  end
427
423
 
428
- path.write TestTemplateBuilder.new(target).call
424
+ path.write TestTemplateBuilder.new(target, paths: args.extras).call
429
425
 
430
426
  puts "Created: #{path}"
431
427
  end
@@ -436,6 +432,8 @@ task :test_generate_stdlib do
436
432
  sh "ruby -c /tmp/Array_test.rb"
437
433
  sh "RBS_GENERATE_TEST_PATH=/tmp/Thread_Mutex_test.rb rake 'generate:stdlib_test[Thread::Mutex]'"
438
434
  sh "ruby -c /tmp/Thread_Mutex_test.rb"
435
+ sh "RBS_GENERATE_TEST_PATH=/tmp/Kconv_test.rb rake 'generate:stdlib_test[Kconv,stdlib/nkf/0,stdlib/kconv/0]'"
436
+ sh "ruby -c /tmp/Kconv_test.rb"
439
437
  end
440
438
 
441
439
  # Pull requests with one of these labels are omitted from the changelog.
@@ -605,30 +603,41 @@ end
605
603
  #
606
604
  def changelog_pull_requests(commits, skip_labels: CHANGELOG_SKIP_LABELS)
607
605
  origins = changelog_origins(commits)
608
- found = changelog_associated_pull_requests(commits.map { |commit| origins[commit] || commit })
609
606
 
610
- # An origin that leads nowhere -- a commit cherry-picked from a fork, or one that went to the
611
- # default branch without a pull request -- falls back to the commit in this history, which is
612
- # at least the backport that brought it here.
613
- fallbacks = commits.select { |commit| origins[commit] && found.fetch(origins[commit], []).empty? }
614
- found.update(changelog_associated_pull_requests(fallbacks)) unless fallbacks.empty?
607
+ # Both ends of each commit, in one query: the origin a cherry-pick records, which is where the
608
+ # change was written and reviewed, and the commit as it sits in this history, whose pull request
609
+ # is the backport that brought it here. On the development line there are no origins and the
610
+ # second end is the only one.
611
+ found = changelog_associated_pull_requests(commits + origins.values)
615
612
 
616
613
  pull_requests = {}
617
614
  skipped = {}
618
615
 
619
616
  commits.each do |commit|
620
- prs = found.fetch(origins[commit] || commit, [])
621
- prs = found.fetch(commit, []) if prs.empty?
617
+ carriers = found.fetch(commit, [])
618
+ prs = origins[commit] ? found.fetch(origins[commit], []) : []
619
+
620
+ # An origin that leads nowhere -- a commit cherry-picked from a fork, or one that went to the
621
+ # default branch without a pull request -- falls back to the commit in this history, which is
622
+ # at least the backport that brought it here. It is the entry itself then, not an annotation.
623
+ backports = prs.empty? ? [] : carriers
624
+ prs = carriers if prs.empty?
622
625
 
623
626
  prs.each do |pr|
624
- if (pr[:labels] & skip_labels).empty?
625
- pull_requests[pr[:number]] ||= pr
626
- else
627
- skipped[pr[:number]] ||= pr
628
- end
627
+ bucket = (pr[:labels] & skip_labels).empty? ? pull_requests : skipped
628
+ entry = (bucket[pr[:number]] ||= pr.merge(backports: []))
629
+ entry[:backports] |= backports.map { |backport| backport.slice(:number, :url) }
629
630
  end
630
631
  end
631
632
 
633
+ # A backport is how a change reached this line, not a change of its own, so it belongs in the
634
+ # entries it carried rather than beside them. It can still arrive as one: the merge commit of the
635
+ # backport is in the history too, and carries no `-x` trailer to resolve, so it looks like an
636
+ # ordinary commit of its own pull request. Drop the ones that annotate something.
637
+ carried = (pull_requests.each_value.to_a + skipped.each_value.to_a).flat_map { |pr| pr[:backports] }
638
+ carried = carried.map { |backport| backport[:number] }.uniq
639
+ carried.each { |number| pull_requests.delete(number) }
640
+
632
641
  [pull_requests.values, skipped.values]
633
642
  end
634
643
 
@@ -677,6 +686,19 @@ def warn_skipped_pull_requests(skipped, skip_labels)
677
686
  $stderr.puts " (⏭️ Skipped #{skipped.size} pull request(s) labeled #{skip_labels.map { |label| "`#{label}`" }.join(" or ")}: #{numbers.join(", ")})"
678
687
  end
679
688
 
689
+ # The links of one changelog entry: the pull request the change was written in, and on a release
690
+ # branch the backport that carried it onto the line.
691
+ #
692
+ # The second link is what keeps a backported entry from reading as a mistake. Its first link is a
693
+ # pull request against the development line, so the same link is listed again when that line ships,
694
+ # and nothing else tells the two occurrences apart.
695
+ #
696
+ def changelog_links(pr)
697
+ links = ["[##{pr[:number]}](#{pr[:url]})"]
698
+ links.concat(pr[:backports].to_a.map { |backport| "Backported in [##{backport[:number]}](#{backport[:url]})" })
699
+ links.join(", ")
700
+ end
701
+
680
702
  # Prints the changelog template listing the pull requests merged between `from` and `HEAD`.
681
703
  #
682
704
  # The changelog goes to STDOUT and everything else goes to STDERR, so that the output can be
@@ -698,7 +720,7 @@ def print_changelog(from, paths: [], skip_labels: CHANGELOG_SKIP_LABELS)
698
720
  else
699
721
  $stderr.puts
700
722
  pull_requests.each do |pr|
701
- puts "* #{pr[:title]} ([##{pr[:number]}](#{pr[:url]}))"
723
+ puts "* #{pr[:title]} (#{changelog_links(pr)})"
702
724
  end
703
725
  $stdout.flush
704
726
  end
@@ -926,6 +948,12 @@ namespace :wasm do
926
948
 
927
949
  desc "Build the RBS parser as a WebAssembly module (requires WASI_SDK_PATH)"
928
950
  task :build do
951
+ # `-DNDEBUG` compiles out `RBS_ASSERT`, the same way ext/rbs_extension does
952
+ # for the MRI extension. The assertions sit in the lexer and the constant
953
+ # pool, so keeping them costs about 20% of parse time; set `DEBUG=1` to keep
954
+ # them when debugging the module itself.
955
+ debug_flags = ENV["DEBUG"] ? [] : ["-DNDEBUG"]
956
+
929
957
  mkdir_p WASM_DIR
930
958
  sh wasi_clang,
931
959
  "--target=wasm32-wasip1",
@@ -933,6 +961,7 @@ namespace :wasm do
933
961
  "-mexec-model=reactor",
934
962
  "-std=gnu11",
935
963
  "-O2",
964
+ *debug_flags,
936
965
  "-Wno-unused-parameter",
937
966
  "-I#{File.join(__dir__, "include")}",
938
967
  "-o", WASM_OUTPUT,
data/config.yml CHANGED
@@ -598,6 +598,9 @@ nodes:
598
598
  - name: rest_keywords
599
599
  c_type: rbs_node
600
600
  optional: true # NULL when no double-splat (e.g., `() -> void` vs `(**String) -> void`)
601
+ - name: forwarding
602
+ c_type: rbs_node
603
+ optional: true # NULL when no forwarding parameter (e.g., `() -> void` vs `(...) -> void`)
601
604
  - name: return_type
602
605
  c_type: rbs_node
603
606
  - name: RBS::Types::Function::Param
@@ -610,6 +613,8 @@ nodes:
610
613
  optional: true # NULL when param is unnamed (e.g., `(String) -> void` vs `(String name) -> void`)
611
614
  locations:
612
615
  - optional: name
616
+ - name: RBS::Types::Function::ForwardingParam
617
+ rust_name: FunctionForwardingParamNode
613
618
  - name: RBS::Types::Interface
614
619
  rust_name: InterfaceTypeNode
615
620
  fields:
data/docs/CONTRIBUTING.md CHANGED
@@ -33,7 +33,7 @@ You will typically follow the steps as follows:
33
33
 
34
34
  1. Run `rbs prototype runtime` to generate list of methods.
35
35
  2. Run `rbs annotate` to import RDoc comments.
36
- 3. Run `rake generate:stdlib_test[LIB]` to generate a test case.
36
+ 3. Run `rake generate:stdlib_test[CLASS,PATH,...]` to generate a test case. Pass the paths to the standard library signatures and their dependencies when needed.
37
37
  4. Write the type definitions and tests.
38
38
 
39
39
  See the next *Useful Tools* section and the guides above for writing and testing RBS files.