changeset 3199:3a6560c043d2

8143852: Implement type variable renaming for functional interface most specific test Reviewed-by: mcimadamore, vromero
author dlsmith
date Fri, 08 Jan 2016 17:02:29 -0700
parents 5ab68e3a1096
children 9f3a70d14025
files src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java test/tools/javac/lambda/MostSpecific15.java test/tools/javac/lambda/MostSpecific16.java test/tools/javac/lambda/MostSpecific16.out test/tools/javac/lambda/MostSpecific17.java test/tools/javac/lambda/MostSpecific18.java test/tools/javac/lambda/MostSpecific19.java test/tools/javac/lambda/MostSpecific19.out test/tools/javac/lambda/MostSpecific20.java test/tools/javac/lambda/MostSpecific21.java test/tools/javac/lambda/MostSpecific21.out test/tools/javac/lambda/MostSpecific22.java test/tools/javac/lambda/MostSpecific23.java test/tools/javac/lambda/MostSpecific23.out test/tools/javac/lambda/MostSpecific24.java test/tools/javac/lambda/MostSpecific24.out test/tools/javac/lambda/MostSpecific25.java test/tools/javac/lambda/MostSpecific25.out test/tools/javac/lambda/MostSpecific26.java test/tools/javac/lambda/MostSpecific26.out test/tools/javac/lambda/MostSpecific27.java test/tools/javac/lambda/MostSpecific28.java test/tools/javac/lambda/MostSpecific28.out
diffstat 24 files changed, 534 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Fri Jan 08 15:15:21 2016 -0800
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Fri Jan 08 17:02:29 2016 -0700
@@ -1146,14 +1146,21 @@
                     if (!visit(supertype(t), supertype(s)))
                         return false;
 
-                    HashSet<UniqueType> set = new HashSet<>();
-                    for (Type x : interfaces(t))
-                        set.add(new UniqueType(x, Types.this));
-                    for (Type x : interfaces(s)) {
-                        if (!set.remove(new UniqueType(x, Types.this)))
+                    Map<Symbol,Type> tMap = new HashMap<>();
+                    for (Type ti : interfaces(t)) {
+                        if (tMap.containsKey(ti)) {
+                            throw new AssertionError("Malformed intersection");
+                        }
+                        tMap.put(ti.tsym, ti);
+                    }
+                    for (Type si : interfaces(s)) {
+                        if (!tMap.containsKey(si.tsym))
+                            return false;
+                        Type ti = tMap.remove(si.tsym);
+                        if (!visit(ti, si))
                             return false;
                     }
-                    return (set.isEmpty());
+                    return tMap.isEmpty();
                 }
                 return t.tsym == s.tsym
                     && visit(t.getEnclosingType(), s.getEnclosingType())
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java	Fri Jan 08 15:15:21 2016 -0800
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java	Fri Jan 08 17:02:29 2016 -0700
@@ -1137,7 +1137,56 @@
 
             /** Parameters {@code t} and {@code s} are unrelated functional interface types. */
             private boolean functionalInterfaceMostSpecific(Type t, Type s, JCTree tree) {
-                FunctionalInterfaceMostSpecificChecker msc = new FunctionalInterfaceMostSpecificChecker(t, s);
+                Type tDesc = 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> sTypeParams = sDesc.getTypeArguments();
+                List<Type> tIter = tTypeParams;
+                List<Type> sIter = sTypeParams;
+                while (tIter.nonEmpty() && sIter.nonEmpty()) {
+                    Type tBound = tIter.head.getUpperBound();
+                    Type sBound = types.subst(sIter.head.getUpperBound(), sTypeParams, tTypeParams);
+                    if (tBound.containsAny(tTypeParams) && inferenceContext().free(sBound)) {
+                        return false;
+                    }
+                    if (!types.isSameType(tBound, inferenceContext().asUndetVar(sBound))) {
+                        return false;
+                    }
+                    tIter = tIter.tail;
+                    sIter = sIter.tail;
+                }
+                if (!tIter.isEmpty() || !sIter.isEmpty()) {
+                    return false;
+                }
+
+                // compare parameters
+                List<Type> tParams = tDesc.getParameterTypes();
+                List<Type> sParams = sDesc.getParameterTypes();
+                while (tParams.nonEmpty() && sParams.nonEmpty()) {
+                    Type tParam = tParams.head;
+                    Type sParam = types.subst(sParams.head, sTypeParams, tTypeParams);
+                    if (tParam.containsAny(tTypeParams) && inferenceContext().free(sParam)) {
+                        return false;
+                    }
+                    if (!types.isSameType(tParam, inferenceContext().asUndetVar(sParam))) {
+                        return false;
+                    }
+                    tParams = tParams.tail;
+                    sParams = sParams.tail;
+                }
+                if (!tParams.isEmpty() || !sParams.isEmpty()) {
+                    return false;
+                }
+
+                // compare returns
+                Type tRet = tDesc.getReturnType();
+                Type sRet = types.subst(sDesc.getReturnType(), sTypeParams, tTypeParams);
+                if (tRet.containsAny(tTypeParams) && inferenceContext().free(sRet)) {
+                    return false;
+                }
+                MostSpecificFunctionReturnChecker msc = new MostSpecificFunctionReturnChecker(tRet, sRet);
                 msc.scan(tree);
                 return msc.result;
             }
