7177306: Regression: unchecked method call does not erase return type

Tue, 25 Sep 2012 11:56:46 +0100

author
mcimadamore
date
Tue, 25 Sep 2012 11:56:46 +0100
changeset 1338
ad2ca2a4ab5e
parent 1337
2eca84194807
child 1339
0e5899f09dab

7177306: Regression: unchecked method call does not erase return type
Summary: Spurious extra call to Attr.checkMethod when method call is unchecked
Reviewed-by: jjg, dlsmith

src/share/classes/com/sun/tools/javac/code/Type.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/code/Types.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Infer.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Resolve.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/resources/compiler.properties file | annotate | diff | comparison | revisions
test/tools/javac/6758789/T6758789b.out file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples.not-yet.txt file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/IncompatibleEqUpperBounds.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/7015430/T7015430.out file | annotate | diff | comparison | revisions
test/tools/javac/generics/7151802/T7151802.out file | annotate | diff | comparison | revisions
test/tools/javac/generics/inference/7177306/T7177306a.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/inference/7177306/T7177306a.out file | annotate | diff | comparison | revisions
test/tools/javac/generics/inference/7177306/T7177306b.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/inference/7177306/T7177306b.out file | annotate | diff | comparison | revisions
test/tools/javac/generics/inference/7177306/T7177306c.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/inference/7177306/T7177306d.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/inference/7177306/T7177306e.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/inference/7177306/T7177306e.out file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/code/Type.java	Tue Sep 25 11:55:34 2012 +0100
     1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Type.java	Tue Sep 25 11:56:46 2012 +0100
     1.3 @@ -30,6 +30,10 @@
     1.4  import com.sun.tools.javac.util.*;
     1.5  import com.sun.tools.javac.code.Symbol.*;
     1.6  
     1.7 +import java.util.EnumMap;
     1.8 +import java.util.EnumSet;
     1.9 +import java.util.Map;
    1.10 +import java.util.Set;
    1.11  import javax.lang.model.type.*;
    1.12  
    1.13  import static com.sun.tools.javac.code.Flags.*;
    1.14 @@ -1168,22 +1172,55 @@
    1.15          }
    1.16      }
    1.17  
    1.18 -    /** A class for instantiatable variables, for use during type
    1.19 -     *  inference.
    1.20 +    /** A class for inference variables, for use during method/diamond type
    1.21 +     *  inference. An inference variable has upper/lower bounds and a set
    1.22 +     *  of equality constraints. Such bounds are set during subtyping, type-containment,
    1.23 +     *  type-equality checks, when the types being tested contain inference variables.
    1.24 +     *  A change listener can be attached to an inference variable, to receive notifications
    1.25 +     *  whenever the bounds of an inference variable change.
    1.26       */
    1.27      public static class UndetVar extends DelegatedType {
    1.28 -        public List<Type> lobounds = List.nil();
    1.29 -        public List<Type> hibounds = List.nil();
    1.30 -        public List<Type> eq = List.nil();
    1.31 +
    1.32 +        /** Inference variable change listener. The listener method is called
    1.33 +         *  whenever a change to the inference variable's bounds occurs
    1.34 +         */
    1.35 +        public interface UndetVarListener {
    1.36 +            /** called when some inference variable bounds (of given kinds ibs) change */
    1.37 +            void varChanged(UndetVar uv, Set<InferenceBound> ibs);
    1.38 +        }
    1.39 +
    1.40 +        /**
    1.41 +         * Inference variable bound kinds
    1.42 +         */
    1.43 +        public enum InferenceBound {
    1.44 +            /** upper bounds */
    1.45 +            UPPER,
    1.46 +            /** lower bounds */
    1.47 +            LOWER,
    1.48 +            /** equality constraints */
    1.49 +            EQ;
    1.50 +        }
    1.51 +
    1.52 +        /** inference variable bounds */
    1.53 +        private Map<InferenceBound, List<Type>> bounds;
    1.54 +
    1.55 +        /** inference variable's inferred type (set from Infer.java) */
    1.56          public Type inst = null;
    1.57  
    1.58 +        /** inference variable's change listener */
    1.59 +        public UndetVarListener listener = null;
    1.60 +
    1.61          @Override
    1.62          public <R,S> R accept(Type.Visitor<R,S> v, S s) {
    1.63              return v.visitUndetVar(this, s);
    1.64          }
    1.65  
    1.66 -        public UndetVar(Type origin) {
    1.67 +        public UndetVar(TypeVar origin, Types types) {
    1.68              super(UNDETVAR, origin);
    1.69 +            bounds = new EnumMap<InferenceBound, List<Type>>(InferenceBound.class);
    1.70 +            bounds.put(InferenceBound.UPPER, types.getBounds(origin));
    1.71 +            bounds.put(InferenceBound.LOWER, List.<Type>nil());
    1.72 +            bounds.put(InferenceBound.EQ, List.<Type>nil());
    1.73          }
    1.74  
    1.75          public String toString() {
    1.76 @@ -1195,6 +1232,48 @@
    1.77              if (inst != null) return inst.baseType();
    1.78              else return this;
    1.79          }
    1.80 +
    1.81 +        /** get all bounds of a given kind */
    1.82 +        public List<Type> getBounds(InferenceBound ib) {
    1.83 +            return bounds.get(ib);
    1.84 +        }
    1.85 +
    1.86 +        /** add a bound of a given kind - this might trigger listener notification */
    1.87 +        public void addBound(InferenceBound ib, Type bound, Types types) {
    1.88 +            List<Type> prevBounds = bounds.get(ib);
    1.89 +            for (Type b : prevBounds) {
    1.90 +                if (types.isSameType(b, bound)) {
    1.91 +                    return;
    1.92 +                }
    1.93 +            }
    1.94 +            bounds.put(ib, prevBounds.prepend(bound));
    1.95 +            notifyChange(EnumSet.of(ib));
    1.96 +        }
    1.97 +
    1.98 +        /** replace types in all bounds - this might trigger listener notification */
    1.99 +        public void substBounds(List<Type> from, List<Type> to, Types types) {
   1.100 +            EnumSet<InferenceBound> changed = EnumSet.noneOf(InferenceBound.class);
   1.101 +            Map<InferenceBound, List<Type>> bounds2 = new EnumMap<InferenceBound, List<Type>>(InferenceBound.class);
   1.102 +            for (Map.Entry<InferenceBound, List<Type>> _entry : bounds.entrySet()) {
   1.103 +                InferenceBound ib = _entry.getKey();
   1.104 +                List<Type> prevBounds = _entry.getValue();
   1.105 +                List<Type> newBounds = types.subst(prevBounds, from, to);
   1.106 +                bounds2.put(ib, newBounds);
   1.107 +                if (prevBounds != newBounds) {
   1.108 +                    changed.add(ib);
   1.109 +                }
   1.110 +            }
   1.111 +            if (!changed.isEmpty()) {
   1.112 +                bounds = bounds2;
   1.113 +                notifyChange(changed);
   1.114 +            }
   1.115 +        }
   1.116 +
   1.117 +        private void notifyChange(EnumSet<InferenceBound> ibs) {
   1.118 +            if (listener != null) {
   1.119 +                listener.varChanged(this, ibs);
   1.120 +            }
   1.121 +        }
   1.122      }
   1.123  
   1.124      /** Represents VOID or NONE.
     2.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java	Tue Sep 25 11:55:34 2012 +0100
     2.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Tue Sep 25 11:56:46 2012 +0100
     2.3 @@ -34,6 +34,7 @@
     2.4  import com.sun.tools.javac.jvm.ClassReader;
     2.5  import com.sun.tools.javac.code.Attribute.RetentionPolicy;
     2.6  import com.sun.tools.javac.code.Lint.LintCategory;
     2.7 +import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
     2.8  import com.sun.tools.javac.comp.Check;
     2.9  
    2.10  import static com.sun.tools.javac.code.Scope.*;
    2.11 @@ -510,7 +511,7 @@
    2.12                      return false;
    2.13                  }
    2.14  
    2.15 -                t.hibounds = t.hibounds.prepend(s);
    2.16 +                t.addBound(InferenceBound.UPPER, s, Types.this);
    2.17                  return true;
    2.18              }
    2.19  
    2.20 @@ -578,7 +579,7 @@
    2.21                  undet.qtype == s ||
    2.22                  s.tag == ERROR ||
    2.23                  s.tag == BOT) return true;
    2.24 -            undet.lobounds = undet.lobounds.prepend(s);
    2.25 +            undet.addBound(InferenceBound.LOWER, s, this);
    2.26              return true;
    2.27          }
    2.28          default:
    2.29 @@ -723,7 +724,7 @@
    2.30                  if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN)
    2.31                      return true;
    2.32  
    2.33 -                t.eq = t.eq.prepend(s);
    2.34 +                t.addBound(InferenceBound.EQ, s, Types.this);
    2.35  
    2.36                  return true;
    2.37              }
    2.38 @@ -735,19 +736,6 @@
    2.39          };
    2.40      // </editor-fold>
    2.41  
    2.42 -    // <editor-fold defaultstate="collapsed" desc="fromUnknownFun">
    2.43 -    /**
    2.44 -     * A mapping that turns all unknown types in this type to fresh
    2.45 -     * unknown variables.
    2.46 -     */
    2.47 -    public Mapping fromUnknownFun = new Mapping("fromUnknownFun") {
    2.48 -            public Type apply(Type t) {
    2.49 -                if (t.tag == UNKNOWN) return new UndetVar(t);
    2.50 -                else return t.map(this);
    2.51 -            }
    2.52 -        };
    2.53 -    // </editor-fold>
    2.54 -
    2.55      // <editor-fold defaultstate="collapsed" desc="Contains Type">
    2.56      public boolean containedBy(Type t, Type s) {
    2.57          switch (t.tag) {
    2.58 @@ -759,12 +747,12 @@
    2.59                      case UNBOUND: //similar to ? extends Object
    2.60                      case EXTENDS: {
    2.61                          Type bound = upperBound(s);
    2.62 -                        undetvar.hibounds = undetvar.hibounds.prepend(bound);
    2.63 +                        undetvar.addBound(InferenceBound.UPPER, bound, this);
    2.64                          break;
    2.65                      }
    2.66                      case SUPER: {
    2.67                          Type bound = lowerBound(s);
    2.68 -                        undetvar.lobounds = undetvar.lobounds.prepend(bound);
    2.69 +                        undetvar.addBound(InferenceBound.LOWER, bound, this);
    2.70                          break;
    2.71                      }
    2.72                  }
     3.1 --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Tue Sep 25 11:55:34 2012 +0100
     3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Tue Sep 25 11:56:46 2012 +0100
     3.3 @@ -28,6 +28,7 @@
     3.4  import com.sun.tools.javac.code.*;
     3.5  import com.sun.tools.javac.code.Symbol.*;
     3.6  import com.sun.tools.javac.code.Type.*;
     3.7 +import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
     3.8  import com.sun.tools.javac.comp.Resolve.InapplicableMethodException;
     3.9  import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode;
    3.10  import com.sun.tools.javac.tree.JCTree;
    3.11 @@ -39,6 +40,7 @@
    3.12  
    3.13  import java.util.HashMap;
    3.14  import java.util.Map;
    3.15 +import java.util.Set;
    3.16  
    3.17  import static com.sun.tools.javac.code.TypeTags.*;
    3.18  
    3.19 @@ -120,8 +122,8 @@
    3.20       *  Throw a NoInstanceException if this not possible.
    3.21       */
    3.22     void maximizeInst(UndetVar that, Warner warn) throws InferenceException {
    3.23 -        List<Type> hibounds = Type.filter(that.hibounds, boundFilter);
    3.24 -        if (that.eq.isEmpty()) {
    3.25 +        List<Type> hibounds = Type.filter(that.getBounds(InferenceBound.UPPER), boundFilter);
    3.26 +        if (that.getBounds(InferenceBound.EQ).isEmpty()) {
    3.27              if (hibounds.isEmpty())
    3.28                  that.inst = syms.objectType;
    3.29              else if (hibounds.tail.isEmpty())
    3.30 @@ -129,7 +131,7 @@
    3.31              else
    3.32                  that.inst = types.glb(hibounds);
    3.33          } else {
    3.34 -            that.inst = that.eq.head;
    3.35 +            that.inst = that.getBounds(InferenceBound.EQ).head;
    3.36          }
    3.37          if (that.inst == null ||
    3.38              that.inst.isErroneous())
    3.39 @@ -149,8 +151,8 @@
    3.40       *  Throw a NoInstanceException if this not possible.
    3.41       */
    3.42      void minimizeInst(UndetVar that, Warner warn) throws InferenceException {
    3.43 -        List<Type> lobounds = Type.filter(that.lobounds, boundFilter);
    3.44 -        if (that.eq.isEmpty()) {
    3.45 +        List<Type> lobounds = Type.filter(that.getBounds(InferenceBound.LOWER), boundFilter);
    3.46 +        if (that.getBounds(InferenceBound.EQ).isEmpty()) {
    3.47              if (lobounds.isEmpty()) {
    3.48                  //do nothing - the inference variable is under-constrained
    3.49                  return;
    3.50 @@ -164,7 +166,7 @@
    3.51                          .setMessage("no.unique.minimal.instance.exists",
    3.52                                      that.qtype, lobounds);
    3.53          } else {
    3.54 -            that.inst = that.eq.head;
    3.55 +            that.inst = that.getBounds(InferenceBound.EQ).head;
    3.56          }
    3.57      }
    3.58  
    3.59 @@ -201,7 +203,8 @@
    3.60              boolean stuck = true;
    3.61              for (Type t : inferenceContext.undetvars) {
    3.62                  UndetVar uv = (UndetVar)t;
    3.63 -                if (uv.inst == null && (uv.eq.nonEmpty() || !inferenceContext.free(uv.hibounds))) {
    3.64 +                if (uv.inst == null && (uv.getBounds(InferenceBound.EQ).nonEmpty() ||
    3.65 +                        !inferenceContext.free(uv.getBounds(InferenceBound.UPPER)))) {
    3.66                      maximizeInst((UndetVar)t, warn);
    3.67                      stuck = false;
    3.68                  }
    3.69 @@ -219,7 +222,7 @@
    3.70                  //variables in remaining upper bounds and continue
    3.71                  for (Type t : inferenceContext.undetvars) {
    3.72                      UndetVar uv = (UndetVar)t;
    3.73 -                    uv.hibounds = inferenceContext.asInstTypes(uv.hibounds, types);
    3.74 +                    uv.substBounds(inferenceContext.inferenceVars(), inferenceContext.instTypes(), types);
    3.75                  }
    3.76              }
    3.77          }
    3.78 @@ -235,7 +238,7 @@
    3.79              UndetVar uv = (UndetVar)t;
    3.80              if (uv.inst == null) {
    3.81                  TypeSymbol fresh_tvar = new TypeSymbol(Flags.SYNTHETIC, uv.qtype.tsym.name, null, uv.qtype.tsym.owner);
    3.82 -                fresh_tvar.type = new TypeVar(fresh_tvar, types.makeCompoundType(uv.hibounds), null);
    3.83 +                fresh_tvar.type = new TypeVar(fresh_tvar, types.makeCompoundType(uv.getBounds(InferenceBound.UPPER)), null);
    3.84                  todo.append(uv);
    3.85                  uv.inst = fresh_tvar.type;
    3.86              }
    3.87 @@ -267,7 +270,7 @@
    3.88                                    boolean useVarargs,
    3.89                                    Warner warn) throws InferenceException {
    3.90          //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
    3.91 -        final InferenceContext inferenceContext = new InferenceContext(tvars, types);
    3.92 +        final InferenceContext inferenceContext = new InferenceContext(tvars, this);
    3.93          inferenceException.clear();
    3.94  
    3.95          try {
    3.96 @@ -286,7 +289,7 @@
    3.97              List<Type> restvars = inferenceContext.restvars();
    3.98  
    3.99              if (!restvars.isEmpty()) {
   3.100 -                if (resultInfo != null) {
   3.101 +                if (resultInfo != null && !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
   3.102                      instantiateUninferred(env.tree.pos(), inferenceContext, mt, resultInfo, warn);
   3.103                      checkWithinBounds(inferenceContext, warn);
   3.104                      mt = (MethodType)inferenceContext.asInstType(mt, types);
   3.105 @@ -332,34 +335,58 @@
   3.106      /** check that type parameters are within their bounds.
   3.107       */
   3.108      void checkWithinBounds(InferenceContext inferenceContext,
   3.109 -                           Warner warn)
   3.110 -        throws InferenceException {
   3.111 -        List<Type> tvars = inferenceContext.inferenceVars();
   3.112 +                           Warner warn) throws InferenceException {
   3.113 +        //step 1 - check compatibility of instantiated type w.r.t. initial bounds
   3.114          for (Type t : inferenceContext.undetvars) {
   3.115              UndetVar uv = (UndetVar)t;
   3.116 -            uv.hibounds = inferenceContext.asInstTypes(uv.hibounds, types);
   3.117 -            uv.lobounds = inferenceContext.asInstTypes(uv.lobounds, types);
   3.118 -            uv.eq = inferenceContext.asInstTypes(uv.eq, types);
   3.119 +            uv.substBounds(inferenceContext.inferenceVars(), inferenceContext.instTypes(), types);
   3.120              checkCompatibleUpperBounds(uv, inferenceContext.inferenceVars());
   3.121 -            if (!inferenceContext.restvars().contains(tvars.head)) {
   3.122 +            if (!inferenceContext.restvars().contains(uv.qtype)) {
   3.123                  Type inst = inferenceContext.asInstType(t, types);
   3.124 -                for (Type u : uv.hibounds) {
   3.125 +                for (Type u : uv.getBounds(InferenceBound.UPPER)) {
   3.126                      if (!types.isSubtypeUnchecked(inst, inferenceContext.asFree(u, types), warn)) {
   3.127                          reportBoundError(uv, BoundErrorKind.UPPER);
   3.128                      }
   3.129                  }
   3.130 -                for (Type l : uv.lobounds) {
   3.131 -                    if (!types.isSubtypeUnchecked(inferenceContext.asFree(l, types), inst, warn)) {
   3.132 +                for (Type l : uv.getBounds(InferenceBound.LOWER)) {
   3.133 +                    Assert.check(!inferenceContext.free(l));
   3.134 +                    if (!types.isSubtypeUnchecked(l, inst, warn)) {
   3.135                          reportBoundError(uv, BoundErrorKind.LOWER);
   3.136                      }
   3.137                  }
   3.138 -                for (Type e : uv.eq) {
   3.139 -                    if (!types.isSameType(inst, inferenceContext.asFree(e, types))) {
   3.140 +                for (Type e : uv.getBounds(InferenceBound.EQ)) {
   3.141 +                    Assert.check(!inferenceContext.free(e));
   3.142 +                    if (!types.isSameType(inst, e)) {
   3.143                          reportBoundError(uv, BoundErrorKind.EQ);
   3.144                      }
   3.145                  }
   3.146              }
   3.147 -            tvars = tvars.tail;
   3.148 +        }
   3.149 +
   3.150 +        //step 2 - check that eq bounds are consistent w.r.t. eq/lower bounds
   3.151 +        for (Type t : inferenceContext.undetvars) {
   3.152 +            UndetVar uv = (UndetVar)t;
   3.153 +            //check eq bounds consistency
   3.154 +            Type eq = null;
   3.155 +            for (Type e : uv.getBounds(InferenceBound.EQ)) {
   3.156 +                Assert.check(!inferenceContext.free(e));
   3.157 +                if (eq != null && !types.isSameType(e, eq)) {
   3.158 +                    reportBoundError(uv, BoundErrorKind.EQ);
   3.159 +                }
   3.160 +                eq = e;
   3.161 +                for (Type l : uv.getBounds(InferenceBound.LOWER)) {
   3.162 +                    Assert.check(!inferenceContext.free(l));
   3.163 +                    if (!types.isSubtypeUnchecked(l, e, warn)) {
   3.164 +                        reportBoundError(uv, BoundErrorKind.BAD_EQ_LOWER);
   3.165 +                    }
   3.166 +                }
   3.167 +                for (Type u : uv.getBounds(InferenceBound.UPPER)) {
   3.168 +                    if (inferenceContext.free(u)) continue;
   3.169 +                    if (!types.isSubtypeUnchecked(e, u, warn)) {
   3.170 +                        reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER);
   3.171 +                    }
   3.172 +                }
   3.173 +            }
   3.174          }
   3.175      }
   3.176  
   3.177 @@ -367,7 +394,7 @@
   3.178          // VGJ: sort of inlined maximizeInst() below.  Adding
   3.179          // bounds can cause lobounds that are above hibounds.
   3.180          ListBuffer<Type> hiboundsNoVars = ListBuffer.lb();
   3.181 -        for (Type t : Type.filter(uv.hibounds, boundFilter)) {
   3.182 +        for (Type t : Type.filter(uv.getBounds(InferenceBound.UPPER), boundFilter)) {
   3.183              if (!t.containsAny(tvars)) {
   3.184                  hiboundsNoVars.append(t);
   3.185              }
   3.186 @@ -388,25 +415,43 @@
   3.187          BAD_UPPER() {
   3.188              @Override
   3.189              InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
   3.190 -                return ex.setMessage("incompatible.upper.bounds", uv.qtype, uv.hibounds);
   3.191 +                return ex.setMessage("incompatible.upper.bounds", uv.qtype,
   3.192 +                        uv.getBounds(InferenceBound.UPPER));
   3.193 +            }
   3.194 +        },
   3.195 +        BAD_EQ_UPPER() {
   3.196 +            @Override
   3.197 +            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
   3.198 +                return ex.setMessage("incompatible.eq.upper.bounds", uv.qtype,
   3.199 +                        uv.getBounds(InferenceBound.EQ), uv.getBounds(InferenceBound.UPPER));
   3.200 +            }
   3.201 +        },
   3.202 +        BAD_EQ_LOWER() {
   3.203 +            @Override
   3.204 +            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
   3.205 +                return ex.setMessage("incompatible.eq.lower.bounds", uv.qtype,
   3.206 +                        uv.getBounds(InferenceBound.EQ), uv.getBounds(InferenceBound.LOWER));
   3.207              }
   3.208          },
   3.209          UPPER() {
   3.210              @Override
   3.211              InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
   3.212 -                return ex.setMessage("inferred.do.not.conform.to.upper.bounds", uv.inst, uv.hibounds);
   3.213 +                return ex.setMessage("inferred.do.not.conform.to.upper.bounds", uv.inst,
   3.214 +                        uv.getBounds(InferenceBound.UPPER));
   3.215              }
   3.216          },
   3.217          LOWER() {
   3.218              @Override
   3.219              InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
   3.220 -                return ex.setMessage("inferred.do.not.conform.to.lower.bounds", uv.inst, uv.lobounds);
   3.221 +                return ex.setMessage("inferred.do.not.conform.to.lower.bounds", uv.inst,
   3.222 +                        uv.getBounds(InferenceBound.LOWER));
   3.223              }
   3.224          },
   3.225          EQ() {
   3.226              @Override
   3.227              InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
   3.228 -                return ex.setMessage("inferred.do.not.conform.to.eq.bounds", uv.inst, uv.eq);
   3.229 +                return ex.setMessage("inferred.do.not.conform.to.eq.bounds", uv.inst,
   3.230 +                        uv.getBounds(InferenceBound.EQ));
   3.231              }
   3.232          };
   3.233  
   3.234 @@ -480,9 +525,9 @@
   3.235       * Mapping that turns inference variables into undet vars
   3.236       * (used by inference context)
   3.237       */
   3.238 -    static Mapping fromTypeVarFun = new Mapping("fromTypeVarFun") {
   3.239 +    Mapping fromTypeVarFun = new Mapping("fromTypeVarFun") {
   3.240          public Type apply(Type t) {
   3.241 -            if (t.tag == TYPEVAR) return new UndetVar(t);
   3.242 +            if (t.tag == TYPEVAR) return new UndetVar((TypeVar)t, types);
   3.243              else return t.map(this);
   3.244          }
   3.245      };
   3.246 @@ -517,13 +562,9 @@
   3.247  
   3.248          List<FreeTypeListener> freetypeListeners = List.nil();
   3.249  
   3.250 -        public InferenceContext(List<Type> inferencevars, Types types) {
   3.251 -            this.undetvars = Type.map(inferencevars, fromTypeVarFun);
   3.252 +        public InferenceContext(List<Type> inferencevars, Infer infer) {
   3.253 +            this.undetvars = Type.map(inferencevars, infer.fromTypeVarFun);
   3.254              this.inferencevars = inferencevars;
   3.255 -            for (Type t : this.undetvars) {
   3.256 -                UndetVar uv = (UndetVar)t;
   3.257 -                uv.hibounds = types.getBounds((TypeVar)uv.qtype);
   3.258 -            }
   3.259          }
   3.260  
   3.261          /**
   3.262 @@ -669,5 +710,5 @@
   3.263          }
   3.264      }
   3.265  
   3.266 -    final InferenceContext emptyContext = new InferenceContext(List.<Type>nil(), types);
   3.267 +    final InferenceContext emptyContext = new InferenceContext(List.<Type>nil(), this);
   3.268  }
     4.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Tue Sep 25 11:55:34 2012 +0100
     4.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Tue Sep 25 11:56:46 2012 +0100
     4.3 @@ -737,7 +737,7 @@
     4.4          return attr.new ResultInfo(VAL, to, checkContext) {
     4.5              @Override
     4.6              protected Type check(DiagnosticPosition pos, Type found) {
     4.7 -                return super.check(pos, chk.checkNonVoid(pos, types.capture(types.upperBound(found))));
     4.8 +                return super.check(pos, chk.checkNonVoid(pos, types.capture(types.upperBound(found.baseType()))));
     4.9              }
    4.10          };
    4.11      }
     5.1 --- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Sep 25 11:55:34 2012 +0100
     5.2 +++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Sep 25 11:56:46 2012 +0100
     5.3 @@ -1652,6 +1652,18 @@
     5.4  compiler.misc.incompatible.upper.bounds=\
     5.5      inference variable {0} has incompatible upper bounds {1}
     5.6  
     5.7 +# 0: type, 1: list of type, 2: list of type
     5.8 +compiler.misc.incompatible.eq.upper.bounds=\
     5.9 +    inference variable {0} has incompatible bounds\n\
    5.10 +    equality constraints: {1}\n\
    5.11 +    upper bounds: {2}
    5.12 +
    5.13 +# 0: type, 1: list of type, 2: list of type
    5.14 +compiler.misc.incompatible.eq.lower.bounds=\
    5.15 +    inference variable {0} has incompatible bounds\n\
    5.16 +    equality constraints: {1}\n\
    5.17 +    lower bounds: {2}
    5.18 +
    5.19  # 0: list of type, 1: type, 2: type
    5.20  compiler.misc.infer.no.conforming.instance.exists=\
    5.21      no instance(s) of type variable(s) {0} exist so that {1} conforms to {2}
     6.1 --- a/test/tools/javac/6758789/T6758789b.out	Tue Sep 25 11:55:34 2012 +0100
     6.2 +++ b/test/tools/javac/6758789/T6758789b.out	Tue Sep 25 11:56:46 2012 +0100
     6.3 @@ -1,4 +1,4 @@
     6.4 -T6758789b.java:16:11: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T6758789a.Foo, T6758789a.Foo<java.lang.Object>
     6.5 +T6758789b.java:16:11: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T6758789a.Foo, T6758789a.Foo<X>
     6.6  T6758789b.java:16:10: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, T6758789a.Foo<X>, T6758789a.Foo, kindname.class, T6758789a
     6.7  - compiler.err.warnings.and.werror
     6.8  1 error
     7.1 --- a/test/tools/javac/diags/examples.not-yet.txt	Tue Sep 25 11:55:34 2012 +0100
     7.2 +++ b/test/tools/javac/diags/examples.not-yet.txt	Tue Sep 25 11:56:46 2012 +0100
     7.3 @@ -65,6 +65,7 @@
     7.4  compiler.misc.kindname.type.variable
     7.5  compiler.misc.kindname.type.variable.bound
     7.6  compiler.misc.kindname.value
     7.7 +compiler.misc.incompatible.eq.lower.bounds              # cannot happen?
     7.8  compiler.misc.no.unique.minimal.instance.exists
     7.9  compiler.misc.resume.abort                              # prompt for a response
    7.10  compiler.misc.source.unavailable                        # DiagnosticSource
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/test/tools/javac/diags/examples/IncompatibleEqUpperBounds.java	Tue Sep 25 11:56:46 2012 +0100
     8.3 @@ -0,0 +1,35 @@
     8.4 +/*
     8.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
     8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.7 + *
     8.8 + * This code is free software; you can redistribute it and/or modify it
     8.9 + * under the terms of the GNU General Public License version 2 only, as
    8.10 + * published by the Free Software Foundation.
    8.11 + *
    8.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    8.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    8.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    8.15 + * version 2 for more details (a copy is included in the LICENSE file that
    8.16 + * accompanied this code).
    8.17 + *
    8.18 + * You should have received a copy of the GNU General Public License version
    8.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    8.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    8.21 + *
    8.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    8.23 + * or visit www.oracle.com if you need additional information or have any
    8.24 + * questions.
    8.25 + */
    8.26 +
    8.27 +//key: compiler.err.cant.apply.symbol.1
    8.28 +//key: compiler.misc.incompatible.eq.upper.bounds
    8.29 +
    8.30 +import java.util.List;
    8.31 +
    8.32 +class IncompatibleEqUpperBounds {
    8.33 +    <S, T extends List<S>> void m(List<? super S> s1, T s2) { }
    8.34 +
    8.35 +    void test(List<Integer> li, List<String> ls) {
    8.36 +        m(li, ls);
    8.37 +    }
    8.38 +}
     9.1 --- a/test/tools/javac/generics/7015430/T7015430.out	Tue Sep 25 11:55:34 2012 +0100
     9.2 +++ b/test/tools/javac/generics/7015430/T7015430.out	Tue Sep 25 11:56:46 2012 +0100
     9.3 @@ -1,14 +1,14 @@
     9.4 -T7015430.java:41:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception>
     9.5 +T7015430.java:41:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
     9.6  T7015430.java:41:14: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
     9.7  T7015430.java:50:42: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
     9.8  T7015430.java:50:41: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
     9.9 -T7015430.java:68:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception>
    9.10 +T7015430.java:68:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
    9.11  T7015430.java:68:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
    9.12  T7015430.java:77:40: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
    9.13  T7015430.java:77:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
    9.14  T7015430.java:104:41: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
    9.15  T7015430.java:104:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
    9.16 -T7015430.java:113:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception>
    9.17 +T7015430.java:113:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
    9.18  T7015430.java:113:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
    9.19  T7015430.java:41:14: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
    9.20  T7015430.java:68:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
    10.1 --- a/test/tools/javac/generics/7151802/T7151802.out	Tue Sep 25 11:55:34 2012 +0100
    10.2 +++ b/test/tools/javac/generics/7151802/T7151802.out	Tue Sep 25 11:56:46 2012 +0100
    10.3 @@ -1,5 +1,5 @@
    10.4  T7151802.java:14:31: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get1, Z, T7151802.Foo, kindname.class, T7151802
    10.5 -T7151802.java:22:31: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo<java.lang.Object>
    10.6 +T7151802.java:22:31: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo<Z>
    10.7  T7151802.java:22:30: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get3, T7151802.Foo<Z>, T7151802.Foo, kindname.class, T7151802
    10.8  T7151802.java:30:36: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get5, compiler.misc.no.args, compiler.misc.no.args, kindname.class, T7151802
    10.9  T7151802.java:38:32: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo<java.lang.String>
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/test/tools/javac/generics/inference/7177306/T7177306a.java	Tue Sep 25 11:56:46 2012 +0100
    11.3 @@ -0,0 +1,19 @@
    11.4 +/**
    11.5 + * @test /nodynamiccopyright/
    11.6 + * @bug 7177306
    11.7 + * @summary Regression: unchecked method call does not erase return type
    11.8 + * @compile/fail/ref=T7177306a.out -Werror -Xlint:unchecked -XDrawDiagnostics T7177306a.java
    11.9 + */
   11.10 +
   11.11 +import java.util.List;
   11.12 +
   11.13 +class T7177306a<A> {
   11.14 +
   11.15 +    public static void test(List l) {
   11.16 +        T7177306a<Object> to = m(l);
   11.17 +    }
   11.18 +
   11.19 +    public static <E> T7177306a<String> m(List<E> le) {
   11.20 +        return null;
   11.21 +    }
   11.22 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/test/tools/javac/generics/inference/7177306/T7177306a.out	Tue Sep 25 11:56:46 2012 +0100
    12.3 @@ -0,0 +1,6 @@
    12.4 +T7177306a.java:13:34: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.util.List, java.util.List<E>
    12.5 +T7177306a.java:13:33: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, java.util.List<E>, java.util.List, kindname.class, T7177306a
    12.6 +T7177306a.java:13:33: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7177306a, T7177306a<java.lang.Object>
    12.7 +- compiler.err.warnings.and.werror
    12.8 +1 error
    12.9 +3 warnings
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/test/tools/javac/generics/inference/7177306/T7177306b.java	Tue Sep 25 11:56:46 2012 +0100
    13.3 @@ -0,0 +1,18 @@
    13.4 +/**
    13.5 + * @test /nodynamiccopyright/
    13.6 + * @bug 7177306
    13.7 + * @summary Regression: unchecked method call does not erase return type
    13.8 + * @compile/fail/ref=T7177306b.out -Werror -Xlint:unchecked -XDrawDiagnostics T7177306b.java
    13.9 + */
   13.10 +
   13.11 +import java.util.List;
   13.12 +
   13.13 +class T7177306b {
   13.14 +
   13.15 +    <T, S extends List<T>> List<T> m(List<? super T> arg1, S arg2, Class<Object> arg3) { return arg2; }
   13.16 +
   13.17 +    void test(List<Integer> li, List<String> ls, Class c) {
   13.18 +        m(li, ls, c);
   13.19 +        // should fail, because of bounds T <: Integer, S :> List<String>
   13.20 +    }
   13.21 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/test/tools/javac/generics/inference/7177306/T7177306b.out	Tue Sep 25 11:56:46 2012 +0100
    14.3 @@ -0,0 +1,2 @@
    14.4 +T7177306b.java:15:9: compiler.err.cant.apply.symbol.1: kindname.method, m, java.util.List<? super T>,S,java.lang.Class<java.lang.Object>, java.util.List<java.lang.Integer>,java.util.List<java.lang.String>,java.lang.Class, kindname.class, T7177306b, (compiler.misc.incompatible.eq.upper.bounds: T, java.lang.String, java.lang.Integer,java.lang.Object)
    14.5 +1 error
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/test/tools/javac/generics/inference/7177306/T7177306c.java	Tue Sep 25 11:56:46 2012 +0100
    15.3 @@ -0,0 +1,38 @@
    15.4 +/*
    15.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
    15.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    15.7 + *
    15.8 + * This code is free software; you can redistribute it and/or modify it
    15.9 + * under the terms of the GNU General Public License version 2 only, as
   15.10 + * published by the Free Software Foundation.
   15.11 + *
   15.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   15.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   15.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   15.15 + * version 2 for more details (a copy is included in the LICENSE file that
   15.16 + * accompanied this code).
   15.17 + *
   15.18 + * You should have received a copy of the GNU General Public License version
   15.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   15.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   15.21 + *
   15.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   15.23 + * or visit www.oracle.com if you need additional information or have any
   15.24 + * questions.
   15.25 + */
   15.26 +
   15.27 +/*
   15.28 + * @test
   15.29 + * @bug 7177306
   15.30 + * @summary Regression: unchecked method call does not erase return type
   15.31 + */
   15.32 +public class T7177306c {
   15.33 +
   15.34 +    static <T> T m(T t) { return (T)"Null"; }
   15.35 +
   15.36 +    public static void main(String[] args) {
   15.37 +        if (m("NonNullConst") != "Null") {
   15.38 +            throw new AssertionError("should not get there!");
   15.39 +        }
   15.40 +    }
   15.41 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/test/tools/javac/generics/inference/7177306/T7177306d.java	Tue Sep 25 11:56:46 2012 +0100
    16.3 @@ -0,0 +1,53 @@
    16.4 +/*
    16.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
    16.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    16.7 + *
    16.8 + * This code is free software; you can redistribute it and/or modify it
    16.9 + * under the terms of the GNU General Public License version 2 only, as
   16.10 + * published by the Free Software Foundation.
   16.11 + *
   16.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   16.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   16.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   16.15 + * version 2 for more details (a copy is included in the LICENSE file that
   16.16 + * accompanied this code).
   16.17 + *
   16.18 + * You should have received a copy of the GNU General Public License version
   16.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   16.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   16.21 + *
   16.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   16.23 + * or visit www.oracle.com if you need additional information or have any
   16.24 + * questions.
   16.25 + */
   16.26 +
   16.27 +/*
   16.28 + * @test
   16.29 + * @bug 7177306
   16.30 + * @summary Regression: unchecked method call does not erase return type
   16.31 + */
   16.32 +import java.util.List;
   16.33 +
   16.34 +public class T7177306d {
   16.35 +
   16.36 +    static int assertionCount = 0;
   16.37 +
   16.38 +    static void assertTrue(boolean cond) {
   16.39 +        if (!cond) {
   16.40 +            throw new AssertionError();
   16.41 +        }
   16.42 +        assertionCount++;
   16.43 +    }
   16.44 +
   16.45 +    static <T, S extends List<T>> void m(List<? super T> arg1, S arg2, Class<Object> arg3) { assertTrue(false); }
   16.46 +    static void m(Object o1, Object o2, Object o3) { assertTrue(true); }
   16.47 +
   16.48 +    static void test(List<Integer> li, List<String> ls, Class c) {
   16.49 +        m(li, ls, c);
   16.50 +    }
   16.51 +
   16.52 +    public static void main(String[] args) {
   16.53 +        test(null, null, null);
   16.54 +        assertTrue(assertionCount == 1);
   16.55 +    }
   16.56 +}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/test/tools/javac/generics/inference/7177306/T7177306e.java	Tue Sep 25 11:56:46 2012 +0100
    17.3 @@ -0,0 +1,17 @@
    17.4 +/**
    17.5 + * @test /nodynamiccopyright/
    17.6 + * @bug 7177306
    17.7 + * @summary Regression: unchecked method call does not erase return type
    17.8 + * @compile/fail/ref=T7177306e.out -XDrawDiagnostics T7177306e.java
    17.9 + */
   17.10 +
   17.11 +import java.util.List;
   17.12 +
   17.13 +class T7177306e {
   17.14 +
   17.15 +    <Z, U extends List<Z>> void m(List<U> lu) { }
   17.16 +
   17.17 +    void test(List<List<?>> llw) {
   17.18 +       m(llw);
   17.19 +    }
   17.20 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/test/tools/javac/generics/inference/7177306/T7177306e.out	Tue Sep 25 11:56:46 2012 +0100
    18.3 @@ -0,0 +1,2 @@
    18.4 +T7177306e.java:15:9: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.util.List<?>, java.util.List<compiler.misc.type.captureof: 1, ?>)
    18.5 +1 error

mercurial