8068995: Cleanup method reference lookup code
authormcimadamore
Thu, 15 Jan 2015 13:58:11 +0000
changeset 28456 b87fdde1404d
parent 28455 41245007c074
child 28457 2c3ccb8ad8e9
8068995: Cleanup method reference lookup code Summary: Simplify method reference code lookup and generate better/more uniform diagnostics Reviewed-by: vromero
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/List.java
langtools/test/tools/javac/diags/examples/BadInstanceMethodInUnboundLookup.java
langtools/test/tools/javac/diags/examples/BadStaticMethodInBoundLookup.java
langtools/test/tools/javac/diags/examples/BadStaticMethodInUnboundLookup.java
langtools/test/tools/javac/diags/examples/NonStaticCantBeRefFragment.java
langtools/test/tools/javac/diags/examples/StaticBoundMref.java
langtools/test/tools/javac/diags/examples/StaticMethodInUnboundLookup.java
langtools/test/tools/javac/lambda/MethodReference22.out
langtools/test/tools/javac/lambda/MethodReference28.out
langtools/test/tools/javac/lambda/MethodReference51.out
langtools/test/tools/javac/lambda/MethodReference55.out
langtools/test/tools/javac/lambda/MethodReference68.out
langtools/test/tools/javac/lambda/MethodReference73.out
langtools/test/tools/javac/lambda/TargetType60.out
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java	Tue Jan 13 19:13:42 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java	Thu Jan 15 13:58:11 2015 +0000
@@ -74,8 +74,7 @@
         WRONG_MTHS(Category.OVERLOAD, KindName.METHOD),
         WRONG_MTH(Category.OVERLOAD, KindName.METHOD),
         ABSENT_MTH(Category.OVERLOAD, KindName.METHOD),
-        ABSENT_TYP(Category.OVERLOAD, KindName.CLASS),
-        WRONG_STATICNESS(Category.OVERLOAD, KindName.METHOD);
+        ABSENT_TYP(Category.OVERLOAD, KindName.CLASS);
 
         // There are essentially two "levels" to the Kind datatype.
         // The first is a totally-ordered set of categories of
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Jan 13 19:13:42 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Jan 15 13:58:11 2015 +0000
@@ -2640,8 +2640,7 @@
             try {
                 refResult = rs.resolveMemberReference(localEnv, that, that.expr.type,
                         that.name, argtypes, typeargtypes, referenceCheck,
-                        resultInfo.checkContext.inferenceContext(),
-                        resultInfo.checkContext.deferredAttrContext().mode);
+                        resultInfo.checkContext.inferenceContext(), rs.basicReferenceChooser);
             } finally {
                 resultInfo.checkContext.inferenceContext().rollback(saved_undet);
             }
@@ -2659,9 +2658,8 @@
                     case WRONG_MTHS:
                     case AMBIGUOUS:
                     case HIDDEN:
+                    case MISSING_ENCL:
                     case STATICERR:
-                    case MISSING_ENCL:
-                    case WRONG_STATICNESS:
                         targetError = true;
                         break;
                     default:
@@ -2722,15 +2720,6 @@
                     return;
                 }
 
-                if (that.sym.isStatic() && !TreeInfo.isStaticSelector(that.expr, names) &&
-                        !that.kind.isUnbound()) {
-                    //no static bound mrefs
-                    log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()),
-                            diags.fragment("static.bound.mref"));
-                    result = that.type = types.createErrorType(currentTarget);
-                    return;
-                }
-
                 if (!refSym.isStatic() && that.kind == JCMemberReference.ReferenceKind.SUPER) {
                     // Check that super-qualified symbols are not abstract (JLS)
                     rs.checkNonAbstract(that.pos(), that.sym);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Tue Jan 13 19:13:42 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Thu Jan 15 13:58:11 2015 +0000
@@ -27,6 +27,9 @@
 
 import com.sun.source.tree.LambdaExpressionTree.BodyKind;
 import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.comp.Resolve.ResolveError;
+import com.sun.tools.javac.resources.CompilerProperties;
+import com.sun.tools.javac.resources.CompilerProperties.Fragments;
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.DefinedBy.Api;
@@ -37,6 +40,7 @@
 import com.sun.tools.javac.comp.Infer.InferenceContext;
 import com.sun.tools.javac.comp.Resolve.MethodResolutionPhase;
 import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
 import com.sun.tools.javac.util.Log.DeferredDiagnosticHandler;
 
 import java.util.ArrayList;
@@ -786,16 +790,22 @@
                     JCMemberReference mref2 = new TreeCopier<Void>(make).copy(tree);
                     mref2.expr = exprTree;
                     Symbol lookupSym =
-                            rs.resolveMemberReferenceByArity(localEnv, mref2, exprTree.type,
-                                tree.name, argtypes.toList(), inferenceContext);
+                            rs.resolveMemberReference(localEnv, mref2, exprTree.type,
+                                    tree.name, argtypes.toList(), List.nil(), rs.arityMethodCheck,
+                                    inferenceContext, rs.structuralReferenceChooser).fst;
                     switch (lookupSym.kind) {
-                        //note: as argtypes are erroneous types, type-errors must
-                        //have been caused by arity mismatch
-                        case ABSENT_MTH:
                         case WRONG_MTH:
                         case WRONG_MTHS:
-                        case WRONG_STATICNESS:
-                           checkContext.report(tree, diags.fragment("incompatible.arg.types.in.mref"));
+                            //note: as argtypes are erroneous types, type-errors must
+                            //have been caused by arity mismatch
+                            checkContext.report(tree, diags.fragment(Fragments.IncompatibleArgTypesInMref));
+                            break;
+                        case ABSENT_MTH:
+                        case STATICERR:
+                            //if no method found, or method found with wrong staticness, report better message
+                            checkContext.report(tree, ((ResolveError)lookupSym).getDiagnostic(DiagnosticType.FRAGMENT,
+                                    tree, exprTree.type.tsym, exprTree.type, tree.name, argtypes.toList(), List.nil()));
+                            break;
                     }
                 }
             }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java	Tue Jan 13 19:13:42 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Jan 15 13:58:11 2015 +0000