@@ -1146,16 +1195,16 @@
              * Tests whether one functional interface type can be considered more specific
              * than another unrelated functional interface type for the scanned expression.
              */
-            class FunctionalInterfaceMostSpecificChecker extends DeferredAttr.PolyScanner {
-
-                final Type t;
-                final Type s;
+            class MostSpecificFunctionReturnChecker extends DeferredAttr.PolyScanner {
+
+                final Type tRet;
+                final Type sRet;
                 boolean result;
 
                 /** Parameters {@code t} and {@code s} are unrelated functional interface types. */
-                FunctionalInterfaceMostSpecificChecker(Type t, Type s) {
-                    this.t = t;
-                    this.s = s;
+                MostSpecificFunctionReturnChecker(Type tRet, Type sRet) {
+                    this.tRet = tRet;
+                    this.sRet = sRet;
                     result = true;
                 }
 
@@ -1172,29 +1221,18 @@
 
                 @Override
                 public void visitReference(JCMemberReference tree) {
-                    Type desc_t = types.findDescriptorType(t);
-                    Type desc_s = types.findDescriptorType(s);
-                    // use inference variables here for more-specific inference (18.5.4)
-                    if (!types.isSameTypes(desc_t.getParameterTypes(),
-                            inferenceContext().asUndetVars(desc_s.getParameterTypes()))) {
+                    if (sRet.hasTag(VOID)) {
+                        result &= true;
+                    } else if (tRet.hasTag(VOID)) {
                         result &= false;
+                    } else if (tRet.isPrimitive() != sRet.isPrimitive()) {
+                        boolean retValIsPrimitive =
+                                tree.refPolyKind == PolyKind.STANDALONE &&
+                                tree.sym.type.getReturnType().isPrimitive();
+                        result &= (retValIsPrimitive == tRet.isPrimitive()) &&
+                                  (retValIsPrimitive != sRet.isPrimitive());
                     } else {
-                        // compare return types
-                        Type ret_t = desc_t.getReturnType();
-                        Type ret_s = desc_s.getReturnType();
-                        if (ret_s.hasTag(VOID)) {
-                            result &= true;
-                        } else if (ret_t.hasTag(VOID)) {
-                            result &= false;
-                        } else if (ret_t.isPrimitive() != ret_s.isPrimitive()) {
-                            boolean retValIsPrimitive =
-                                    tree.refPolyKind == PolyKind.STANDALONE &&
-                                    tree.sym.type.getReturnType().isPrimitive();
-                            result &= (retValIsPrimitive == ret_t.isPrimitive()) &&
-                                      (retValIsPrimitive != ret_s.isPrimitive());
-                        } else {
-                            result &= compatibleBySubtyping(ret_t, ret_s);
-                        }
+                        result &= compatibleBySubtyping(tRet, sRet);
                     }
                 }
 
@@ -1205,35 +1243,24 @@
 
                 @Override
                 public void visitLambda(JCLambda tree) {
-                    Type desc_t = types.findDescriptorType(t);
-                    Type desc_s = types.findDescriptorType(s);
-                    // use inference variables here for more-specific inference (18.5.4)
-                    if (!types.isSameTypes(desc_t.getParameterTypes(),
-                            inferenceContext().asUndetVars(desc_s.getParameterTypes()))) {
+                    if (sRet.hasTag(VOID)) {
+                        result &= true;
+                    } else if (tRet.hasTag(VOID)) {
                         result &= false;
                     } else {
-                        // compare return types
-                        Type ret_t = desc_t.getReturnType();
-                        Type ret_s = desc_s.getReturnType();
-                        if (ret_s.hasTag(VOID)) {
-                            result &= true;
-                        } else if (ret_t.hasTag(VOID)) {
-                            result &= false;
+                        List<JCExpression> lambdaResults = lambdaResults(tree);
+                        if (!lambdaResults.isEmpty() && unrelatedFunctionalInterfaces(tRet, sRet)) {
+                            for (JCExpression expr : lambdaResults) {
+                                result &= functionalInterfaceMostSpecific(tRet, sRet, expr);
+                            }
+                        } else if (!lambdaResults.isEmpty() && tRet.isPrimitive() != sRet.isPrimitive()) {
+                            for (JCExpression expr : lambdaResults) {
+                                boolean retValIsPrimitive = expr.isStandalone() && expr.type.isPrimitive();
+                                result &= (retValIsPrimitive == tRet.isPrimitive()) &&
+                                        (retValIsPrimitive != sRet.isPrimitive());
+                            }
                         } else {
-                            List<JCExpression> lambdaResults = lambdaResults(tree);
-                            if (!lambdaResults.isEmpty() && unrelatedFunctionalInterfaces(ret_t, ret_s)) {
-                                for (JCExpression expr : lambdaResults) {
-                                    result &= functionalInterfaceMostSpecific(ret_t, ret_s, expr);
-                                }
-                            } else if (!lambdaResults.isEmpty() && ret_t.isPrimitive() != ret_s.isPrimitive()) {
-                                for (JCExpression expr : lambdaResults) {
-                                    boolean retValIsPrimitive = expr.isStandalone() && expr.type.isPrimitive();
-                                    result &= (retValIsPrimitive == ret_t.isPrimitive()) &&
-                                            (retValIsPrimitive != ret_s.isPrimitive());
-                                }
-                            } else {
-                                result &= compatibleBySubtyping(ret_t, ret_s);
-                            }
+                            result &= compatibleBySubtyping(tRet, sRet);
                         }
                     }
                 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific15.java	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,43 @@
+/*
+ * 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 8143852
+ * @summary Rename functional interface method type parameters during most specific test
+ * @compile MostSpecific15.java
+ */
+class MostSpecific15 {
+    interface F1 { <X> Object apply(X arg); }
+    interface F2 { <Y> String apply(Y arg); }
+
+    static void m1(F1 f) {}
+    static void m1(F2 f) {}
+
+    static String foo(Object in) { return "a"; }
+
+    void test() {
+        m1(MostSpecific15::foo);
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific16.java	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8143852
+ * @summary Rename functional interface method type parameters during most specific test
+ * @compile/fail/ref=MostSpecific16.out -XDrawDiagnostics MostSpecific16.java
+ */
+class MostSpecific16 {
+    interface F1 { <X> Object apply(Object arg); }
+    interface F2 { String apply(Object arg); }
+
+    static void m1(F1 f) {}
+    static void m1(F2 f) {}
+
+    static String foo(Object in) { return "a"; }
+
+    void test() {
+        m1(MostSpecific16::foo);
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific16.out	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,2 @@
+MostSpecific16.java:17:9: compiler.err.ref.ambiguous: m1, kindname.method, m1(MostSpecific16.F1), MostSpecific16, kindname.method, m1(MostSpecific16.F2), MostSpecific16
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific17.java	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,47 @@
+/*
+ * 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 8143852
+ * @summary Rename functional interface method type parameters during most specific test
+ * @compile MostSpecific17.java
+ */
+class MostSpecific17 {
+
+    interface A<T> {}
+    interface B<T> extends A<T> {}
+
+    interface F1 { <X> A<? super X> apply(Object arg); }
+    interface F2 { <Y> B<? super Y> apply(Object arg); }
+
+    static void m1(F1 f) {}
+    static void m1(F2 f) {}
+
+    static B<Object> foo(Object in) { return null; }
+
+    void test() {
+        m1(MostSpecific17::foo);
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific18.java	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,43 @@
+/*
+ * 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 8143852
+ * @summary Test that generic function interface method bounds are the same
+ * @compile MostSpecific18.java
+ */
+class MostSpecific18 {
+    interface F1 { <X extends Number> Object apply(X arg); }
+    interface F2 { <Y extends Number> String apply(Y arg); }
+
+    static void m1(F1 f) {}
+    static void m1(F2 f) {}
+
+    static String foo(Object in) { return "a"; }
+
+    void test() {
+        m1(MostSpecific18::foo);
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific19.java	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8143852
+ * @summary Test that generic function interface method bounds are the same
+ * @compile/fail/ref=MostSpecific19.out -XDrawDiagnostics MostSpecific19.java
+ */
+class MostSpecific19 {
+    interface F1 { <X extends Number> Object apply(X arg); }
+    interface F2 { <Y extends Integer> String apply(Y arg); }
+
+    static void m1(F1 f) {}
+    static void m1(F2 f) {}
+
+    static String foo(Object in) { return "a"; }
+
+    void test() {
+        m1(MostSpecific19::foo);
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific19.out	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,2 @@
+MostSpecific19.java:17:9: compiler.err.ref.ambiguous: m1, kindname.method, m1(MostSpecific19.F1), MostSpecific19, kindname.method, m1(MostSpecific19.F2), MostSpecific19
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific20.java	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,43 @@
+/*
+ * 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 8143852
+ * @summary Test that generic function interface method bounds are the same
+ * @compile MostSpecific20.java
+ */
+class MostSpecific20 {
+    interface F1 { <X extends Iterable<X>> Object apply(X arg); }
+    interface F2 { <Y extends Iterable<Y>> String apply(Y arg); }
+
+    static void m1(F1 f) {}
+    static void m1(F2 f) {}
+
+    static String foo(Object in) { return "a"; }
+
+    void test() {
+        m1(MostSpecific20::foo);
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific21.java	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8143852
+ * @summary Most specific inference constraints derived from both functional interface method parameters and tparam bounds
+ * @compile/fail/ref=MostSpecific21.out -XDrawDiagnostics MostSpecific21.java
+ */
+class MostSpecific21 {
+    interface F1<T> { <X extends T> Object apply(T arg); }
+    interface F2 { <Y extends Number> String apply(Integer arg); }
+
+    static <T> T m1(F1<T> f) { return null; }
+    static Object m1(F2 f) { return null; }
+
+    static String foo(Object in) { return "a"; }
+
+    void test() {
+        m1(MostSpecific21::foo);
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific21.out	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,2 @@
+MostSpecific21.java:17:9: compiler.err.ref.ambiguous: m1, kindname.method, <T>m1(MostSpecific21.F1<T>), MostSpecific21, kindname.method, m1(MostSpecific21.F2), MostSpecific21
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific22.java	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,43 @@
+/*
+ * 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 8143852
+ * @summary Most specific inference constraints derived from both functional interface method parameters and tparam bounds
+ * @compile MostSpecific22.java
+ */
+class MostSpecific22 {
+    interface F1<T> { <X extends T> Object apply(T arg); }
+    interface F2 { <Y extends Number> String apply(Number arg); }
+
+    static <T> T m1(F1<T> f) { return null; }
+    static Object m1(F2 f) { return null; }
+
+    static String foo(Object in) { return "a"; }
+
+    void test() {
+        m1(MostSpecific22::foo);
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific23.java	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8143852
+ * @summary Most specific failure if ivar can be bounded by functional interface method tparam
+ * @compile/fail/ref=MostSpecific23.out -XDrawDiagnostics MostSpecific23.java
+ */
+class MostSpecific23 {
+    interface F1<T> { <X extends T> Object apply(Integer arg); }
+    interface F2 { <Y extends Class<Y>> String apply(Integer arg); }
+
+    static <T> T m1(F1<T> f) { return null; }
+    static Object m1(F2 f) { return null; }
+
+    static String foo(Object in) { return "a"; }
+
+    void test() {
+        m1(MostSpecific23::foo);
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific23.out	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,2 @@
+MostSpecific23.java:17:9: compiler.err.ref.ambiguous: m1, kindname.method, <T>m1(MostSpecific23.F1<T>), MostSpecific23, kindname.method, m1(MostSpecific23.F2), MostSpecific23
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific24.java	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8143852
+ * @summary Most specific failure if ivar can be bounded by functional interface method tparam
+ * @compile/fail/ref=MostSpecific24.out -XDrawDiagnostics MostSpecific24.java
+ */
+class MostSpecific24 {
+    interface F1<T> { <X> Object apply(Class<T> arg); }
+    interface F2 { <Y> String apply(Class<Y> arg); }
+
+    static <T> T m1(F1<T> f) { return null; }
+    static Object m1(F2 f) { return null; }
+
+    static String foo(Object in) { return "a"; }
+
+    void test() {
+        m1(MostSpecific24::foo);
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific24.out	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,2 @@
+MostSpecific24.java:17:9: compiler.err.ref.ambiguous: m1, kindname.method, <T>m1(MostSpecific24.F1<T>), MostSpecific24, kindname.method, m1(MostSpecific24.F2), MostSpecific24
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific25.java	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8143852
+ * @summary Most specific failure if ivar can be bounded by functional interface method tparam
+ * @compile/fail/ref=MostSpecific25.out -XDrawDiagnostics MostSpecific25.java
+ */
+class MostSpecific25 {
+    interface F1<T> { <X> T apply(Integer arg); }
+    interface F2 { <Y> Class<? super Y> apply(Integer arg); }
+
+    static <T> T m1(F1<T> f) { return null; }
+    static Object m1(F2 f) { return null; }
+
+    static Class<Object> foo(Object in) { return Object.class; }
+
+    void test() {
+        m1(MostSpecific25::foo);
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific25.out	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,2 @@
+MostSpecific25.java:17:9: compiler.err.ref.ambiguous: m1, kindname.method, <T>m1(MostSpecific25.F1<T>), MostSpecific25, kindname.method, m1(MostSpecific25.F2), MostSpecific25
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific26.java	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8143852
+ * @summary Most specific inference constraints derived from intersection bound
+ * @compile/fail/ref=MostSpecific26.out -XDrawDiagnostics MostSpecific26.java
+ */
+class MostSpecific26 {
+    interface F1<T> { <X extends Iterable<T> & Runnable> Object apply(T arg); }
+    interface F2 { <Y extends Iterable<Number> & Runnable> String apply(Integer arg); }
+
+    static <T> T m1(F1<T> f) { return null; }
+    static Object m1(F2 f) { return null; }
+
+    static String foo(Object in) { return "a"; }
+
+    void test() {
+        m1(MostSpecific26::foo);
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific26.out	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,2 @@
+MostSpecific26.java:17:9: compiler.err.ref.ambiguous: m1, kindname.method, <T>m1(MostSpecific26.F1<T>), MostSpecific26, kindname.method, m1(MostSpecific26.F2), MostSpecific26
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific27.java	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,43 @@
+/*
+ * 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 8143852
+ * @summary Most specific inference constraints derived from intersection bound
+ * @compile MostSpecific27.java
+ */
+class MostSpecific27 {
+    interface F1<T> { <X extends Iterable<T> & Runnable> Object apply(T arg); }
+    interface F2 { <Y extends Iterable<Number> & Runnable> String apply(Number arg); }
+
+    static <T> T m1(F1<T> f) { return null; }
+    static Object m1(F2 f) { return null; }
+
+    static String foo(Object in) { return "a"; }
+
+    void test() {
+        m1(MostSpecific27::foo);
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific28.java	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8143852
+ * @summary Test that functional interface method parameter types are equal, even for an explicit lambda
+ * @compile/fail/ref=MostSpecific28.out -XDrawDiagnostics MostSpecific28.java
+ */
+class MostSpecific28 {
+
+    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<Number, Boolean> f) {}
+
+    static String foo(Object in) { return "a"; }
+
+    void test() {
+        m1((Number n) -> true);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MostSpecific28.out	Fri Jan 08 17:02:29 2016 -0700
@@ -0,0 +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
+1 error