diff -r 8ae974495e73 -r 6508d7e812e1 src/share/classes/com/sun/tools/javac/comp/Check.java --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Mon Oct 20 13:42:45 2008 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Thu Oct 23 17:59:16 2008 +0100 @@ -424,43 +424,43 @@ * @param bs The bound. */ private void checkExtends(DiagnosticPosition pos, Type a, TypeVar bs) { - if (a.tag == TYPEVAR && ((TypeVar)a).isCaptured()) { - CapturedType ct = (CapturedType)a; - boolean ok; - if (ct.bound.isErroneous()) {//capture doesn't exist - ok = false; + if (a.isUnbound()) { + return; + } else if (a.tag != WILDCARD) { + a = types.upperBound(a); + for (List l = types.getBounds(bs); l.nonEmpty(); l = l.tail) { + if (!types.isSubtype(a, l.head)) { + log.error(pos, "not.within.bounds", a); + return; + } + } + } else if (a.isExtendsBound()) { + if (!types.isCastable(bs.getUpperBound(), types.upperBound(a), Warner.noWarnings)) + log.error(pos, "not.within.bounds", a); + } else if (a.isSuperBound()) { + if (types.notSoftSubtype(types.lowerBound(a), bs.getUpperBound())) + log.error(pos, "not.within.bounds", a); + } + } + + /** Check that a type is within some bounds. + * + * Used in TypeApply to verify that, e.g., X in V is a valid + * type argument. + * @param pos Position to be used for error reporting. + * @param a The type that should be bounded by bs. + * @param bs The bound. + */ + private void checkCapture(JCTypeApply tree) { + List args = tree.getTypeArguments(); + for (Type arg : types.capture(tree.type).getTypeArguments()) { + if (arg.tag == TYPEVAR && arg.getUpperBound().isErroneous()) { + log.error(args.head.pos, "not.within.bounds", args.head.type); + break; } - else { - switch (ct.wildcard.kind) { - case EXTENDS: - ok = types.isCastable(bs.getUpperBound(), - types.upperBound(a), - Warner.noWarnings); - break; - case SUPER: - ok = !types.notSoftSubtype(types.lowerBound(a), - bs.getUpperBound()); - break; - case UNBOUND: - ok = true; - break; - default: - throw new AssertionError("Invalid bound kind"); - } - } - if (!ok) - log.error(pos, "not.within.bounds", a); + args = args.tail; } - else { - a = types.upperBound(a); - for (List l = types.getBounds(bs); l.nonEmpty(); l = l.tail) { - if (!types.isSubtype(a, l.head)) { - log.error(pos, "not.within.bounds", a); - return; - } - } - } - } + } /** Check that type is different from 'void'. * @param pos Position to be used for error reporting. @@ -803,7 +803,7 @@ public void visitTypeApply(JCTypeApply tree) { if (tree.type.tag == CLASS) { List formals = tree.type.tsym.type.getTypeArguments(); - List actuals = types.capture(tree.type).getTypeArguments(); + List actuals = tree.type.getTypeArguments(); List args = tree.arguments; List forms = formals; ListBuffer tvars_buf = new ListBuffer(); @@ -826,24 +826,28 @@ } args = tree.arguments; + List tvars_cap = types.substBounds(formals, + formals, + types.capture(tree.type).getTypeArguments()); + while (args.nonEmpty() && tvars_cap.nonEmpty()) { + // Let the actual arguments know their bound + args.head.type.withTypeVar((TypeVar)tvars_cap.head); + args = args.tail; + tvars_cap = tvars_cap.tail; + } + + args = tree.arguments; List tvars = tvars_buf.toList(); + while (args.nonEmpty() && tvars.nonEmpty()) { - // Let the actual arguments know their bound - args.head.type.withTypeVar(tvars.head); + checkExtends(args.head.pos(), + args.head.type, + tvars.head); args = args.tail; tvars = tvars.tail; } - args = tree.arguments; - tvars = tvars_buf.toList(); - while (args.nonEmpty() && tvars.nonEmpty()) { - checkExtends(args.head.pos(), - actuals.head, - tvars.head); - args = args.tail; - tvars = tvars.tail; - actuals = actuals.tail; - } + checkCapture(tree); // Check that this type is either fully parameterized, or // not parameterized at all.