@@ -25,7 +25,6 @@
 
 package com.sun.tools.javac.comp;
 
-import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
 import com.sun.tools.javac.api.Formattable.LocalizedString;
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Scope.WriteableScope;
@@ -40,6 +39,7 @@
 import com.sun.tools.javac.comp.Infer.FreeTypeListener;
 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
 import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.Template;
+import com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind;
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.main.Option;
 import com.sun.tools.javac.tree.*;
@@ -65,6 +65,7 @@
 
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Flags.BLOCK;
+import static com.sun.tools.javac.code.Flags.STATIC;
 import static com.sun.tools.javac.code.Kinds.*;
 import static com.sun.tools.javac.code.Kinds.Kind.*;
 import static com.sun.tools.javac.code.TypeTag.*;
@@ -105,15 +106,10 @@
         context.put(resolveKey, this);
         syms = Symtab.instance(context);
 
-        varNotFound = new
-            SymbolNotFoundError(ABSENT_VAR);
-        methodNotFound = new
-            SymbolNotFoundError(ABSENT_MTH);
-        methodWithCorrectStaticnessNotFound = new
-            SymbolNotFoundError(WRONG_STATICNESS,
-                "method found has incorrect staticness");
-        typeNotFound = new
-            SymbolNotFoundError(ABSENT_TYP);
+        varNotFound = new SymbolNotFoundError(ABSENT_VAR);
+        methodNotFound = new SymbolNotFoundError(ABSENT_MTH);
+        typeNotFound = new SymbolNotFoundError(ABSENT_TYP);
+        referenceNotFound = new ReferenceLookupResult(methodNotFound, null);
 
         names = Names.instance(context);
         log = Log.instance(context);
@@ -145,9 +141,11 @@
      */
     private final SymbolNotFoundError varNotFound;
     private final SymbolNotFoundError methodNotFound;
-    private final SymbolNotFoundError methodWithCorrectStaticnessNotFound;
     private final SymbolNotFoundError typeNotFound;
 
