diff -r 866c87c01285 -r a204cf7aab7e src/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Jul 17 14:09:46 2013 +0100 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Jul 17 14:11:41 2013 +0100 @@ -961,10 +961,23 @@ DeferredType dt = (DeferredType)found; return dt.check(this); } else { - return super.check(pos, chk.checkNonVoid(pos, types.capture(types.upperBound(found.baseType())))); + return super.check(pos, chk.checkNonVoid(pos, types.capture(U(found.baseType())))); } } + /** + * javac has a long-standing 'simplification' (see 6391995): + * given an actual argument type, the method check is performed + * on its upper bound. This leads to inconsistencies when an + * argument type is checked against itself. For example, given + * a type-variable T, it is not true that {@code U(T) <: T}, + * so we need to guard against that. + */ + private Type U(Type found) { + return found == pt ? + found : types.upperBound(found); + } + @Override protected MethodResultInfo dup(Type newPt) { return new MethodResultInfo(newPt, checkContext);