Skip to content

GROOVY-12139: vararg-of-arrays argument wrapping fails under classic …#2675

Merged
paulk-asert merged 1 commit into
apache:masterfrom
paulk-asert:groovy12139
Jul 8, 2026
Merged

GROOVY-12139: vararg-of-arrays argument wrapping fails under classic …#2675
paulk-asert merged 1 commit into
apache:masterfrom
paulk-asert:groovy12139

Conversation

@paulk-asert

Copy link
Copy Markdown
Contributor

…compilation

GROOVY-11182's reproducer (a single byte[] passed to a byte[]... parameter) still failed with IllegalArgumentException when dispatched through MetaMethod#doMethodInvoke — the classic call-site path, and any other route through the reflective MOP invocation. The original fix only added a test; the invokedynamic chain's own varargs adaptation happened to handle the case, masking the gap under the default compilation mode.

Root cause: ParameterTypes#fitToVargs treated any trailing array argument as the pre-packed varargs array. Being an array is not sufficient — a byte[] passed to byte[]... is a single element of the byte[][] varargs array. The argument now passes through only when it is assignable to the varargs parameter type or is an array of the same dimension (whose elements the downstream argument coercion converts, e.g. Integer[] for int...); otherwise it is wrapped as an element.

Adds a classic-compilation (indy=false) variant of the GROOVY-11182 test. Also reproducible on GROOVY_5_0_X, so a candidate for backport.

…compilation

GROOVY-11182's reproducer (a single byte[] passed to a byte[]...
parameter) still failed with IllegalArgumentException when dispatched
through MetaMethod#doMethodInvoke — the classic call-site path, and any
other route through the reflective MOP invocation. The original fix
only added a test; the invokedynamic chain's own varargs adaptation
happened to handle the case, masking the gap under the default
compilation mode.

Root cause: ParameterTypes#fitToVargs treated any trailing array
argument as the pre-packed varargs array. Being an array is not
sufficient — a byte[] passed to byte[]... is a single element of the
byte[][] varargs array. The argument now passes through only when it is
assignable to the varargs parameter type or is an array of the same
dimension (whose elements the downstream argument coercion converts,
e.g. Integer[] for int...); otherwise it is wrapped as an element.

Adds a classic-compilation (indy=false) variant of the GROOVY-11182
test. Also reproducible on GROOVY_5_0_X, so a candidate for backport.
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 68.6889%. Comparing base (c6fa475) to head (2d46893).
⚠️ Report is 3 commits behind head on master.

Files with missing lines Patch % Lines
...org/codehaus/groovy/reflection/ParameterTypes.java 80.0000% 0 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                 @@
##               master      #2675        +/-   ##
==================================================
+ Coverage     68.5934%   68.6889%   +0.0955%     
- Complexity      33951      34106       +155     
==================================================
  Files            1535       1536         +1     
  Lines          128543     128903       +360     
  Branches        23335      23363        +28     
==================================================
+ Hits            88172      88542       +370     
+ Misses          32555      32530        -25     
- Partials         7816       7831        +15     
Files with missing lines Coverage Δ
...org/codehaus/groovy/reflection/ParameterTypes.java 70.8108% <80.0000%> (+0.4811%) ⬆️

... and 10 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@testlens-app

testlens-app Bot commented Jul 8, 2026

Copy link
Copy Markdown

✅ All tests passed ✅

🏷️ Commit: 2d46893
▶️ Tests: 103206 executed
⚪️ Checks: 31/31 completed


Learn more about TestLens at testlens.app.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes classic (non-invokedynamic) reflective MOP varargs adaptation for “vararg-of-arrays” cases, where a trailing array argument was incorrectly treated as the already-packed varargs array (e.g., byte[] passed to byte[]... should be wrapped into byte[][]).

Changes:

  • Refines ParameterTypes#fitToVargs so the last argument only passes through as the varargs array when it’s assignable to the varargs parameter type, or when it’s an array of the same dimension (allowing downstream coercion like Integer[]int[]).
  • Adds a classic-compilation (indy=false) regression test variant for GROOVY-11182 to cover the MetaMethod#doMethodInvoke path.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/test/groovy/bugs/Groovy11182.groovy Adds a classic-compilation regression test using GroovyShell with indy=false to exercise the reflective/MOP call-site path.
src/main/java/org/codehaus/groovy/reflection/ParameterTypes.java Updates varargs argument “fit” logic to avoid misclassifying trailing arrays as the pre-packed varargs array in vararg-of-arrays scenarios.

@paulk-asert paulk-asert merged commit e3c89fd into apache:master Jul 8, 2026
32 checks passed
@paulk-asert paulk-asert deleted the groovy12139 branch July 8, 2026 02:02
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.

3 participants