6638712: Inference with wildcard types causes selection of inapplicable method
Added global sanity check in order to make sure that return type inference does not violate bounds constraints Reviewed-by: jjg
This commit is contained in:
parent
fda3d758e3
commit
3b51e6ae0d
@ -1066,6 +1066,21 @@ public class Type implements PrimitiveType {
|
|||||||
return qtype.isErroneous();
|
return qtype.isErroneous();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces this ForAll's typevars with a set of concrete Java types
|
||||||
|
* and returns the instantiated generic type. Subclasses might override
|
||||||
|
* in order to check that the list of types is a valid instantiation
|
||||||
|
* of the ForAll's typevars.
|
||||||
|
*
|
||||||
|
* @param actuals list of actual types
|
||||||
|
* @param types types instance
|
||||||
|
* @return qtype where all occurrences of tvars are replaced
|
||||||
|
* by types in actuals
|
||||||
|
*/
|
||||||
|
public Type inst(List<Type> actuals, Types types) {
|
||||||
|
return types.subst(qtype, tvars, actuals);
|
||||||
|
}
|
||||||
|
|
||||||
public Type map(Mapping f) {
|
public Type map(Mapping f) {
|
||||||
return f.apply(qtype);
|
return f.apply(qtype);
|
||||||
}
|
}
|
||||||
|
@ -343,6 +343,14 @@ public class Types {
|
|||||||
if (s.tag >= firstPartialTag)
|
if (s.tag >= firstPartialTag)
|
||||||
return isSuperType(s, t);
|
return isSuperType(s, t);
|
||||||
|
|
||||||
|
if (s.isCompound()) {
|
||||||
|
for (Type s2 : interfaces(s).prepend(supertype(s))) {
|
||||||
|
if (!isSubtype(t, s2, capture))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Type lower = lowerBound(s);
|
Type lower = lowerBound(s);
|
||||||
if (s != lower)
|
if (s != lower)
|
||||||
return isSubtype(capture ? capture(t) : t, lower, false);
|
return isSubtype(capture ? capture(t) : t, lower, false);
|
||||||
@ -2870,6 +2878,14 @@ public class Types {
|
|||||||
/**
|
/**
|
||||||
* Capture conversion as specified by JLS 3rd Ed.
|
* Capture conversion as specified by JLS 3rd Ed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
public List<Type> capture(List<Type> ts) {
|
||||||
|
List<Type> buf = List.nil();
|
||||||
|
for (Type t : ts) {
|
||||||
|
buf = buf.prepend(capture(t));
|
||||||
|
}
|
||||||
|
return buf.reverse();
|
||||||
|
}
|
||||||
public Type capture(Type t) {
|
public Type capture(Type t) {
|
||||||
if (t.tag != CLASS)
|
if (t.tag != CLASS)
|
||||||
return t;
|
return t;
|
||||||
|
@ -391,6 +391,10 @@ public class Check {
|
|||||||
diags.fragment("incompatible.types" + (d!=null ? ".1" : ""), d),
|
diags.fragment("incompatible.types" + (d!=null ? ".1" : ""), d),
|
||||||
t, pt);
|
t, pt);
|
||||||
}
|
}
|
||||||
|
} catch (Infer.InvalidInstanceException ex) {
|
||||||
|
JCDiagnostic d = ex.getDiagnostic();
|
||||||
|
log.error(pos, "invalid.inferred.types", t.tvars, d);
|
||||||
|
return types.createErrorType(pt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import com.sun.tools.javac.util.*;
|
|||||||
import com.sun.tools.javac.util.List;
|
import com.sun.tools.javac.util.List;
|
||||||
import com.sun.tools.javac.code.*;
|
import com.sun.tools.javac.code.*;
|
||||||
import com.sun.tools.javac.code.Type.*;
|
import com.sun.tools.javac.code.Type.*;
|
||||||
|
import com.sun.tools.javac.code.Symbol.*;
|
||||||
import com.sun.tools.javac.util.JCDiagnostic;
|
import com.sun.tools.javac.util.JCDiagnostic;
|
||||||
|
|
||||||
import static com.sun.tools.javac.code.TypeTags.*;
|
import static com.sun.tools.javac.code.TypeTags.*;
|
||||||
@ -49,6 +50,7 @@ public class Infer {
|
|||||||
|
|
||||||
Symtab syms;
|
Symtab syms;
|
||||||
Types types;
|
Types types;
|
||||||
|
Resolve rs;
|
||||||
JCDiagnostic.Factory diags;
|
JCDiagnostic.Factory diags;
|
||||||
|
|
||||||
public static Infer instance(Context context) {
|
public static Infer instance(Context context) {
|
||||||
@ -62,48 +64,60 @@ public class Infer {
|
|||||||
context.put(inferKey, this);
|
context.put(inferKey, this);
|
||||||
syms = Symtab.instance(context);
|
syms = Symtab.instance(context);
|
||||||
types = Types.instance(context);
|
types = Types.instance(context);
|
||||||
|
rs = Resolve.instance(context);
|
||||||
diags = JCDiagnostic.Factory.instance(context);
|
diags = JCDiagnostic.Factory.instance(context);
|
||||||
ambiguousNoInstanceException =
|
ambiguousNoInstanceException =
|
||||||
new NoInstanceException(true, diags);
|
new NoInstanceException(true, diags);
|
||||||
unambiguousNoInstanceException =
|
unambiguousNoInstanceException =
|
||||||
new NoInstanceException(false, diags);
|
new NoInstanceException(false, diags);
|
||||||
|
invalidInstanceException =
|
||||||
|
new InvalidInstanceException(diags);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class NoInstanceException extends RuntimeException {
|
public static class InferenceException extends RuntimeException {
|
||||||
private static final long serialVersionUID = 0;
|
private static final long serialVersionUID = 0;
|
||||||
|
|
||||||
boolean isAmbiguous; // exist several incomparable best instances?
|
|
||||||
|
|
||||||
JCDiagnostic diagnostic;
|
JCDiagnostic diagnostic;
|
||||||
JCDiagnostic.Factory diags;
|
JCDiagnostic.Factory diags;
|
||||||
|
|
||||||
NoInstanceException(boolean isAmbiguous, JCDiagnostic.Factory diags) {
|
InferenceException(JCDiagnostic.Factory diags) {
|
||||||
this.diagnostic = null;
|
this.diagnostic = null;
|
||||||
this.isAmbiguous = isAmbiguous;
|
|
||||||
this.diags = diags;
|
this.diags = diags;
|
||||||
}
|
}
|
||||||
NoInstanceException setMessage(String key) {
|
|
||||||
this.diagnostic = diags.fragment(key);
|
InferenceException setMessage(String key, Object... args) {
|
||||||
return this;
|
this.diagnostic = diags.fragment(key, args);
|
||||||
}
|
|
||||||
NoInstanceException setMessage(String key, Object arg1) {
|
|
||||||
this.diagnostic = diags.fragment(key, arg1);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
NoInstanceException setMessage(String key, Object arg1, Object arg2) {
|
|
||||||
this.diagnostic = diags.fragment(key, arg1, arg2);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
NoInstanceException setMessage(String key, Object arg1, Object arg2, Object arg3) {
|
|
||||||
this.diagnostic = diags.fragment(key, arg1, arg2, arg3);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JCDiagnostic getDiagnostic() {
|
public JCDiagnostic getDiagnostic() {
|
||||||
return diagnostic;
|
return diagnostic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class NoInstanceException extends InferenceException {
|
||||||
|
private static final long serialVersionUID = 1;
|
||||||
|
|
||||||
|
boolean isAmbiguous; // exist several incomparable best instances?
|
||||||
|
|
||||||
|
NoInstanceException(boolean isAmbiguous, JCDiagnostic.Factory diags) {
|
||||||
|
super(diags);
|
||||||
|
this.isAmbiguous = isAmbiguous;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class InvalidInstanceException extends InferenceException {
|
||||||
|
private static final long serialVersionUID = 2;
|
||||||
|
|
||||||
|
InvalidInstanceException(JCDiagnostic.Factory diags) {
|
||||||
|
super(diags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final NoInstanceException ambiguousNoInstanceException;
|
private final NoInstanceException ambiguousNoInstanceException;
|
||||||
private final NoInstanceException unambiguousNoInstanceException;
|
private final NoInstanceException unambiguousNoInstanceException;
|
||||||
|
private final InvalidInstanceException invalidInstanceException;
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Auxiliary type values and classes
|
* Auxiliary type values and classes
|
||||||
@ -233,7 +247,7 @@ public class Infer {
|
|||||||
*/
|
*/
|
||||||
public Type instantiateExpr(ForAll that,
|
public Type instantiateExpr(ForAll that,
|
||||||
Type to,
|
Type to,
|
||||||
Warner warn) throws NoInstanceException {
|
Warner warn) throws InferenceException {
|
||||||
List<Type> undetvars = Type.map(that.tvars, fromTypeVarFun);
|
List<Type> undetvars = Type.map(that.tvars, fromTypeVarFun);
|
||||||
for (List<Type> l = undetvars; l.nonEmpty(); l = l.tail) {
|
for (List<Type> l = undetvars; l.nonEmpty(); l = l.tail) {
|
||||||
UndetVar v = (UndetVar) l.head;
|
UndetVar v = (UndetVar) l.head;
|
||||||
@ -259,8 +273,7 @@ public class Infer {
|
|||||||
List<Type> targs = Type.map(undetvars, getInstFun);
|
List<Type> targs = Type.map(undetvars, getInstFun);
|
||||||
targs = types.subst(targs, that.tvars, targs);
|
targs = types.subst(targs, that.tvars, targs);
|
||||||
checkWithinBounds(that.tvars, targs, warn);
|
checkWithinBounds(that.tvars, targs, warn);
|
||||||
|
return that.inst(targs, types);
|
||||||
return getInstFun.apply(qtype1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Instantiate method type `mt' by finding instantiations of
|
/** Instantiate method type `mt' by finding instantiations of
|
||||||
@ -268,36 +281,42 @@ public class Infer {
|
|||||||
*/
|
*/
|
||||||
public Type instantiateMethod(List<Type> tvars,
|
public Type instantiateMethod(List<Type> tvars,
|
||||||
MethodType mt,
|
MethodType mt,
|
||||||
List<Type> argtypes,
|
final List<Type> argtypes,
|
||||||
boolean allowBoxing,
|
final boolean allowBoxing,
|
||||||
boolean useVarargs,
|
final boolean useVarargs,
|
||||||
Warner warn) throws NoInstanceException {
|
final Warner warn) throws InferenceException {
|
||||||
//-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
|
//-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
|
||||||
List<Type> undetvars = Type.map(tvars, fromTypeVarFun);
|
List<Type> undetvars = Type.map(tvars, fromTypeVarFun);
|
||||||
List<Type> formals = mt.argtypes;
|
List<Type> formals = mt.argtypes;
|
||||||
|
//need to capture exactly once - otherwise subsequent
|
||||||
|
//applicability checks might fail
|
||||||
|
final List<Type> capturedArgs = types.capture(argtypes);
|
||||||
|
List<Type> actuals = capturedArgs;
|
||||||
|
List<Type> actualsNoCapture = argtypes;
|
||||||
// instantiate all polymorphic argument types and
|
// instantiate all polymorphic argument types and
|
||||||
// set up lower bounds constraints for undetvars
|
// set up lower bounds constraints for undetvars
|
||||||
Type varargsFormal = useVarargs ? formals.last() : null;
|
Type varargsFormal = useVarargs ? formals.last() : null;
|
||||||
while (argtypes.nonEmpty() && formals.head != varargsFormal) {
|
while (actuals.nonEmpty() && formals.head != varargsFormal) {
|
||||||
Type ft = formals.head;
|
Type formal = formals.head;
|
||||||
Type at = argtypes.head.baseType();
|
Type actual = actuals.head.baseType();
|
||||||
if (at.tag == FORALL)
|
Type actualNoCapture = actualsNoCapture.head.baseType();
|
||||||
at = instantiateArg((ForAll) at, ft, tvars, warn);
|
if (actual.tag == FORALL)
|
||||||
Type sft = types.subst(ft, tvars, undetvars);
|
actual = instantiateArg((ForAll)actual, formal, tvars, warn);
|
||||||
|
Type undetFormal = types.subst(formal, tvars, undetvars);
|
||||||
boolean works = allowBoxing
|
boolean works = allowBoxing
|
||||||
? types.isConvertible(at, sft, warn)
|
? types.isConvertible(actual, undetFormal, warn)
|
||||||
: types.isSubtypeUnchecked(at, sft, warn);
|
: types.isSubtypeUnchecked(actual, undetFormal, warn);
|
||||||
if (!works) {
|
if (!works) {
|
||||||
throw unambiguousNoInstanceException
|
throw unambiguousNoInstanceException
|
||||||
.setMessage("no.conforming.assignment.exists",
|
.setMessage("no.conforming.assignment.exists",
|
||||||
tvars, at, ft);
|
tvars, actualNoCapture, formal);
|
||||||
}
|
}
|
||||||
formals = formals.tail;
|
formals = formals.tail;
|
||||||
argtypes = argtypes.tail;
|
actuals = actuals.tail;
|
||||||
|
actualsNoCapture = actualsNoCapture.tail;
|
||||||
}
|
}
|
||||||
if (formals.head != varargsFormal || // not enough args
|
if (formals.head != varargsFormal || // not enough args
|
||||||
!useVarargs && argtypes.nonEmpty()) { // too many args
|
!useVarargs && actuals.nonEmpty()) { // too many args
|
||||||
// argument lists differ in length
|
// argument lists differ in length
|
||||||
throw unambiguousNoInstanceException
|
throw unambiguousNoInstanceException
|
||||||
.setMessage("arg.length.mismatch");
|
.setMessage("arg.length.mismatch");
|
||||||
@ -305,20 +324,21 @@ public class Infer {
|
|||||||
|
|
||||||
// for varargs arguments as well
|
// for varargs arguments as well
|
||||||
if (useVarargs) {
|
if (useVarargs) {
|
||||||
Type elt = types.elemtype(varargsFormal);
|
Type elemType = types.elemtype(varargsFormal);
|
||||||
Type sft = types.subst(elt, tvars, undetvars);
|
Type elemUndet = types.subst(elemType, tvars, undetvars);
|
||||||
while (argtypes.nonEmpty()) {
|
while (actuals.nonEmpty()) {
|
||||||
Type ft = sft;
|
Type actual = actuals.head.baseType();
|
||||||
Type at = argtypes.head.baseType();
|
Type actualNoCapture = actualsNoCapture.head.baseType();
|
||||||
if (at.tag == FORALL)
|
if (actual.tag == FORALL)
|
||||||
at = instantiateArg((ForAll) at, ft, tvars, warn);
|
actual = instantiateArg((ForAll)actual, elemType, tvars, warn);
|
||||||
boolean works = types.isConvertible(at, sft, warn);
|
boolean works = types.isConvertible(actual, elemUndet, warn);
|
||||||
if (!works) {
|
if (!works) {
|
||||||
throw unambiguousNoInstanceException
|
throw unambiguousNoInstanceException
|
||||||
.setMessage("no.conforming.assignment.exists",
|
.setMessage("no.conforming.assignment.exists",
|
||||||
tvars, at, ft);
|
tvars, actualNoCapture, elemType);
|
||||||
}
|
}
|
||||||
argtypes = argtypes.tail;
|
actuals = actuals.tail;
|
||||||
|
actualsNoCapture = actualsNoCapture.tail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,16 +369,38 @@ public class Infer {
|
|||||||
}
|
}
|
||||||
checkWithinBounds(tvars, undettypes.toList(), warn);
|
checkWithinBounds(tvars, undettypes.toList(), warn);
|
||||||
|
|
||||||
|
mt = (MethodType)types.subst(mt, tvars, insttypes.toList());
|
||||||
|
|
||||||
if (!restvars.isEmpty()) {
|
if (!restvars.isEmpty()) {
|
||||||
// if there are uninstantiated variables,
|
// if there are uninstantiated variables,
|
||||||
// quantify result type with them
|
// quantify result type with them
|
||||||
mt = new MethodType(mt.argtypes,
|
final List<Type> inferredTypes = insttypes.toList();
|
||||||
new ForAll(restvars.toList(), mt.restype),
|
final List<Type> all_tvars = tvars; //this is the wrong tvars
|
||||||
mt.thrown, syms.methodClass);
|
final MethodType mt2 = new MethodType(mt.argtypes, null, mt.thrown, syms.methodClass);
|
||||||
|
mt2.restype = new ForAll(restvars.toList(), mt.restype) {
|
||||||
|
@Override
|
||||||
|
public Type inst(List<Type> inferred, Types types) throws NoInstanceException {
|
||||||
|
List<Type> formals = types.subst(mt2.argtypes, tvars, inferred);
|
||||||
|
if (!rs.argumentsAcceptable(capturedArgs, formals,
|
||||||
|
allowBoxing, useVarargs, warn)) {
|
||||||
|
// inferred method is not applicable
|
||||||
|
throw invalidInstanceException.setMessage("inferred.do.not.conform.to.params", formals, argtypes);
|
||||||
|
}
|
||||||
|
// check that inferred bounds conform to their bounds
|
||||||
|
checkWithinBounds(all_tvars,
|
||||||
|
types.subst(inferredTypes, tvars, inferred), warn);
|
||||||
|
return super.inst(inferred, types);
|
||||||
|
}};
|
||||||
|
return mt2;
|
||||||
|
}
|
||||||
|
else if (!rs.argumentsAcceptable(capturedArgs, mt.getParameterTypes(), allowBoxing, useVarargs, warn)) {
|
||||||
|
// inferred method is not applicable
|
||||||
|
throw invalidInstanceException.setMessage("inferred.do.not.conform.to.params", mt.getParameterTypes(), argtypes);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// return instantiated version of method type
|
||||||
|
return mt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return instantiated version of method type
|
|
||||||
return types.subst(mt, tvars, insttypes.toList());
|
|
||||||
}
|
}
|
||||||
//where
|
//where
|
||||||
|
|
||||||
@ -370,7 +412,7 @@ public class Infer {
|
|||||||
private Type instantiateArg(ForAll that,
|
private Type instantiateArg(ForAll that,
|
||||||
Type to,
|
Type to,
|
||||||
List<Type> tvars,
|
List<Type> tvars,
|
||||||
Warner warn) throws NoInstanceException {
|
Warner warn) throws InferenceException {
|
||||||
List<Type> targs;
|
List<Type> targs;
|
||||||
try {
|
try {
|
||||||
return instantiateExpr(that, to, warn);
|
return instantiateExpr(that, to, warn);
|
||||||
@ -387,16 +429,16 @@ public class Infer {
|
|||||||
private void checkWithinBounds(List<Type> tvars,
|
private void checkWithinBounds(List<Type> tvars,
|
||||||
List<Type> arguments,
|
List<Type> arguments,
|
||||||
Warner warn)
|
Warner warn)
|
||||||
throws NoInstanceException {
|
throws InvalidInstanceException {
|
||||||
for (List<Type> tvs = tvars, args = arguments;
|
for (List<Type> tvs = tvars, args = arguments;
|
||||||
tvs.nonEmpty();
|
tvs.nonEmpty();
|
||||||
tvs = tvs.tail, args = args.tail) {
|
tvs = tvs.tail, args = args.tail) {
|
||||||
if (args.head instanceof UndetVar) continue;
|
if (args.head instanceof UndetVar) continue;
|
||||||
List<Type> bounds = types.subst(types.getBounds((TypeVar)tvs.head), tvars, arguments);
|
List<Type> bounds = types.subst(types.getBounds((TypeVar)tvs.head), tvars, arguments);
|
||||||
if (!types.isSubtypeUnchecked(args.head, bounds, warn))
|
if (!types.isSubtypeUnchecked(args.head, bounds, warn))
|
||||||
throw unambiguousNoInstanceException
|
throw invalidInstanceException
|
||||||
.setMessage("inferred.do.not.conform.to.bounds",
|
.setMessage("inferred.do.not.conform.to.bounds",
|
||||||
arguments, tvars);
|
args.head, bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -299,7 +299,7 @@ public class Resolve {
|
|||||||
boolean allowBoxing,
|
boolean allowBoxing,
|
||||||
boolean useVarargs,
|
boolean useVarargs,
|
||||||
Warner warn)
|
Warner warn)
|
||||||
throws Infer.NoInstanceException {
|
throws Infer.InferenceException {
|
||||||
if (useVarargs && (m.flags() & VARARGS) == 0) return null;
|
if (useVarargs && (m.flags() & VARARGS) == 0) return null;
|
||||||
Type mt = types.memberType(site, m);
|
Type mt = types.memberType(site, m);
|
||||||
|
|
||||||
@ -370,7 +370,7 @@ public class Resolve {
|
|||||||
try {
|
try {
|
||||||
return rawInstantiate(env, site, m, argtypes, typeargtypes,
|
return rawInstantiate(env, site, m, argtypes, typeargtypes,
|
||||||
allowBoxing, useVarargs, warn);
|
allowBoxing, useVarargs, warn);
|
||||||
} catch (Infer.NoInstanceException ex) {
|
} catch (Infer.InferenceException ex) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -584,7 +584,7 @@ public class Resolve {
|
|||||||
default: return bestSoFar;
|
default: return bestSoFar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Infer.NoInstanceException ex) {
|
} catch (Infer.InferenceException ex) {
|
||||||
switch (bestSoFar.kind) {
|
switch (bestSoFar.kind) {
|
||||||
case ABSENT_MTH:
|
case ABSENT_MTH:
|
||||||
return wrongMethod.setWrongSym(sym, ex.getDiagnostic());
|
return wrongMethod.setWrongSym(sym, ex.getDiagnostic());
|
||||||
|
@ -84,7 +84,7 @@ compiler.err.cant.apply.symbol=\
|
|||||||
{0} {1} in {4} {5} cannot be applied to given types\n\
|
{0} {1} in {4} {5} cannot be applied to given types\n\
|
||||||
required: {2}\n\
|
required: {2}\n\
|
||||||
found: {3}
|
found: {3}
|
||||||
compiler.err.cant.apply.symbol.1=\
|
compiler.err.cant.apply.symbol.1=\
|
||||||
{0} {1} in {4} {5} cannot be applied to given types;\n\
|
{0} {1} in {4} {5} cannot be applied to given types;\n\
|
||||||
required: {2}\n\
|
required: {2}\n\
|
||||||
found: {3}\n\
|
found: {3}\n\
|
||||||
@ -469,6 +469,8 @@ compiler.err.undetermined.type=\
|
|||||||
type parameters of {0} cannot be determined
|
type parameters of {0} cannot be determined
|
||||||
compiler.err.undetermined.type.1=\
|
compiler.err.undetermined.type.1=\
|
||||||
type parameters of {0} cannot be determined; {1}
|
type parameters of {0} cannot be determined; {1}
|
||||||
|
compiler.err.invalid.inferred.types=\
|
||||||
|
invalid inferred types for {0}; {1}
|
||||||
compiler.err.unreachable.stmt=\
|
compiler.err.unreachable.stmt=\
|
||||||
unreachable statement
|
unreachable statement
|
||||||
compiler.err.initializer.must.be.able.to.complete.normally=\
|
compiler.err.initializer.must.be.able.to.complete.normally=\
|
||||||
@ -995,7 +997,13 @@ compiler.misc.no.conforming.assignment.exists=\
|
|||||||
compiler.misc.arg.length.mismatch=\
|
compiler.misc.arg.length.mismatch=\
|
||||||
cannot instantiate from arguments because actual and formal argument lists differ in length
|
cannot instantiate from arguments because actual and formal argument lists differ in length
|
||||||
compiler.misc.inferred.do.not.conform.to.bounds=\
|
compiler.misc.inferred.do.not.conform.to.bounds=\
|
||||||
inferred type argument(s) {0} do not conform to bounds of type variable(s) {1}
|
inferred type does not conform to declared bound(s)\n\
|
||||||
|
inferred: {0}\n\
|
||||||
|
bound(s): {1}
|
||||||
|
compiler.misc.inferred.do.not.conform.to.params=\
|
||||||
|
actual arguments do not conforms to inferred formal arguments\n\
|
||||||
|
required: {0}\n\
|
||||||
|
found: {1}
|
||||||
|
|
||||||
#####
|
#####
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
* @test
|
* @test
|
||||||
* @bug 6476073
|
* @bug 6476073
|
||||||
* @summary Capture using super wildcard of type variables doesn't work
|
* @summary Capture using super wildcard of type variables doesn't work
|
||||||
|
* @ignore awaiting for 6650759 (see bug report for a detailed evaluation)
|
||||||
* @compile T6476073.java
|
* @compile T6476073.java
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 6638712
|
||||||
|
* @author mcimadamore
|
||||||
|
* @summary Inference with wildcard types causes selection of inapplicable method
|
||||||
|
* @compile/fail/ref=T6638712a.out -XDrawDiagnostics T6638712a.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
class T6638712a {
|
||||||
|
|
||||||
|
<T> Comparator<T> compound(Iterable<? extends Comparator<? super T>> it) {}
|
||||||
|
|
||||||
|
public void test(List<Comparator<?>> x) {
|
||||||
|
Comparator<String> c3 = compound(x);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
T6638712a.java:39:41: compiler.err.invalid.inferred.types: T, (compiler.misc.inferred.do.not.conform.to.params: java.lang.Iterable<? extends java.util.Comparator<? super java.lang.String>>, java.util.List<java.util.Comparator<?>>)
|
||||||
|
1 error
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 6638712
|
||||||
|
* @author mcimadamore
|
||||||
|
* @summary Inference with wildcard types causes selection of inapplicable method
|
||||||
|
* @compile/fail/ref=T6638712b.out -XDrawDiagnostics T6638712b.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
class T6638712b<X> {
|
||||||
|
|
||||||
|
<I extends T6638712b<T>, T> T m(I test) { return null; }
|
||||||
|
|
||||||
|
void test(T6638712b<Integer> x) {
|
||||||
|
String i = m(x);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
T6638712b.java:37:21: compiler.err.invalid.inferred.types: T, (compiler.misc.inferred.do.not.conform.to.bounds: T6638712b<java.lang.Integer>, T6638712b<java.lang.String>)
|
||||||
|
1 error
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 6638712 6707034
|
||||||
|
* @author mcimadamore
|
||||||
|
* @summary Inference with wildcard types causes selection of inapplicable method
|
||||||
|
* @compile/fail/ref=T6638712c.out -XDrawDiagnostics T6638712c.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
class T6638712c {
|
||||||
|
|
||||||
|
<T> T sort(T[] a, Comparator<? super T> c) { return null; }
|
||||||
|
|
||||||
|
void test(Enum[] e, Comparator<Enum<?>> comp) {
|
||||||
|
sort(e, comp);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
T6638712c.java:39:9: compiler.err.cant.apply.symbol: kindname.method, sort, T[],java.util.Comparator<? super T>, java.lang.Enum[],java.util.Comparator<java.lang.Enum<?>>, kindname.class, T6638712c, null
|
||||||
|
1 error
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 6638712 6730468
|
||||||
|
* @author mcimadamore
|
||||||
|
* @summary Inference with wildcard types causes selection of inapplicable method
|
||||||
|
* @compile/fail/ref=T6638712d.out -XDrawDiagnostics T6638712d.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class T6638712d {
|
||||||
|
|
||||||
|
<U> U m(U u, List<List<U>> list) { return null; }
|
||||||
|
|
||||||
|
void test(List<List<String>> lls) {
|
||||||
|
m(1, lls);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
T6638712d.java:39:9: compiler.err.cant.apply.symbol: kindname.method, m, U,java.util.List<java.util.List<U>>, int,java.util.List<java.util.List<java.lang.String>>, kindname.class, T6638712d, null
|
||||||
|
1 error
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 6638712 6795689
|
||||||
|
* @author mcimadamore
|
||||||
|
* @summary Inference with wildcard types causes selection of inapplicable method
|
||||||
|
* @compile/fail/ref=T6638712e.out -XDrawDiagnostics T6638712e.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
class T6638712e {
|
||||||
|
|
||||||
|
static class Foo<A, B> {
|
||||||
|
<X> Foo<X, B> m(Foo<? super X, ? extends A> foo) { return null;}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Test {
|
||||||
|
Foo<Object, String> test(Foo<Boolean, String> foo1, Foo<Boolean, Boolean> foo2) {
|
||||||
|
return foo1.m(foo2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
T6638712e.java:40:27: compiler.err.invalid.inferred.types: X, (compiler.misc.inferred.do.not.conform.to.params: T6638712e.Foo<? super java.lang.Object,? extends java.lang.Boolean>, T6638712e.Foo<java.lang.Boolean,java.lang.Boolean>)
|
||||||
|
1 error
|
Loading…
x
Reference in New Issue
Block a user