8055514: Wrong, confusing error when non-static varargs referenced in static context
authormcimadamore
Mon, 08 Sep 2014 14:16:33 +0100
changeset 26533 8fba085fbdbf
parent 26532 aa84b6606229
child 26534 43bd005b6972
8055514: Wrong, confusing error when non-static varargs referenced in static context Summary: Improved heuristics in MethodResolutionPhase.mergeResults() Reviewed-by: vromero
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java
langtools/test/tools/javac/varargs/8055514/T8055514.java
langtools/test/tools/javac/varargs/8055514/T8055514.out
--- 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;
+                    }
                 }
             }
         };
--- /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
+    }
+}
--- /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