Wed, 10 Sep 2014 10:51:36 +0100
8055514: Wrong, confusing error when non-static varargs referenced in static context
Summary: Improved heuristics in MethodResolutionPhase.mergeResults()
Reviewed-by: vromero
1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Sep 10 10:50:59 2014 +0100 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Sep 10 10:51:36 2014 +0100 1.3 @@ -3045,7 +3045,7 @@ 1.4 /** 1.5 * Should lookup stop at given phase with given result 1.6 */ 1.7 - protected boolean shouldStop(Symbol sym, MethodResolutionPhase phase) { 1.8 + final boolean shouldStop(Symbol sym, MethodResolutionPhase phase) { 1.9 return phase.ordinal() > maxPhase.ordinal() || 1.10 sym.kind < ERRONEOUS || sym.kind == AMBIGUOUS; 1.11 } 1.12 @@ -4228,15 +4228,39 @@ 1.13 VARARITY(true, true) { 1.14 @Override 1.15 public Symbol mergeResults(Symbol bestSoFar, Symbol sym) { 1.16 - switch (sym.kind) { 1.17 - case WRONG_MTH: 1.18 - return (bestSoFar.kind == WRONG_MTH || bestSoFar.kind == WRONG_MTHS) ? 1.19 - bestSoFar : 1.20 - sym; 1.21 - case ABSENT_MTH: 1.22 - return bestSoFar; 1.23 - default: 1.24 - return sym; 1.25 + //Check invariants (see {@code LookupHelper.shouldStop}) 1.26 + Assert.check(bestSoFar.kind >= ERRONEOUS && bestSoFar.kind != AMBIGUOUS); 1.27 + if (sym.kind < ERRONEOUS) { 1.28 + //varargs resolution successful 1.29 + return sym; 1.30 + } else { 1.31 + //pick best error 1.32 + switch (bestSoFar.kind) { 1.33 + case WRONG_MTH: 1.34 + case WRONG_MTHS: 1.35 + //Override previous errors if they were caused by argument mismatch. 1.36 + //This generally means preferring current symbols - but we need to pay 1.37 + //attention to the fact that the varargs lookup returns 'less' candidates 1.38 + //than the previous rounds, and adjust that accordingly. 1.39 + switch (sym.kind) { 1.40 + case WRONG_MTH: 1.41 + //if the previous round matched more than one method, return that 1.42 + //result instead 1.43 + return bestSoFar.kind == WRONG_MTHS ? 1.44 + bestSoFar : sym; 1.45 + case ABSENT_MTH: 1.46 + //do not override erroneous symbol if the arity lookup did not 1.47 + //match any method 1.48 + return bestSoFar; 1.49 + case WRONG_MTHS: 1.50 + default: 1.51 + //safe to override 1.52 + return sym; 1.53 + } 1.54 + default: 1.55 + //otherwise, return first error 1.56 + return bestSoFar; 1.57 + } 1.58 } 1.59 } 1.60 };
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/tools/javac/varargs/8055514/T8055514.java Wed Sep 10 10:51:36 2014 +0100 2.3 @@ -0,0 +1,26 @@ 2.4 +/* 2.5 + * @test /nodynamiccopyright/ 2.6 + * @bug 8055514 2.7 + * @summary Wrong, confusing error when non-static varargs referenced in static context 2.8 + * @compile/fail/ref=T8055514.out -Xlint:varargs -Werror -XDrawDiagnostics T8055514.java 2.9 + */ 2.10 +class T8055514 { 2.11 + void m(int... args) { } 2.12 + 2.13 + void m2(int... args) { } 2.14 + static void m2(String s) { } 2.15 + 2.16 + void m3(int... args) { } 2.17 + static void m3(String s) { } 2.18 + static void m3(Runnable r) { } 2.19 + 2.20 + void m4(int... args) { } 2.21 + void m4(int i1, int i2, int i3) { } 2.22 + 2.23 + static void test() { 2.24 + m(1,2,3); //only one candidate (varargs) - varargs error wins 2.25 + m2(1,2,3); //two candidates - only one applicable (varargs) - varargs error wins 2.26 + m3(1,2,3); //three candidates - only one applicable (varargs) - varargs error wins 2.27 + m4(1,2,3); //two candidates - both applicable - basic error wins 2.28 + } 2.29 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/tools/javac/varargs/8055514/T8055514.out Wed Sep 10 10:51:36 2014 +0100 3.3 @@ -0,0 +1,5 @@ 3.4 +T8055514.java:21:9: compiler.err.non-static.cant.be.ref: kindname.method, m(int...) 3.5 +T8055514.java:22:9: compiler.err.non-static.cant.be.ref: kindname.method, m2(int...) 3.6 +T8055514.java:23:9: compiler.err.non-static.cant.be.ref: kindname.method, m3(int...) 3.7 +T8055514.java:24:9: compiler.err.non-static.cant.be.ref: kindname.method, m4(int,int,int) 3.8 +4 errors