+    /** empty reference lookup result */
+    private final ReferenceLookupResult referenceNotFound;
+
     public static Resolve instance(Context context) {
         Resolve instance = context.get(resolveKey);
         if (instance == null)
@@ -2680,69 +2678,16 @@
                                   List<Type> argtypes,
                                   List<Type> typeargtypes,
                                   MethodResolutionPhase maxPhase) {
-        ReferenceLookupHelper result;
         if (!name.equals(names.init)) {
             //method reference
-            result =
-                    new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
+            return new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
+        } else if (site.hasTag(ARRAY)) {
+            //array constructor reference
+            return new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
         } else {
-            if (site.hasTag(ARRAY)) {
-                //array constructor reference
-                result =
-                        new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
-            } else {
-                //class constructor reference
-                result =
-                        new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
-            }
+            //class constructor reference
+            return new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
         }
-        return result;
-    }
-
-    Symbol resolveMemberReferenceByArity(Env<AttrContext> env,
-                                  JCMemberReference referenceTree,
-                                  Type site,
-                                  Name name,
-                                  List<Type> argtypes,
-                                  InferenceContext inferenceContext) {
-
-        boolean isStaticSelector = TreeInfo.isStaticSelector(referenceTree.expr, names);
-        site = types.capture(site);
-
-        ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper(
-                referenceTree, site, name, argtypes, null, VARARITY);
-        //step 1 - bound lookup
-        Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
-        Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym,
-                arityMethodCheck, boundLookupHelper);
-        if (isStaticSelector &&
-            !name.equals(names.init) &&
-            !boundSym.isStatic() &&
-            !boundSym.kind.isOverloadError()) {
-            boundSym = methodNotFound;
-        }
-
-        //step 2 - unbound lookup
-        Symbol unboundSym = methodNotFound;
-        ReferenceLookupHelper unboundLookupHelper = null;
-        Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
-        if (isStaticSelector) {
-            unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext);
-            unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym,
-                    arityMethodCheck, unboundLookupHelper);
-            if (unboundSym.isStatic() &&
-                !unboundSym.kind.isOverloadError()) {
-                unboundSym = methodNotFound;
-            }
-        }
-
-        //merge results
-        Symbol bestSym = choose(boundSym, unboundSym);
-        env.info.pendingResolutionPhase = bestSym == unboundSym ?
-                unboundEnv.info.pendingResolutionPhase :
-                boundEnv.info.pendingResolutionPhase;
-
-        return bestSym;
     }
 
     /**
@@ -2763,8 +2708,8 @@
      * the receiver argument type is used to infer an instantiation for the raw
      * qualifier type.
      *
-     * When a multi-step resolution process is exploited, it is an error
-     * if two candidates are found (ambiguity).
+     * When a multi-step resolution process is exploited, the process of picking
+     * the resulting symbol is delegated to an helper class {@link com.sun.tools.javac.comp.Resolve.ReferenceChooser}.
      *
      * This routine returns a pair (T,S), where S is the member reference symbol,
      * and T is the type of the class in which S is defined. This is necessary as
@@ -2779,7 +2724,7 @@
                                   List<Type> typeargtypes,
                                   MethodCheck methodCheck,
                                   InferenceContext inferenceContext,
-                                  AttrMode mode) {
+                                  ReferenceChooser referenceChooser) {
 
         site = types.capture(site);
         ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper(
@@ -2787,102 +2732,29 @@
 
         //step 1 - bound lookup
         Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
-        Symbol origBoundSym;
-        boolean staticErrorForBound = false;
         MethodResolutionContext boundSearchResolveContext = new MethodResolutionContext();
         boundSearchResolveContext.methodCheck = methodCheck;
-        Symbol boundSym = origBoundSym = lookupMethod(boundEnv, env.tree.pos(),
+        Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(),
                 site.tsym, boundSearchResolveContext, boundLookupHelper);
-        SearchResultKind boundSearchResultKind = SearchResultKind.NOT_APPLICABLE_MATCH;
-        boolean isStaticSelector = TreeInfo.isStaticSelector(referenceTree.expr, names);
-        boolean shouldCheckForStaticness = isStaticSelector &&
-                referenceTree.getMode() == ReferenceMode.INVOKE;
-        if (boundSym.kind != WRONG_MTHS && boundSym.kind != WRONG_MTH) {
-            if (shouldCheckForStaticness) {
-                if (!boundSym.isStatic()) {
-                    staticErrorForBound = true;
-                    if (hasAnotherApplicableMethod(
-                            boundSearchResolveContext, boundSym, true)) {
-                        boundSearchResultKind = SearchResultKind.BAD_MATCH_MORE_SPECIFIC;
-                    } else {
-                        boundSearchResultKind = SearchResultKind.BAD_MATCH;
-                        if (!boundSym.kind.isOverloadError()) {
-                            boundSym = methodWithCorrectStaticnessNotFound;
-                        }
-                    }
-                } else if (!boundSym.kind.isOverloadError()) {
-                    boundSearchResultKind = SearchResultKind.GOOD_MATCH;
-                }
-            }
-        }
+        ReferenceLookupResult boundRes = new ReferenceLookupResult(boundSym, boundSearchResolveContext);
 
         //step 2 - unbound lookup
-        Symbol origUnboundSym = null;
         Symbol unboundSym = methodNotFound;
-        ReferenceLookupHelper unboundLookupHelper = null;
         Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
-        SearchResultKind unboundSearchResultKind = SearchResultKind.NOT_APPLICABLE_MATCH;
-        boolean staticErrorForUnbound = false;
-        if (isStaticSelector) {
-            unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext);
+        ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext);
+        ReferenceLookupResult unboundRes = referenceNotFound;
+        if (unboundLookupHelper != null) {
             MethodResolutionContext unboundSearchResolveContext =
                     new MethodResolutionContext();
             unboundSearchResolveContext.methodCheck = methodCheck;
-            unboundSym = origUnboundSym = lookupMethod(unboundEnv, env.tree.pos(),
+            unboundSym = lookupMethod(unboundEnv, env.tree.pos(),
                     site.tsym, unboundSearchResolveContext, unboundLookupHelper);
-
-            if (unboundSym.kind != WRONG_MTH && unboundSym.kind != WRONG_MTHS) {
-                if (shouldCheckForStaticness) {
-                    if (unboundSym.isStatic()) {
-                        staticErrorForUnbound = true;
-                        if (hasAnotherApplicableMethod(
-                                unboundSearchResolveContext, unboundSym, false)) {
-                            unboundSearchResultKind = SearchResultKind.BAD_MATCH_MORE_SPECIFIC;
-                        } else {
-                            unboundSearchResultKind = SearchResultKind.BAD_MATCH;
-                            if (!unboundSym.kind.isOverloadError()) {
-                                unboundSym = methodWithCorrectStaticnessNotFound;
-                            }
-                        }
-                    } else if (!unboundSym.kind.isOverloadError()) {
-                        unboundSearchResultKind = SearchResultKind.GOOD_MATCH;
-                    }
-                }
-            }
+            unboundRes = new ReferenceLookupResult(unboundSym, unboundSearchResolveContext);
         }
 
         //merge results
         Pair<Symbol, ReferenceLookupHelper> res;
-        Symbol bestSym = choose(boundSym, unboundSym);
-        if (!bestSym.kind.isOverloadError() &&
-            (staticErrorForBound || staticErrorForUnbound)) {
-            if (staticErrorForBound) {
-                boundSym = methodWithCorrectStaticnessNotFound;
-            }
-            if (staticErrorForUnbound) {
-                unboundSym = methodWithCorrectStaticnessNotFound;
-            }
-            bestSym = choose(boundSym, unboundSym);
-        }
-        if (bestSym == methodWithCorrectStaticnessNotFound && mode == AttrMode.CHECK) {
-            Symbol symToPrint = origBoundSym;
-            String errorFragmentToPrint = "non-static.cant.be.ref";
-            if (staticErrorForBound && staticErrorForUnbound) {
-                if (unboundSearchResultKind == SearchResultKind.BAD_MATCH_MORE_SPECIFIC) {
-                    symToPrint = origUnboundSym;
-                    errorFragmentToPrint = "static.method.in.unbound.lookup";
-                }
-            } else {
-                if (!staticErrorForBound) {
-                    symToPrint = origUnboundSym;
-                    errorFragmentToPrint = "static.method.in.unbound.lookup";
-                }
-            }
-            log.error(referenceTree.expr.pos(), "invalid.mref",
-                Kinds.kindName(referenceTree.getMode()),
-                diags.fragment(errorFragmentToPrint,
-                Kinds.kindName(symToPrint), symToPrint));
-        }
+        Symbol bestSym = referenceChooser.result(boundRes, unboundRes);
         res = new Pair<>(bestSym,
                 bestSym == unboundSym ? unboundLookupHelper : boundLookupHelper);
         env.info.pendingResolutionPhase = bestSym == unboundSym ?
@@ -2892,67 +2764,213 @@
         return res;
     }
 
-    enum SearchResultKind {
-        GOOD_MATCH,                 //type I
-        BAD_MATCH_MORE_SPECIFIC,    //type II
-        BAD_MATCH,                  //type III
-        NOT_APPLICABLE_MATCH        //type IV
-    }
-
-    boolean hasAnotherApplicableMethod(MethodResolutionContext resolutionContext,
-            Symbol bestSoFar, boolean staticMth) {
-        for (Candidate c : resolutionContext.candidates) {
-            if (resolutionContext.step != c.step ||
-                !c.isApplicable() ||
-                c.sym == bestSoFar) {
-                continue;
-            } else {
-                if (c.sym.isStatic() == staticMth) {
-                    return true;
+    /**
+     * This class is used to represent a method reference lookup result. It keeps track of two
+     * things: (i) the symbol found during a method reference lookup and (ii) the static kind
+     * of the lookup (see {@link com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind}).
+     */
+    static class ReferenceLookupResult {
+
+        /**
+         * Static kind associated with a method reference lookup. Erroneous lookups end up with
+         * the UNDEFINED kind; successful lookups will end up with either STATIC, NON_STATIC,
+         * depending on whether all applicable candidates are static or non-static methods,
+         * respectively. If a successful lookup has both static and non-static applicable methods,
+         * its kind is set to BOTH.
+         */
+        enum StaticKind {
+            STATIC,
+            NON_STATIC,
+            BOTH,
+            UNDEFINED;
+
+            /**
+             * Retrieve the static kind associated with a given (method) symbol.
+             */
+            static StaticKind from(Symbol s) {
+                return s.isStatic() ?
+                        STATIC : NON_STATIC;
+            }
+
+            /**
+             * Merge two static kinds together.
+             */
+            static StaticKind reduce(StaticKind sk1, StaticKind sk2) {
+                if (sk1 == UNDEFINED) {
+                    return sk2;
+                } else if (sk2 == UNDEFINED) {
+                    return sk1;
+                } else {
+                    return sk1 == sk2 ? sk1 : BOTH;
                 }
             }
         }
-        return false;
-    }
-
-    //where
-        private Symbol choose(Symbol boundSym, Symbol unboundSym) {
-            if (lookupSuccess(boundSym) && lookupSuccess(unboundSym)) {
-                return ambiguityError(boundSym, unboundSym);
-            } else if (lookupSuccess(boundSym) ||
-                    (canIgnore(unboundSym) && !canIgnore(boundSym))) {
-                return boundSym;
-            } else if (lookupSuccess(unboundSym) ||
-                    (canIgnore(boundSym) && !canIgnore(unboundSym))) {
-                return unboundSym;
-            } else {
-                return boundSym;
+
+        /** The static kind. */
+        StaticKind staticKind;
+
+        /** The lookup result. */
+        Symbol sym;
+
+        ReferenceLookupResult(Symbol sym, MethodResolutionContext resolutionContext) {
+            this.staticKind = staticKind(sym, resolutionContext);
+            this.sym = sym;
+        }
+
+        private StaticKind staticKind(Symbol sym, MethodResolutionContext resolutionContext) {
+            switch (sym.kind) {
+                case MTH:
+                case AMBIGUOUS:
+                    return resolutionContext.candidates.stream()
+                            .filter(c -> c.isApplicable() && c.step == resolutionContext.step)
+                            .map(c -> StaticKind.from(c.sym))
+                            .reduce(StaticKind::reduce)
+                            .orElse(StaticKind.UNDEFINED);
+                case HIDDEN:
+                    return StaticKind.from(((AccessError)sym).sym);
+                default:
+                    return StaticKind.UNDEFINED;
             }
         }
 
-        private boolean lookupSuccess(Symbol s) {
-            return s.kind == MTH || s.kind == AMBIGUOUS;
+        /**
+         * Does this result corresponds to a successful lookup (i.e. one where a method has been found?)
+         */
+        boolean isSuccess() {
+            return staticKind != StaticKind.UNDEFINED;
         }
 
-        private boolean canIgnore(Symbol s) {
-            switch (s.kind) {
+        /**
+         * Does this result have given static kind?
+         */
+        boolean hasKind(StaticKind sk) {
+            return this.staticKind == sk;
+        }
+
+        /**
+         * Error recovery helper: can this lookup result be ignored (for the purpose of returning
+         * some 'better' result) ?
+         */
+        boolean canIgnore() {
+            switch (sym.kind) {
                 case ABSENT_MTH:
                     return true;
                 case WRONG_MTH:
                     InapplicableSymbolError errSym =
-                            (InapplicableSymbolError)s.baseSymbol();
+                            (InapplicableSymbolError)sym.baseSymbol();
                     return new Template(MethodCheckDiag.ARITY_MISMATCH.regex())
                             .matches(errSym.errCandidate().snd);
                 case WRONG_MTHS:
                     InapplicableSymbolsError errSyms =
-                            (InapplicableSymbolsError)s.baseSymbol();
+                            (InapplicableSymbolsError)sym.baseSymbol();
                     return errSyms.filterCandidates(errSyms.mapCandidates()).isEmpty();
-                case WRONG_STATICNESS:
-                    return false;
                 default:
                     return false;
             }
         }
+    }
+
+    /**
+     * This abstract class embodies the logic that converts one (bound lookup) or two (unbound lookup)
+     * {@code ReferenceLookupResult} objects into a (@code Symbol), which is then regarded as the
+     * result of method reference resolution.
+     */
+    abstract class ReferenceChooser {
+        /**
+         * Generate a result from a pair of lookup result objects. This method delegates to the
+         * appropriate result generation routine.
+         */
+        Symbol result(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
+            return unboundRes != referenceNotFound ?
+                    unboundResult(boundRes, unboundRes) :
+                    boundResult(boundRes);
+        }
+
+        /**
+         * Generate a symbol from a given bound lookup result.
+         */
+        abstract Symbol boundResult(ReferenceLookupResult boundRes);
+
+        /**
+         * Generate a symbol from a pair of bound/unbound lookup results.
+         */
+        abstract Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes);
+    }
+
+    /**
+     * This chooser implements the selection strategy used during a full lookup; this logic
+     * is described in JLS SE 8 (15.3.2).
+     */
+    ReferenceChooser basicReferenceChooser = new ReferenceChooser() {
+
+        @Override
+        Symbol boundResult(ReferenceLookupResult boundRes) {
+            return !boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC) ?
+                    boundRes.sym : //the search produces a non-static method
+                    new BadMethodReferenceError(boundRes.sym, false);
+        }
+
+        @Override
+        Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
+            if (boundRes.hasKind(StaticKind.STATIC) &&
+                    (!unboundRes.isSuccess() || unboundRes.hasKind(StaticKind.STATIC))) {
+                //the first search produces a static method and no non-static method is applicable
+                //during the second search
+                return boundRes.sym;
+            } else if (unboundRes.hasKind(StaticKind.NON_STATIC) &&
+                    (!boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC))) {
+                //the second search produces a non-static method and no static method is applicable
+                //during the first search
+                return unboundRes.sym;
+            } else if (boundRes.isSuccess() && unboundRes.isSuccess()) {
+                //both searches produce some result; ambiguity (error recovery)
+                return ambiguityError(boundRes.sym, unboundRes.sym);
+            } else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
+                //Both searches failed to produce a result with correct staticness (i.e. first search
+                //produces an non-static method). Alternatively, a given search produced a result
+                //with the right staticness, but the other search has applicable methods with wrong
+                //staticness (error recovery)
+                return new BadMethodReferenceError(boundRes.isSuccess() ? boundRes.sym : unboundRes.sym, true);
+            } else {
+                //both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
+                return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
+                        unboundRes.sym : boundRes.sym;
+            }
+        }
+    };
+
+    /**
+     * This chooser implements the selection strategy used during an arity-based lookup; this logic
+     * is described in JLS SE 8 (15.12.2.1).
+     */
+    ReferenceChooser structuralReferenceChooser = new ReferenceChooser() {
+
+        @Override
+        Symbol boundResult(ReferenceLookupResult boundRes) {
+            return (!boundRes.isSuccess() || !boundRes.hasKind(StaticKind.STATIC)) ?
+                    boundRes.sym : //the search has at least one applicable non-static method
+                    new BadMethodReferenceError(boundRes.sym, false);
+        }
+
+        @Override
+        Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
+            if (boundRes.isSuccess() && !boundRes.hasKind(StaticKind.NON_STATIC)) {
+                //the first serach has at least one applicable static method
+                return boundRes.sym;
+            } else if (unboundRes.isSuccess() && !unboundRes.hasKind(StaticKind.STATIC)) {
+                //the second search has at least one applicable non-static method
+                return unboundRes.sym;
+            } else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
+                //either the first search produces a non-static method, or second search produces
+                //a non-static method (error recovery)
+                return new BadMethodReferenceError(boundRes.isSuccess() ? boundRes.sym : unboundRes.sym, true);
+            } else {
+                //both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
+                return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
+                        unboundRes.sym : boundRes.sym;
+            }
+        }
+    };
 
     /**
      * Helper for defining custom method-like lookup logic; a lookup helper
@@ -3070,22 +3088,7 @@
          * method returns an dummy lookup helper.
          */
         ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
