langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
changeset 21009 b35973e2d42e
parent 20608 5cc020154cff
child 21018 95d225149128
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Oct 10 10:51:15 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Oct 10 13:55:41 2013 -0400
@@ -792,17 +792,19 @@
         Type t = tree.type != null ?
             tree.type :
             attribType(tree, env);
-        return checkBase(t, tree, env, classExpected, interfaceExpected, checkExtensible);
+        return checkBase(t, tree, env, classExpected, interfaceExpected, false, checkExtensible);
     }
     Type checkBase(Type t,
                    JCTree tree,
                    Env<AttrContext> env,
                    boolean classExpected,
-                   boolean interfaceOrArrayExpected,
+                   boolean interfacesOnlyExpected,
+                   boolean interfacesOrArraysExpected,
                    boolean checkExtensible) {
         if (t.isErroneous())
             return t;
-        if (t.hasTag(TYPEVAR) && !classExpected && !interfaceOrArrayExpected) {
+        if (t.hasTag(TYPEVAR) && !classExpected &&
+            !interfacesOrArraysExpected && !interfacesOnlyExpected) {
             // check that type variable is already visible
             if (t.getUpperBound() == null) {
                 log.error(tree.pos(), "illegal.forward.ref");
@@ -814,9 +816,14 @@
             t = chk.checkClassOrArrayType(tree.pos(), t,
                                           checkExtensible|!allowGenerics);
         }
-        if (interfaceOrArrayExpected &&
+        if (interfacesOnlyExpected && !t.tsym.isInterface()) {
+            log.error(tree.pos(), "intf.expected.here");
+            // return errType is necessary since otherwise there might
+            // be undetected cycles which cause attribution to loop
+            return types.createErrorType(t);
+        } else if (interfacesOrArraysExpected &&
             !(t.tsym.isInterface() || t.getTag() == ARRAY)) {
-            log.error(tree.pos(), "intf.expected.here");
+            log.error(tree.pos(), "intf.or.array.expected.here");
             // return errType is necessary since otherwise there might
             // be undetected cycles which cause attribution to loop
             return types.createErrorType(t);
@@ -3988,7 +3995,7 @@
         Set<Type> boundSet = new HashSet<Type>();
         if (bounds.nonEmpty()) {
             // accept class or interface or typevar as first bound.
-            bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false);
+            bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false, false);
             boundSet.add(types.erasure(bounds.head.type));
             if (bounds.head.type.isErroneous()) {
                 return bounds.head.type;
@@ -4004,7 +4011,7 @@
                 // if first bound was a class or interface, accept only interfaces
                 // as further bounds.
                 for (JCExpression bound : bounds.tail) {
-                    bound.type = checkBase(bound.type, bound, env, false, true, false);
+                    bound.type = checkBase(bound.type, bound, env, false, false, true, false);
                     if (bound.type.isErroneous()) {
                         bounds = List.of(bound);
                     }