diff --git a/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/TypeUtilsTest.java b/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/TypeUtilsTest.java index 7b2c4fbcc5c..7758f99be21 100644 --- a/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/TypeUtilsTest.java +++ b/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/TypeUtilsTest.java @@ -245,4 +245,36 @@ public J.VariableDeclarations.NamedVariable visitVariable(J.VariableDeclarations ) ); } + + @Test + void isAssignableToGenericTypeVariable() { + rewriteRun( + java( + """ + import java.util.Map; + import java.util.function.Supplier; + + class Test { + void m(Supplier> map) { + } + void foo() { + Map map = null; + m(() -> map); + } + } + """, + spec -> spec.afterRecipe(cu -> new JavaIsoVisitor<>() { + @Override + public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Object o) { + JavaType paramType = method.getMethodType().getParameterTypes().get(0); + assertThat(paramType).isInstanceOf(JavaType.Parameterized.class); + JavaType argType = method.getArguments().get(0).getType(); + assertThat(argType).isInstanceOf(JavaType.Parameterized.class); + assertThat(TypeUtils.isAssignableTo(paramType, argType)).isTrue(); + return method; + } + }.visit(cu, new InMemoryExecutionContext())) + ) + ); + } } diff --git a/rewrite-java/src/main/java/org/openrewrite/java/tree/TypeUtils.java b/rewrite-java/src/main/java/org/openrewrite/java/tree/TypeUtils.java index e61b423b2f0..7fb2798abe0 100644 --- a/rewrite-java/src/main/java/org/openrewrite/java/tree/TypeUtils.java +++ b/rewrite-java/src/main/java/org/openrewrite/java/tree/TypeUtils.java @@ -202,9 +202,12 @@ public static boolean isAssignableTo(@Nullable JavaType to, @Nullable JavaType f JavaType.FullyQualified toFq = (JavaType.FullyQualified) to; return isAssignableTo(toFq.getFullyQualifiedName(), from); } else if (to instanceof JavaType.GenericTypeVariable) { - JavaType.GenericTypeVariable genericTo = (JavaType.GenericTypeVariable) to; - if (genericTo.getBounds().isEmpty()) { - return genericTo.getName().equals("?"); + JavaType.GenericTypeVariable toGeneric = (JavaType.GenericTypeVariable) to; + List toBounds = toGeneric.getBounds(); + if (toBounds.isEmpty()) { + return toGeneric.getName().equals("?"); + } else if (toBounds.size() == 1) { + return isAssignableTo(toBounds.get(0), from); } return false; } else if (to instanceof JavaType.Variable) {