-            //dummy loopkup helper that always return 'methodNotFound'
-            return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
-                @Override
-                ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
-                    return this;
-                }
-                @Override
-                Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
-                    return methodNotFound;
-                }
-                @Override
-                ReferenceKind referenceKind(Symbol sym) {
-                    Assert.error();
-                    return null;
-                }
-            };
+            return null;
         }
 
         /**
@@ -3124,12 +3127,31 @@
 
         @Override
         ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
-            if (TreeInfo.isStaticSelector(referenceTree.expr, names) &&
-                    argtypes.nonEmpty() &&
-                    (argtypes.head.hasTag(NONE) ||
-                    types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head), site))) {
-                return new UnboundMethodReferenceLookupHelper(referenceTree, name,
-                        site, argtypes, typeargtypes, maxPhase);
+            if (TreeInfo.isStaticSelector(referenceTree.expr, names)) {
+                if (argtypes.nonEmpty() &&
+                        (argtypes.head.hasTag(NONE) ||
+                        types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head), site))) {
+                    return new UnboundMethodReferenceLookupHelper(referenceTree, name,
+                            site, argtypes, typeargtypes, maxPhase);
+                } else {
+                    return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
+                        @Override
+                        ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
+                            return this;
+                        }
+
+                        @Override
+                        Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
+                            return methodNotFound;
+                        }
+
+                        @Override
+                        ReferenceKind referenceKind(Symbol sym) {
+                            Assert.error();
+                            return null;
+                        }
+                    };
+                }
             } else {
                 return super.unboundLookup(inferenceContext);
             }
@@ -3231,16 +3253,10 @@
                 findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) :
                 findMethod(env, site, name, argtypes, typeargtypes,
                         phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
-            return sym.kind != MTH ||
-                          site.getEnclosingType().hasTag(NONE) ||
-                          hasEnclosingInstance(env, site) ?
-                          sym : new InvalidSymbolError(MISSING_ENCL, sym, null) {
-                    @Override
-                    JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
-                       return diags.create(dkind, log.currentSource(), pos,
-                            "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType());
-                    }
-                };
+            return (sym.kind != MTH ||
+                    site.getEnclosingType().hasTag(NONE) ||
+                    hasEnclosingInstance(env, site)) ?
+                    sym : new BadConstructorReferenceError(sym);
         }
 
         @Override
@@ -3613,8 +3629,7 @@
                 hasLocation = !location.name.equals(names._this) &&
                         !location.name.equals(names._super);
             }
-            boolean isConstructor = (kind == ABSENT_MTH || kind == WRONG_STATICNESS) &&
-                    name == names.init;
+            boolean isConstructor = name == names.init;
             KindName kindname = isConstructor ? KindName.CONSTRUCTOR : kind.absentKind();
             Name idname = isConstructor ? site.tsym.name : name;
             String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
@@ -4019,13 +4034,13 @@
             Name sname = s1.name;
             if (sname == names.init) sname = s1.owner.name;
             return diags.create(dkind, log.currentSource(),
-                      pos, "ref.ambiguous", sname,
-                      kindName(s1),
-                      s1,
-                      s1.location(site, types),
-                      kindName(s2),
-                      s2,
-                      s2.location(site, types));
+                    pos, "ref.ambiguous", sname,
+                    kindName(s1),
+                    s1,
+                    s1.location(site, types),
+                    kindName(s2),
+                    s2,
+                    s2.location(site, types));
         }
 
         /**
@@ -4108,6 +4123,52 @@
     }
 
     /**
+     * BadMethodReferenceError error class indicating that a method reference symbol has been found,
+     * but with the wrong staticness.
+     */
+    class BadMethodReferenceError extends StaticError {
+
+        boolean unboundLookup;
+
+        public BadMethodReferenceError(Symbol sym, boolean unboundLookup) {
+            super(sym);
+            this.unboundLookup = unboundLookup;
+        }
+
+        @Override
+        JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
+            final String key;
+            if (!unboundLookup) {
+                key = "bad.static.method.in.bound.lookup";
+            } else if (sym.isStatic()) {
+                key = "bad.static.method.in.unbound.lookup";
+            } else {
+                key = "bad.instance.method.in.unbound.lookup";
+            }
+            return sym.kind.isOverloadError() ?
+                    ((ResolveError)sym).getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes) :
+                    diags.create(dkind, log.currentSource(), pos, key, Kinds.kindName(sym), sym);
+        }
+    }
+
+    /**
+     * BadConstructorReferenceError error class indicating that a constructor reference symbol has been found,
+     * but pointing to a class for which an enclosing instance is not available.
+     */
+    class BadConstructorReferenceError extends InvalidSymbolError {
+
+        public BadConstructorReferenceError(Symbol sym) {
+            super(MISSING_ENCL, sym, "BadConstructorReferenceError");
+        }
+
+        @Override
+        JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
+           return diags.create(dkind, log.currentSource(), pos,
+                "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType());
+        }
+    }
+
+    /**
      * Helper class for method resolution diagnostic simplification.
      * Certain resolution diagnostic are rewritten as simpler diagnostic
      * where the enclosing resolution diagnostic (i.e. 'inapplicable method')
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Jan 13 19:13:42 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Jan 15 13:58:11 2015 +0000
@@ -262,9 +262,6 @@
 compiler.misc.static.mref.with.targs=\
     parameterized qualifier on static method reference
 
-compiler.misc.static.bound.mref=\
-    static bound method reference
-
 # 0: symbol
 compiler.err.cant.assign.val.to.final.var=\
     cannot assign a value to final variable {0}
@@ -2050,12 +2047,16 @@
     non-static {0} {1} cannot be referenced from a static context
 
 # 0: symbol kind, 1: symbol
-compiler.misc.non-static.cant.be.ref=\
-    non-static {0} {1} cannot be referenced from a static context
+compiler.misc.bad.static.method.in.unbound.lookup=\
+    unexpected static {0} {1} found in unbound lookup
 
 # 0: symbol kind, 1: symbol
-compiler.misc.static.method.in.unbound.lookup=\
-    static {0} {1} found in unbound lookup
+compiler.misc.bad.instance.method.in.unbound.lookup=\
+    unexpected instance {0} {1} found in unbound lookup
+
+# 0: symbol kind, 1: symbol
+compiler.misc.bad.static.method.in.bound.lookup=\
+    unexpected static {0} {1} found in bound lookup
 
 ## Both arguments ({0}, {1}) are "kindname"s.  {0} is a comma-separated list
 ## of kindnames (the list should be identical to that provided in source.
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/List.java	Tue Jan 13 19:13:42 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/List.java	Thu Jan 15 13:58:11 2015 +0000
@@ -33,6 +33,7 @@
 import java.util.AbstractCollection;
 import java.util.ListIterator;
 import java.util.NoSuchElementException;
+import java.util.stream.Collector;
 
 /** A class for generic linked lists. Links are supposed to be
  *  immutable, the only exception being the incremental construction of
@@ -537,4 +538,14 @@
 
         return Collections.unmodifiableList(a);
     }
+
+    /**
+     * Collect elements into a new list (using a @code{ListBuffer})
+     */
+    public static <Z> Collector<Z, ListBuffer<Z>, List<Z>> collector() {
+        return Collector.of(ListBuffer::new,
+                (buf, el)->buf.add(el),
+                (buf1, buf2)-> { buf1.addAll(buf2); return buf1; },
+                buf->buf.toList());
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/BadInstanceMethodInUnboundLookup.java	Thu Jan 15 13:58:11 2015 +0000
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015, 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.bad.instance.method.in.unbound.lookup
+// key: compiler.misc.invalid.mref
+// key: compiler.err.prob.found.req
+
+class BadInstanceMethodInUnboundLookup {
+
+    interface SAM {
+        void m(Integer u);
+    }
+
+    void f(Integer i) { }
+
+    static void test() {
+        SAM s = BadInstanceMethodInUnboundLookup::f;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/BadStaticMethodInBoundLookup.java	Thu Jan 15 13:58:11 2015 +0000
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015, 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.invalid.mref
+// key: compiler.misc.bad.static.method.in.bound.lookup
+// key: compiler.err.prob.found.req
+
+class BadStaticMethodInBoundLookup {
+
+    Runnable r = new BadStaticMethodInBoundLookup()::m;
+
+    static void m() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/BadStaticMethodInUnboundLookup.java	Thu Jan 15 13:58:11 2015 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015, 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.invalid.mref
+// key: compiler.misc.bad.static.method.in.unbound.lookup
+// key: compiler.err.prob.found.req
+
+class BadStaticMethodInUnboundLookup {
+
+    interface SAM {
+        void m(BadStaticMethodInUnboundLookup m);
+    }
+
+    SAM s = BadStaticMethodInUnboundLookup::m;
+
+    static void m() { }
+}
--- a/langtools/test/tools/javac/diags/examples/NonStaticCantBeRefFragment.java	Tue Jan 13 19:13:42 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, 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.non-static.cant.be.ref
-// key: compiler.err.invalid.mref
-
-class NonStaticCantBeRefFragment {
-
-    interface SAM {
-        void m(Integer u);
-    }
-
-    void f(Integer i) { }
-
-    static void test() {
-        SAM s = NonStaticCantBeRefFragment::f;
-    }
-}
--- a/langtools/test/tools/javac/diags/examples/StaticBoundMref.java	Tue Jan 13 19:13:42 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2012, 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.err.invalid.mref
-// key: compiler.misc.static.bound.mref
-
-class StaticBoundMref {
-
-    Runnable r = new StaticBoundMref()::m;
-
-    static void m() { }
-}
--- a/langtools/test/tools/javac/diags/examples/StaticMethodInUnboundLookup.java	Tue Jan 13 19:13:42 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2013, 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.err.invalid.mref
-// key: compiler.misc.static.method.in.unbound.lookup
-
-class StaticBoundMref {
-
-    interface SAM {
-        void m(StaticBoundMref m);
-    }
-
-    SAM s = StaticBoundMref::m;
-
-    static void m() { }
-}
--- a/langtools/test/tools/javac/lambda/MethodReference22.out	Tue Jan 13 19:13:42 2015 +0100
+++ b/langtools/test/tools/javac/lambda/MethodReference22.out	Thu Jan 15 13:58:11 2015 +0000
@@ -1,9 +1,9 @@
-MethodReference22.java:40:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m1(java.lang.String))
-MethodReference22.java:41:9: compiler.err.cant.apply.symbol: kindname.method, call1, MethodReference22.SAM1, @999, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.mref))
-MethodReference22.java:46:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String))
-MethodReference22.java:47:9: compiler.err.cant.apply.symbol: kindname.method, call1, MethodReference22.SAM1, @1270, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.mref))
-MethodReference22.java:55:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m3(MethodReference22,java.lang.String))
-MethodReference22.java:56:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1574, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.mref))
+MethodReference22.java:40:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m1(java.lang.String)))
+MethodReference22.java:41:9: compiler.err.cant.apply.symbol: kindname.method, call1, MethodReference22.SAM1, @999, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m1(java.lang.String)))
+MethodReference22.java:46:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m4(java.lang.String)))
+MethodReference22.java:47:9: compiler.err.cant.apply.symbol: kindname.method, call1, MethodReference22.SAM1, @1270, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m4(java.lang.String)))
+MethodReference22.java:55:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference22,java.lang.String), MethodReference22, kindname.method, m3(java.lang.String), MethodReference22))
+MethodReference22.java:56:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1574, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m3(MethodReference22,java.lang.String)))
 MethodReference22.java:57:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22))
 MethodReference22.java:58:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1667, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22)))
 MethodReference22.java:63:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22
