8034223: Most-specific should not have any special treatment for boxed vs. unboxed types
Summary: Rewrite most-specific logic to conform to JLS 8 15.12.2.5
Reviewed-by: vromero
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java Fri May 09 22:27:07 2014 -0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java Tue May 13 15:29:09 2014 -0600
@@ -234,7 +234,7 @@
public boolean allowGraphInference() {
return compareTo(JDK1_8) >= 0;
}
- public boolean allowStructuralMostSpecific() {
+ public boolean allowFunctionalInterfaceMostSpecific() {
return compareTo(JDK1_8) >= 0;
}
public static SourceVersion toSourceVersion(Source source) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri May 09 22:27:07 2014 -0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Tue May 13 15:29:09 2014 -0600
@@ -94,7 +94,7 @@
public final boolean boxingEnabled;
public final boolean varargsEnabled;
public final boolean allowMethodHandles;
- public final boolean allowStructuralMostSpecific;
+ public final boolean allowFunctionalInterfaceMostSpecific;
private final boolean debugResolve;
private final boolean compactMethodDiags;
final EnumSet<VerboseResolutionMode> verboseResolutionMode;
@@ -135,7 +135,7 @@
verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
Target target = Target.instance(context);
allowMethodHandles = target.hasMethodHandles();
- allowStructuralMostSpecific = source.allowStructuralMostSpecific();
+ allowFunctionalInterfaceMostSpecific = source.allowFunctionalInterfaceMostSpecific();
polymorphicSignatureScope = new Scope(syms.noSymbol);
inapplicableMethodException = new InapplicableMethodException(diags);
@@ -1084,50 +1084,47 @@
}
public boolean compatible(Type found, Type req, Warner warn) {
- if (!allowStructuralMostSpecific || actual == null) {
- return super.compatible(found, req, warn);
- } else {
- switch (actual.getTag()) {
- case DEFERRED:
- DeferredType dt = (DeferredType) actual;
- DeferredType.SpeculativeCache.Entry e = dt.speculativeCache.get(deferredAttrContext.msym, deferredAttrContext.phase);
- return (e == null || e.speculativeTree == deferredAttr.stuckTree)
- ? super.compatible(found, req, warn) :
- mostSpecific(found, req, e.speculativeTree, warn);
- default:
- return standaloneMostSpecific(found, req, actual, warn);
+ if (allowFunctionalInterfaceMostSpecific &&
+ unrelatedFunctionalInterfaces(found, req) &&
+ (actual != null && actual.getTag() == DEFERRED)) {
+ DeferredType dt = (DeferredType) actual;
+ DeferredType.SpeculativeCache.Entry e =
+ dt.speculativeCache.get(deferredAttrContext.msym, deferredAttrContext.phase);
+ if (e != null && e.speculativeTree != deferredAttr.stuckTree) {
+ return functionalInterfaceMostSpecific(found, req, e.speculativeTree, warn);
}
}
+ return super.compatible(found, req, warn);
}
- private boolean mostSpecific(Type t, Type s, JCTree tree, Warner warn) {
- MostSpecificChecker msc = new MostSpecificChecker(t, s, warn);
+ /** Whether {@code t} and {@code s} are unrelated functional interface types. */
+ private boolean unrelatedFunctionalInterfaces(Type t, Type s) {
+ return types.isFunctionalInterface(t.tsym) &&
+ types.isFunctionalInterface(s.tsym) &&
+ types.asSuper(t, s.tsym) == null &&
+ types.asSuper(s, t.tsym) == null;
+ }
+
+ /** Parameters {@code t} and {@code s} are unrelated functional interface types. */
+ private boolean functionalInterfaceMostSpecific(Type t, Type s, JCTree tree, Warner warn) {
+ FunctionalInterfaceMostSpecificChecker msc = new FunctionalInterfaceMostSpecificChecker(t, s, warn);
msc.scan(tree);
return msc.result;
}
- boolean polyMostSpecific(Type t1, Type t2, Warner warn) {
- return (!t1.isPrimitive() && t2.isPrimitive())
- ? true : super.compatible(t1, t2, warn);
- }
-
- boolean standaloneMostSpecific(Type t1, Type t2, Type exprType, Warner warn) {
- return (exprType.isPrimitive() == t1.isPrimitive()
- && exprType.isPrimitive() != t2.isPrimitive())
- ? true : super.compatible(t1, t2, warn);
- }
-
/**
- * Structural checker for most specific.
+ * Tests whether one functional interface type can be considered more specific
+ * than another unrelated functional interface type for the scanned expression.
*/
- class MostSpecificChecker extends DeferredAttr.PolyScanner {
+ class FunctionalInterfaceMostSpecificChecker extends DeferredAttr.PolyScanner {
final Type t;
final Type s;
final Warner warn;
boolean result;
- MostSpecificChecker(Type t, Type s, Warner warn) {
+ /** Parameters {@code t} and {@code s} are unrelated functional interface types. */
+ FunctionalInterfaceMostSpecificChecker(Type t, Type s, Warner warn) {
this.t = t;
this.s = s;
this.warn = warn;
@@ -1136,102 +1133,96 @@
@Override
void skip(JCTree tree) {
- result &= standaloneMostSpecific(t, s, tree.type, warn);
+ result &= false;
}
@Override
public void visitConditional(JCConditional tree) {
- if (tree.polyKind == PolyKind.STANDALONE) {
- result &= standaloneMostSpecific(t, s, tree.type, warn);
- } else {
- super.visitConditional(tree);
- }
- }
-
- @Override
- public void visitApply(JCMethodInvocation tree) {
- result &= (tree.polyKind == PolyKind.STANDALONE)
- ? standaloneMostSpecific(t, s, tree.type, warn)
- : polyMostSpecific(t, s, warn);
- }
-
- @Override
- public void visitNewClass(JCNewClass tree) {
- result &= (tree.polyKind == PolyKind.STANDALONE)
- ? standaloneMostSpecific(t, s, tree.type, warn)
- : polyMostSpecific(t, s, warn);
+ scan(tree.truepart);
+ scan(tree.falsepart);
}
@Override
public void visitReference(JCMemberReference tree) {
- if (types.isFunctionalInterface(t.tsym) &&
- types.isFunctionalInterface(s.tsym)) {
- Type desc_t = types.findDescriptorType(t);
- Type desc_s = types.findDescriptorType(s);
- if (types.isSameTypes(desc_t.getParameterTypes(),
- inferenceContext().asUndetVars(desc_s.getParameterTypes()))) {
- if (types.asSuper(t, s.tsym) != null ||
- types.asSuper(s, t.tsym) != null) {
- result &= MostSpecificCheckContext.super.compatible(t, s, warn);
- } else if (!desc_s.getReturnType().hasTag(VOID)) {
- //perform structural comparison
- Type ret_t = desc_t.getReturnType();
- Type ret_s = desc_s.getReturnType();
- result &= ((tree.refPolyKind == PolyKind.STANDALONE)
- ? standaloneMostSpecific(ret_t, ret_s, tree.sym.type.getReturnType(), warn)
- : polyMostSpecific(ret_t, ret_s, warn));
- } else {
- return;
- }
+ 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()))) {
+ 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;
+ } 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 &= MostSpecificCheckContext.super.compatible(ret_t, ret_s, warn);
}
- } else {
- result &= false;
}
}
@Override
public void visitLambda(JCLambda tree) {
- if (types.isFunctionalInterface(t.tsym) &&
- types.isFunctionalInterface(s.tsym)) {
- Type desc_t = types.findDescriptorType(t);
- Type desc_s = types.findDescriptorType(s);
- if (types.isSameTypes(desc_t.getParameterTypes(),
- inferenceContext().asUndetVars(desc_s.getParameterTypes()))) {
- if (types.asSuper(t, s.tsym) != null ||
- types.asSuper(s, t.tsym) != null) {
- result &= MostSpecificCheckContext.super.compatible(t, s, warn);
- } else if (!desc_s.getReturnType().hasTag(VOID)) {
- //perform structural comparison
- Type ret_t = desc_t.getReturnType();
- Type ret_s = desc_s.getReturnType();
- scanLambdaBody(tree, ret_t, ret_s);
- } else {
- return;
+ 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()))) {
+ 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;
+ } else if (unrelatedFunctionalInterfaces(ret_t, ret_s)) {
+ for (JCExpression expr : lambdaResults(tree)) {
+ result &= functionalInterfaceMostSpecific(ret_t, ret_s, expr, warn);
}
+ } else if (ret_t.isPrimitive() != ret_s.isPrimitive()) {
+ for (JCExpression expr : lambdaResults(tree)) {
+ boolean retValIsPrimitive = expr.isStandalone() && expr.type.isPrimitive();
+ result &= (retValIsPrimitive == ret_t.isPrimitive()) &&
+ (retValIsPrimitive != ret_s.isPrimitive());
+ }
+ } else {
+ result &= MostSpecificCheckContext.super.compatible(ret_t, ret_s, warn);
}
- } else {
- result &= false;
}
}
//where
- void scanLambdaBody(JCLambda lambda, final Type t, final Type s) {
+ private List<JCExpression> lambdaResults(JCLambda lambda) {
if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) {
- result &= MostSpecificCheckContext.this.mostSpecific(t, s, lambda.body, warn);
+ return List.of((JCExpression) lambda.body);
} else {
+ final ListBuffer<JCExpression> buffer = new ListBuffer<>();
DeferredAttr.LambdaReturnScanner lambdaScanner =
new DeferredAttr.LambdaReturnScanner() {
@Override
public void visitReturn(JCReturn tree) {
if (tree.expr != null) {
- result &= MostSpecificCheckContext.this.mostSpecific(t, s, tree.expr, warn);
+ buffer.append(tree.expr);
}
}
};
lambdaScanner.scan(lambda.body);
+ return buffer.toList();
}
}
}
+
}
public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java Fri May 09 22:27:07 2014 -0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java Tue May 13 15:29:09 2014 -0600
@@ -643,6 +643,9 @@
super.setPos(pos);
return this;
}
+
+ public boolean isPoly() { return false; }
+ public boolean isStandalone() { return true; }
}
/**
@@ -663,6 +666,9 @@
/** is this poly expression a 'true' poly expression? */
public PolyKind polyKind;
+
+ @Override public boolean isPoly() { return polyKind == PolyKind.POLY; }
+ @Override public boolean isStandalone() { return polyKind == PolyKind.STANDALONE; }
}
/**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific10.java Tue May 13 15:29:09 2014 -0600
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, 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 8034223
+ * @summary Structural most-specific logic for lambdas, method refs, parens, and conditionals
+ * @compile MostSpecific10.java
+ */
+class MostSpecific10 {
+
+ interface GetInt {
+ int get();
+ }
+
+ interface GetInteger {
+ Integer get();
+ }
+
+ void m(GetInt getter) {}
+ void m(GetInteger getter) {}
+
+ void test(boolean cond) {
+ m(() -> 23);
+ m("abc"::length);
+ m(( () -> 23 ));
+ m(( "abc"::length ));
+ m(cond ? () -> 23 : "abc"::length);
+ m(( cond ? () -> 23 : "abc"::length ));
+ m(cond ? (() -> 23) : ("abc"::length) );
+ m(( cond ? () -> 23 : cond ? ("abc"::length) : (() -> 23) ));
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific11.java Tue May 13 15:29:09 2014 -0600
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2014, 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 8034223
+ * @summary Return type Object is not more specific than return type String
+ * @compile MostSpecific11.java
+ */
+class MostSpecific11 {
+
+ interface I { Object run(); }
+ interface J { String run(); }
+
+ void m(I arg) {}
+ void m(J arg) {}
+
+ void test() {
+ m(() -> { throw new RuntimeException(); });
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific12.java Tue May 13 15:29:09 2014 -0600
@@ -0,0 +1,38 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8034223
+ * @summary Most-specific testing with inference variables in function parameter types
+ * @compile/fail/ref=MostSpecific12.out -XDrawDiagnostics MostSpecific12.java
+ */
+class MostSpecific12 {
+
+ interface I<T> { void take(T arg1, String arg2); }
+ interface J<T> { void take(String arg1, T arg2); }
+ interface K { void take(String arg1, String arg2); }
+
+ <T> void m1(I<T> arg) {}
+ void m1(K arg) {}
+
+ <T> void m2(J<T> arg) {}
+ <T> void m2(K arg) {}
+
+ <T> void m3(I<T> arg) {}
+ <T> void m3(J<T> arg) {}
+
+ void test() {
+ m1((String s1, String s2) -> {}); // ok
+ m2((String s1, String s2) -> {}); // ok
+ m3((String s1, String s2) -> {}); // error
+
+ m1(this::referencedMethod); // ok
+ m2(this::referencedMethod); // ok
+ m3(this::referencedMethod); // error
+
+ m1(String::compareTo); // ok
+ m2(String::compareTo); // ok
+ m3(String::compareTo); // error
+ }
+
+ void referencedMethod(String s1, String s2) {}
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific12.out Tue May 13 15:29:09 2014 -0600
@@ -0,0 +1,4 @@
+MostSpecific12.java:25:9: compiler.err.ref.ambiguous: m3, kindname.method, <T>m3(MostSpecific12.I<T>), MostSpecific12, kindname.method, <T>m3(MostSpecific12.J<T>), MostSpecific12
+MostSpecific12.java:29:9: compiler.err.ref.ambiguous: m3, kindname.method, <T>m3(MostSpecific12.I<T>), MostSpecific12, kindname.method, <T>m3(MostSpecific12.J<T>), MostSpecific12
+MostSpecific12.java:33:9: compiler.err.ref.ambiguous: m3, kindname.method, <T>m3(MostSpecific12.I<T>), MostSpecific12, kindname.method, <T>m3(MostSpecific12.J<T>), MostSpecific12
+3 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific13.java Tue May 13 15:29:09 2014 -0600
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8034223
+ * @summary Most-specific testing with inference variables in function parameter types
+ * @compile/fail/ref=MostSpecific13.out -XDrawDiagnostics MostSpecific13.java
+ */
+class MostSpecific13 {
+
+ interface UnaryOp<T> { T apply(T arg); }
+ interface IntegerToNumber { Number apply(Integer arg); }
+
+ <T> void m(UnaryOp<T> f) {}
+ void m(IntegerToNumber f) {}
+
+ void test() {
+ m((Integer i) -> i); // error
+ m(this::id); // error
+ }
+
+ Integer id(Integer arg) { return arg; }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific13.out Tue May 13 15:29:09 2014 -0600
@@ -0,0 +1,3 @@
+MostSpecific13.java:16:9: compiler.err.ref.ambiguous: m, kindname.method, <T>m(MostSpecific13.UnaryOp<T>), MostSpecific13, kindname.method, m(MostSpecific13.IntegerToNumber), MostSpecific13
+MostSpecific13.java:17:9: compiler.err.ref.ambiguous: m, kindname.method, <T>m(MostSpecific13.UnaryOp<T>), MostSpecific13, kindname.method, m(MostSpecific13.IntegerToNumber), MostSpecific13
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific14.java Tue May 13 15:29:09 2014 -0600
@@ -0,0 +1,33 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8034223
+ * @summary Most-specific testing for nested functional interface types
+ * @compile/fail/ref=MostSpecific14.out -XDrawDiagnostics MostSpecific14.java
+ */
+class MostSpecific14 {
+ interface ToNumber { Number get(); }
+ interface ToToNumber { ToNumber get(); }
+ interface Factory<T> { T get(); }
+
+ void m1(Factory<Factory<Object>> f) {}
+ void m1(ToToNumber f) {}
+
+ void m2(Factory<Factory<Number>> f) {}
+ void m2(ToToNumber f) {}
+
+ void m3(Factory<Factory<Integer>> f) {}
+ void m3(ToToNumber f) {}
+
+
+ void test() {
+ m1(() -> () -> 23); // ok: choose ToToNumber
+ m2(() -> () -> 23); // error: ambiguous
+ m3(() -> () -> 23); // ok: choose Factory<Factory<Integer>>
+
+ m1(() -> this::getInteger); // ok: choose ToToNumber
+ m2(() -> this::getInteger); // error: ambiguous
+ m3(() -> this::getInteger); // ok: choose Factory<Factory<Integer>>
+ }
+
+ Integer getInteger() { return 23; }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific14.out Tue May 13 15:29:09 2014 -0600
@@ -0,0 +1,3 @@
+MostSpecific14.java:24:9: compiler.err.ref.ambiguous: m2, kindname.method, m2(MostSpecific14.Factory<MostSpecific14.Factory<java.lang.Number>>), MostSpecific14, kindname.method, m2(MostSpecific14.ToToNumber), MostSpecific14
+MostSpecific14.java:28:9: compiler.err.ref.ambiguous: m2, kindname.method, m2(MostSpecific14.Factory<MostSpecific14.Factory<java.lang.Number>>), MostSpecific14, kindname.method, m2(MostSpecific14.ToToNumber), MostSpecific14
+2 errors
--- a/langtools/test/tools/javac/lambda/TargetType16.java Fri May 09 22:27:07 2014 -0400
+++ b/langtools/test/tools/javac/lambda/TargetType16.java Tue May 13 15:29:09 2014 -0600
@@ -1,9 +1,9 @@
/*
* @test /nodynamiccopyright/
- * @bug 8003280
+ * @bug 8003280 8034223
* @summary Add lambda tests
* Check void-compatibility in strict vs. loose conversion contexts
- * @compile/fail/ref=TargetType16.out -XDrawDiagnostics TargetType16.java
+ * @compile TargetType16.java
*/
class TargetType16 {
@@ -20,6 +20,6 @@
static <T> void m(SAM2<T> s2) { }
public static void main(String[] args) {
- m(() -> { throw new AssertionError(); }); //ambiguous
+ m(() -> { throw new AssertionError(); }); // prefer SAM2
}
}
--- a/langtools/test/tools/javac/lambda/TargetType16.out Fri May 09 22:27:07 2014 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-TargetType16.java:23:9: compiler.err.ref.ambiguous: m, kindname.method, m(TargetType16.SAM1), TargetType16, kindname.method, <T>m(TargetType16.SAM2<T>), TargetType16
-1 error
--- a/langtools/test/tools/javac/lambda/TargetType23.java Fri May 09 22:27:07 2014 -0400
+++ b/langtools/test/tools/javac/lambda/TargetType23.java Tue May 13 15:29:09 2014 -0600
@@ -31,7 +31,12 @@
void call(Sam2 s) { }
<Z> void call(Sam3<Z> s) { }
+ void call2(Sam0 s) { }
+ void call2(Sam2 s) { }
+ <Z> void call2(Sam3<Z> s) { }
+
void test() {
- call(()-> { throw new RuntimeException(); }); //ambiguous - both call(Sam0), call(Sam2), call(Sam3) match
+ call(()-> { throw new RuntimeException(); }); // ambiguous - call(Sam1) vs. call(Sam2)
+ call2(()-> { throw new RuntimeException(); }); // ok
}
}
--- a/langtools/test/tools/javac/lambda/TargetType23.out Fri May 09 22:27:07 2014 -0400
+++ b/langtools/test/tools/javac/lambda/TargetType23.out Tue May 13 15:29:09 2014 -0600
@@ -1,2 +1,2 @@
-TargetType23.java:35:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType23.Sam2), TargetType23, kindname.method, <Z>call(TargetType23.Sam3<Z>), TargetType23
+TargetType23.java:39:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType23.Sam1), TargetType23, kindname.method, call(TargetType23.Sam2), TargetType23
1 error
--- a/langtools/test/tools/javac/resolve/ResolveHarness.java Fri May 09 22:27:07 2014 -0400
+++ b/langtools/test/tools/javac/resolve/ResolveHarness.java Tue May 13 15:29:09 2014 -0600
@@ -23,8 +23,8 @@
/*
* @test
- * @bug 7098660 8014649
- * @summary Write better overload resolution/inference tests
+ * @bug 7098660 8014649 8034223
+ * @summary Test harness for overload resolution/inference tests
* @library /tools/javac/lib
* @build JavacTestingAbstractProcessor ResolveHarness
* @run main ResolveHarness
--- a/langtools/test/tools/javac/resolve/tests/PrimitiveOverReferenceVarargsAmbiguous.java Fri May 09 22:27:07 2014 -0400
+++ b/langtools/test/tools/javac/resolve/tests/PrimitiveOverReferenceVarargsAmbiguous.java Tue May 13 15:29:09 2014 -0600
@@ -23,44 +23,44 @@
@TraceResolve(keys={"compiler.err.ref.ambiguous"})
class PrimitiveOverReferenceVarargsAmbiguous {
- @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_byte(byte... b) {}
- @Candidate(applicable=Phase.VARARGS)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_byte(Byte... b) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_short(short... s) {}
- @Candidate(applicable=Phase.VARARGS)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_short(Short... s) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_int(int... i) {}
- @Candidate(applicable=Phase.VARARGS)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_int(Integer... i) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_long(long... l) {}
- @Candidate(applicable=Phase.VARARGS)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_long(Long... l) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_float(float... f) {}
- @Candidate(applicable=Phase.VARARGS)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_float(Float... f) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_double(double... d) {}
- @Candidate(applicable=Phase.VARARGS)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_double(Double... d) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_char(char... c) {}
- @Candidate(applicable=Phase.VARARGS)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_char(Character... c) {}
- @Candidate(applicable=Phase.VARARGS, mostSpecific=true)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_bool(boolean... z) {}
- @Candidate(applicable=Phase.VARARGS)
+ @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_bool(Boolean... z) {}
{
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/resolve/tests/PrimitiveVsReferenceSamePhase.java Tue May 13 15:29:09 2014 -0600
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+
+@TraceResolve(keys={"compiler.err.ref.ambiguous"})
+class PrimitiveVsReferenceSamePhase {
+ @Candidate(applicable=Phase.BOX, mostSpecific=false)
+ static void m_byte(Byte b1, byte b2) {}
+ @Candidate(applicable=Phase.BOX, mostSpecific=false)
+ static void m_byte(Byte b1, Byte b2) {}
+
+ @Candidate(applicable=Phase.BOX, mostSpecific=false)
+ static void m_short(Short s1, short s2) {}
+ @Candidate(applicable=Phase.BOX, mostSpecific=false)
+ static void m_short(Short s1, Short s2) {}
+
+ @Candidate(applicable=Phase.BOX, mostSpecific=false)
+ static void m_int(Integer i1, int i2) {}
+ @Candidate(applicable=Phase.BOX, mostSpecific=false)
+ static void m_int(Integer i1, Integer i2) {}
+
+ @Candidate(applicable=Phase.BOX, mostSpecific=false)
+ static void m_long(Long l1, long l2) {}
+ @Candidate(applicable=Phase.BOX, mostSpecific=false)
+ static void m_long(Long l1, Long l2) {}
+
+ @Candidate(applicable=Phase.BOX, mostSpecific=false)
+ static void m_float(Float f1, float f2) {}
+ @Candidate(applicable=Phase.BOX, mostSpecific=false)
+ static void m_float(Float f1, Float f2) {}
+
+ @Candidate(applicable=Phase.BOX, mostSpecific=false)
+ static void m_double(Double d1, double d2) {}
+ @Candidate(applicable=Phase.BOX, mostSpecific=false)
+ static void m_double(Double d1, Double d2) {}
+
+ @Candidate(applicable=Phase.BOX, mostSpecific=false)
+ static void m_char(Character c1, char c2) {}
+ @Candidate(applicable=Phase.BOX, mostSpecific=false)
+ static void m_char(Character c1, Character c2) {}
+
+ @Candidate(applicable=Phase.BOX, mostSpecific=false)
+ static void m_bool(Boolean z1, boolean z2) {}
+ @Candidate(applicable=Phase.BOX, mostSpecific=false)
+ static void m_bool(Boolean z1, Boolean z2) {}
+
+ {
+ m_byte((byte)0, (byte)0);
+ m_short((short)0, (short)0);
+ m_int(0, 0);
+ m_long(0L, 0L);
+ m_float(0.0f, 0.0f);
+ m_double(0.0, 0.0);
+ m_char('?', '?');
+ m_bool(false, false);
+ }
+}