langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
changeset 1527 815e743a83ba
parent 1358 a51c5f89f8af
child 1531 37df4e42719a
equal deleted inserted replaced
1486:a7d1338ca96e 1527:815e743a83ba
   422      *  @param pos           Position to be used for error reporting.
   422      *  @param pos           Position to be used for error reporting.
   423      *  @param a             The type that should be bounded by bs.
   423      *  @param a             The type that should be bounded by bs.
   424      *  @param bs            The bound.
   424      *  @param bs            The bound.
   425      */
   425      */
   426     private void checkExtends(DiagnosticPosition pos, Type a, TypeVar bs) {
   426     private void checkExtends(DiagnosticPosition pos, Type a, TypeVar bs) {
   427         if (a.tag == TYPEVAR && ((TypeVar)a).isCaptured()) {
   427          if (a.isUnbound()) {
   428             CapturedType ct = (CapturedType)a;
   428              return;
   429             boolean ok;
   429          } else if (a.tag != WILDCARD) {
   430             if (ct.bound.isErroneous()) {//capture doesn't exist
   430              a = types.upperBound(a);
   431                 ok = false;
   431              for (List<Type> l = types.getBounds(bs); l.nonEmpty(); l = l.tail) {
   432             }
   432                  if (!types.isSubtype(a, l.head)) {
   433             else {
   433                      log.error(pos, "not.within.bounds", a);
   434                 switch (ct.wildcard.kind) {
   434                      return;
   435                     case EXTENDS:
   435                  }
   436                         ok = types.isCastable(bs.getUpperBound(),
   436              }
   437                                 types.upperBound(a),
   437          } else if (a.isExtendsBound()) {
   438                                 Warner.noWarnings);
   438              if (!types.isCastable(bs.getUpperBound(), types.upperBound(a), Warner.noWarnings))
   439                         break;
   439                  log.error(pos, "not.within.bounds", a);
   440                     case SUPER:
   440          } else if (a.isSuperBound()) {
   441                         ok = !types.notSoftSubtype(types.lowerBound(a),
   441              if (types.notSoftSubtype(types.lowerBound(a), bs.getUpperBound()))
   442                                 bs.getUpperBound());
   442                  log.error(pos, "not.within.bounds", a);
   443                         break;
   443          }
   444                     case UNBOUND:
   444      }
   445                         ok = true;
   445 
   446                         break;
   446     /** Check that a type is within some bounds.
   447                     default:
   447      *
   448                         throw new AssertionError("Invalid bound kind");
   448      *  Used in TypeApply to verify that, e.g., X in V<X> is a valid
   449                 }
   449      *  type argument.
   450             }
   450      *  @param pos           Position to be used for error reporting.
   451             if (!ok)
   451      *  @param a             The type that should be bounded by bs.
   452                 log.error(pos, "not.within.bounds", a);
   452      *  @param bs            The bound.
   453         }
   453      */
   454         else {
   454     private void checkCapture(JCTypeApply tree) {
   455             a = types.upperBound(a);
   455         List<JCExpression> args = tree.getTypeArguments();
   456             for (List<Type> l = types.getBounds(bs); l.nonEmpty(); l = l.tail) {
   456         for (Type arg : types.capture(tree.type).getTypeArguments()) {
   457                 if (!types.isSubtype(a, l.head)) {
   457             if (arg.tag == TYPEVAR && arg.getUpperBound().isErroneous()) {
   458                     log.error(pos, "not.within.bounds", a);
   458                 log.error(args.head.pos, "not.within.bounds", args.head.type);
   459                     return;
   459                 break;
   460                 }
   460             }
   461             }
   461             args = args.tail;
   462         }
   462         }
   463     }
   463      }
   464 
   464 
   465     /** Check that type is different from 'void'.
   465     /** Check that type is different from 'void'.
   466      *  @param pos           Position to be used for error reporting.
   466      *  @param pos           Position to be used for error reporting.
   467      *  @param t             The type to be checked.
   467      *  @param t             The type to be checked.
   468      */
   468      */
   801         }
   801         }
   802 
   802 
   803         public void visitTypeApply(JCTypeApply tree) {
   803         public void visitTypeApply(JCTypeApply tree) {
   804             if (tree.type.tag == CLASS) {
   804             if (tree.type.tag == CLASS) {
   805                 List<Type> formals = tree.type.tsym.type.getTypeArguments();
   805                 List<Type> formals = tree.type.tsym.type.getTypeArguments();
   806                 List<Type> actuals = types.capture(tree.type).getTypeArguments();
   806                 List<Type> actuals = tree.type.getTypeArguments();
   807                 List<JCExpression> args = tree.arguments;
   807                 List<JCExpression> args = tree.arguments;
   808                 List<Type> forms = formals;
   808                 List<Type> forms = formals;
   809                 ListBuffer<TypeVar> tvars_buf = new ListBuffer<TypeVar>();
   809                 ListBuffer<TypeVar> tvars_buf = new ListBuffer<TypeVar>();
   810 
   810 
   811                 // For matching pairs of actual argument types `a' and
   811                 // For matching pairs of actual argument types `a' and
   824                     args = args.tail;
   824                     args = args.tail;
   825                     forms = forms.tail;
   825                     forms = forms.tail;
   826                 }
   826                 }
   827 
   827 
   828                 args = tree.arguments;
   828                 args = tree.arguments;
       
   829                 List<Type> tvars_cap = types.substBounds(formals,
       
   830                                           formals,
       
   831                                           types.capture(tree.type).getTypeArguments());
       
   832                 while (args.nonEmpty() && tvars_cap.nonEmpty()) {
       
   833                     // Let the actual arguments know their bound
       
   834                     args.head.type.withTypeVar((TypeVar)tvars_cap.head);
       
   835                     args = args.tail;
       
   836                     tvars_cap = tvars_cap.tail;
       
   837                 }
       
   838 
       
   839                 args = tree.arguments;
   829                 List<TypeVar> tvars = tvars_buf.toList();
   840                 List<TypeVar> tvars = tvars_buf.toList();
   830                 while (args.nonEmpty() && tvars.nonEmpty()) {
   841 
   831                     // Let the actual arguments know their bound
       
   832                     args.head.type.withTypeVar(tvars.head);
       
   833                     args = args.tail;
       
   834                     tvars = tvars.tail;
       
   835                 }
       
   836 
       
   837                 args = tree.arguments;
       
   838                 tvars = tvars_buf.toList();
       
   839                 while (args.nonEmpty() && tvars.nonEmpty()) {
   842                 while (args.nonEmpty() && tvars.nonEmpty()) {
   840                     checkExtends(args.head.pos(),
   843                     checkExtends(args.head.pos(),
   841                                  actuals.head,
   844                                  args.head.type,
   842                                  tvars.head);
   845                                  tvars.head);
   843                     args = args.tail;
   846                     args = args.tail;
   844                     tvars = tvars.tail;
   847                     tvars = tvars.tail;
   845                     actuals = actuals.tail;
   848                 }
   846                 }
   849 
       
   850                 checkCapture(tree);
   847 
   851 
   848                 // Check that this type is either fully parameterized, or
   852                 // Check that this type is either fully parameterized, or
   849                 // not parameterized at all.
   853                 // not parameterized at all.
   850                 if (tree.type.getEnclosingType().isRaw())
   854                 if (tree.type.getEnclosingType().isRaw())
   851                     log.error(tree.pos(), "improperly.formed.type.inner.raw.param");
   855                     log.error(tree.pos(), "improperly.formed.type.inner.raw.param");