6732484: Bound error on wildcard code

Thu, 23 Oct 2008 17:59:16 +0100

author
mcimadamore
date
Thu, 23 Oct 2008 17:59:16 +0100
changeset 154
6508d7e812e1
parent 151
8ae974495e73
child 155
4d2d8b6459e1

6732484: Bound error on wildcard code
Summary: Check.checkExtends should cope with captured type-variables
Reviewed-by: jjg

src/share/classes/com/sun/tools/javac/code/Type.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Check.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/wildcards/T6732484.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/code/Type.java	Mon Oct 20 13:42:45 2008 -0700
     1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Type.java	Thu Oct 23 17:59:16 2008 +0100
     1.3 @@ -360,17 +360,6 @@
     1.4      public boolean isUnbound() { return false; }
     1.5      public Type withTypeVar(Type t) { return this; }
     1.6  
     1.7 -    public static List<Type> removeBounds(List<Type> ts) {
     1.8 -        ListBuffer<Type> result = new ListBuffer<Type>();
     1.9 -        for(;ts.nonEmpty(); ts = ts.tail) {
    1.10 -            result.append(ts.head.removeBounds());
    1.11 -        }
    1.12 -        return result.toList();
    1.13 -    }
    1.14 -    public Type removeBounds() {
    1.15 -        return this;
    1.16 -    }
    1.17 -
    1.18      /** The underlying method type of this type.
    1.19       */
    1.20      public MethodType asMethodType() { throw new AssertionError(); }
    1.21 @@ -489,10 +478,6 @@
    1.22                  return new WildcardType(t, kind, tsym, bound);
    1.23          }
    1.24  
    1.25 -        public Type removeBounds() {
    1.26 -            return isUnbound() ? this : type;
    1.27 -        }
    1.28 -
    1.29          public Type getExtendsBound() {
    1.30              if (kind == EXTENDS)
    1.31                  return type;
     2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Oct 20 13:42:45 2008 -0700
     2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Oct 23 17:59:16 2008 +0100
     2.3 @@ -424,43 +424,43 @@
     2.4       *  @param bs            The bound.
     2.5       */
     2.6      private void checkExtends(DiagnosticPosition pos, Type a, TypeVar bs) {
     2.7 -        if (a.tag == TYPEVAR && ((TypeVar)a).isCaptured()) {
     2.8 -            CapturedType ct = (CapturedType)a;
     2.9 -            boolean ok;
    2.10 -            if (ct.bound.isErroneous()) {//capture doesn't exist
    2.11 -                ok = false;
    2.12 +         if (a.isUnbound()) {
    2.13 +             return;
    2.14 +         } else if (a.tag != WILDCARD) {
    2.15 +             a = types.upperBound(a);
    2.16 +             for (List<Type> l = types.getBounds(bs); l.nonEmpty(); l = l.tail) {
    2.17 +                 if (!types.isSubtype(a, l.head)) {
    2.18 +                     log.error(pos, "not.within.bounds", a);
    2.19 +                     return;
    2.20 +                 }
    2.21 +             }
    2.22 +         } else if (a.isExtendsBound()) {
    2.23 +             if (!types.isCastable(bs.getUpperBound(), types.upperBound(a), Warner.noWarnings))
    2.24 +                 log.error(pos, "not.within.bounds", a);
    2.25 +         } else if (a.isSuperBound()) {
    2.26 +             if (types.notSoftSubtype(types.lowerBound(a), bs.getUpperBound()))
    2.27 +                 log.error(pos, "not.within.bounds", a);
    2.28 +         }
    2.29 +     }
    2.30 +
    2.31 +    /** Check that a type is within some bounds.
    2.32 +     *
    2.33 +     *  Used in TypeApply to verify that, e.g., X in V<X> is a valid
    2.34 +     *  type argument.
    2.35 +     *  @param pos           Position to be used for error reporting.
    2.36 +     *  @param a             The type that should be bounded by bs.
    2.37 +     *  @param bs            The bound.
    2.38 +     */
    2.39 +    private void checkCapture(JCTypeApply tree) {
    2.40 +        List<JCExpression> args = tree.getTypeArguments();
    2.41 +        for (Type arg : types.capture(tree.type).getTypeArguments()) {
    2.42 +            if (arg.tag == TYPEVAR && arg.getUpperBound().isErroneous()) {
    2.43 +                log.error(args.head.pos, "not.within.bounds", args.head.type);
    2.44 +                break;
    2.45              }
    2.46 -            else {
    2.47 -                switch (ct.wildcard.kind) {
    2.48 -                    case EXTENDS:
    2.49 -                        ok = types.isCastable(bs.getUpperBound(),
    2.50 -                                types.upperBound(a),
    2.51 -                                Warner.noWarnings);
    2.52 -                        break;
    2.53 -                    case SUPER:
    2.54 -                        ok = !types.notSoftSubtype(types.lowerBound(a),
    2.55 -                                bs.getUpperBound());
    2.56 -                        break;
    2.57 -                    case UNBOUND:
    2.58 -                        ok = true;
    2.59 -                        break;
    2.60 -                    default:
    2.61 -                        throw new AssertionError("Invalid bound kind");
    2.62 -                }
    2.63 -            }
    2.64 -            if (!ok)
    2.65 -                log.error(pos, "not.within.bounds", a);
    2.66 +            args = args.tail;
    2.67          }
    2.68 -        else {
    2.69 -            a = types.upperBound(a);
    2.70 -            for (List<Type> l = types.getBounds(bs); l.nonEmpty(); l = l.tail) {
    2.71 -                if (!types.isSubtype(a, l.head)) {
    2.72 -                    log.error(pos, "not.within.bounds", a);
    2.73 -                    return;
    2.74 -                }
    2.75 -            }
    2.76 -        }
    2.77 -    }
    2.78 +     }
    2.79  
    2.80      /** Check that type is different from 'void'.
    2.81       *  @param pos           Position to be used for error reporting.
    2.82 @@ -803,7 +803,7 @@
    2.83          public void visitTypeApply(JCTypeApply tree) {
    2.84              if (tree.type.tag == CLASS) {
    2.85                  List<Type> formals = tree.type.tsym.type.getTypeArguments();
    2.86 -                List<Type> actuals = types.capture(tree.type).getTypeArguments();
    2.87 +                List<Type> actuals = tree.type.getTypeArguments();
    2.88                  List<JCExpression> args = tree.arguments;
    2.89                  List<Type> forms = formals;
    2.90                  ListBuffer<TypeVar> tvars_buf = new ListBuffer<TypeVar>();
    2.91 @@ -826,24 +826,28 @@
    2.92                  }
    2.93  
    2.94                  args = tree.arguments;
    2.95 +                List<Type> tvars_cap = types.substBounds(formals,
    2.96 +                                          formals,
    2.97 +                                          types.capture(tree.type).getTypeArguments());
    2.98 +                while (args.nonEmpty() && tvars_cap.nonEmpty()) {
    2.99 +                    // Let the actual arguments know their bound
   2.100 +                    args.head.type.withTypeVar((TypeVar)tvars_cap.head);
   2.101 +                    args = args.tail;
   2.102 +                    tvars_cap = tvars_cap.tail;
   2.103 +                }
   2.104 +
   2.105 +                args = tree.arguments;
   2.106                  List<TypeVar> tvars = tvars_buf.toList();
   2.107 +
   2.108                  while (args.nonEmpty() && tvars.nonEmpty()) {
   2.109 -                    // Let the actual arguments know their bound
   2.110 -                    args.head.type.withTypeVar(tvars.head);
   2.111 +                    checkExtends(args.head.pos(),
   2.112 +                                 args.head.type,
   2.113 +                                 tvars.head);
   2.114                      args = args.tail;
   2.115                      tvars = tvars.tail;
   2.116                  }
   2.117  
   2.118 -                args = tree.arguments;
   2.119 -                tvars = tvars_buf.toList();
   2.120 -                while (args.nonEmpty() && tvars.nonEmpty()) {
   2.121 -                    checkExtends(args.head.pos(),
   2.122 -                                 actuals.head,
   2.123 -                                 tvars.head);
   2.124 -                    args = args.tail;
   2.125 -                    tvars = tvars.tail;
   2.126 -                    actuals = actuals.tail;
   2.127 -                }
   2.128 +                checkCapture(tree);
   2.129  
   2.130                  // Check that this type is either fully parameterized, or
   2.131                  // not parameterized at all.
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/test/tools/javac/generics/wildcards/T6732484.java	Thu Oct 23 17:59:16 2008 +0100
     3.3 @@ -0,0 +1,37 @@
     3.4 +/*
     3.5 + * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
     3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.7 + *
     3.8 + * This code is free software; you can redistribute it and/or modify it
     3.9 + * under the terms of the GNU General Public License version 2 only, as
    3.10 + * published by the Free Software Foundation.
    3.11 + *
    3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    3.15 + * version 2 for more details (a copy is included in the LICENSE file that
    3.16 + * accompanied this code).
    3.17 + *
    3.18 + * You should have received a copy of the GNU General Public License version
    3.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    3.21 + *
    3.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    3.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
    3.24 + * have any questions.
    3.25 + */
    3.26 +
    3.27 +/*
    3.28 + * @test
    3.29 + * @bug 6732484
    3.30 + * @summary Bound error on wildcard code
    3.31 + * @author Maurizio Cimadamore
    3.32 + * @compile T6732484.java
    3.33 + */
    3.34 +
    3.35 +class T6732484 {
    3.36 +    class A<T extends A<T>> {}
    3.37 +    class B extends A<B> {}
    3.38 +
    3.39 +    A<? super B> f;
    3.40 +}
    3.41 \ No newline at end of file

mercurial