changeset 1103:05814303a056

7098660: Write better overload resolution/inference tests Summary: Add overload/inference debug diagnostics - added test harness using annotations to check outcome of overload resolution/inference Reviewed-by: jjg
author mcimadamore
date Mon, 24 Oct 2011 13:00:30 +0100
parents d346ab55031b
children b73a9be0b993
files src/share/classes/com/sun/tools/javac/code/Printer.java src/share/classes/com/sun/tools/javac/comp/Infer.java src/share/classes/com/sun/tools/javac/comp/Resolve.java src/share/classes/com/sun/tools/javac/resources/compiler.properties test/tools/javac/diags/examples/ApplicableMethodFound.java test/tools/javac/diags/examples/ApplicableMethodFound1.java test/tools/javac/diags/examples/DeferredMethodInst.java test/tools/javac/diags/examples/FullInstSig.java test/tools/javac/diags/examples/NotApplicableMethodFound.java test/tools/javac/diags/examples/PartialInstSig.java test/tools/javac/diags/examples/VerboseResolveMulti.java test/tools/javac/diags/examples/VerboseResolveMulti1.java test/tools/javac/resolve/Candidate.java test/tools/javac/resolve/Pos.java test/tools/javac/resolve/ResolveHarness.java test/tools/javac/resolve/TraceResolve.java test/tools/javac/resolve/tests/BoxedReturnTypeInference.java test/tools/javac/resolve/tests/PrimitiveOverReferenceOverInferred.java test/tools/javac/resolve/tests/PrimitiveOverReferenceOverVarargs.java test/tools/javac/resolve/tests/PrimitiveOverReferenceVarargsAmbiguous.java test/tools/javac/resolve/tests/PrimitiveOverload.java test/tools/javac/resolve/tests/PrimitiveReturnTypeInference.java test/tools/javac/resolve/tests/ReferenceOverInferred.java test/tools/javac/resolve/tests/ReferenceOverVarargs.java test/tools/javac/resolve/tests/ReferenceOverload.java
diffstat 25 files changed, 1854 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/code/Printer.java	Mon Oct 24 13:00:20 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/code/Printer.java	Mon Oct 24 13:00:30 2011 +0100
@@ -258,7 +258,7 @@
             ClassType norm = (ClassType) t.tsym.type;
             if (norm == null) {
                 s = localize(locale, "compiler.misc.anonymous.class", (Object) null);
-            } else if (norm.interfaces_field.nonEmpty()) {
+            } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
                 s = localize(locale, "compiler.misc.anonymous.class",
                         visit(norm.interfaces_field.head, locale));
             } else {
--- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Mon Oct 24 13:00:20 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Mon Oct 24 13:00:30 2011 +0100
@@ -34,7 +34,8 @@
 import com.sun.tools.javac.code.Type.*;
 import com.sun.tools.javac.code.Type.ForAll.ConstraintKind;
 import com.sun.tools.javac.code.Symbol.*;
-import com.sun.tools.javac.util.JCDiagnostic;
+import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 
 import static com.sun.tools.javac.code.TypeTags.*;
 
@@ -56,6 +57,7 @@
     Types types;
     Check chk;
     Resolve rs;
+    Log log;
     JCDiagnostic.Factory diags;
 
     public static Infer instance(Context context) {
@@ -70,6 +72,7 @@
         syms = Symtab.instance(context);
         types = Types.instance(context);
         rs = Resolve.instance(context);
+        log = Log.instance(context);
         chk = Check.instance(context);
         diags = JCDiagnostic.Factory.instance(context);
         ambiguousNoInstanceException =
@@ -460,7 +463,7 @@
             // quantify result type with them
             final List<Type> inferredTypes = insttypes.toList();
             final List<Type> all_tvars = tvars; //this is the wrong tvars
-            return new UninferredMethodType(mt, restvars.toList()) {
+            return new UninferredMethodType(env.tree.pos(), msym, mt, restvars.toList()) {
                 @Override
                 List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
                     for (Type t : restundet.toList()) {
@@ -502,13 +505,17 @@
          * type - when the return type is instantiated (see Infer.instantiateExpr)
          * the underlying method type is also updated.
          */
-        static abstract class UninferredMethodType extends DelegatedType {
+        abstract class UninferredMethodType extends DelegatedType {
 
             final List<Type> tvars;
+            final Symbol msym;
+            final DiagnosticPosition pos;
 
-            public UninferredMethodType(MethodType mtype, List<Type> tvars) {
+            public UninferredMethodType(DiagnosticPosition pos, Symbol msym, MethodType mtype, List<Type> tvars) {
                 super(METHOD, new MethodType(mtype.argtypes, null, mtype.thrown, mtype.tsym));
                 this.tvars = tvars;
+                this.msym = msym;
+                this.pos = pos;
                 asMethodType().restype = new UninferredReturnType(tvars, mtype.restype);
             }
 
@@ -543,6 +550,9 @@
                 public Type inst(List<Type> actuals, Types types) {
                     Type newRestype = super.inst(actuals, types);
                     instantiateReturnType(newRestype, actuals, types);
+                    if (rs.verboseResolutionMode.contains(VerboseResolutionMode.DEFERRED_INST)) {
+                        log.note(pos, "deferred.method.inst", msym, UninferredMethodType.this.qtype, newRestype);
+                    }
                     return newRestype;
                 }
                 @Override
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Oct 24 13:00:20 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Oct 24 13:00:30 2011 +0100
@@ -25,29 +25,33 @@
 
 package com.sun.tools.javac.comp;
 
-import com.sun.tools.javac.util.*;
-import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
+import com.sun.tools.javac.api.Formattable.LocalizedString;
 import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Type.*;
+import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.tree.*;
-import com.sun.tools.javac.api.Formattable.LocalizedString;
-import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
+import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
 
-import com.sun.tools.javac.code.Type.*;
-import com.sun.tools.javac.code.Symbol.*;
-import com.sun.tools.javac.tree.JCTree.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.lang.model.element.ElementVisitor;
 
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Kinds.*;
 import static com.sun.tools.javac.code.TypeTags.*;
-import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
-import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
-import javax.lang.model.element.ElementVisitor;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.HashMap;
-import java.util.HashSet;
+import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
 
 /** Helper class for name resolution, used mostly by the attribution phase.
  *
@@ -73,9 +77,45 @@
     public final boolean varargsEnabled; // = source.allowVarargs();
     public final boolean allowMethodHandles;
     private final boolean debugResolve;
+    final EnumSet<VerboseResolutionMode> verboseResolutionMode;
 
     Scope polymorphicSignatureScope;
 
+    enum VerboseResolutionMode {
+        SUCCESS("success"),
+        FAILURE("failure"),
+        APPLICABLE("applicable"),
+        INAPPLICABLE("inapplicable"),
+        DEFERRED_INST("deferred-inference"),
+        PREDEF("predef"),
+        OBJECT_INIT("object-init"),
+        INTERNAL("internal");
+
+        String opt;
+
+        private VerboseResolutionMode(String opt) {
+            this.opt = opt;
+        }
+
+        static EnumSet<VerboseResolutionMode> getVerboseResolutionMode(Options opts) {
+            String s = opts.get("verboseResolution");
+            EnumSet<VerboseResolutionMode> res = EnumSet.noneOf(VerboseResolutionMode.class);
+            if (s == null) return res;
+            if (s.contains("all")) {
+                res = EnumSet.allOf(VerboseResolutionMode.class);
+            }
+            Collection<String> args = Arrays.asList(s.split(","));
+            for (VerboseResolutionMode mode : values()) {
+                if (args.contains(mode.opt)) {
+                    res.add(mode);
+                } else if (args.contains("-" + mode.opt)) {
+                    res.remove(mode);
+                }
+            }
+            return res;
+        }
+    }
+
     public static Resolve instance(Context context) {
         Resolve instance = context.get(resolveKey);
         if (instance == null)
@@ -111,6 +151,7 @@
         varargsEnabled = source.allowVarargs();
         Options options = Options.instance(context);
         debugResolve = options.isSet("debugresolve");
+        verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
         Target target = Target.instance(context);
         allowMethodHandles = target.hasMethodHandles();
         polymorphicSignatureScope = new Scope(syms.noSymbol);
@@ -684,9 +725,11 @@
         if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;
         Assert.check(sym.kind < AMBIGUOUS);
         try {
-            rawInstantiate(env, site, sym, argtypes, typeargtypes,
+            Type mt = rawInstantiate(env, site, sym, argtypes, typeargtypes,
                                allowBoxing, useVarargs, Warner.noWarnings);
+            if (!operator) addVerboseApplicableCandidateDiag(sym ,mt);
         } catch (InapplicableMethodException ex) {
+            if (!operator) addVerboseInapplicableCandidateDiag(sym, ex.getDiagnostic());
             switch (bestSoFar.kind) {
             case ABSENT_MTH:
                 return wrongMethod.setWrongSym(sym, ex.getDiagnostic());
@@ -709,6 +752,34 @@
             : mostSpecific(sym, bestSoFar, env, site,
                            allowBoxing && operator, useVarargs);
     }
+    //where
+        void addVerboseApplicableCandidateDiag(Symbol sym, Type inst) {
+            if (!verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE))
+                return;
+
+            JCDiagnostic subDiag = null;
+            if (inst.getReturnType().tag == FORALL) {
+                Type diagType = types.createMethodTypeWithReturn(inst.asMethodType(),
+                                                                ((ForAll)inst.getReturnType()).qtype);
+                subDiag = diags.fragment("partial.inst.sig", diagType);
+            } else if (sym.type.tag == FORALL) {
+                subDiag = diags.fragment("full.inst.sig", inst.asMethodType());
+            }
+
+            String key = subDiag == null ?
+                    "applicable.method.found" :
+                    "applicable.method.found.1";
+
+            verboseResolutionCandidateDiags.put(sym,
+                    diags.fragment(key, verboseResolutionCandidateDiags.size(), sym, subDiag));
+        }
+
+        void addVerboseInapplicableCandidateDiag(Symbol sym, JCDiagnostic subDiag) {
+            if (!verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))
+                return;
+            verboseResolutionCandidateDiags.put(sym,
+                    diags.fragment("not.applicable.method.found", verboseResolutionCandidateDiags.size(), sym, subDiag));
+        }
 
     /* Return the most specific of the two methods for a call,
      *  given that both are accessible and applicable.
@@ -906,8 +977,9 @@
                       boolean allowBoxing,
                       boolean useVarargs,
                       boolean operator) {
+        verboseResolutionCandidateDiags.clear();
         Symbol bestSoFar = methodNotFound;
-        return findMethod(env,
+        bestSoFar = findMethod(env,
                           site,
                           name,
                           argtypes,
@@ -919,6 +991,8 @@
                           useVarargs,
                           operator,
                           new HashSet<TypeSymbol>());
+        reportVerboseResolutionDiagnostic(env.tree.pos(), name, site, argtypes, typeargtypes, bestSoFar);
+        return bestSoFar;
     }
     // where
     private Symbol findMethod(Env<AttrContext> env,
@@ -976,6 +1050,37 @@
         }
         return bestSoFar;
     }
+    //where
+        void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) {
+            boolean success = bestSoFar.kind < ERRONEOUS;
+
+            if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) {
+                return;
+            } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) {
+                return;
+            }
+
+            if (bestSoFar.name == names.init &&
+                    bestSoFar.owner == syms.objectType.tsym &&
+                    !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) {
+                return; //skip diags for Object constructor resolution
+            } else if (site == syms.predefClass.type && !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) {
+                return; //skip spurious diags for predef symbols (i.e. operators)
+            } else if (internalResolution && !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) {
+                return;
+            }
+
+            int pos = 0;
+            for (Symbol s : verboseResolutionCandidateDiags.keySet()) {
+                if (s == bestSoFar) break;
+                pos++;
+            }
+            String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1";
+            JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name, site.tsym, pos, currentStep,
+                    methodArguments(argtypes), methodArguments(typeargtypes));
+            JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, List.from(verboseResolutionCandidateDiags.values().toArray(new JCDiagnostic[verboseResolutionCandidateDiags.size()])));
+            log.report(d);
+        }
 
     /** Find unqualified method matching given name, type and value arguments.
      *  @param env       The current environment.
@@ -1544,12 +1649,19 @@
                                         Type site, Name name,
                                         List<Type> argtypes,
                                         List<Type> typeargtypes) {
-        Symbol sym = resolveQualifiedMethod(
-            pos, env, site.tsym, site, name, argtypes, typeargtypes);
-        if (sym.kind == MTH) return (MethodSymbol)sym;
-        else throw new FatalError(
-                 diags.fragment("fatal.err.cant.locate.meth",
-                                name));
+        boolean prevInternal = internalResolution;
+        try {
+            internalResolution = true;
+            Symbol sym = resolveQualifiedMethod(
+                pos, env, site.tsym, site, name, argtypes, typeargtypes);
+            if (sym.kind == MTH) return (MethodSymbol)sym;
+            else throw new FatalError(
+                     diags.fragment("fatal.err.cant.locate.meth",
+                                    name));
+        }
+        finally {
+            internalResolution = prevInternal;
+        }
     }
 
     /** Resolve constructor.
@@ -1830,7 +1942,7 @@
     private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
 
     public Object methodArguments(List<Type> argtypes) {
-        return argtypes.isEmpty() ? noArgs : argtypes;
+        return argtypes == null || argtypes.isEmpty() ? noArgs : argtypes;
     }
 
     /**
@@ -2377,10 +2489,15 @@
     private Map<MethodResolutionPhase, Symbol> methodResolutionCache =
         new HashMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.values().length);
 
+    private Map<Symbol, JCDiagnostic> verboseResolutionCandidateDiags =
+        new LinkedHashMap<Symbol, JCDiagnostic>();
+
     final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
 
     private MethodResolutionPhase currentStep = null;
 
+    private boolean internalResolution = false;
+
     private MethodResolutionPhase firstErroneousResolutionPhase() {
         MethodResolutionPhase bestSoFar = BASIC;
         Symbol sym = methodNotFound;
--- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Oct 24 13:00:20 2011 +0100
+++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Oct 24 13:00:30 2011 +0100
@@ -1944,6 +1944,55 @@
     (use -source 7 or higher to enable strings in switch)
 
 ########################################
+# Diagnostics for verbose resolution
+# used by Resolve (debug only)
+########################################
+
+# 0: number, 1: symbol, 2: unused
+compiler.misc.applicable.method.found=\
+    #{0} applicable method found: {1}
+
+# 0: number, 1: symbol, 2: message segment
+compiler.misc.applicable.method.found.1=\
+    #{0} applicable method found: {1}\n\
+    ({2})
+
+# 0: number, 1: symbol, 2: message segment
+compiler.misc.not.applicable.method.found=\
+    #{0} not applicable method found: {1}\n\
+    ({2})
+
+# 0: type
+compiler.misc.full.inst.sig=\
+    fully instantiated to: {0}
+
+# 0: type
+compiler.misc.partial.inst.sig=\
+    partially instantiated to: {0}
+
+# 0: name, 1: symbol, 2: number, 3: MethodResolutionPhase, 4: list of type or message segment, 5: list of type or message segment
+compiler.note.verbose.resolve.multi=\
+    resolving method {0} in type {1} to candidate {2}\n\
+    phase: {3}\n\
+    with actuals: {4}\n\
+    with type-args: {5}\n\
+    candidates:
+
+# 0: name, 1: symbol, 2: unused, 3: MethodResolutionPhase, 4: list of type or message segment, 5: list of type or message segment
+compiler.note.verbose.resolve.multi.1=\
+    erroneous resolution for method {0} in type {1}\n\
+    phase: {3}\n\
+    with actuals: {4}\n\
+    with type-args: {5}\n\
+    candidates:
+
+# 0: symbol, 1: type, 2: type
+compiler.note.deferred.method.inst=\
+    Deferred instantiation of method {0}\n\
+    instantiated signature: {1}\n\
+    target-type: {2}
+
+########################################
 # Diagnostics for where clause implementation
 # used by the RichDiagnosticFormatter.
 ########################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/ApplicableMethodFound.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+// key: compiler.misc.applicable.method.found
+// key: compiler.note.verbose.resolve.multi
+// options: -XDverboseResolution=applicable,success
+
+class ApplicableMethodFound {
+
+    void m() {}
+
+    { m(); }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/ApplicableMethodFound1.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+// key: compiler.misc.applicable.method.found.1
+// key: compiler.note.verbose.resolve.multi
+// key: compiler.misc.full.inst.sig
+// options: -XDverboseResolution=applicable,success
+
+class ApplicableMethodFound1 {
+
+    <X> void m(X x) {}
+
+    { m(1); }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/DeferredMethodInst.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+// key: compiler.misc.applicable.method.found.1
+// key: compiler.note.verbose.resolve.multi
+// key: compiler.note.deferred.method.inst
+// key: compiler.misc.partial.inst.sig
+// options: -XDverboseResolution=applicable,success,deferred-inference
+
+class DeferredMethodInst {
+
+    <X> X m() { return null; }
+
+    { Integer i = m(); }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/FullInstSig.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+// key: compiler.misc.applicable.method.found.1
+// key: compiler.note.verbose.resolve.multi
+// key: compiler.misc.full.inst.sig
+// options: -XDverboseResolution=applicable,success
+
+class FullInstSig {
+
+    <X> void m(X x) {}
+
+    { m(1); }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/NotApplicableMethodFound.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+// key: compiler.misc.not.applicable.method.found
+// key: compiler.note.verbose.resolve.multi.1
+// key: compiler.err.cant.apply.symbol.1
+// key: compiler.misc.no.conforming.assignment.exists
+// options: -XDverboseResolution=inapplicable,failure
+
+class NotApplicableMethodFound {
+
+    void m(int i) {}
+
+    { m(""); }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/PartialInstSig.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+// key: compiler.misc.applicable.method.found.1
+// key: compiler.note.verbose.resolve.multi
+// key: compiler.misc.partial.inst.sig
+// options: -XDverboseResolution=applicable,success
+
+class PartialInstSig {
+
+    <X> X m() { return null; }
+
+    { m(); }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/VerboseResolveMulti.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+// key: compiler.misc.applicable.method.found
+// key: compiler.note.verbose.resolve.multi
+// options: -XDverboseResolution=applicable,success
+
+class VerboseResolveMulti {
+
+    void m() {}
+
+    { m(); }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/VerboseResolveMulti1.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+// key: compiler.misc.not.applicable.method.found
+// key: compiler.note.verbose.resolve.multi.1
+// key: compiler.err.cant.apply.symbol.1
+// key: compiler.misc.no.conforming.assignment.exists
+// options: -XDverboseResolution=inapplicable,failure
+
+class VerboseResolveMulti1 {
+
+    void m(int i) {}
+
+    { m(""); }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/resolve/Candidate.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
+@interface Candidate {
+    /**
+     * the candidate position (line/col of the method call for which this candidate
+     * is a potential overload candidate)
+     */
+    Pos pos() default @Pos(userDefined=false);
+    /**
+     * resolution phases for which this candidate is applicable
+     */
+    Phase[] applicable() default { };
+    /**
+     * is this candidate the most specific (in the resolution phases for which it
+     * is also applicable)
+     */
+    boolean mostSpecific() default false;
+    /**
+     * this candidate inferred signature (in the resolution phases for which it
+     * is also applicable, in case it corresponds to a generic method)
+     */
+    String sig() default "";
+}
+
+enum Phase {
+    BASIC("BASIC"),
+    BOX("BOX"),
+    VARARGS("VARARITY");
+
+    final String javacString;
+
+    private Phase(String javacString) {
+        this.javacString = javacString;
+    }
+
+    static Phase fromString(String s) {
+        for (Phase phase : Phase.values()) {
+            if (phase.javacString.equals(s)) {
+                return phase;
+            }
+        }
+        throw new AssertionError("Invalid resolution phase string " + s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/resolve/Pos.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+@Target(ElementType.ANNOTATION_TYPE)
+@interface Pos {
+    long line() default -1;
+    long col() default -1;
+    boolean userDefined() default true;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/resolve/ResolveHarness.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,475 @@
+/*
+ * Copyright (c) 2011, 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 7098660
+ * @summary Write better overload resolution/inference tests
+ * @library ../lib
+ * @build JavacTestingAbstractProcessor ResolveHarness
+ * @run main ResolveHarness
+ */
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.api.ClientCodeWrapper.DiagnosticSourceUnwrapper;
+import com.sun.tools.javac.code.Type.MethodType;
+import com.sun.tools.javac.util.JCDiagnostic;
+
+import java.io.File;
+import java.util.Set;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic;
+import javax.tools.Diagnostic.Kind;
+import javax.tools.DiagnosticListener;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+import static javax.tools.StandardLocation.*;
+
+public class ResolveHarness implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+    static int nerrors = 0;
+
+    static final JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+    static final StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+
+    public static void main(String[] args) throws Exception {
+        fm.setLocation(SOURCE_PATH,
+                Arrays.asList(new File(System.getProperty("test.src"), "tests")));
+        for (JavaFileObject jfo : fm.list(SOURCE_PATH, "", Collections.singleton(JavaFileObject.Kind.SOURCE), true)) {
+            new ResolveHarness(jfo).check();
+        }
+        if (nerrors > 0) {
+            throw new AssertionError("Errors were found");
+        }
+    }
+
+
+    JavaFileObject jfo;
+    DiagnosticProcessor[] diagProcessors;
+    Map<ElementKey, Candidate> candidatesMap = new HashMap<ElementKey, Candidate>();
+    Set<String> declaredKeys = new HashSet<>();
+    List<Diagnostic<? extends JavaFileObject>> diags = new ArrayList<>();
+    List<ElementKey> seenCandidates = new ArrayList<>();
+
+    protected ResolveHarness(JavaFileObject jfo) {
+        this.jfo = jfo;
+        this.diagProcessors = new DiagnosticProcessor[] {
+            new VerboseResolutionNoteProcessor(),
+            new VerboseDeferredInferenceNoteProcessor(),
+            new ErrorProcessor()
+        };
+    }
+
+    protected void check() throws Exception {
+        String[] options = {
+            "-XDshouldStopPolicy=ATTR",
+            "-XDverboseResolution=success,failure,applicable,inapplicable,deferred-inference"
+        };
+
+        AbstractProcessor[] processors = { new ResolveCandidateFinder(), null };
+
+        @SuppressWarnings("unchecked")
+        DiagnosticListener<? super JavaFileObject>[] diagListeners =
+                new DiagnosticListener[] { new DiagnosticHandler(false), new DiagnosticHandler(true) };
+
+        for (int i = 0 ; i < options.length ; i ++) {
+            JavacTask ct = (JavacTask)comp.getTask(null, fm, diagListeners[i],
+                    Arrays.asList(options[i]), null, Arrays.asList(jfo));
+            if (processors[i] != null) {
+                ct.setProcessors(Collections.singleton(processors[i]));
+            }
+            ct.analyze();
+        }
+
+        //check diags
+        for (Diagnostic<? extends JavaFileObject> diag : diags) {
+            for (DiagnosticProcessor proc : diagProcessors) {
+                if (proc.matches(diag)) {
+                    proc.process(diag);
+                    break;
+                }
+            }
+        }
+        //check all candidates have been used up
+        for (Map.Entry<ElementKey, Candidate> entry : candidatesMap.entrySet()) {
+            if (!seenCandidates.contains(entry.getKey())) {
+                error("Redundant @Candidate annotation on method " + entry.getKey().elem);
+            }
+        }
+    }
+
+    public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+        diags.add(diagnostic);
+    }
+
+    Candidate getCandidateAtPos(Element methodSym, long line, long col) {
+        Candidate c = candidatesMap.get(new ElementKey(methodSym));
+        if (c != null) {
+            Pos pos = c.pos();
+            if (!pos.userDefined() ||
+                    (pos.line() == line && pos.col() == col)) {
+                seenCandidates.add(new ElementKey(methodSym));
+                return c;
+            }
+        } else {
+            error("Missing @Candidate annotation on method " + methodSym);
+        }
+        return null;
+    }
+
+    void checkSig(Candidate c, Element methodSym, MethodType mtype) {
+        if (c.sig().length() > 0 && !c.sig().equals(mtype.toString())) {
+            error("Inferred type mismatch for method: " + methodSym);
+        }
+    }
+
+    protected void error(String msg) {
+        nerrors++;
+        System.err.printf("Error occurred while checking file: %s\nreason: %s\n", jfo.getName(), msg);
+    }
+
+    /**
+     * Base class for diagnostic processor. It provides methods for matching and
+     * processing a given diagnostic object (overridden by subclasses).
+     */
+    abstract class DiagnosticProcessor {
+
+        List<String> codes;
+        Diagnostic.Kind kind;
+
+        public DiagnosticProcessor(Kind kind, String... codes) {
+            this.codes = Arrays.asList(codes);
+            this.kind = kind;
+        }
+
+        abstract void process(Diagnostic<? extends JavaFileObject> diagnostic);
+
+        boolean matches(Diagnostic<? extends JavaFileObject> diagnostic) {
+            return (codes.isEmpty() || codes.contains(diagnostic.getCode())) &&
+                    diagnostic.getKind() == kind;
+        }
+
+        JCDiagnostic asJCDiagnostic(Diagnostic<? extends JavaFileObject> diagnostic) {
+            if (diagnostic instanceof JCDiagnostic) {
+                return (JCDiagnostic)diagnostic;
+            } else if (diagnostic instanceof DiagnosticSourceUnwrapper) {
+                return ((DiagnosticSourceUnwrapper)diagnostic).d;
+            } else {
+                throw new AssertionError("Cannot convert diagnostic to JCDiagnostic: " + diagnostic.getClass().getName());
+            }
+        }
+
+        List<JCDiagnostic> subDiagnostics(Diagnostic<? extends JavaFileObject> diagnostic) {
+            JCDiagnostic diag = asJCDiagnostic(diagnostic);
+            if (diag instanceof JCDiagnostic.MultilineDiagnostic) {
+                return ((JCDiagnostic.MultilineDiagnostic)diag).getSubdiagnostics();
+            } else {
+                throw new AssertionError("Cannot extract subdiagnostics: " + diag.getClass().getName());
+            }
+        }
+    }
+
+    /**
+     * Processor for verbose resolution notes generated by javac. The processor
+     * checks that the diagnostic is associated with a method declared by
+     * a class annotated with the special @TraceResolve marker annotation. If
+     * that's the case, all subdiagnostics (one for each resolution candidate)
+     * are checked against the corresponding @Candidate annotations, using
+     * a VerboseCandidateSubdiagProcessor.
+     */
+    class VerboseResolutionNoteProcessor extends DiagnosticProcessor {
+
+        VerboseResolutionNoteProcessor() {
+            super(Kind.NOTE,
+                    "compiler.note.verbose.resolve.multi",
+                    "compiler.note.verbose.resolve.multi.1");
+        }
+
+        @Override
+        void process(Diagnostic<? extends JavaFileObject> diagnostic) {
+            Element siteSym = getSiteSym(diagnostic);
+            if (siteSym.getAnnotation(TraceResolve.class) == null) {
+                return;
+            }
+            int candidateIdx = 0;
+            for (JCDiagnostic d : subDiagnostics(diagnostic)) {
+                boolean isMostSpecific = candidateIdx++ == mostSpecific(diagnostic);
+                VerboseCandidateSubdiagProcessor subProc =
+                        new VerboseCandidateSubdiagProcessor(isMostSpecific, phase(diagnostic), success(diagnostic));
+                if (subProc.matches(d)) {
+                    subProc.process(d);
+                } else {
+                    throw new AssertionError("Bad subdiagnostic: " + d.getCode());
+                }
+            }
+        }
+
+        Element getSiteSym(Diagnostic<? extends JavaFileObject> diagnostic) {
+            return (Element)asJCDiagnostic(diagnostic).getArgs()[1];
+        }
+
+        int mostSpecific(Diagnostic<? extends JavaFileObject> diagnostic) {
+            return success(diagnostic) ?
+                    (Integer)asJCDiagnostic(diagnostic).getArgs()[2] : -1;
+        }
+
+        boolean success(Diagnostic<? extends JavaFileObject> diagnostic) {
+            return diagnostic.getCode().equals("compiler.note.verbose.resolve.multi");
+        }
+
+        Phase phase(Diagnostic<? extends JavaFileObject> diagnostic) {
+            return Phase.fromString(asJCDiagnostic(diagnostic).getArgs()[3].toString());
+        }
+    }
+
+    /**
+     * Processor for verbose resolution subdiagnostic notes generated by javac.
+     * The processor checks that the details of the overload candidate
+     * match against the info contained in the corresponding @Candidate
+     * annotation (if any).
+     */
+    class VerboseCandidateSubdiagProcessor extends DiagnosticProcessor {
+
+        boolean mostSpecific;
+        Phase phase;
+        boolean success;
+
+        public VerboseCandidateSubdiagProcessor(boolean mostSpecific, Phase phase, boolean success) {
+            super(Kind.OTHER,
+                    "compiler.misc.applicable.method.found",
+                    "compiler.misc.applicable.method.found.1",
+                    "compiler.misc.not.applicable.method.found");
+            this.mostSpecific = mostSpecific;
+            this.phase = phase;
+            this.success = success;
+        }
+
+        @Override
+        void process(Diagnostic<? extends JavaFileObject> diagnostic) {
+            Element methodSym = methodSym(diagnostic);
+            Candidate c = getCandidateAtPos(methodSym,
+                    asJCDiagnostic(diagnostic).getLineNumber(),
+                    asJCDiagnostic(diagnostic).getColumnNumber());
+            if (c == null) {
+                return; //nothing to check
+            }
+
+            if (c.applicable().length == 0 && c.mostSpecific()) {
+                error("Inapplicable method cannot be most specific " + methodSym);
+            }
+
+            if (isApplicable(diagnostic) != Arrays.asList(c.applicable()).contains(phase)) {
+                error("Invalid candidate's applicability " + methodSym);
+            }
+
+            if (success) {
+                for (Phase p : c.applicable()) {
+                    if (phase.ordinal() < p.ordinal()) {
+                        error("Invalid phase " + p + " on method " + methodSym);
+                    }
+                }
+            }
+
+            if (Arrays.asList(c.applicable()).contains(phase)) { //applicable
+                if (c.mostSpecific() != mostSpecific) {
+                    error("Invalid most specific value for method " + methodSym);
+                }
+                MethodType mtype = getSig(diagnostic);
+                if (mtype != null) {
+                    checkSig(c, methodSym, mtype);
+                }
+            }
+        }
+
+        boolean isApplicable(Diagnostic<? extends JavaFileObject> diagnostic) {
+            return !diagnostic.getCode().equals("compiler.misc.not.applicable.method.found");
+        }
+
+        Element methodSym(Diagnostic<? extends JavaFileObject> diagnostic) {
+            return (Element)asJCDiagnostic(diagnostic).getArgs()[1];
+        }
+
+        MethodType getSig(Diagnostic<? extends JavaFileObject> diagnostic) {
+            JCDiagnostic details = (JCDiagnostic)asJCDiagnostic(diagnostic).getArgs()[2];
+            if (details == null) {
+                return null;
+            } else if (details instanceof JCDiagnostic) {
+                return details.getCode().equals("compiler.misc.full.inst.sig") ?
+                        (MethodType)details.getArgs()[0] : null;
+            } else {
+                throw new AssertionError("Bad diagnostic arg: " + details);
+            }
+        }
+    }
+
+    /**
+     * Processor for verbose deferred inference notes generated by javac. The
+     * processor checks that the inferred signature for a given generic method
+     * call corresponds to the one (if any) declared in the @Candidate annotation.
+     */
+    class VerboseDeferredInferenceNoteProcessor extends DiagnosticProcessor {
+
+        public VerboseDeferredInferenceNoteProcessor() {
+            super(Kind.NOTE, "compiler.note.deferred.method.inst");
+        }
+
+        @Override
+        void process(Diagnostic<? extends JavaFileObject> diagnostic) {
+            Element methodSym = methodSym(diagnostic);
+            Candidate c = getCandidateAtPos(methodSym,
+                    asJCDiagnostic(diagnostic).getLineNumber(),
+                    asJCDiagnostic(diagnostic).getColumnNumber());
+            MethodType sig = sig(diagnostic);
+            if (c != null && sig != null) {
+                checkSig(c, methodSym, sig);
+            }
+        }
+
+        Element methodSym(Diagnostic<? extends JavaFileObject> diagnostic) {
+            return (Element)asJCDiagnostic(diagnostic).getArgs()[0];
+        }
+
+        MethodType sig(Diagnostic<? extends JavaFileObject> diagnostic) {
+            return (MethodType)asJCDiagnostic(diagnostic).getArgs()[1];
+        }
+    }
+
+    /**
+     * Processor for all error diagnostics; if the error key is not declared in
+     * the test file header, the processor reports an error.
+     */
+    class ErrorProcessor extends DiagnosticProcessor {
+
+        public ErrorProcessor() {
+            super(Diagnostic.Kind.ERROR);
+        }
+
+        @Override
+        void process(Diagnostic<? extends JavaFileObject> diagnostic) {
+            if (!declaredKeys.contains(diagnostic.getCode())) {
+                error("Unexpected compilation error key '" + diagnostic.getCode() + "'");
+            }
+        }
+    }
+
+    @SupportedAnnotationTypes({"Candidate","TraceResolve"})
+    class ResolveCandidateFinder extends JavacTestingAbstractProcessor {
+
+        @Override
+        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+            if (roundEnv.processingOver())
+                return true;
+
+            TypeElement traceResolveAnno = elements.getTypeElement("TraceResolve");
+            TypeElement candidateAnno = elements.getTypeElement("Candidate");
+
+            if (!annotations.contains(traceResolveAnno)) {
+                error("no @TraceResolve annotation found in test class");
+            }
+
+            if (!annotations.contains(candidateAnno)) {
+                error("no @candidate annotation found in test class");
+            }
+
+            for (Element elem: roundEnv.getElementsAnnotatedWith(traceResolveAnno)) {
+                TraceResolve traceResolve = elem.getAnnotation(TraceResolve.class);
+                declaredKeys.addAll(Arrays.asList(traceResolve.keys()));
+            }
+
+            for (Element elem: roundEnv.getElementsAnnotatedWith(candidateAnno)) {
+                candidatesMap.put(new ElementKey(elem), elem.getAnnotation(Candidate.class));
+            }
+            return true;
+        }
+    }
+
+    class ElementKey {
+
+        String key;
+        Element elem;
+
+        public ElementKey(Element elem) {
+            this.elem = elem;
+            this.key = computeKey(elem);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof ElementKey) {
+                ElementKey other = (ElementKey)obj;
+                return other.key.equals(key);
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return key.hashCode();
+        }
+
+        String computeKey(Element e) {
+            StringBuilder buf = new StringBuilder();
+            while (e != null) {
+                buf.append(e.toString());
+                e = e.getEnclosingElement();
+            }
+            buf.append(jfo.getName());
+            return buf.toString();
+        }
+
+        @Override
+        public String toString() {
+            return "Key{"+key+"}";
+        }
+    }
+
+    class DiagnosticHandler implements DiagnosticListener<JavaFileObject> {
+
+        boolean shouldRecordDiags;
+
+        DiagnosticHandler(boolean shouldRecordDiags) {
+            this.shouldRecordDiags = shouldRecordDiags;
+        }
+
+        public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+            if (shouldRecordDiags)
+                diags.add(diagnostic);
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/resolve/TraceResolve.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE)
+@interface TraceResolve {
+    String[] keys() default {};
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/resolve/tests/BoxedReturnTypeInference.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2011, 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
+class BoxedReturnTypeInference {
+    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Byte", mostSpecific=true)
+    static <B> B m_byte() { return null; }
+
+    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Short", mostSpecific=true)
+    static <S> S m_short() { return null; }
+
+    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Integer", mostSpecific=true)
+    static <I> I m_int() { return null; }
+
+    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Long", mostSpecific=true)
+    static <L> L m_long() { return null; }
+
+    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Float", mostSpecific=true)
+    static <F> F m_float() { return null; }
+
+    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Double", mostSpecific=true)
+    static <D> D m_double() { return null; }
+
+    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Character", mostSpecific=true)
+    static <C> C m_char() { return null; }
+
+    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Boolean", mostSpecific=true)
+    static <Z> Z m_bool() { return null; }
+
+    {
+        Byte b = m_byte();
+        Short s = m_short();
+        Integer i = m_int();
+        Long l = m_long();
+        Float f = m_float();
+        Double d = m_double();
+        Character c= m_char();
+        Boolean z = m_bool();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/resolve/tests/PrimitiveOverReferenceOverInferred.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2011, 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
+class PrimitiveOverReference {
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_byte(byte b) {}
+    @Candidate
+    static void m_byte(Byte b) {}
+    @Candidate
+    static <B> void m_byte(B b) {}
+
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_short(short s) {}
+    @Candidate
+    static void m_short(Short s) {}
+    @Candidate
+    static <S> void m_short(S s) {}
+
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_int(int i) {}
+    @Candidate
+    static void m_int(Integer i) {}
+    @Candidate
+    static <I> void m_int(I i) {}
+
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_long(long l) {}
+    @Candidate
+    static void m_long(Long l) {}
+    @Candidate
+    static <L> void m_long(L l) {}
+
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_float(float f) {}
+    @Candidate
+    static void m_float(Float f) {}
+    @Candidate
+    static <F> void m_float(F f) {}
+
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_double(double d) {}
+    @Candidate
+    static void m_double(Double d) {}
+    @Candidate
+    static <D> void m_double(D d) {}
+
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_char(char c) {}
+    @Candidate
+    static void m_char(Character c) {}
+    @Candidate
+    static <C> void m_char(C c) {}
+
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_bool(boolean z) {}
+    @Candidate
+    static void m_bool(Boolean z) {}
+    @Candidate
+    static <Z> void m_bool(Z z) {}
+
+    {
+        m_byte((byte)0);
+        m_short((short)0);
+        m_int(0);
+        m_long(0L);
+        m_float(0.0f);
+        m_double(0.0);
+        m_char('?');
+        m_bool(false);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/resolve/tests/PrimitiveOverReferenceOverVarargs.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2011, 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
+class PrimitiveOverReference {
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_byte(byte b) {}
+    @Candidate
+    static void m_byte(Byte b) {}
+    @Candidate
+    static void m_byte(byte... b) {}
+    @Candidate
+    static void m_byte(Byte... b) {}
+
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_short(short s) {}
+    @Candidate
+    static void m_short(Short s) {}
+    @Candidate
+    static void m_short(short... s) {}
+    @Candidate
+    static void m_short(Short... s) {}
+
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_int(int i) {}
+    @Candidate
+    static void m_int(Integer i) {}
+    @Candidate
+    static void m_int(int... i) {}
+    @Candidate
+    static void m_int(Integer... i) {}
+
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_long(long l) {}
+    @Candidate
+    static void m_long(Long l) {}
+    @Candidate
+    static void m_long(long... l) {}
+    @Candidate
+    static void m_long(Long... l) {}
+
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_float(float f) {}
+    @Candidate
+    static void m_float(Float f) {}
+    @Candidate
+    static void m_float(float... f) {}
+    @Candidate
+    static void m_float(Float... f) {}
+
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_double(double d) {}
+    @Candidate
+    static void m_double(Double d) {}
+    @Candidate
+    static void m_double(double... d) {}
+    @Candidate
+    static void m_double(Double... d) {}
+
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_char(char c) {}
+    @Candidate
+    static void m_char(Character c) {}
+    @Candidate
+    static void m_char(char... c) {}
+    @Candidate
+    static void m_char(Character... c) {}
+
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_bool(boolean z) {}
+    @Candidate
+    static void m_bool(Boolean z) {}
+    @Candidate
+    static void m_bool(boolean... z) {}
+    @Candidate
+    static void m_bool(Boolean... z) {}
+
+    {
+        m_byte((byte)0);
+        m_short((short)0);
+        m_int(0);
+        m_long(0L);
+        m_float(0.0f);
+        m_double(0.0);
+        m_char('?');
+        m_bool(false);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/resolve/tests/PrimitiveOverReferenceVarargsAmbiguous.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2011, 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 PrimitiveOverReferenceVarargsAmbiguous {
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    static void m_byte(byte... b) {}
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    static void m_byte(Byte... b) {}
+
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    static void m_short(short... s) {}
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    static void m_short(Short... s) {}
+
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    static void m_int(int... i) {}
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    static void m_int(Integer... i) {}
+
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    static void m_long(long... l) {}
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    static void m_long(Long... l) {}
+
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    static void m_float(float... f) {}
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    static void m_float(Float... f) {}
+
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    static void m_double(double... d) {}
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    static void m_double(Double... d) {}
+
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    static void m_char(char... c) {}
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    static void m_char(Character... c) {}
+
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    static void m_bool(boolean... z) {}
+    @Candidate(applicable=Phase.VARARGS, mostSpecific=false)
+    static void m_bool(Boolean... z) {}
+
+    {
+        m_byte((byte)0);
+        m_short((short)0);
+        m_int(0);
+        m_long(0L);
+        m_float(0.0f);
+        m_double(0.0);
+        m_char('?');
+        m_bool(false);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/resolve/tests/PrimitiveOverload.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2011, 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
+class PrimitiveOverload {
+
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_byte(byte b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_byte(short b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_byte(int b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_byte(long b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_byte(float b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_byte(double b) {}
+
+    @Candidate
+    static void m_short(byte b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_short(short b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_short(int b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_short(long b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_short(float b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_short(double b) {}
+
+    @Candidate
+    static void m_int(byte b) {}
+    @Candidate
+    static void m_int(short b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_int(int b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_int(long b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_int(float b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_int(double b) {}
+
+    @Candidate
+    static void m_long(byte b) {}
+    @Candidate
+    static void m_long(short b) {}
+    @Candidate
+    static void m_long(int b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_long(long b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_long(float b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_long(double b) {}
+
+    @Candidate
+    static void m_float(byte b) {}
+    @Candidate
+    static void m_float(short b) {}
+    @Candidate
+    static void m_float(int b) {}
+    @Candidate
+    static void m_float(long b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_float(float b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_float(double b) {}
+
+    @Candidate
+    static void m_double(byte b) {}
+    @Candidate
+    static void m_double(short b) {}
+    @Candidate
+    static void m_double(int b) {}
+    @Candidate
+    static void m_double(long b) {}
+    @Candidate
+    static void m_double(float b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_double(double b) {}
+
+    {
+        m_byte((byte)0);
+        m_short((short)0);
+        m_int(0);
+        m_long(0L);
+        m_float(0.0f);
+        m_double(0.0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/resolve/tests/PrimitiveReturnTypeInference.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2011, 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
+class PrimitiveReturnTypeInference {
+    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Byte", mostSpecific=true)
+    static <B> B m_byte() { return null; }
+
+    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Short", mostSpecific=true)
+    static <S> S m_short() { return null; }
+
+    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Integer", mostSpecific=true)
+    static <I> I m_int() { return null; }
+
+    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Long", mostSpecific=true)
+    static <L> L m_long() { return null; }
+
+    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Float", mostSpecific=true)
+    static <F> F m_float() { return null; }
+
+    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Double", mostSpecific=true)
+    static <D> D m_double() { return null; }
+
+    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Character", mostSpecific=true)
+    static <C> C m_char() { return null; }
+
+    @Candidate(applicable=Phase.BASIC, sig="()java.lang.Boolean", mostSpecific=true)
+    static <Z> Z m_bool() { return null; }
+
+    {
+        byte b = m_byte();
+        short s = m_short();
+        int i = m_int();
+        long l = m_long();
+        float f = m_float();
+        double d = m_double();
+        char c= m_char();
+        boolean z = m_bool();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/resolve/tests/ReferenceOverInferred.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2011, 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
+class PrimitiveOverInferred {
+    @Candidate(applicable=Phase.BOX, mostSpecific=true)
+    static void m_byte(Byte b) {}
+    @Candidate(applicable=Phase.BOX, sig="(java.lang.Byte)void")
+    static <B> void m_byte(B b) {}
+
+    @Candidate(applicable=Phase.BOX, mostSpecific=true)
+    static void m_short(Short s) {}
+    @Candidate(applicable=Phase.BOX, sig="(java.lang.Short)void")
+    static <S> void m_short(S s) {}
+
+    @Candidate(applicable=Phase.BOX, mostSpecific=true)
+    static void m_int(Integer i) {}
+    @Candidate(applicable=Phase.BOX, sig="(java.lang.Integer)void")
+    static <I> void m_int(I i) {}
+
+    @Candidate(applicable=Phase.BOX, mostSpecific=true)
+    static void m_long(Long l) {}
+    @Candidate(applicable=Phase.BOX, sig="(java.lang.Long)void")
+    static <L> void m_long(L l) {}
+
+    @Candidate(applicable=Phase.BOX, mostSpecific=true)
+    static void m_float(Float f) {}
+    @Candidate(applicable=Phase.BOX, sig="(java.lang.Float)void")
+    static <F> void m_float(F f) {}
+
+    @Candidate(applicable=Phase.BOX, mostSpecific=true)
+    static void m_double(Double d) {}
+    @Candidate(applicable=Phase.BOX, sig="(java.lang.Double)void")
+    static <D> void m_double(D d) {}
+
+    @Candidate(applicable=Phase.BOX, mostSpecific=true)
+    static void m_char(Character c) {}
+    @Candidate(applicable=Phase.BOX, sig="(java.lang.Character)void")
+    static <C> void m_char(C c) {}
+
+    @Candidate(applicable=Phase.BOX, mostSpecific=true)
+    static void m_bool(Boolean z) {}
+    @Candidate(applicable=Phase.BOX, sig="(java.lang.Boolean)void")
+    static <Z> void m_bool(Z z) {}
+
+    {
+        m_byte((byte)0);
+        m_short((short)0);
+        m_int(0);
+        m_long(0L);
+        m_float(0.0f);
+        m_double(0.0);
+        m_char('?');
+        m_bool(false);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/resolve/tests/ReferenceOverVarargs.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2011, 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
+class ReferenceOverVarargs {
+
+    @Candidate(applicable=Phase.BOX, mostSpecific=true)
+    static void m_byte(Byte b) {}
+    @Candidate
+    static void m_byte(byte... b) {}
+    @Candidate
+    static void m_byte(Byte... b) {}
+
+    @Candidate(applicable=Phase.BOX, mostSpecific=true)
+    static void m_short(Short s) {}
+    @Candidate
+    static void m_short(short... s) {}
+    @Candidate
+    static void m_short(Short... s) {}
+
+    @Candidate(applicable=Phase.BOX, mostSpecific=true)
+    static void m_int(Integer i) {}
+    @Candidate
+    static void m_int(int... i) {}
+    @Candidate
+    static void m_int(Integer... i) {}
+
+    @Candidate(applicable=Phase.BOX, mostSpecific=true)
+    static void m_long(Long l) {}
+    @Candidate
+    static void m_long(long... l) {}
+    @Candidate
+    static void m_long(Long... l) {}
+
+    @Candidate(applicable=Phase.BOX, mostSpecific=true)
+    static void m_float(Float f) {}
+    @Candidate
+    static void m_float(float... f) {}
+    @Candidate
+    static void m_float(Float... f) {}
+
+    @Candidate(applicable=Phase.BOX, mostSpecific=true)
+    static void m_double(Double d) {}
+    @Candidate
+    static void m_double(double... d) {}
+    @Candidate
+    static void m_double(Double... d) {}
+
+    @Candidate(applicable=Phase.BOX, mostSpecific=true)
+    static void m_char(Character c) {}
+    @Candidate
+    static void m_char(char... c) {}
+    @Candidate
+    static void m_char(Character... c) {}
+
+    @Candidate(applicable=Phase.BOX, mostSpecific=true)
+    static void m_bool(Boolean z) {}
+    @Candidate
+    static void m_bool(boolean... z) {}
+    @Candidate
+    static void m_bool(Boolean... z) {}
+
+    {
+        m_byte((byte)0);
+        m_short((short)0);
+        m_int(0);
+        m_long(0L);
+        m_float(0.0f);
+        m_double(0.0);
+        m_char('?');
+        m_bool(false);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/resolve/tests/ReferenceOverload.java	Mon Oct 24 13:00:30 2011 +0100
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2011, 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
+class ReferenceOverload {
+
+    static class A {}
+    static class B extends A {}
+    static class C extends B {}
+    static class D extends C {}
+    static class E extends D {}
+
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_A(A a) {}
+    @Candidate
+    static void m_A(B a) {}
+    @Candidate
+    static void m_A(C a) {}
+    @Candidate
+    static void m_A(D a) {}
+    @Candidate
+    static void m_A(E a) {}
+
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_B(A b) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_B(B b) {}
+    @Candidate
+    static void m_B(C b) {}
+    @Candidate
+    static void m_B(D b) {}
+    @Candidate
+    static void m_B(E b) {}
+
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_C(A c) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_C(B c) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_C(C c) {}
+    @Candidate
+    static void m_C(D c) {}
+    @Candidate
+    static void m_C(E c) {}
+
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_D(A d) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_D(B d) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_D(C d) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_D(D d) {}
+    @Candidate
+    static void m_D(E d) {}
+
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_E(A e) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_E(B e) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_E(C e) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=false)
+    static void m_E(D e) {}
+    @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+    static void m_E(E e) {}
+
+    {
+        m_A((A)null);
+        m_B((B)null);
+        m_C((C)null);
+        m_D((D)null);
+        m_E((E)null);
+    }
+}