--- a/langtools/test/tools/javac/lambda/MethodReference28.out	Tue Jan 13 19:13:42 2015 +0100
+++ b/langtools/test/tools/javac/lambda/MethodReference28.out	Thu Jan 15 13:58:11 2015 +0000
@@ -1,7 +1,7 @@
 MethodReference28.java:31:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, static_m2, java.lang.Integer,java.lang.Integer, int, kindname.class, MethodReference28, (compiler.misc.arg.length.mismatch)))
 MethodReference28.java:32:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, static_m3, java.lang.String, int, kindname.class, MethodReference28, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String))))
 MethodReference28.java:33:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, static_m4, java.lang.String[], int, kindname.class, MethodReference28, (compiler.misc.varargs.argument.mismatch: (compiler.misc.inconvertible.types: int, java.lang.String))))
-MethodReference28.java:37:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m1(java.lang.Integer))
+MethodReference28.java:37:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m1(java.lang.Integer)))
 MethodReference28.java:38:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m2, java.lang.Integer,java.lang.Integer, int, kindname.class, MethodReference28, (compiler.misc.arg.length.mismatch)))
 MethodReference28.java:39:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m3, java.lang.String, int, kindname.class, MethodReference28, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String))))
 MethodReference28.java:40:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m4, java.lang.String[], int, kindname.class, MethodReference28, (compiler.misc.varargs.argument.mismatch: (compiler.misc.inconvertible.types: int, java.lang.String))))
