8026231: Look at 'static' flag when checking method references
Reviewed-by: jjg, dlsmith
This commit is contained in:
parent
b140c3c382
commit
e6e0508e1a
@ -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;
|
||||
|
@ -2697,9 +2697,10 @@ public class Attr extends JCTree.Visitor {
|
||||
Pair<Symbol, Resolve.ReferenceLookupHelper> refResult = null;
|
||||
List<Type> 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
|
||||
|
@ -643,15 +643,16 @@ public class DeferredAttr extends JCTree.Visitor {
|
||||
}
|
||||
JCMemberReference mref2 = new TreeCopier<Void>(make).copy(tree);
|
||||
mref2.expr = exprTree;
|
||||
Pair<Symbol, ?> 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<Void>(make).copy(tree);
|
||||
mref2.expr = exprTree;
|
||||
Pair<Symbol, ReferenceLookupHelper> lookupRes =
|
||||
rs.resolveMemberReference(tree, localEnv, mref2, exprTree.type,
|
||||
tree.name, List.<Type>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 ||
|
||||
|
@ -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<AttrContext> env,
|
||||
JCMemberReference referenceTree,
|
||||
Type site,
|
||||
Name name) {
|
||||
|
||||
site = types.capture(site);
|
||||
|
||||
ReferenceLookupHelper lookupHelper = makeReferenceLookupHelper(
|
||||
referenceTree, site, name, List.<Type>nil(), null, VARARITY);
|
||||
|
||||
Env<AttrContext> 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<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);
|
||||
} 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<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 < ERRONEOUS) {
|
||||
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 < 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<Symbol, ReferenceLookupHelper> resolveMemberReference(DiagnosticPosition pos,
|
||||
Env<AttrContext> env,
|
||||
Pair<Symbol, ReferenceLookupHelper> resolveMemberReference(Env<AttrContext> env,
|
||||
JCMemberReference referenceTree,
|
||||
Type site,
|
||||
Name name, List<Type> argtypes,
|
||||
Name name,
|
||||
List<Type> argtypes,
|
||||
List<Type> 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<AttrContext> 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<AttrContext> 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<Symbol, ReferenceLookupHelper> res;
|
||||
Symbol bestSym = choose(boundSym, unboundSym);
|
||||
res = new Pair<Symbol, ReferenceLookupHelper>(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;
|
||||
}
|
||||
//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;
|
||||
|
||||
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 {
|
||||
return s1;
|
||||
if (c.sym.isStatic() == staticMth) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<Type> argtypes, List<Type> 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);
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -1,2 +1,3 @@
|
||||
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)
|
||||
1 error
|
||||
MethodReference68.java:21:12: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, getName())
|
||||
2 errors
|
||||
|
110
langtools/test/tools/javac/lambda/MethodReference73.java
Normal file
110
langtools/test/tools/javac/lambda/MethodReference73.java
Normal file
@ -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
|
||||
}
|
||||
}
|
13
langtools/test/tools/javac/lambda/MethodReference73.out
Normal file
13
langtools/test/tools/javac/lambda/MethodReference73.out
Normal file
@ -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
|
@ -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)
|
||||
|
@ -1,8 +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:60: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: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>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: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
|
||||
7 errors
|
||||
5 errors
|
||||
|
Loading…
x
Reference in New Issue
Block a user