6638712: Inference with wildcard types causes selection of inapplicable method
Summary: Added global sanity check in order to make sure that return type inference does not violate bounds constraints
Reviewed-by: jjg
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Tue Jun 16 10:46:16 2009 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Tue Jun 16 10:46:37 2009 +0100
@@ -1066,6 +1066,21 @@
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) {
return f.apply(qtype);
}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Tue Jun 16 10:46:16 2009 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Tue Jun 16 10:46:37 2009 +0100
@@ -343,6 +343,14 @@
if (s.tag >= firstPartialTag)
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);
if (s != lower)
return isSubtype(capture ? capture(t) : t, lower, false);
@@ -2870,6 +2878,14 @@
/**
* 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) {
if (t.tag != CLASS)
return t;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Jun 16 10:46:16 2009 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Jun 16 10:46:37 2009 +0100
@@ -391,6 +391,10 @@
diags.fragment("incompatible.types" + (d!=null ? ".1" : ""), d),
t, pt);
}
+ } catch (Infer.InvalidInstanceException ex) {
+ JCDiagnostic d = ex.getDiagnostic();
+ log.error(pos, "invalid.inferred.types", t.tvars, d);
+ return types.createErrorType(pt);
}
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Jun 16 10:46:16 2009 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Jun 16 10:46:37 2009 +0100
@@ -29,6 +29,7 @@
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Type.*;
+import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.util.JCDiagnostic;
import static com.sun.tools.javac.code.TypeTags.*;
@@ -49,6 +50,7 @@
Symtab syms;
Types types;
+ Resolve rs;
JCDiagnostic.Factory diags;
public static Infer instance(Context context) {
@@ -62,48 +64,60 @@
context.put(inferKey, this);
syms = Symtab.instance(context);
types = Types.instance(context);
+ rs = Resolve.instance(context);
diags = JCDiagnostic.Factory.instance(context);
ambiguousNoInstanceException =
new NoInstanceException(true, diags);
unambiguousNoInstanceException =
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;
- boolean isAmbiguous; // exist several incomparable best instances?
-
JCDiagnostic diagnostic;
JCDiagnostic.Factory diags;
- NoInstanceException(boolean isAmbiguous, JCDiagnostic.Factory diags) {
+ InferenceException(JCDiagnostic.Factory diags) {
this.diagnostic = null;
- this.isAmbiguous = isAmbiguous;
this.diags = diags;
}
- NoInstanceException setMessage(String key) {
- this.diagnostic = diags.fragment(key);
- return this;
- }
- NoInstanceException setMessage(String key, Object arg1) {
- this.diagnostic = diags.fragment(key, arg1);
+
+ InferenceException setMessage(String key, Object... args) {
+ this.diagnostic = diags.fragment(key, args);
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;
- }
+
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 unambiguousNoInstanceException;
+ private final InvalidInstanceException invalidInstanceException;
/***************************************************************************
* Auxiliary type values and classes
@@ -233,7 +247,7 @@
*/
public Type instantiateExpr(ForAll that,
Type to,
- Warner warn) throws NoInstanceException {
+ Warner warn) throws InferenceException {
List<Type> undetvars = Type.map(that.tvars, fromTypeVarFun);
for (List<Type> l = undetvars; l.nonEmpty(); l = l.tail) {
UndetVar v = (UndetVar) l.head;
@@ -259,8 +273,7 @@
List<Type> targs = Type.map(undetvars, getInstFun);
targs = types.subst(targs, that.tvars, targs);
checkWithinBounds(that.tvars, targs, warn);
-
- return getInstFun.apply(qtype1);
+ return that.inst(targs, types);
}
/** Instantiate method type `mt' by finding instantiations of
@@ -268,36 +281,42 @@
*/
public Type instantiateMethod(List<Type> tvars,
MethodType mt,
- List<Type> argtypes,
- boolean allowBoxing,
- boolean useVarargs,
- Warner warn) throws NoInstanceException {
+ final List<Type> argtypes,
+ final boolean allowBoxing,
+ final boolean useVarargs,
+ final Warner warn) throws InferenceException {
//-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
List<Type> undetvars = Type.map(tvars, fromTypeVarFun);
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
// set up lower bounds constraints for undetvars
Type varargsFormal = useVarargs ? formals.last() : null;
- while (argtypes.nonEmpty() && formals.head != varargsFormal) {
- Type ft = formals.head;
- Type at = argtypes.head.baseType();
- if (at.tag == FORALL)
- at = instantiateArg((ForAll) at, ft, tvars, warn);
- Type sft = types.subst(ft, tvars, undetvars);
+ while (actuals.nonEmpty() && formals.head != varargsFormal) {
+ Type formal = formals.head;
+ Type actual = actuals.head.baseType();
+ Type actualNoCapture = actualsNoCapture.head.baseType();
+ if (actual.tag == FORALL)
+ actual = instantiateArg((ForAll)actual, formal, tvars, warn);
+ Type undetFormal = types.subst(formal, tvars, undetvars);
boolean works = allowBoxing
- ? types.isConvertible(at, sft, warn)
- : types.isSubtypeUnchecked(at, sft, warn);
+ ? types.isConvertible(actual, undetFormal, warn)
+ : types.isSubtypeUnchecked(actual, undetFormal, warn);
if (!works) {
throw unambiguousNoInstanceException
.setMessage("no.conforming.assignment.exists",
- tvars, at, ft);
+ tvars, actualNoCapture, formal);
}
formals = formals.tail;
- argtypes = argtypes.tail;
+ actuals = actuals.tail;
+ actualsNoCapture = actualsNoCapture.tail;
}
if (formals.head != varargsFormal || // not enough args
- !useVarargs && argtypes.nonEmpty()) { // too many args
+ !useVarargs && actuals.nonEmpty()) { // too many args
// argument lists differ in length
throw unambiguousNoInstanceException
.setMessage("arg.length.mismatch");
@@ -305,20 +324,21 @@
// for varargs arguments as well
if (useVarargs) {
- Type elt = types.elemtype(varargsFormal);
- Type sft = types.subst(elt, tvars, undetvars);
- while (argtypes.nonEmpty()) {
- Type ft = sft;
- Type at = argtypes.head.baseType();
- if (at.tag == FORALL)
- at = instantiateArg((ForAll) at, ft, tvars, warn);
- boolean works = types.isConvertible(at, sft, warn);
+ Type elemType = types.elemtype(varargsFormal);
+ Type elemUndet = types.subst(elemType, tvars, undetvars);
+ while (actuals.nonEmpty()) {
+ Type actual = actuals.head.baseType();
+ Type actualNoCapture = actualsNoCapture.head.baseType();
+ if (actual.tag == FORALL)
+ actual = instantiateArg((ForAll)actual, elemType, tvars, warn);
+ boolean works = types.isConvertible(actual, elemUndet, warn);
if (!works) {
throw unambiguousNoInstanceException
.setMessage("no.conforming.assignment.exists",
- tvars, at, ft);
+ tvars, actualNoCapture, elemType);
}
- argtypes = argtypes.tail;
+ actuals = actuals.tail;
+ actualsNoCapture = actualsNoCapture.tail;
}
}
@@ -349,16 +369,38 @@
}
checkWithinBounds(tvars, undettypes.toList(), warn);
+ mt = (MethodType)types.subst(mt, tvars, insttypes.toList());
+
if (!restvars.isEmpty()) {
// if there are uninstantiated variables,
// quantify result type with them
- mt = new MethodType(mt.argtypes,
- new ForAll(restvars.toList(), mt.restype),
- mt.thrown, syms.methodClass);
+ final List<Type> inferredTypes = insttypes.toList();
+ final List<Type> all_tvars = tvars; //this is the wrong tvars
+ 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;
}
-
- // return instantiated version of method type
- return types.subst(mt, tvars, insttypes.toList());
+ 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;
+ }
}
//where
@@ -370,7 +412,7 @@
private Type instantiateArg(ForAll that,
Type to,
List<Type> tvars,
- Warner warn) throws NoInstanceException {
+ Warner warn) throws InferenceException {
List<Type> targs;
try {
return instantiateExpr(that, to, warn);
@@ -387,16 +429,16 @@
private void checkWithinBounds(List<Type> tvars,
List<Type> arguments,
Warner warn)
- throws NoInstanceException {
+ throws InvalidInstanceException {
for (List<Type> tvs = tvars, args = arguments;
tvs.nonEmpty();
tvs = tvs.tail, args = args.tail) {
if (args.head instanceof UndetVar) continue;
List<Type> bounds = types.subst(types.getBounds((TypeVar)tvs.head), tvars, arguments);
if (!types.isSubtypeUnchecked(args.head, bounds, warn))
- throw unambiguousNoInstanceException
+ throw invalidInstanceException
.setMessage("inferred.do.not.conform.to.bounds",
- arguments, tvars);
+ args.head, bounds);
}
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Tue Jun 16 10:46:16 2009 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Tue Jun 16 10:46:37 2009 +0100
@@ -299,7 +299,7 @@
boolean allowBoxing,
boolean useVarargs,
Warner warn)
- throws Infer.NoInstanceException {
+ throws Infer.InferenceException {
if (useVarargs && (m.flags() & VARARGS) == 0) return null;
Type mt = types.memberType(site, m);
@@ -370,7 +370,7 @@
try {
return rawInstantiate(env, site, m, argtypes, typeargtypes,
allowBoxing, useVarargs, warn);
- } catch (Infer.NoInstanceException ex) {
+ } catch (Infer.InferenceException ex) {
return null;
}
}
@@ -584,7 +584,7 @@
default: return bestSoFar;
}
}
- } catch (Infer.NoInstanceException ex) {
+ } catch (Infer.InferenceException ex) {
switch (bestSoFar.kind) {
case ABSENT_MTH:
return wrongMethod.setWrongSym(sym, ex.getDiagnostic());
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Jun 16 10:46:16 2009 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Jun 16 10:46:37 2009 +0100
@@ -84,7 +84,7 @@
{0} {1} in {4} {5} cannot be applied to given types\n\
required: {2}\n\
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\
required: {2}\n\
found: {3}\n\
@@ -469,6 +469,8 @@
type parameters of {0} cannot be determined
compiler.err.undetermined.type.1=\
type parameters of {0} cannot be determined; {1}
+compiler.err.invalid.inferred.types=\
+ invalid inferred types for {0}; {1}
compiler.err.unreachable.stmt=\
unreachable statement
compiler.err.initializer.must.be.able.to.complete.normally=\
@@ -995,7 +997,13 @@
compiler.misc.arg.length.mismatch=\
cannot instantiate from arguments because actual and formal argument lists differ in length
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}
#####
--- a/langtools/test/tools/javac/generics/inference/6302954/T6476073.java Tue Jun 16 10:46:16 2009 +0100
+++ b/langtools/test/tools/javac/generics/inference/6302954/T6476073.java Tue Jun 16 10:46:37 2009 +0100
@@ -25,6 +25,7 @@
* @test
* @bug 6476073
* @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
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712a.java Tue Jun 16 10:46:37 2009 +0100
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712a.out Tue Jun 16 10:46:37 2009 +0100
@@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712b.java Tue Jun 16 10:46:37 2009 +0100
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712b.out Tue Jun 16 10:46:37 2009 +0100
@@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712c.java Tue Jun 16 10:46:37 2009 +0100
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712c.out Tue Jun 16 10:46:37 2009 +0100
@@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712d.java Tue Jun 16 10:46:37 2009 +0100
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712d.out Tue Jun 16 10:46:37 2009 +0100
@@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712e.java Tue Jun 16 10:46:37 2009 +0100
@@ -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);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712e.out Tue Jun 16 10:46:37 2009 +0100
@@ -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