--- a/langtools/test/tools/javac/lambda/MethodReference51.out	Tue Jan 13 19:13:42 2015 +0100
+++ b/langtools/test/tools/javac/lambda/MethodReference51.out	Thu Jan 15 13:58:11 2015 +0000
@@ -2,6 +2,6 @@
 MethodReference51.java:40:21: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, f, java.lang.String, int, kindname.class, MethodReference51, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String))))
 MethodReference51.java:41:21: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbols: kindname.method, g, int,{(compiler.misc.inapplicable.method: kindname.method, MethodReference51, g(java.lang.Integer,java.lang.Number), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, MethodReference51, g(java.lang.Number,java.lang.Integer), (compiler.misc.arg.length.mismatch))}))
 MethodReference51.java:42:32: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: g, kindname.method, g(java.lang.Integer,java.lang.Number), MethodReference51, kindname.method, g(java.lang.Number,java.lang.Integer), MethodReference51))
-MethodReference51.java:43:21: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, h(int))
+MethodReference51.java:43:21: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, h(int)))
 MethodReference51.java:44:21: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.not.def.access.class.intf.cant.access: j(int), MethodReference51.Foo))
 6 errors
--- a/langtools/test/tools/javac/lambda/MethodReference55.out	Tue Jan 13 19:13:42 2015 +0100
+++ b/langtools/test/tools/javac/lambda/MethodReference55.out	Thu Jan 15 13:58:11 2015 +0000
@@ -1,3 +1,3 @@
-MethodReference55.java:36:11: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.bound.mref)
-MethodReference55.java:39:11: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.bound.mref)
+MethodReference55.java:36:11: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.static.method.in.bound.lookup: kindname.method, m(java.lang.Object)))
+MethodReference55.java:39:9: compiler.err.cant.apply.symbol: kindname.method, g, MethodReference55.V, @1384, kindname.class, MethodReference55<X>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.static.method.in.bound.lookup: kindname.method, m(java.lang.Object))))
 2 errors
