--- old/src/share/classes/com/sun/tools/javac/code/Types.java 2009-12-27 19:02:16.000000000 +0100 +++ new/src/share/classes/com/sun/tools/javac/code/Types.java 2009-12-27 19:02:16.000000000 +0100 @@ -373,7 +373,8 @@ case BOT: return s.tag == BOT || s.tag == CLASS || - s.tag == ARRAY || s.tag == TYPEVAR; + s.tag == ARRAY || s.tag == TYPEVAR || + s.tag == FUNCTION; case NONE: return false; default: @@ -444,6 +445,30 @@ && isSubtypeNoCapture(sup.getEnclosingType(), s.getEnclosingType()); } + + @Override + public Boolean visitMethodType(MethodType t, Type s) { + if (s.tsym == syms.objectType.tsym || s.tsym == syms.methodHandleType.tsym) + return true; + + if (s.tag != FUNCTION) + return false; + + //check covariance/contravariance + MethodType mType = (MethodType) s; + if (!(isSubtypeNoCapture(t.restype, mType.restype))) + return false; + + List lt = t.argtypes; + List lmType = mType.argtypes; + while (lt.nonEmpty() && lmType.nonEmpty()) { + if (!(isSubtypeNoCapture(lmType.head, lt.head))) + return false; + lt = lt.tail; + lmType = lmType.tail; + } + return lt.isEmpty() && lmType.isEmpty(); + } @Override public Boolean visitArrayType(ArrayType t, Type s) { @@ -1097,6 +1122,19 @@ } @Override + public Boolean visitMethodType(MethodType t, Type s) { + if (isSubtype(t, s)) + return true; + if (s.tsym == syms.methodHandleType.tsym) { + warnStack.head.warnUnchecked(); + return true; + } + if (s.tag != METHOD) + return false; + return isCastable(s, t); + } + + @Override public Boolean visitErrorType(ErrorType t, Type s) { return true; } @@ -1270,6 +1308,17 @@ public Boolean visitTypeVar(TypeVar t, Void ignored) { return false; } + + @Override + public Boolean visitMethodType(MethodType t, Void ignored) { + if (!isReifiable(t.restype)) + return false; + for(List l = t.argtypes; l.isEmpty(); l = l.tail) { + if (!isReifiable(l.head)) + return false; + } + return true; + } }; // @@ -1583,6 +1632,13 @@ public Type visitTypeVar(TypeVar t, Boolean recurse) { return erasure(t.bound, recurse); } + + @Override + public Type visitMethodType(MethodType t, Boolean recurse) { + if (t.tag == FUNCTION) + return syms.methodHandleType; + return super.visitMethodType(t, recurse); + } @Override public Type visitErrorType(ErrorType t, Boolean recurse) { @@ -2009,7 +2065,7 @@ @Override public Boolean visitMethodType(MethodType t, Type s) { - return s.tag == METHOD + return (s.tag == METHOD || s.tag == FUNCTION) && containsTypeEquivalent(t.argtypes, s.getParameterTypes()); } @@ -2100,7 +2156,7 @@ thrown == t.thrown) return t; else - return new MethodType(argtypes, restype, thrown, t.tsym); + return new MethodType(t.tag, argtypes, restype, thrown, t.tsym); } @Override