1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Mon Oct 20 13:42:45 2008 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Thu Oct 23 17:59:16 2008 +0100 1.3 @@ -424,43 +424,43 @@ 1.4 * @param bs The bound. 1.5 */ 1.6 private void checkExtends(DiagnosticPosition pos, Type a, TypeVar bs) { 1.7 - if (a.tag == TYPEVAR && ((TypeVar)a).isCaptured()) { 1.8 - CapturedType ct = (CapturedType)a; 1.9 - boolean ok; 1.10 - if (ct.bound.isErroneous()) {//capture doesn't exist 1.11 - ok = false; 1.12 + if (a.isUnbound()) { 1.13 + return; 1.14 + } else if (a.tag != WILDCARD) { 1.15 + a = types.upperBound(a); 1.16 + for (List<Type> l = types.getBounds(bs); l.nonEmpty(); l = l.tail) { 1.17 + if (!types.isSubtype(a, l.head)) { 1.18 + log.error(pos, "not.within.bounds", a); 1.19 + return; 1.20 + } 1.21 + } 1.22 + } else if (a.isExtendsBound()) { 1.23 + if (!types.isCastable(bs.getUpperBound(), types.upperBound(a), Warner.noWarnings)) 1.24 + log.error(pos, "not.within.bounds", a); 1.25 + } else if (a.isSuperBound()) { 1.26 + if (types.notSoftSubtype(types.lowerBound(a), bs.getUpperBound())) 1.27 + log.error(pos, "not.within.bounds", a); 1.28 + } 1.29 + } 1.30 + 1.31 + /** Check that a type is within some bounds. 1.32 + * 1.33 + * Used in TypeApply to verify that, e.g., X in V<X> is a valid 1.34 + * type argument. 1.35 + * @param pos Position to be used for error reporting. 1.36 + * @param a The type that should be bounded by bs. 1.37 + * @param bs The bound. 1.38 + */ 1.39 + private void checkCapture(JCTypeApply tree) { 1.40 + List<JCExpression> args = tree.getTypeArguments(); 1.41 + for (Type arg : types.capture(tree.type).getTypeArguments()) { 1.42 + if (arg.tag == TYPEVAR && arg.getUpperBound().isErroneous()) { 1.43 + log.error(args.head.pos, "not.within.bounds", args.head.type); 1.44 + break; 1.45 } 1.46 - else { 1.47 - switch (ct.wildcard.kind) { 1.48 - case EXTENDS: 1.49 - ok = types.isCastable(bs.getUpperBound(), 1.50 - types.upperBound(a), 1.51 - Warner.noWarnings); 1.52 - break; 1.53 - case SUPER: 1.54 - ok = !types.notSoftSubtype(types.lowerBound(a), 1.55 - bs.getUpperBound()); 1.56 - break; 1.57 - case UNBOUND: 1.58 - ok = true; 1.59 - break; 1.60 - default: 1.61 - throw new AssertionError("Invalid bound kind"); 1.62 - } 1.63 - } 1.64 - if (!ok) 1.65 - log.error(pos, "not.within.bounds", a); 1.66 + args = args.tail; 1.67 } 1.68 - else { 1.69 - a = types.upperBound(a); 1.70 - for (List<Type> l = types.getBounds(bs); l.nonEmpty(); l = l.tail) { 1.71 - if (!types.isSubtype(a, l.head)) { 1.72 - log.error(pos, "not.within.bounds", a); 1.73 - return; 1.74 - } 1.75 - } 1.76 - } 1.77 - } 1.78 + } 1.79 1.80 /** Check that type is different from 'void'. 1.81 * @param pos Position to be used for error reporting. 1.82 @@ -803,7 +803,7 @@ 1.83 public void visitTypeApply(JCTypeApply tree) { 1.84 if (tree.type.tag == CLASS) { 1.85 List<Type> formals = tree.type.tsym.type.getTypeArguments(); 1.86 - List<Type> actuals = types.capture(tree.type).getTypeArguments(); 1.87 + List<Type> actuals = tree.type.getTypeArguments(); 1.88 List<JCExpression> args = tree.arguments; 1.89 List<Type> forms = formals; 1.90 ListBuffer<TypeVar> tvars_buf = new ListBuffer<TypeVar>(); 1.91 @@ -826,24 +826,28 @@ 1.92 } 1.93 1.94 args = tree.arguments; 1.95 + List<Type> tvars_cap = types.substBounds(formals, 1.96 + formals, 1.97 + types.capture(tree.type).getTypeArguments()); 1.98 + while (args.nonEmpty() && tvars_cap.nonEmpty()) { 1.99 + // Let the actual arguments know their bound 1.100 + args.head.type.withTypeVar((TypeVar)tvars_cap.head); 1.101 + args = args.tail; 1.102 + tvars_cap = tvars_cap.tail; 1.103 + } 1.104 + 1.105 + args = tree.arguments; 1.106 List<TypeVar> tvars = tvars_buf.toList(); 1.107 + 1.108 while (args.nonEmpty() && tvars.nonEmpty()) { 1.109 - // Let the actual arguments know their bound 1.110 - args.head.type.withTypeVar(tvars.head); 1.111 + checkExtends(args.head.pos(), 1.112 + args.head.type, 1.113 + tvars.head); 1.114 args = args.tail; 1.115 tvars = tvars.tail; 1.116 } 1.117 1.118 - args = tree.arguments; 1.119 - tvars = tvars_buf.toList(); 1.120 - while (args.nonEmpty() && tvars.nonEmpty()) { 1.121 - checkExtends(args.head.pos(), 1.122 - actuals.head, 1.123 - tvars.head); 1.124 - args = args.tail; 1.125 - tvars = tvars.tail; 1.126 - actuals = actuals.tail; 1.127 - } 1.128 + checkCapture(tree); 1.129 1.130 // Check that this type is either fully parameterized, or 1.131 // not parameterized at all.