--- a/langtools/test/tools/javac/lambda/MethodReference68.out	Tue Jan 13 19:13:42 2015 +0100
+++ b/langtools/test/tools/javac/lambda/MethodReference68.out	Thu Jan 15 13:58:11 2015 +0000
@@ -1,3 +1,2 @@
 MethodReference68.java:21:10: compiler.err.cant.apply.symbol: kindname.method, g, MethodReference68.F<Z>,Z[], @493,int, kindname.class, MethodReference68, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, MethodReference68.Foo,java.lang.Object)
-MethodReference68.java:21:12: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, getName())
-2 errors
+1 error
--- a/langtools/test/tools/javac/lambda/MethodReference73.out	Tue Jan 13 19:13:42 2015 +0100
+++ b/langtools/test/tools/javac/lambda/MethodReference73.out	Thu Jan 15 13:58:11 2015 +0000
@@ -2,12 +2,12 @@
 MethodReference73.java:90:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m2, kindname.method, m2(MethodReference73,java.lang.String), MethodReference73, kindname.method, m2(java.lang.String), MethodReference73))
 MethodReference73.java:91:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference73,java.lang.String), MethodReference73, kindname.method, m3(java.lang.String), MethodReference73))
 MethodReference73.java:92:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference73,java.lang.String), MethodReference73, kindname.method, m4(java.lang.String), MethodReference73))
