8143852: Implement type variable renaming for functional interface most specific test

Reviewed-by: mcimadamore, vromero
This commit is contained in:
Dan Smith 2016-01-08 17:02:29 -07:00
parent c2eb8c18a2
commit cbaccb91f0
24 changed files with 533 additions and 60 deletions

View file

@ -1146,14 +1146,21 @@ public class Types {
if (!visit(supertype(t), supertype(s))) if (!visit(supertype(t), supertype(s)))
return false; return false;
HashSet<UniqueType> set = new HashSet<>(); Map<Symbol,Type> tMap = new HashMap<>();
for (Type x : interfaces(t)) for (Type ti : interfaces(t)) {
set.add(new UniqueType(x, Types.this)); if (tMap.containsKey(ti)) {
for (Type x : interfaces(s)) { throw new AssertionError("Malformed intersection");
if (!set.remove(new UniqueType(x, Types.this))) }
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 false;
} }
return (set.isEmpty()); return tMap.isEmpty();
} }
return t.tsym == s.tsym return t.tsym == s.tsym
&& visit(t.getEnclosingType(), s.getEnclosingType()) && visit(t.getEnclosingType(), s.getEnclosingType())

View file

@ -1137,7 +1137,56 @@ public class Resolve {
/** Parameters {@code t} and {@code s} are unrelated functional interface types. */ /** Parameters {@code t} and {@code s} are unrelated functional interface types. */
private boolean functionalInterfaceMostSpecific(Type t, Type s, JCTree tree) { 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); msc.scan(tree);
return msc.result; return msc.result;
} }
@ -1146,16 +1195,16 @@ public class Resolve {
* Tests whether one functional interface type can be considered more specific * Tests whether one functional interface type can be considered more specific
* than another unrelated functional interface type for the scanned expression. * than another unrelated functional interface type for the scanned expression.
*/ */
class FunctionalInterfaceMostSpecificChecker extends DeferredAttr.PolyScanner { class MostSpecificFunctionReturnChecker extends DeferredAttr.PolyScanner {
final Type t; final Type tRet;
final Type s; final Type sRet;
boolean result; boolean result;
/** Parameters {@code t} and {@code s} are unrelated functional interface types. */ /** Parameters {@code t} and {@code s} are unrelated functional interface types. */
FunctionalInterfaceMostSpecificChecker(Type t, Type s) { MostSpecificFunctionReturnChecker(Type tRet, Type sRet) {
this.t = t; this.tRet = tRet;
this.s = s; this.sRet = sRet;
result = true; result = true;
} }
@ -1172,29 +1221,18 @@ public class Resolve {
@Override @Override
public void visitReference(JCMemberReference tree) { public void visitReference(JCMemberReference tree) {
Type desc_t = types.findDescriptorType(t); if (sRet.hasTag(VOID)) {
Type desc_s = types.findDescriptorType(s); result &= true;
// use inference variables here for more-specific inference (18.5.4) } else if (tRet.hasTag(VOID)) {
if (!types.isSameTypes(desc_t.getParameterTypes(),
inferenceContext().asUndetVars(desc_s.getParameterTypes()))) {
result &= false; 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 { } else {
// compare return types result &= compatibleBySubtyping(tRet, sRet);
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);
}
} }
} }
@ -1205,35 +1243,24 @@ public class Resolve {
@Override @Override
public void visitLambda(JCLambda tree) { public void visitLambda(JCLambda tree) {
Type desc_t = types.findDescriptorType(t); if (sRet.hasTag(VOID)) {
Type desc_s = types.findDescriptorType(s); result &= true;
// use inference variables here for more-specific inference (18.5.4) } else if (tRet.hasTag(VOID)) {
if (!types.isSameTypes(desc_t.getParameterTypes(),
inferenceContext().asUndetVars(desc_s.getParameterTypes()))) {
result &= false; result &= false;
} else { } else {
// compare return types List<JCExpression> lambdaResults = lambdaResults(tree);
Type ret_t = desc_t.getReturnType(); if (!lambdaResults.isEmpty() && unrelatedFunctionalInterfaces(tRet, sRet)) {
Type ret_s = desc_s.getReturnType(); for (JCExpression expr : lambdaResults) {
if (ret_s.hasTag(VOID)) { result &= functionalInterfaceMostSpecific(tRet, sRet, expr);
result &= true;
} else if (ret_t.hasTag(VOID)) {
result &= false;
} 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);
} }
} 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 {
result &= compatibleBySubtyping(tRet, sRet);
} }
} }
} }

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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