Fix TypeUtils.isAssignable() for wildcards with multiple upper bounds - #1782
Fix TypeUtils.isAssignable() for wildcards with multiple upper bounds#1782Alwaysgaurav1 wants to merge 1 commit into
Conversation
|
@garydgregory, please review it quickly. |
|
@Alwaysgaurav1 |
|
Okay, whenever you want . I am okay. |
|
@Alwaysgaurav1
At updated See: The result changes from false to true. This is not itself evidence of incorrect behavior, but it needs an explicit rationale and positive/negative tests. Either include those or leave the lower-bound change for a separate PR.
All four assertions use a target with one upper bound. Add a target with multiple bounds where only one is satisfied, and another where all are satisfied. Also test the reverse direction: |
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Pull request overview
Fixes TypeUtils.isAssignable(Type, WildcardType, Map) so wildcard assignability works correctly when the source wildcard has multiple upper bounds (intersection types).
Changes:
- Update wildcard upper-bound checking to require any source upper bound to satisfy each target upper bound.
- Apply similar “any bound” logic to lower-bound checking.
- Add a regression test for wildcard assignability with multiple upper bounds.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/main/java/org/apache/commons/lang3/reflect/TypeUtils.java | Adjusts wildcard upper/lower bound matching logic in isAssignable(...). |
| src/test/java/org/apache/commons/lang3/reflect/TypeUtilsTest.java | Adds a regression test covering intersection upper bounds assignability. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| for (Type toBound : toLowerBounds) { | ||
| // if there are assignments for unresolved type variables, | ||
| // now's the time to substitute them. | ||
| toBound = substituteTypeVariables(toBound, typeVarAssigns); | ||
| // each lower bound of the target type has to be assignable to | ||
| // each | ||
| // lower bound of the subject type | ||
| // at least one lower bound of the subject type | ||
| boolean satisfied = false; | ||
| for (final Type bound : lowerBounds) { | ||
| if (!isAssignable(toBound, bound, typeVarAssigns)) { | ||
| return false; | ||
| if (isAssignable(toBound, bound, typeVarAssigns)) { | ||
| satisfied = true; | ||
| break; | ||
| } | ||
| } | ||
| if (!satisfied) { | ||
| return false; | ||
| } | ||
| } |
| // each lower bound of the target type has to be assignable to | ||
| // each | ||
| // lower bound of the subject type | ||
| // at least one lower bound of the subject type |
Description
Fixes an issue in
TypeUtils.isAssignable(Type, WildcardType, Map)where checking assignability of aWildcardTypewith multiple upper bounds (intersection types such as? extends Serializable & Cloneable) to anotherWildcardType(such as? extends Serializable) incorrectly returnedfalse.Root Cause
When the subject
typeis aWildcardType, the upper bounds loop previously enforced that every upper bound in the subject wildcard had to be assignable to each target upper boundtoBound(forall bound in upperBounds: isAssignable(bound, toBound)):