提交 8cc3b940 编写于 作者: D dlsmith

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
上级 16dd4916
...@@ -230,7 +230,7 @@ public enum Source { ...@@ -230,7 +230,7 @@ public enum Source {
public boolean allowGraphInference() { public boolean allowGraphInference() {
return compareTo(JDK1_8) >= 0; return compareTo(JDK1_8) >= 0;
} }
public boolean allowStructuralMostSpecific() { public boolean allowFunctionalInterfaceMostSpecific() {
return compareTo(JDK1_8) >= 0; return compareTo(JDK1_8) >= 0;
} }
public static SourceVersion toSourceVersion(Source source) { public static SourceVersion toSourceVersion(Source source) {
......
...@@ -95,7 +95,7 @@ public class Resolve { ...@@ -95,7 +95,7 @@ public class Resolve {
public final boolean boxingEnabled; public final boolean boxingEnabled;
public final boolean varargsEnabled; public final boolean varargsEnabled;
public final boolean allowMethodHandles; public final boolean allowMethodHandles;
public final boolean allowStructuralMostSpecific; public final boolean allowFunctionalInterfaceMostSpecific;
private final boolean debugResolve; private final boolean debugResolve;
private final boolean compactMethodDiags; private final boolean compactMethodDiags;
final EnumSet<VerboseResolutionMode> verboseResolutionMode; final EnumSet<VerboseResolutionMode> verboseResolutionMode;
...@@ -136,7 +136,7 @@ public class Resolve { ...@@ -136,7 +136,7 @@ public class Resolve {
verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options); verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
Target target = Target.instance(context); Target target = Target.instance(context);
allowMethodHandles = target.hasMethodHandles(); allowMethodHandles = target.hasMethodHandles();
allowStructuralMostSpecific = source.allowStructuralMostSpecific(); allowFunctionalInterfaceMostSpecific = source.allowFunctionalInterfaceMostSpecific();
polymorphicSignatureScope = new Scope(syms.noSymbol); polymorphicSignatureScope = new Scope(syms.noSymbol);
inapplicableMethodException = new InapplicableMethodException(diags); inapplicableMethodException = new InapplicableMethodException(diags);
...@@ -1081,50 +1081,47 @@ public class Resolve { ...@@ -1081,50 +1081,47 @@ public class Resolve {
} }
public boolean compatible(Type found, Type req, Warner warn) { public boolean compatible(Type found, Type req, Warner warn) {
if (!allowStructuralMostSpecific || actual == null) { if (allowFunctionalInterfaceMostSpecific &&
return super.compatible(found, req, warn); unrelatedFunctionalInterfaces(found, req) &&
} else { (actual != null && actual.getTag() == DEFERRED)) {
switch (actual.getTag()) { DeferredType dt = (DeferredType) actual;
case DEFERRED: DeferredType.SpeculativeCache.Entry e =
DeferredType dt = (DeferredType) actual; dt.speculativeCache.get(deferredAttrContext.msym, deferredAttrContext.phase);
DeferredType.SpeculativeCache.Entry e = dt.speculativeCache.get(deferredAttrContext.msym, deferredAttrContext.phase); if (e != null && e.speculativeTree != deferredAttr.stuckTree) {
return (e == null || e.speculativeTree == deferredAttr.stuckTree) return functionalInterfaceMostSpecific(found, req, e.speculativeTree, warn);
? super.compatible(found, req, warn) :
mostSpecific(found, req, e.speculativeTree, warn);
default:
return standaloneMostSpecific(found, req, actual, warn);
} }
} }
return super.compatible(found, req, warn);
} }
private boolean mostSpecific(Type t, Type s, JCTree tree, Warner warn) { /** Whether {@code t} and {@code s} are unrelated functional interface types. */
MostSpecificChecker msc = new MostSpecificChecker(t, s, warn); private boolean unrelatedFunctionalInterfaces(Type t, Type s) {
msc.scan(tree); return types.isFunctionalInterface(t.tsym) &&
return msc.result; types.isFunctionalInterface(s.tsym) &&
} types.asSuper(t, s.tsym) == null &&
types.asSuper(s, t.tsym) == null;
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) { /** Parameters {@code t} and {@code s} are unrelated functional interface types. */
return (exprType.isPrimitive() == t1.isPrimitive() private boolean functionalInterfaceMostSpecific(Type t, Type s, JCTree tree, Warner warn) {
&& exprType.isPrimitive() != t2.isPrimitive()) FunctionalInterfaceMostSpecificChecker msc = new FunctionalInterfaceMostSpecificChecker(t, s, warn);
? true : super.compatible(t1, t2, warn); msc.scan(tree);
return msc.result;
} }
/** /**
* 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 t;
final Type s; final Type s;
final Warner warn; final Warner warn;
boolean result; 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.t = t;
this.s = s; this.s = s;
this.warn = warn; this.warn = warn;
...@@ -1133,102 +1130,96 @@ public class Resolve { ...@@ -1133,102 +1130,96 @@ public class Resolve {
@Override @Override
void skip(JCTree tree) { void skip(JCTree tree) {
result &= standaloneMostSpecific(t, s, tree.type, warn); result &= false;
} }
@Override @Override
public void visitConditional(JCConditional tree) { public void visitConditional(JCConditional tree) {
if (tree.polyKind == PolyKind.STANDALONE) { scan(tree.truepart);
result &= standaloneMostSpecific(t, s, tree.type, warn); scan(tree.falsepart);
} 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);
} }
@Override @Override
public void visitReference(JCMemberReference tree) { public void visitReference(JCMemberReference tree) {
if (types.isFunctionalInterface(t.tsym) && Type desc_t = types.findDescriptorType(t);
types.isFunctionalInterface(s.tsym)) { Type desc_s = types.findDescriptorType(s);
Type desc_t = types.findDescriptorType(t); // use inference variables here for more-specific inference (18.5.4)
Type desc_s = types.findDescriptorType(s); if (!types.isSameTypes(desc_t.getParameterTypes(),
if (types.isSameTypes(desc_t.getParameterTypes(), inferenceContext().asUndetVars(desc_s.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;
}
}
} else {
result &= false; 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);
}
} }
} }
@Override @Override
public void visitLambda(JCLambda tree) { public void visitLambda(JCLambda tree) {
if (types.isFunctionalInterface(t.tsym) && Type desc_t = types.findDescriptorType(t);
types.isFunctionalInterface(s.tsym)) { Type desc_s = types.findDescriptorType(s);
Type desc_t = types.findDescriptorType(t); // use inference variables here for more-specific inference (18.5.4)
Type desc_s = types.findDescriptorType(s); if (!types.isSameTypes(desc_t.getParameterTypes(),
if (types.isSameTypes(desc_t.getParameterTypes(), inferenceContext().asUndetVars(desc_s.getParameterTypes()))) {
inferenceContext().asUndetVars(desc_s.getParameterTypes()))) { result &= false;
if (types.asSuper(t, s.tsym) != null || } else {
types.asSuper(s, t.tsym) != null) { // compare return types
result &= MostSpecificCheckContext.super.compatible(t, s, warn); Type ret_t = desc_t.getReturnType();
} else if (!desc_s.getReturnType().hasTag(VOID)) { Type ret_s = desc_s.getReturnType();
//perform structural comparison if (ret_s.hasTag(VOID)) {
Type ret_t = desc_t.getReturnType(); result &= true;
Type ret_s = desc_s.getReturnType(); } else if (ret_t.hasTag(VOID)) {
scanLambdaBody(tree, ret_t, ret_s); result &= false;
} else { } else if (unrelatedFunctionalInterfaces(ret_t, ret_s)) {
return; 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 //where
void scanLambdaBody(JCLambda lambda, final Type t, final Type s) { private List<JCExpression> lambdaResults(JCLambda lambda) {
if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) { if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) {
result &= MostSpecificCheckContext.this.mostSpecific(t, s, lambda.body, warn); return List.of((JCExpression) lambda.body);
} else { } else {
final ListBuffer<JCExpression> buffer = new ListBuffer<>();
DeferredAttr.LambdaReturnScanner lambdaScanner = DeferredAttr.LambdaReturnScanner lambdaScanner =
new DeferredAttr.LambdaReturnScanner() { new DeferredAttr.LambdaReturnScanner() {
@Override @Override
public void visitReturn(JCReturn tree) { public void visitReturn(JCReturn tree) {
if (tree.expr != null) { if (tree.expr != null) {
result &= MostSpecificCheckContext.this.mostSpecific(t, s, tree.expr, warn); buffer.append(tree.expr);
} }
} }
}; };
lambdaScanner.scan(lambda.body); lambdaScanner.scan(lambda.body);
return buffer.toList();
} }
} }
} }
} }
public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) { public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
......
...@@ -609,6 +609,9 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { ...@@ -609,6 +609,9 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
super.setPos(pos); super.setPos(pos);
return this; return this;
} }
public boolean isPoly() { return false; }
public boolean isStandalone() { return true; }
} }
/** /**
...@@ -629,6 +632,9 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { ...@@ -629,6 +632,9 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
/** is this poly expression a 'true' poly expression? */ /** is this poly expression a 'true' poly expression? */
public PolyKind polyKind; public PolyKind polyKind;
@Override public boolean isPoly() { return polyKind == PolyKind.POLY; }
@Override public boolean isStandalone() { return polyKind == PolyKind.STANDALONE; }
} }
/** /**
......
/*
* 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) ));
}
}
/*
* 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(); });
}
}
/*
* @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) {}
}
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
/*
* @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
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
/*
* @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
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
/* /*
* @test /nodynamiccopyright/ * @test /nodynamiccopyright/
* @bug 8003280 * @bug 8003280 8034223
* @summary Add lambda tests * @summary Add lambda tests
* Check void-compatibility in strict vs. loose conversion contexts * Check void-compatibility in strict vs. loose conversion contexts
* @compile/fail/ref=TargetType16.out -XDrawDiagnostics TargetType16.java * @compile TargetType16.java
*/ */
class TargetType16 { class TargetType16 {
...@@ -20,6 +20,6 @@ class TargetType16 { ...@@ -20,6 +20,6 @@ class TargetType16 {
static <T> void m(SAM2<T> s2) { } static <T> void m(SAM2<T> s2) { }
public static void main(String[] args) { public static void main(String[] args) {
m(() -> { throw new AssertionError(); }); //ambiguous m(() -> { throw new AssertionError(); }); // prefer SAM2
} }
} }
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
...@@ -31,7 +31,12 @@ class TargetType23 { ...@@ -31,7 +31,12 @@ class TargetType23 {
void call(Sam2 s) { } void call(Sam2 s) { }
<Z> void call(Sam3<Z> s) { } <Z> void call(Sam3<Z> s) { }
void call2(Sam0 s) { }
void call2(Sam2 s) { }
<Z> void call2(Sam3<Z> s) { }
void test() { 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
} }
} }
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 1 error
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
/* /*
* @test * @test
* @bug 7098660 8014649 * @bug 7098660 8014649 8034223
* @summary Write better overload resolution/inference tests * @summary Test harness for overload resolution/inference tests
* @library /tools/javac/lib * @library /tools/javac/lib
* @build JavacTestingAbstractProcessor ResolveHarness * @build JavacTestingAbstractProcessor ResolveHarness
* @run main ResolveHarness * @run main ResolveHarness
......
...@@ -23,44 +23,44 @@ ...@@ -23,44 +23,44 @@
@TraceResolve(keys={"compiler.err.ref.ambiguous"}) @TraceResolve(keys={"compiler.err.ref.ambiguous"})
class PrimitiveOverReferenceVarargsAmbiguous { class PrimitiveOverReferenceVarargsAmbiguous {
@Candidate(applicable=Phase.VARARGS, mostSpecific=true) @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_byte(byte... b) {} static void m_byte(byte... b) {}
@Candidate(applicable=Phase.VARARGS) @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_byte(Byte... b) {} static void m_byte(Byte... b) {}
@Candidate(applicable=Phase.VARARGS, mostSpecific=true) @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_short(short... s) {} static void m_short(short... s) {}
@Candidate(applicable=Phase.VARARGS) @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_short(Short... s) {} static void m_short(Short... s) {}
@Candidate(applicable=Phase.VARARGS, mostSpecific=true) @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_int(int... i) {} static void m_int(int... i) {}
@Candidate(applicable=Phase.VARARGS) @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_int(Integer... i) {} static void m_int(Integer... i) {}
@Candidate(applicable=Phase.VARARGS, mostSpecific=true) @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_long(long... l) {} static void m_long(long... l) {}
@Candidate(applicable=Phase.VARARGS) @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_long(Long... l) {} static void m_long(Long... l) {}
@Candidate(applicable=Phase.VARARGS, mostSpecific=true) @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_float(float... f) {} static void m_float(float... f) {}
@Candidate(applicable=Phase.VARARGS) @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_float(Float... f) {} static void m_float(Float... f) {}
@Candidate(applicable=Phase.VARARGS, mostSpecific=true) @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_double(double... d) {} static void m_double(double... d) {}
@Candidate(applicable=Phase.VARARGS) @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_double(Double... d) {} static void m_double(Double... d) {}
@Candidate(applicable=Phase.VARARGS, mostSpecific=true) @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_char(char... c) {} static void m_char(char... c) {}
@Candidate(applicable=Phase.VARARGS) @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_char(Character... c) {} static void m_char(Character... c) {}
@Candidate(applicable=Phase.VARARGS, mostSpecific=true) @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_bool(boolean... z) {} static void m_bool(boolean... z) {}
@Candidate(applicable=Phase.VARARGS) @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
static void m_bool(Boolean... z) {} static void m_bool(Boolean... z) {}
{ {
......
/*
* 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);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册