From 1ecce1151253a568713892fe57750b3da7142141 Mon Sep 17 00:00:00 2001 From: vromero Date: Fri, 15 Nov 2013 11:08:12 +0000 Subject: 8026231: Look at 'static' flag when checking method references Reviewed-by: jjg, dlsmith --- .../classes/com/sun/tools/javac/code/Kinds.java | 25 +- .../classes/com/sun/tools/javac/comp/Attr.java | 28 +- .../com/sun/tools/javac/comp/DeferredAttr.java | 18 +- .../classes/com/sun/tools/javac/comp/Resolve.java | 284 ++++++++++++++++++--- test/tools/javac/lambda/MethodReference22.java | 20 +- test/tools/javac/lambda/MethodReference22.out | 22 +- test/tools/javac/lambda/MethodReference51.java | 12 +- test/tools/javac/lambda/MethodReference68.out | 3 +- test/tools/javac/lambda/MethodReference73.java | 110 ++++++++ test/tools/javac/lambda/MethodReference73.out | 13 + test/tools/javac/lambda/TargetType60.java | 2 +- test/tools/javac/lambda/TargetType60.out | 6 +- 12 files changed, 424 insertions(+), 119 deletions(-) create mode 100644 test/tools/javac/lambda/MethodReference73.java create mode 100644 test/tools/javac/lambda/MethodReference73.out diff --git a/src/share/classes/com/sun/tools/javac/code/Kinds.java b/src/share/classes/com/sun/tools/javac/code/Kinds.java index 1ea1d4e4..2325d94a 100644 --- a/src/share/classes/com/sun/tools/javac/code/Kinds.java +++ b/src/share/classes/com/sun/tools/javac/code/Kinds.java @@ -87,16 +87,17 @@ public class Kinds { /** Kinds for erroneous symbols that complement the above */ - public static final int ERRONEOUS = 1 << 7; - public static final int AMBIGUOUS = ERRONEOUS+1; // ambiguous reference - public static final int HIDDEN = ERRONEOUS+2; // hidden method or field - public static final int STATICERR = ERRONEOUS+3; // nonstatic member from static context - public static final int MISSING_ENCL = ERRONEOUS+4; // missing enclosing class - public static final int ABSENT_VAR = ERRONEOUS+5; // missing variable - public static final int WRONG_MTHS = ERRONEOUS+6; // methods with wrong arguments - public static final int WRONG_MTH = ERRONEOUS+7; // one method with wrong arguments - public static final int ABSENT_MTH = ERRONEOUS+8; // missing method - public static final int ABSENT_TYP = ERRONEOUS+9; // missing type + public static final int ERRONEOUS = 1 << 7; + public static final int AMBIGUOUS = ERRONEOUS + 1; // ambiguous reference + public static final int HIDDEN = ERRONEOUS + 2; // hidden method or field + public static final int STATICERR = ERRONEOUS + 3; // nonstatic member from static context + public static final int MISSING_ENCL = ERRONEOUS + 4; // missing enclosing class + public static final int ABSENT_VAR = ERRONEOUS + 5; // missing variable + public static final int WRONG_MTHS = ERRONEOUS + 6; // methods with wrong arguments + public static final int WRONG_MTH = ERRONEOUS + 7; // one method with wrong arguments + public static final int ABSENT_MTH = ERRONEOUS + 8; // missing method + public static final int ABSENT_TYP = ERRONEOUS + 9; // missing type + public static final int WRONG_STATICNESS = ERRONEOUS + 10; // wrong staticness for method references public enum KindName implements Formattable { ANNOTATION("kindname.annotation"), @@ -231,14 +232,14 @@ public class Kinds { return KindName.CLASS; } - /** A KindName representing the kind of a a missing symbol, given an + /** A KindName representing the kind of a missing symbol, given an * error kind. * */ public static KindName absentKind(int kind) { switch (kind) { case ABSENT_VAR: return KindName.VAR; - case WRONG_MTHS: case WRONG_MTH: case ABSENT_MTH: + case WRONG_MTHS: case WRONG_MTH: case ABSENT_MTH: case WRONG_STATICNESS: return KindName.METHOD; case ABSENT_TYP: return KindName.CLASS; diff --git a/src/share/classes/com/sun/tools/javac/comp/Attr.java b/src/share/classes/com/sun/tools/javac/comp/Attr.java index 822dbb6f..bc02d7b2 100644 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -2697,9 +2697,10 @@ public class Attr extends JCTree.Visitor { Pair refResult = null; List saved_undet = resultInfo.checkContext.inferenceContext().save(); try { - refResult = rs.resolveMemberReference(that.pos(), localEnv, that, that.expr.type, - that.name, argtypes, typeargtypes, true, referenceCheck, - resultInfo.checkContext.inferenceContext()); + refResult = rs.resolveMemberReference(localEnv, that, that.expr.type, + that.name, argtypes, typeargtypes, referenceCheck, + resultInfo.checkContext.inferenceContext(), + resultInfo.checkContext.deferredAttrContext().mode); } finally { resultInfo.checkContext.inferenceContext().rollback(saved_undet); } @@ -2719,6 +2720,7 @@ public class Attr extends JCTree.Visitor { case HIDDEN: case STATICERR: case MISSING_ENCL: + case WRONG_STATICNESS: targetError = true; break; default: @@ -2770,26 +2772,6 @@ public class Attr extends JCTree.Visitor { chk.checkRaw(that.expr, localEnv); } - if (!that.kind.isUnbound() && - that.getMode() == ReferenceMode.INVOKE && - TreeInfo.isStaticSelector(that.expr, names) && - !that.sym.isStatic()) { - log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()), - diags.fragment("non-static.cant.be.ref", Kinds.kindName(refSym), refSym)); - result = that.type = types.createErrorType(target); - return; - } - - if (that.kind.isUnbound() && - that.getMode() == ReferenceMode.INVOKE && - TreeInfo.isStaticSelector(that.expr, names) && - that.sym.isStatic()) { - log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()), - diags.fragment("static.method.in.unbound.lookup", Kinds.kindName(refSym), refSym)); - result = that.type = types.createErrorType(target); - return; - } - if (that.sym.isStatic() && TreeInfo.isStaticSelector(that.expr, names) && exprType.getTypeArguments().nonEmpty()) { //static ref with class type-args diff --git a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java index 6357419c..c37841c8 100644 --- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java +++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java @@ -643,15 +643,16 @@ public class DeferredAttr extends JCTree.Visitor { } JCMemberReference mref2 = new TreeCopier(make).copy(tree); mref2.expr = exprTree; - Pair lookupRes = - rs.resolveMemberReference(tree, localEnv, mref2, exprTree.type, - tree.name, argtypes.toList(), null, true, rs.arityMethodCheck, inferenceContext); - switch (lookupRes.fst.kind) { + Symbol lookupSym = + rs.resolveMemberReferenceByArity(localEnv, mref2, exprTree.type, + tree.name, argtypes.toList(), inferenceContext); + switch (lookupSym.kind) { //note: as argtypes are erroneous types, type-errors must //have been caused by arity mismatch case Kinds.ABSENT_MTH: case Kinds.WRONG_MTH: case Kinds.WRONG_MTHS: + case Kinds.WRONG_STATICNESS: checkContext.report(tree, diags.fragment("incompatible.arg.types.in.mref")); } } @@ -1037,11 +1038,10 @@ public class DeferredAttr extends JCTree.Visitor { attr.memberReferenceQualifierResult(tree)); JCMemberReference mref2 = new TreeCopier(make).copy(tree); mref2.expr = exprTree; - Pair lookupRes = - rs.resolveMemberReference(tree, localEnv, mref2, exprTree.type, - tree.name, List.nil(), null, true, rs.nilMethodCheck, - infer.emptyContext); - Symbol res = tree.sym = lookupRes.fst; + Symbol res = + rs.getMemberReference(tree, localEnv, mref2, + exprTree.type, tree.name); + tree.sym = res; if (res.kind >= Kinds.ERRONEOUS || res.type.hasTag(FORALL) || (res.flags() & Flags.VARARGS) != 0 || diff --git a/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/share/classes/com/sun/tools/javac/comp/Resolve.java index b5c0cfe6..0664eeb3 100644 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -25,6 +25,7 @@ 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.Symbol.*; @@ -110,6 +111,9 @@ public class Resolve { SymbolNotFoundError(ABSENT_VAR); methodNotFound = new SymbolNotFoundError(ABSENT_MTH); + methodWithCorrectStaticnessNotFound = new + SymbolNotFoundError(WRONG_STATICNESS, + "method found has incorrect staticness"); typeNotFound = new SymbolNotFoundError(ABSENT_TYP); @@ -144,6 +148,7 @@ public class Resolve { */ private final SymbolNotFoundError varNotFound; private final SymbolNotFoundError methodNotFound; + private final SymbolNotFoundError methodWithCorrectStaticnessNotFound; private final SymbolNotFoundError typeNotFound; public static Resolve instance(Context context) { @@ -868,6 +873,12 @@ public class Resolve { } }; + /** + * This class handles method reference applicability checks; since during + * these checks it's sometime possible to have inference variables on + * the actual argument types list, the method applicability check must be + * extended so that inference variables are 'opened' as needed. + */ class MethodReferenceCheck extends AbstractMethodCheck { InferenceContext pendingInferenceContext; @@ -2674,6 +2685,97 @@ public class Resolve { return resolveOperator(pos, optag, env, List.of(left, right)); } + Symbol getMemberReference(DiagnosticPosition pos, + Env env, + JCMemberReference referenceTree, + Type site, + Name name) { + + site = types.capture(site); + + ReferenceLookupHelper lookupHelper = makeReferenceLookupHelper( + referenceTree, site, name, List.nil(), null, VARARITY); + + Env newEnv = env.dup(env.tree, env.info.dup()); + Symbol sym = lookupMethod(newEnv, env.tree.pos(), site.tsym, + nilMethodCheck, lookupHelper); + + env.info.pendingResolutionPhase = newEnv.info.pendingResolutionPhase; + + return sym; + } + + ReferenceLookupHelper makeReferenceLookupHelper(JCMemberReference referenceTree, + Type site, + Name name, + List argtypes, + List typeargtypes, + MethodResolutionPhase maxPhase) { + ReferenceLookupHelper result; + if (!name.equals(names.init)) { + //method reference + result = + new MethodReferenceLookupHelper(referenceTree, name, 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); + } + } + return result; + } + + Symbol resolveMemberReferenceByArity(Env env, + JCMemberReference referenceTree, + Type site, + Name name, + List 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 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 < ERRONEOUS) { + boundSym = methodNotFound; + } + + //step 2 - unbound lookup + Symbol unboundSym = methodNotFound; + ReferenceLookupHelper unboundLookupHelper = null; + Env 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 < ERRONEOUS) { + unboundSym = methodNotFound; + } + } + + //merge results + Symbol bestSym = choose(boundSym, unboundSym); + env.info.pendingResolutionPhase = bestSym == unboundSym ? + unboundEnv.info.pendingResolutionPhase : + boundEnv.info.pendingResolutionPhase; + + return bestSym; + } + /** * Resolution of member references is typically done as a single * overload resolution step, where the argument types A are inferred from @@ -2700,47 +2802,118 @@ public class Resolve { * the type T might be dynamically inferred (i.e. if constructor reference * has a raw qualifier). */ - Pair resolveMemberReference(DiagnosticPosition pos, - Env env, + Pair resolveMemberReference(Env env, JCMemberReference referenceTree, Type site, - Name name, List argtypes, + Name name, + List argtypes, List typeargtypes, - boolean boxingAllowed, MethodCheck methodCheck, - InferenceContext inferenceContext) { - MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC; + InferenceContext inferenceContext, + AttrMode mode) { site = types.capture(site); - - ReferenceLookupHelper boundLookupHelper; - if (!name.equals(names.init)) { - //method reference - boundLookupHelper = - new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase); - } else if (site.hasTag(ARRAY)) { - //array constructor reference - boundLookupHelper = - new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase); - } else { - //class constructor reference - boundLookupHelper = - new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase); - } + ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper( + referenceTree, site, name, argtypes, typeargtypes, VARARITY); //step 1 - bound lookup Env boundEnv = env.dup(env.tree, env.info.dup()); - Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, methodCheck, boundLookupHelper); + Symbol origBoundSym; + boolean staticErrorForBound = false; + MethodResolutionContext boundSearchResolveContext = new MethodResolutionContext(); + boundSearchResolveContext.methodCheck = methodCheck; + Symbol boundSym = origBoundSym = 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 < ERRONEOUS) { + boundSym = methodWithCorrectStaticnessNotFound; + } + } + } else if (boundSym.kind < ERRONEOUS) { + boundSearchResultKind = SearchResultKind.GOOD_MATCH; + } + } + } //step 2 - unbound lookup - ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext); + Symbol origUnboundSym = null; + Symbol unboundSym = methodNotFound; + ReferenceLookupHelper unboundLookupHelper = null; Env unboundEnv = env.dup(env.tree, env.info.dup()); - Symbol unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, methodCheck, unboundLookupHelper); + SearchResultKind unboundSearchResultKind = SearchResultKind.NOT_APPLICABLE_MATCH; + boolean staticErrorForUnbound = false; + if (isStaticSelector) { + unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext); + MethodResolutionContext unboundSearchResolveContext = + new MethodResolutionContext(); + unboundSearchResolveContext.methodCheck = methodCheck; + unboundSym = origUnboundSym = 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 < ERRONEOUS) { + unboundSym = methodWithCorrectStaticnessNotFound; + } + } + } else if (unboundSym.kind < ERRONEOUS) { + unboundSearchResultKind = SearchResultKind.GOOD_MATCH; + } + } + } + } //merge results Pair res; Symbol bestSym = choose(boundSym, unboundSym); - res = new Pair(bestSym, + if (bestSym.kind < ERRONEOUS && (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)); + } + res = new Pair<>(bestSym, bestSym == unboundSym ? unboundLookupHelper : boundLookupHelper); env.info.pendingResolutionPhase = bestSym == unboundSym ? unboundEnv.info.pendingResolutionPhase : @@ -2748,18 +2921,42 @@ public class Resolve { 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; + } + } + } + return false; + } + //where - private Symbol choose(Symbol s1, Symbol s2) { - if (lookupSuccess(s1) && lookupSuccess(s2)) { - return ambiguityError(s1, s2); - } else if (lookupSuccess(s1) || - (canIgnore(s2) && !canIgnore(s1))) { - return s1; - } else if (lookupSuccess(s2) || - (canIgnore(s1) && !canIgnore(s2))) { - return s2; + 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 s1; + return boundSym; } } @@ -2780,6 +2977,8 @@ public class Resolve { InapplicableSymbolsError errSyms = (InapplicableSymbolsError)s; return errSyms.filterCandidates(errSyms.mapCandidates()).isEmpty(); + case WRONG_STATICNESS: + return false; default: return false; } @@ -2894,7 +3093,6 @@ public class Resolve { List argtypes, List typeargtypes, MethodResolutionPhase maxPhase) { super(name, site, argtypes, typeargtypes, maxPhase); this.referenceTree = referenceTree; - } /** @@ -3324,6 +3522,11 @@ public class Resolve { return false; } + @Override + public boolean isStatic() { + return false; + } + /** * Create an external representation for this erroneous symbol to be * used during attribution - by default this returns the symbol of a @@ -3398,7 +3601,11 @@ public class Resolve { class SymbolNotFoundError extends ResolveError { SymbolNotFoundError(int kind) { - super(kind, "symbol not found error"); + this(kind, "symbol not found error"); + } + + SymbolNotFoundError(int kind, String debugName) { + super(kind, debugName); } @Override @@ -3436,7 +3643,8 @@ public class Resolve { hasLocation = !location.name.equals(names._this) && !location.name.equals(names._super); } - boolean isConstructor = kind == ABSENT_MTH && name == names.init; + boolean isConstructor = (kind == ABSENT_MTH || kind == WRONG_STATICNESS) && + name == names.init; KindName kindname = isConstructor ? KindName.CONSTRUCTOR : absentKind(kind); Name idname = isConstructor ? site.tsym.name : name; String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation); diff --git a/test/tools/javac/lambda/MethodReference22.java b/test/tools/javac/lambda/MethodReference22.java index 9517ee00..094ef893 100644 --- a/test/tools/javac/lambda/MethodReference22.java +++ b/test/tools/javac/lambda/MethodReference22.java @@ -48,19 +48,19 @@ class MethodReference22 { } static void test2() { - SAM2 s1 = MethodReference22::m1; //ambiguous - call2(MethodReference22::m1); //ambiguous - SAM2 s2 = MethodReference22::m2; //ambiguous - call2(MethodReference22::m2); //ambiguous - SAM2 s3 = MethodReference22::m3; //ambiguous - call2(MethodReference22::m3); //ambiguous - SAM2 s4 = MethodReference22::m4; //ambiguous - call2(MethodReference22::m4); //ambiguous + SAM2 s1 = MethodReference22::m1; //ok + call2(MethodReference22::m1); //ok + SAM2 s2 = MethodReference22::m2; //ok + call2(MethodReference22::m2); //ok + SAM2 s3 = MethodReference22::m3; //fail + call2(MethodReference22::m3); //fail + SAM2 s4 = MethodReference22::m4; //fail + call2(MethodReference22::m4); //fail } static void test3() { - call3(MethodReference22::m1); //fail - call3(MethodReference22::m2); //ok + call3(MethodReference22::m1); //ok + call3(MethodReference22::m2); //ambiguous call3(MethodReference22::m3); //ok call3(MethodReference22::m4); //fail } diff --git a/test/tools/javac/lambda/MethodReference22.out b/test/tools/javac/lambda/MethodReference22.out index dfd2ebe5..4a857282 100644 --- a/test/tools/javac/lambda/MethodReference22.out +++ b/test/tools/javac/lambda/MethodReference22.out @@ -1,19 +1,11 @@ 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:15: 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:15: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String)) -MethodReference22.java:51:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m1, kindname.method, m1(MethodReference22,java.lang.String), MethodReference22, kindname.method, m1(java.lang.String), MethodReference22)) -MethodReference22.java:52:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1401, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m1, kindname.method, m1(MethodReference22,java.lang.String), MethodReference22, kindname.method, m1(java.lang.String), MethodReference22))) -MethodReference22.java:53:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m2, kindname.method, m2(MethodReference22,java.lang.String), MethodReference22, kindname.method, m2(java.lang.String), MethodReference22)) -MethodReference22.java:54:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1504, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m2, kindname.method, m2(MethodReference22,java.lang.String), MethodReference22, kindname.method, m2(java.lang.String), MethodReference22))) -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:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1607, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (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: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: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, @1710, 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:62:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22 -MethodReference22.java:62:15: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m1(java.lang.String)) +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 -MethodReference22.java:64:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22 -MethodReference22.java:65:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22 -MethodReference22.java:65:15: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String)) -18 errors +MethodReference22.java:65:14: compiler.err.cant.apply.symbol: kindname.method, call3, MethodReference22.SAM2, @1881, 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))) +10 errors diff --git a/test/tools/javac/lambda/MethodReference51.java b/test/tools/javac/lambda/MethodReference51.java index 1ce3d74f..be0c65b0 100644 --- a/test/tools/javac/lambda/MethodReference51.java +++ b/test/tools/javac/lambda/MethodReference51.java @@ -36,11 +36,11 @@ class TestMethodReference51 { static void test() { - IntSam s1 = MethodReference51::unknown; //method not found - IntSam s2 = MethodReference51::f; //inapplicable method - IntSam s3 = MethodReference51::g; //inapplicable methods - IntegerIntegerSam s4 = MethodReference51::g; //ambiguous - IntSam s5 = MethodReference51::h; //static error - IntSam s6 = MethodReference51.foo::j; //inaccessible method + IntSam s1 = MethodReference51::unknown; //fail + IntSam s2 = MethodReference51::f; //fail + IntSam s3 = MethodReference51::g; //fail + IntegerIntegerSam s4 = MethodReference51::g; //fail + IntSam s5 = MethodReference51::h; //fail + IntSam s6 = MethodReference51.foo::j; //fail } } diff --git a/test/tools/javac/lambda/MethodReference68.out b/test/tools/javac/lambda/MethodReference68.out index 2db24d17..1319f33a 100644 --- a/test/tools/javac/lambda/MethodReference68.out +++ b/test/tools/javac/lambda/MethodReference68.out @@ -1,2 +1,3 @@ MethodReference68.java:21:10: compiler.err.cant.apply.symbol: kindname.method, g, MethodReference68.F,Z[], @493,int, kindname.class, MethodReference68, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, MethodReference68.Foo,java.lang.Object) -1 error +MethodReference68.java:21:12: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, getName()) +2 errors diff --git a/test/tools/javac/lambda/MethodReference73.java b/test/tools/javac/lambda/MethodReference73.java new file mode 100644 index 00000000..a65d85bc --- /dev/null +++ b/test/tools/javac/lambda/MethodReference73.java @@ -0,0 +1,110 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8026231 + * @summary Look at 'static' flag when checking method references + * @compile/fail/ref=MethodReference73.out -XDrawDiagnostics MethodReference73.java + */ + +public class MethodReference73 { + + interface SAM { + void m(MethodReference73 rec, String x); + } + + void m1(MethodReference73 rec, String x) {} + static void m1(MethodReference73 rec, Object x) {} + void m1(String x) {} + + static void m2(MethodReference73 rec, String x) {} + void m2(Object x) {} + static void m2(String x) {} + + static void m3(MethodReference73 rec, String x) {} + void m3(String x) {} + + void m4(MethodReference73 rec, String x) {} + static void m4(MethodReference73 rec, Object x) {} + static void m4(String x) {} + void m4(Object x) {} + + static void m5(MethodReference73 rec, String x) {} + static void m5(String x) {} + + static void m6(MethodReference73 rec, String x) {} + void m6(String x, int i) {} + + void m7(MethodReference73 rec, String x) {} + void m7(String x) {} + + static void m8(MethodReference73 rec, String x, int i) {} + void m8(String x) {} + + void m9(MethodReference73 rec, String x) {} + static void m9(MethodReference73 rec, Object x) {} + static void m9(String x) {} + + void m10(MethodReference73 rec, String x) {} + static void m10(MethodReference73 rec, Object x) {} + void m10(String x, int i) {} + + void m11(MethodReference73 rec, String x) {} + void m11(Object x) {} + static void m11(String x) {} + + static void m12(MethodReference73 rec, String x, int i) {} + void m12(Object x) {} + static void m12(String x) {} + + void m13(MethodReference73 rec, String x) {} + void m13(String x, int i) {} + + static void m14(MethodReference73 rec, String x, int i) {} + static void m14(String x) {} + + void m15(MethodReference73 rec, String x) {} + static void m15(String x) {} + + static void m16(MethodReference73 rec, String x, int i) {} + void m16(String x, int i) {} + + /** For method references with a type selector two searches are performed. + * Each of them may yield one of the following results: + * I) a good match + * II) a bad match more specific than a good match + * III) a bad match with no good matches + * IV) no applicable method found + * + * Whether a match is considered to be good or not depends on the staticness + * of the matched method. The expected result of the first search is a static + * method. The expected result of the second search is an instance method. + * + * If the most specific method has the wrong staticness but there is an + * applicable method with the right staticness then we have the (II) case. + * The (III) case is reserved for those cases when the most specific method + * has the wrong staticness but there is no applicable method with the right + * staticness. + */ + + static void test() { + SAM s1 = MethodReference73::m1; //(II, I) ambiguous + SAM s2 = MethodReference73::m2; //(I, II) ambiguous + SAM s3 = MethodReference73::m3; //(I, I) ambiguous + SAM s4 = MethodReference73::m4; //(II, II) ambiguous + + SAM s5 = MethodReference73::m5; //(I, III) first search's result gets selected + SAM s6 = MethodReference73::m6; //(I, IV) first search's result gets selected + + SAM s7 = MethodReference73::m7; //(III, I) second search's result gets selected + SAM s8 = MethodReference73::m8; //(IV, I) second search's result gets selected + + SAM s9 = MethodReference73::m9; //(II, III) method matched by first search has the wrong staticness + SAM s10 = MethodReference73::m10; //(II, IV) method matched by first search has the wrong staticness + SAM s11 = MethodReference73::m11; //(III, II) method matched by second search has the wrong staticness + SAM s12 = MethodReference73::m12; //(IV, II) method matched by second search has the wrong staticness + SAM s13 = MethodReference73::m13; //(III, IV) method matched by first search has the wrong staticness + SAM s14 = MethodReference73::m14; //(IV, III) method matched by second search has the wrong staticness + SAM s15 = MethodReference73::m15; //(III, III) method matched by first search has the wrong staticness + + SAM s16 = MethodReference73::m16; //(IV, IV) incompatible types, invalid method reference + } +} diff --git a/test/tools/javac/lambda/MethodReference73.out b/test/tools/javac/lambda/MethodReference73.out new file mode 100644 index 00000000..717c414a --- /dev/null +++ b/test/tools/javac/lambda/MethodReference73.out @@ -0,0 +1,13 @@ +MethodReference73.java:89:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m1, kindname.method, m1(MethodReference73,java.lang.String), MethodReference73, kindname.method, m1(java.lang.String), MethodReference73)) +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: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 diff --git a/test/tools/javac/lambda/TargetType60.java b/test/tools/javac/lambda/TargetType60.java index 0506f39a..b5acd32d 100644 --- a/test/tools/javac/lambda/TargetType60.java +++ b/test/tools/javac/lambda/TargetType60.java @@ -57,7 +57,7 @@ class TargetType60 { static void testUnbound() { TargetType60 s1 = u(TargetType60::n0); //ok - resolves to u(Sam1) - TargetType60 s2 = u(TargetType60::n1); //ambiguous (u(Sam1), u(Sam2) apply) + TargetType60 s2 = u(TargetType60::n1); //ok - resolves to u(Sam2) TargetType60 s3 = u(TargetType60::n2); //none is applicable TargetType60 s4 = u(TargetType60::n01);//ambiguous (u(Sam1), u(Sam2) apply) TargetType60 s5 = u(TargetType60::n012);//ambiguous (u(Sam1), u(Sam2) apply) diff --git a/test/tools/javac/lambda/TargetType60.out b/test/tools/javac/lambda/TargetType60.out index e0bf52fc..2613d0bb 100644 --- a/test/tools/javac/lambda/TargetType60.out +++ b/test/tools/javac/lambda/TargetType60.out @@ -1,8 +1,6 @@ TargetType60.java:54:21: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType60.Sam0), TargetType60, kindname.method, g(TargetType60.Sam1), TargetType60 TargetType60.java:55:21: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType60.Sam1), TargetType60, kindname.method, g(TargetType60.Sam2), TargetType60 -TargetType60.java:60:27: compiler.err.ref.ambiguous: u, kindname.method, u(TargetType60.Sam1), TargetType60, kindname.method, u(TargetType60.Sam2), TargetType60 -TargetType60.java:60:29: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, n1(java.lang.String)) -TargetType60.java:61:29: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, n2(TargetType60,java.lang.String)) +TargetType60.java:61:27: compiler.err.cant.apply.symbols: kindname.method, u, @1639,{(compiler.misc.inapplicable.method: kindname.method, TargetType60, u(TargetType60.Sam1), (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(TargetType60.Sam2), (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:62:27: compiler.err.ref.ambiguous: u, kindname.method, u(TargetType60.Sam1), TargetType60, kindname.method, u(TargetType60.Sam2), TargetType60 TargetType60.java:63:27: compiler.err.ref.ambiguous: u, kindname.method, u(TargetType60.Sam1), TargetType60, kindname.method, u(TargetType60.Sam2), TargetType60 -7 errors +5 errors -- cgit v1.2.3