diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java index 3cd3859b0cd..309bf3ff846 100644 --- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -3747,12 +3747,12 @@ private void inferMethodReferenceType(final ClassNode receiver, final ArgumentLi if (i >= nthParameter && paramType.isArray()) paramType = paramType.getComponentType(); - if (!isFunctionalInterface(paramType.redirect())) { - addError("The argument is a method reference, but the parameter type is not a functional interface", argumentExpression); - newArgumentExpressions.add(argumentExpression); - } else { + if (isFunctionalInterface(paramType)) { methodReferencePositions.add(i); newArgumentExpressions.add(constructLambdaExpressionForMethodReference(paramType, (MethodReferenceExpression) argumentExpression)); + } else { + newArgumentExpressions.add(argumentExpression); + addStaticTypeError("Argument is a method reference, but parameter type '" + prettyPrintTypeName(paramType) + "' is not a functional interface", argumentExpression); } } } diff --git a/src/test/groovy/transform/stc/MethodReferenceTest.groovy b/src/test/groovy/transform/stc/MethodReferenceTest.groovy index b99bee86186..20bac107ec0 100644 --- a/src/test/groovy/transform/stc/MethodReferenceTest.groovy +++ b/src/test/groovy/transform/stc/MethodReferenceTest.groovy @@ -1494,7 +1494,7 @@ final class MethodReferenceTest { baz(this::foo) // not yet supported! } ''' - assert err =~ /The argument is a method reference, but the parameter type is not a functional interface/ + assert err =~ /Argument is a method reference, but parameter type 'java.lang.Object' is not a functional interface/ } @Test // GROOVY-10336 @@ -1511,7 +1511,27 @@ final class MethodReferenceTest { } } ''' - assert err =~ /The argument is a method reference, but the parameter type is not a functional interface/ + assert err =~ /Argument is a method reference, but parameter type 'java.lang.Object' is not a functional interface/ + } + + @Test // GROOVY-10979 + void testNotFunctionalInterface3() { + def err = shouldFail imports + ''' + Integer m(String x) { + return 1 + } + @CompileStatic + void test() { + java.util.stream.Stream x = null + BiFunction, Number, Function> y = null + BinaryOperator> z = null + // reduce number(s) to string-to-integer functions + x.>reduce(this::m, y, z) + x.reduce(this::m, y, z) + x.reduce((s) -> 1, y, z) + } + ''' + assert err =~ /Argument is a method reference, but parameter type 'U' is not a functional interface/ } @Test // GROOVY-11254