8144767: Fix handling of capture variables in most-specific test
authordlsmith
Fri, 10 Jun 2016 15:08:00 -0600
changeset 38913 5b15a5ed3b0d
parent 38912 2ddd6171351e
child 38914 2f652b30f1b0
8144767: Fix handling of capture variables in most-specific test Reviewed-by: vromero
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java
langtools/test/tools/javac/lambda/MostSpecific28.java
langtools/test/tools/javac/lambda/MostSpecific28.out
langtools/test/tools/javac/lambda/MostSpecific29.java
langtools/test/tools/javac/lambda/MostSpecific30.java
langtools/test/tools/javac/lambda/MostSpecific30.out
langtools/test/tools/javac/lambda/MostSpecific31.java
langtools/test/tools/javac/lambda/MostSpecific31.out
langtools/test/tools/javac/lambda/MostSpecific32.java
langtools/test/tools/javac/lambda/MostSpecific32.out
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java	Fri Jun 10 11:11:52 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java	Fri Jun 10 15:08:00 2016 -0600
@@ -1155,12 +1155,18 @@
 
             /** Parameters {@code t} and {@code s} are unrelated functional interface types. */
             private boolean functionalInterfaceMostSpecific(Type t, Type s, JCTree tree) {
-                Type tDesc = types.findDescriptorType(t);
+                Type tDesc = types.findDescriptorType(types.capture(t));
+                Type tDescNoCapture = types.findDescriptorType(t);
                 Type sDesc = types.findDescriptorType(s);
-
-                // compare type parameters -- can't use Types.hasSameBounds because bounds may have ivars
                 final List<Type> tTypeParams = tDesc.getTypeArguments();
+                final List<Type> tTypeParamsNoCapture = tDescNoCapture.getTypeArguments();
                 final List<Type> sTypeParams = sDesc.getTypeArguments();
+
+                // compare type parameters
+                if (tDesc.hasTag(FORALL) && !types.hasSameBounds((ForAll) tDesc, (ForAll) tDescNoCapture)) {
+                    return false;
+                }
+                // can't use Types.hasSameBounds on sDesc because bounds may have ivars
                 List<Type> tIter = tTypeParams;
                 List<Type> sIter = sTypeParams;
                 while (tIter.nonEmpty() && sIter.nonEmpty()) {
@@ -1181,20 +1187,26 @@
 
                 // compare parameters
                 List<Type> tParams = tDesc.getParameterTypes();
+                List<Type> tParamsNoCapture = tDescNoCapture.getParameterTypes();
                 List<Type> sParams = sDesc.getParameterTypes();
-                while (tParams.nonEmpty() && sParams.nonEmpty()) {
+                while (tParams.nonEmpty() && tParamsNoCapture.nonEmpty() && sParams.nonEmpty()) {
                     Type tParam = tParams.head;
+                    Type tParamNoCapture = types.subst(tParamsNoCapture.head, tTypeParamsNoCapture, tTypeParams);
                     Type sParam = types.subst(sParams.head, sTypeParams, tTypeParams);
                     if (tParam.containsAny(tTypeParams) && inferenceContext().free(sParam)) {
                         return false;
                     }
-                    if (!types.isSameType(tParam, inferenceContext().asUndetVar(sParam))) {
+                    if (!types.isSubtype(inferenceContext().asUndetVar(sParam), tParam)) {
+                        return false;
+                    }
+                    if (!types.isSameType(tParamNoCapture, inferenceContext().asUndetVar(sParam))) {
                         return false;
                     }
                     tParams = tParams.tail;
+                    tParamsNoCapture = tParamsNoCapture.tail;
                     sParams = sParams.tail;
                 }
-                if (!tParams.isEmpty() || !sParams.isEmpty()) {
+                if (!tParams.isEmpty() || !tParamsNoCapture.isEmpty() || !sParams.isEmpty()) {
                     return false;
                 }
 
--- a/langtools/test/tools/javac/lambda/MostSpecific28.java	Fri Jun 10 11:11:52 2016 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific28.java	Fri Jun 10 15:08:00 2016 -0600
@@ -12,8 +12,6 @@
     static void m1(Pred<? super Integer> f) {}
     static void m1(Fun<Number, Boolean> f) {}
 
-    static String foo(Object in) { return "a"; }
-
     void test() {
         m1((Number n) -> true);
     }
--- a/langtools/test/tools/javac/lambda/MostSpecific28.out	Fri Jun 10 11:11:52 2016 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific28.out	Fri Jun 10 15:08:00 2016 -0600
@@ -1,2 +1,2 @@
-MostSpecific28.java:18:9: compiler.err.ref.ambiguous: m1, kindname.method, m1(MostSpecific28.Pred<? super java.lang.Integer>), MostSpecific28, kindname.method, m1(MostSpecific28.Fun<java.lang.Number,java.lang.Boolean>), MostSpecific28
+MostSpecific28.java:16:9: compiler.err.ref.ambiguous: m1, kindname.method, m1(MostSpecific28.Pred<? super java.lang.Integer>), MostSpecific28, kindname.method, m1(MostSpecific28.Fun<java.lang.Number,java.lang.Boolean>), MostSpecific28
 1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific29.java	Fri Jun 10 15:08:00 2016 -0600
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016, 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 8144767
+ * @summary Correct most-specific test when wildcards appear in functional interface type
+ * @compile MostSpecific29.java
+ */
+class MostSpecific29 {
+
+    interface Pred<T> { boolean test(T arg); }
+    interface Fun<T,R> { R apply(T arg); }
+
+    static void m1(Pred<? super Integer> f) {}
+    static void m1(Fun<Integer, Boolean> f) {}
+
+    void test() {
+        m1((Integer n) -> true);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific30.java	Fri Jun 10 15:08:00 2016 -0600
@@ -0,0 +1,19 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8144767
+ * @summary Correct most-specific test when wildcards appear in functional interface type
+ * @compile/fail/ref=MostSpecific30.out -XDrawDiagnostics MostSpecific30.java
+ */
+class MostSpecific30 {
+
+    interface Pred<T> { boolean test(T arg); }
+    interface Fun<T,R> { R apply(T arg); }
+
+    static void m1(Pred<? extends Integer> f) {}
+    static void m1(Fun<Integer, Boolean> f) {}
+
+    void test() {
+        m1((Integer n) -> true);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific30.out	Fri Jun 10 15:08:00 2016 -0600
@@ -0,0 +1,2 @@
+MostSpecific30.java:16:9: compiler.err.ref.ambiguous: m1, kindname.method, m1(MostSpecific30.Pred<? extends java.lang.Integer>), MostSpecific30, kindname.method, m1(MostSpecific30.Fun<java.lang.Integer,java.lang.Boolean>), MostSpecific30
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific31.java	Fri Jun 10 15:08:00 2016 -0600
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8144767
+ * @summary Correct most-specific test when wildcards appear in functional interface type
+ * @compile/fail/ref=MostSpecific31.out -XDrawDiagnostics MostSpecific31.java
+ */
+class MostSpecific31 {
+
+    interface Pred<T> { boolean test(T arg); }
+    interface Fun<T,R> { R apply(T arg); }
+
+    static void m1(Pred<? super Number> f) {}
+    static void m1(Fun<Integer, Boolean> f) {}
+
+    static boolean foo(Object arg) { return false; }
+
+    void test() {
+        m1(MostSpecific31::foo);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific31.out	Fri Jun 10 15:08:00 2016 -0600
@@ -0,0 +1,2 @@
+MostSpecific31.java:18:9: compiler.err.ref.ambiguous: m1, kindname.method, m1(MostSpecific31.Pred<? super java.lang.Number>), MostSpecific31, kindname.method, m1(MostSpecific31.Fun<java.lang.Integer,java.lang.Boolean>), MostSpecific31
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific32.java	Fri Jun 10 15:08:00 2016 -0600
@@ -0,0 +1,22 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8144767
+ * @summary Correct most-specific test when wildcards appear in functional interface type
+ * @compile/fail/ref=MostSpecific32.out -XDrawDiagnostics MostSpecific32.java
+ */
+class MostSpecific32 {
+
+    interface A<T> {}
+    interface B<T> extends A<T> {}
+
+    interface F1<S> { A<S> apply(); }
+    interface F2<S> { B<S> apply(); }
+
+    static void m1(F1<? extends Number> f1) {}
+    static void m1(F2<? extends Number> f2) {}
+
+    void test() {
+        m1(() -> null); // B<CAP ext Number> </: A<Number>
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific32.out	Fri Jun 10 15:08:00 2016 -0600
@@ -0,0 +1,2 @@
+MostSpecific32.java:19:9: compiler.err.ref.ambiguous: m1, kindname.method, m1(MostSpecific32.F1<? extends java.lang.Number>), MostSpecific32, kindname.method, m1(MostSpecific32.F2<? extends java.lang.Number>), MostSpecific32
+1 error