# HG changeset patch # User mcimadamore # Date 1410182193 -3600 # Node ID 8fba085fbdbf1720410537ff6e65fb2b11709857 # Parent aa84b660622983fc2486e81ffc3ff811d52c3648 8055514: Wrong, confusing error when non-static varargs referenced in static context Summary: Improved heuristics in MethodResolutionPhase.mergeResults() Reviewed-by: vromero diff -r aa84b6606229 -r 8fba085fbdbf langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Mon Sep 08 13:11:28 2014 +0200 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Mon Sep 08 14:16:33 2014 +0100 @@ -2992,7 +2992,7 @@ /** * Should lookup stop at given phase with given result */ - protected boolean shouldStop(Symbol sym, MethodResolutionPhase phase) { + final boolean shouldStop(Symbol sym, MethodResolutionPhase phase) { return phase.ordinal() > maxPhase.ordinal() || sym.kind < ERRONEOUS || sym.kind == AMBIGUOUS; } @@ -4174,15 +4174,39 @@ VARARITY(true, true) { @Override public Symbol mergeResults(Symbol bestSoFar, Symbol sym) { - switch (sym.kind) { - case WRONG_MTH: - return (bestSoFar.kind == WRONG_MTH || bestSoFar.kind == WRONG_MTHS) ? - bestSoFar : - sym; - case ABSENT_MTH: - return bestSoFar; - default: - return sym; + //Check invariants (see {@code LookupHelper.shouldStop}) + Assert.check(bestSoFar.kind >= ERRONEOUS && bestSoFar.kind != AMBIGUOUS); + if (sym.kind < ERRONEOUS) { + //varargs resolution successful + return sym; + } else { + //pick best error + switch (bestSoFar.kind) { + case WRONG_MTH: + case WRONG_MTHS: + //Override previous errors if they were caused by argument mismatch. + //This generally means preferring current symbols - but we need to pay + //attention to the fact that the varargs lookup returns 'less' candidates + //than the previous rounds, and adjust that accordingly. + switch (sym.kind) { + case WRONG_MTH: + //if the previous round matched more than one method, return that + //result instead + return bestSoFar.kind == WRONG_MTHS ? + bestSoFar : sym; + case ABSENT_MTH: + //do not override erroneous symbol if the arity lookup did not + //match any method + return bestSoFar; + case WRONG_MTHS: + default: + //safe to override + return sym; + } + default: + //otherwise, return first error + return bestSoFar; + } } } }; diff -r aa84b6606229 -r 8fba085fbdbf langtools/test/tools/javac/varargs/8055514/T8055514.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/varargs/8055514/T8055514.java Mon Sep 08 14:16:33 2014 +0100 @@ -0,0 +1,26 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8055514 + * @summary Wrong, confusing error when non-static varargs referenced in static context + * @compile/fail/ref=T8055514.out -Xlint:varargs -Werror -XDrawDiagnostics T8055514.java + */ +class T8055514 { + void m(int... args) { } + + void m2(int... args) { } + static void m2(String s) { } + + void m3(int... args) { } + static void m3(String s) { } + static void m3(Runnable r) { } + + void m4(int... args) { } + void m4(int i1, int i2, int i3) { } + + static void test() { + m(1,2,3); //only one candidate (varargs) - varargs error wins + m2(1,2,3); //two candidates - only one applicable (varargs) - varargs error wins + m3(1,2,3); //three candidates - only one applicable (varargs) - varargs error wins + m4(1,2,3); //two candidates - both applicable - basic error wins + } +} diff -r aa84b6606229 -r 8fba085fbdbf langtools/test/tools/javac/varargs/8055514/T8055514.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/varargs/8055514/T8055514.out Mon Sep 08 14:16:33 2014 +0100 @@ -0,0 +1,5 @@ +T8055514.java:21:9: compiler.err.non-static.cant.be.ref: kindname.method, m(int...) +T8055514.java:22:9: compiler.err.non-static.cant.be.ref: kindname.method, m2(int...) +T8055514.java:23:9: compiler.err.non-static.cant.be.ref: kindname.method, m3(int...) +T8055514.java:24:9: compiler.err.non-static.cant.be.ref: kindname.method, m4(int,int,int) +4 errors