changeset 47880:bbd692ad4fa3 jdk-10+33

8191655: LambdaConversionException: Invalid receiver type interface; not a subtype of implementation type interface Reviewed-by: mcimadamore
author sadayapalam
date Wed, 22 Nov 2017 18:07:53 +0530
parents 3812717dc3e9
children 66350f079368 19fa40d2e7d8
files src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java test/langtools/tools/javac/lambda/methodReferenceExecution/MethodReferenceIntersectionInducedTest.java test/langtools/tools/javac/lambda/methodReferenceExecution/MethodReferenceUnionTypeTest.java
diffstat 3 files changed, 124 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Tue Nov 21 16:54:46 2017 -0800
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Wed Nov 22 18:07:53 2017 +0530
@@ -2269,17 +2269,22 @@
 
             /**
              * Erasure destroys the implementation parameter subtype
-             * relationship for intersection types
+             * relationship for intersection types.
+             * Have similar problems for union types too.
              */
-            boolean interfaceParameterIsIntersectionType() {
+            boolean interfaceParameterIsIntersectionOrUnionType() {
                 List<Type> tl = tree.getDescriptorType(types).getParameterTypes();
                 for (; tl.nonEmpty(); tl = tl.tail) {
                     Type pt = tl.head;
-                    if (pt.getKind() == TypeKind.TYPEVAR) {
-                        TypeVar tv = (TypeVar) pt;
-                        if (tv.bound.getKind() == TypeKind.INTERSECTION) {
+                    switch (pt.getKind()) {
+                        case INTERSECTION:
+                        case UNION:
                             return true;
-                        }
+                        case TYPEVAR:
+                            TypeVar tv = (TypeVar) pt;
+                            if (tv.bound.getKind() == TypeKind.INTERSECTION) {
+                                return true;
+                            }
                     }
                 }
                 return false;
@@ -2290,7 +2295,7 @@
              * (i.e. var args need to be expanded or "super" is used)
              */
             final boolean needsConversionToLambda() {
-                return interfaceParameterIsIntersectionType() ||
+                return interfaceParameterIsIntersectionOrUnionType() ||
                         isSuper ||
                         needsVarArgsConversion() ||
                         isArrayOp() ||
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/lambda/methodReferenceExecution/MethodReferenceIntersectionInducedTest.java	Wed Nov 22 18:07:53 2017 +0530
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8191655
+ * @summary LambdaConversionException: Invalid receiver type interface; not a subtype of implementation type interface
+ * @run main MethodReferenceIntersectionInducedTest
+ */
+
+
+import java.util.function.Consumer;
+public class MethodReferenceIntersectionInducedTest {
+   static String blah;
+   <T> void forAll(Consumer<T> consumer, T... values) { consumer.accept(values[0]); }
+
+   public void secondTest() {
+       forAll(Picture::draw, new MyPicture(), new Universal());
+   }
+
+   interface Shape { void draw(); }
+   interface Marker { }
+   interface Picture { void draw(); }
+
+   class MyShape implements Marker, Shape { public void draw() { } }
+   class MyPicture implements Marker, Picture { public void draw() { blah = "MyPicture"; } }
+   class Universal implements Marker, Picture, Shape { public void draw() { System.out.println("Universal"); } }
+
+   public static void main(String[] args) {
+       new MethodReferenceIntersectionInducedTest().secondTest();
+       if (!blah.equals("MyPicture"))
+            throw new AssertionError("Incorrect output");
+   }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/lambda/methodReferenceExecution/MethodReferenceUnionTypeTest.java	Wed Nov 22 18:07:53 2017 +0530
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8191655
+ * @summary LambdaConversionException: Invalid receiver type interface; not a subtype of implementation type interface
+ * @run main MethodReferenceUnionTypeTest
+ */
+
+import java.util.function.Consumer;
+public class MethodReferenceUnionTypeTest {
+   static String blah = "NONE";
+   <T> void forAll(Consumer<T> consumer, T value) { consumer.accept(value); }
+
+   public void secondTest() {
+       try {
+          throwing();
+        } catch (A | B ex) {
+            forAll(Picture::draw, ex);
+        }
+   }
+
+   void throwing() throws A, B { throw new A();}
+
+   interface Shape { void draw(); }
+   interface Marker { }
+   interface Picture { void draw();  }
+
+   class A extends Exception implements Marker, Picture { public void draw() { blah = "A"; }}
+   class B extends Exception implements Marker, Picture, Shape { public void draw() {}}
+
+   public static void main(String[] args) {
+       new MethodReferenceUnionTypeTest().secondTest();
+       if (!blah.equals("A"))
+            throw new AssertionError("Incorrect output");
+   }
+}
\ No newline at end of file