Skip to content

GROOVY-12154: box primitive lambda param when the target SAM param is…#2697

Merged
paulk-asert merged 1 commit into
apache:masterfrom
paulk-asert:groovy12154
Jul 12, 2026
Merged

GROOVY-12154: box primitive lambda param when the target SAM param is…#2697
paulk-asert merged 1 commit into
apache:masterfrom
paulk-asert:groovy12154

Conversation

@paulk-asert

Copy link
Copy Markdown
Contributor

… a reference type

A @CompileStatic lambda declaring a primitive parameter (e.g. (int a) -> ...) against a generic functional interface (e.g. Function<Integer,Integer>) compiled cleanly but threw at runtime:

java.lang.invoke.LambdaConversionException:
int is not a subtype of class java.lang.Object

AbstractFunctionalInterfaceWriter.convertParameterType always emitted a primitive implementation-method parameter when the lambda declared a primitive, ignoring the target (functional-interface) parameter type. But LambdaMetafactory links against the erased SAM signature (Object) and will not unbox to a primitive, so the implementation method must accept the boxed type when the SAM parameter is a reference type. It stays primitive only when the SAM parameter is itself primitive (e.g. IntUnaryOperator), preserving GROOVY-9790.

… a reference type

A @CompileStatic lambda declaring a primitive parameter (e.g. (int a) -> ...)
against a generic functional interface (e.g. Function<Integer,Integer>)
compiled cleanly but threw at runtime:

  java.lang.invoke.LambdaConversionException:
    int is not a subtype of class java.lang.Object

AbstractFunctionalInterfaceWriter.convertParameterType always emitted a
primitive implementation-method parameter when the lambda declared a
primitive, ignoring the target (functional-interface) parameter type. But
LambdaMetafactory links against the erased SAM signature (Object) and will
not unbox to a primitive, so the implementation method must accept the boxed
type when the SAM parameter is a reference type. It stays primitive only when
the SAM parameter is itself primitive (e.g. IntUnaryOperator), preserving
GROOVY-9790.
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 69.1047%. Comparing base (c9363db) to head (e27f3d3).
⚠️ Report is 3 commits behind head on master.

Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                 @@
##               master      #2697        +/-   ##
==================================================
- Coverage     69.1083%   69.1047%   -0.0036%     
- Complexity      34235      34236         +1     
==================================================
  Files            1537       1537                
  Lines          129310     129311         +1     
  Branches        23478      23479         +1     
==================================================
- Hits            89364      89360         -4     
- Misses          31936      31941         +5     
  Partials         8010       8010                
Files with missing lines Coverage Δ
...sgen/asm/sc/AbstractFunctionalInterfaceWriter.java 94.1606% <100.0000%> (+1.5135%) ⬆️

... and 7 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 12, 2026

Copy link
Copy Markdown

✅ All tests passed ✅

🏷️ Commit: e27f3d3
▶️ Tests: 103577 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 a @CompileStatic lambda/SAM linkage issue where a lambda declaring a primitive parameter (e.g., int) could target a generic functional interface (erased to Object) and compile, but then fail at runtime with LambdaConversionException due to a primitive implementation-method parameter.

Changes:

  • Update AbstractFunctionalInterfaceWriter.convertParameterType to emit a boxed implementation parameter when the target SAM parameter is a reference type, while preserving primitive parameters for primitive-SAM targets (retaining GROOVY-9790 behavior).
  • Add a focused regression test suite covering primitive params targeting generic SAMs (single/multiple params, defaults, long) and ensuring primitive-SAM cases remain unaffected.

Reviewed changes

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

File Description
src/main/java/org/codehaus/groovy/classgen/asm/sc/AbstractFunctionalInterfaceWriter.java Adjusts lambda parameter type reconciliation so impl-method params are boxed when the SAM parameter is a reference type, preventing LambdaMetafactory linkage failures.
src/test/groovy/bugs/Groovy12154.groovy Adds regression coverage for GROOVY-12154 and verifies GROOVY-9790 behavior is preserved.

@paulk-asert paulk-asert merged commit 86c6648 into apache:master Jul 12, 2026
32 checks passed
@paulk-asert paulk-asert deleted the groovy12154 branch July 12, 2026 21:30
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