src/share/classes/com/sun/tools/javac/code/Types.java

Print this page

        

@@ -371,11 +371,12 @@
                 case TYPEVAR:
                     return isSubtypeNoCapture(t.getUpperBound(), s);
                 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:
                     throw new AssertionError("isSubtype " + t.tag);
                 }

@@ -444,10 +445,34 @@
                     && 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<Type> lt = t.argtypes;
+              List<Type> 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) {
                 if (s.tag == ARRAY) {
                     if (t.elemtype.tag <= lastBaseTag)
                         return isSameType(t.elemtype, elemtype(s));
                     else

@@ -1095,10 +1120,23 @@
                     return isCastable(t.bound, s, warnStack.head);
                 }
             }
 
             @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;
             }
         };
     // </editor-fold>

@@ -1268,10 +1306,21 @@
 
             @Override
             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<Type> l = t.argtypes; l.isEmpty(); l = l.tail) {
+                    if (!isReifiable(l.head))
+                        return false;
+                }
+                return true;
+            }
         };
     // </editor-fold>
 
     // <editor-fold defaultstate="collapsed" desc="Array Utils">
     public boolean isArray(Type t) {

@@ -1583,10 +1632,17 @@
             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) {
                 return t;
             }
         };
 

@@ -2007,11 +2063,11 @@
                 throw new AssertionError();
             }
 
             @Override
             public Boolean visitMethodType(MethodType t, Type s) {
-                return s.tag == METHOD
+                return (s.tag == METHOD || s.tag == FUNCTION)
                     && containsTypeEquivalent(t.argtypes, s.getParameterTypes());
             }
 
             @Override
             public Boolean visitForAll(ForAll t, Type s) {

@@ -2098,11 +2154,11 @@
             if (argtypes == t.argtypes &&
                 restype == t.restype &&
                 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
         public Type visitTypeVar(TypeVar t, Void ignored) {
             for (List<Type> from = this.from, to = this.to;