-MethodReference73.java:100:18: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m9(MethodReference73,java.lang.String))
-MethodReference73.java:101:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m10(MethodReference73,java.lang.String))
-MethodReference73.java:102:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.method.in.unbound.lookup: kindname.method, m11(java.lang.String))
-MethodReference73.java:103:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.method.in.unbound.lookup: kindname.method, m12(java.lang.String))
-MethodReference73.java:104:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m13(MethodReference73,java.lang.String))
-MethodReference73.java:105:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.method.in.unbound.lookup: kindname.method, m14(java.lang.String))
-MethodReference73.java:106:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m15(MethodReference73,java.lang.String))
+MethodReference73.java:100:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m9, kindname.method, m9(MethodReference73,java.lang.String), MethodReference73, kindname.method, m9(java.lang.String), MethodReference73))
+MethodReference73.java:101:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m10(MethodReference73,java.lang.String)))
+MethodReference73.java:102:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m11, kindname.method, m11(MethodReference73,java.lang.String), MethodReference73, kindname.method, m11(java.lang.String), MethodReference73))
+MethodReference73.java:103:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.static.method.in.unbound.lookup: kindname.method, m12(java.lang.String)))
+MethodReference73.java:104:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m13(MethodReference73,java.lang.String)))
+MethodReference73.java:105:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.static.method.in.unbound.lookup: kindname.method, m14(java.lang.String)))
+MethodReference73.java:106:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m15, kindname.method, m15(MethodReference73,java.lang.String), MethodReference73, kindname.method, m15(java.lang.String), MethodReference73))
 MethodReference73.java:108:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbols: kindname.method, m16, MethodReference73,java.lang.String,{(compiler.misc.inapplicable.method: kindname.method, MethodReference73, m16(MethodReference73,java.lang.String,int), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, MethodReference73, m16(java.lang.String,int), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: MethodReference73, java.lang.String)))}))
 12 errors
--- a/langtools/test/tools/javac/lambda/TargetType60.out	Tue Jan 13 19:13:42 2015 +0100
+++ b/langtools/test/tools/javac/lambda/TargetType60.out	Thu Jan 15 13:58:11 2015 +0000
@@ -1,6 +1,6 @@
 TargetType60.java:54:21: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType60.Sam0), TargetType60, kindname.method, <U>g(TargetType60.Sam1<U>), TargetType60
 TargetType60.java:55:21: compiler.err.ref.ambiguous: g, kindname.method, <U>g(TargetType60.Sam1<U>), TargetType60, kindname.method, <U>g(TargetType60.Sam2<U,java.lang.String>), TargetType60
-TargetType60.java:61:27: compiler.err.cant.apply.symbols: kindname.method, u, @1639,{(compiler.misc.inapplicable.method: kindname.method, TargetType60, <U>u(TargetType60.Sam1<U>), (compiler.misc.infer.no.conforming.assignment.exists: U, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, n2, TargetType60,java.lang.String, U, kindname.class, TargetType60, (compiler.misc.arg.length.mismatch))))),(compiler.misc.inapplicable.method: kindname.method, TargetType60, <U>u(TargetType60.Sam2<U,java.lang.String>), (compiler.misc.infer.no.conforming.assignment.exists: U, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.resolve.location.args: kindname.method, n2, , U,java.lang.String, (compiler.misc.location: kindname.class, TargetType60, null)))))}
+TargetType60.java:61:27: compiler.err.cant.apply.symbols: kindname.method, u, @1639,{(compiler.misc.inapplicable.method: kindname.method, TargetType60, <U>u(TargetType60.Sam1<U>), (compiler.misc.infer.no.conforming.assignment.exists: U, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, n2, TargetType60,java.lang.String, U, kindname.class, TargetType60, (compiler.misc.arg.length.mismatch))))),(compiler.misc.inapplicable.method: kindname.method, TargetType60, <U>u(TargetType60.Sam2<U,java.lang.String>), (compiler.misc.infer.no.conforming.assignment.exists: U, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, n2(TargetType60,java.lang.String)))))}
 TargetType60.java:62:27: compiler.err.ref.ambiguous: u, kindname.method, <U>u(TargetType60.Sam1<U>), TargetType60, kindname.method, <U>u(TargetType60.Sam2<U,java.lang.String>), TargetType60
 TargetType60.java:63:27: compiler.err.ref.ambiguous: u, kindname.method, <U>u(TargetType60.Sam1<U>), TargetType60, kindname.method, <U>u(TargetType60.Sam2<U,java.lang.String>), TargetType60
 5 errors