changeset 1567:ad2ca2a4ab5e

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
author mcimadamore
date Tue, 25 Sep 2012 11:56:46 +0100
parents 2eca84194807
children 0e5899f09dab
files src/share/classes/com/sun/tools/javac/code/Type.java src/share/classes/com/sun/tools/javac/code/Types.java src/share/classes/com/sun/tools/javac/comp/Infer.java src/share/classes/com/sun/tools/javac/comp/Resolve.java src/share/classes/com/sun/tools/javac/resources/compiler.properties test/tools/javac/6758789/T6758789b.out test/tools/javac/diags/examples.not-yet.txt test/tools/javac/diags/examples/IncompatibleEqUpperBounds.java test/tools/javac/generics/7015430/T7015430.out test/tools/javac/generics/7151802/T7151802.out test/tools/javac/generics/inference/7177306/T7177306a.java test/tools/javac/generics/inference/7177306/T7177306a.out test/tools/javac/generics/inference/7177306/T7177306b.java test/tools/javac/generics/inference/7177306/T7177306b.out test/tools/javac/generics/inference/7177306/T7177306c.java test/tools/javac/generics/inference/7177306/T7177306d.java test/tools/javac/generics/inference/7177306/T7177306e.java test/tools/javac/generics/inference/7177306/T7177306e.out
diffstat 18 files changed, 379 insertions(+), 68 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/code/Type.java	Tue Sep 25 11:55:34 2012 +0100
+++ b/src/share/classes/com/sun/tools/javac/code/Type.java	Tue Sep 25 11:56:46 2012 +0100
@@ -30,6 +30,10 @@
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.code.Symbol.*;
 
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
 import javax.lang.model.type.*;
 
 import static com.sun.tools.javac.code.Flags.*;
@@ -1168,22 +1172,55 @@
         }
     }
 
-    /** A class for instantiatable variables, for use during type
-     *  inference.
+    /** A class for inference variables, for use during method/diamond type
+     *  inference. An inference variable has upper/lower bounds and a set
+     *  of equality constraints. Such bounds are set during subtyping, type-containment,
+     *  type-equality checks, when the types being tested contain inference variables.
+     *  A change listener can be attached to an inference variable, to receive notifications
+     *  whenever the bounds of an inference variable change.
      */
     public static class UndetVar extends DelegatedType {
-        public List<Type> lobounds = List.nil();
-        public List<Type> hibounds = List.nil();
-        public List<Type> eq = List.nil();
+
+        /** Inference variable change listener. The listener method is called
+         *  whenever a change to the inference variable's bounds occurs
+         */
+        public interface UndetVarListener {
+            /** called when some inference variable bounds (of given kinds ibs) change */
+            void varChanged(UndetVar uv, Set<InferenceBound> ibs);
+        }
+
+        /**
+         * Inference variable bound kinds
+         */
+        public enum InferenceBound {
+            /** upper bounds */
+            UPPER,
+            /** lower bounds */
+            LOWER,
+            /** equality constraints */
+            EQ;
+        }
+
+        /** inference variable bounds */
+        private Map<InferenceBound, List<Type>> bounds;
+
+        /** inference variable's inferred type (set from Infer.java) */
         public Type inst = null;
 
+        /** inference variable's change listener */
+        public UndetVarListener listener = null;
+
         @Override
         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
             return v.visitUndetVar(this, s);
         }
 
-        public UndetVar(Type origin) {
+        public UndetVar(TypeVar origin, Types types) {
             super(UNDETVAR, origin);
+            bounds = new EnumMap<InferenceBound, List<Type>>(InferenceBound.class);
+            bounds.put(InferenceBound.UPPER, types.getBounds(origin));
+            bounds.put(InferenceBound.LOWER, List.<Type>nil());
+            bounds.put(InferenceBound.EQ, List.<Type>nil());
         }
 
         public String toString() {
@@ -1195,6 +1232,48 @@
             if (inst != null) return inst.baseType();
             else return this;
         }
+
+        /** get all bounds of a given kind */
+        public List<Type> getBounds(InferenceBound ib) {
+            return bounds.get(ib);
+        }
+
+        /** add a bound of a given kind - this might trigger listener notification */
+        public void addBound(InferenceBound ib, Type bound, Types types) {
+            List<Type> prevBounds = bounds.get(ib);
+            for (Type b : prevBounds) {
+                if (types.isSameType(b, bound)) {
+                    return;
+                }
+            }
+            bounds.put(ib, prevBounds.prepend(bound));
+            notifyChange(EnumSet.of(ib));
+        }
+
+        /** replace types in all bounds - this might trigger listener notification */
+        public void substBounds(List<Type> from, List<Type> to, Types types) {
+            EnumSet<InferenceBound> changed = EnumSet.noneOf(InferenceBound.class);
+            Map<InferenceBound, List<Type>> bounds2 = new EnumMap<InferenceBound, List<Type>>(InferenceBound.class);
+            for (Map.Entry<InferenceBound, List<Type>> _entry : bounds.entrySet()) {
+                InferenceBound ib = _entry.getKey();
+                List<Type> prevBounds = _entry.getValue();
+                List<Type> newBounds = types.subst(prevBounds, from, to);
+                bounds2.put(ib, newBounds);
+                if (prevBounds != newBounds) {
+                    changed.add(ib);
+                }
+            }
+            if (!changed.isEmpty()) {
+                bounds = bounds2;
+                notifyChange(changed);
+            }
+        }
+
+        private void notifyChange(EnumSet<InferenceBound> ibs) {
+            if (listener != null) {
+                listener.varChanged(this, ibs);
+            }
+        }
     }
 
     /** Represents VOID or NONE.
--- a/src/share/classes/com/sun/tools/javac/code/Types.java	Tue Sep 25 11:55:34 2012 +0100
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Tue Sep 25 11:56:46 2012 +0100
@@ -34,6 +34,7 @@
 import com.sun.tools.javac.jvm.ClassReader;
 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
 import com.sun.tools.javac.code.Lint.LintCategory;
+import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
 import com.sun.tools.javac.comp.Check;
 
 import static com.sun.tools.javac.code.Scope.*;
@@ -510,7 +511,7 @@
                     return false;
                 }
 
-                t.hibounds = t.hibounds.prepend(s);
+                t.addBound(InferenceBound.UPPER, s, Types.this);
                 return true;
             }
 
@@ -578,7 +579,7 @@
                 undet.qtype == s ||
                 s.tag == ERROR ||
                 s.tag == BOT) return true;
-            undet.lobounds = undet.lobounds.prepend(s);
+            undet.addBound(InferenceBound.LOWER, s, this);
             return true;
         }
         default:
@@ -723,7 +724,7 @@
                 if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN)
                     return true;
 
-                t.eq = t.eq.prepend(s);
+                t.addBound(InferenceBound.EQ, s, Types.this);
 
                 return true;
             }
@@ -735,19 +736,6 @@
         };
     // </editor-fold>
 
-    // <editor-fold defaultstate="collapsed" desc="fromUnknownFun">
-    /**
-     * A mapping that turns all unknown types in this type to fresh
-     * unknown variables.
-     */
-    public Mapping fromUnknownFun = new Mapping("fromUnknownFun") {
-            public Type apply(Type t) {
-                if (t.tag == UNKNOWN) return new UndetVar(t);
-                else return t.map(this);
-            }
-        };
-    // </editor-fold>
-
     // <editor-fold defaultstate="collapsed" desc="Contains Type">
     public boolean containedBy(Type t, Type s) {
         switch (t.tag) {
@@ -759,12 +747,12 @@
                     case UNBOUND: //similar to ? extends Object
                     case EXTENDS: {
                         Type bound = upperBound(s);
-                        undetvar.hibounds = undetvar.hibounds.prepend(bound);
+                        undetvar.addBound(InferenceBound.UPPER, bound, this);
                         break;
                     }
                     case SUPER: {
                         Type bound = lowerBound(s);
-                        undetvar.lobounds = undetvar.lobounds.prepend(bound);
+                        undetvar.addBound(InferenceBound.LOWER, bound, this);
                         break;
                     }
                 }
--- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Tue Sep 25 11:55:34 2012 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Tue Sep 25 11:56:46 2012 +0100
@@ -28,6 +28,7 @@
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Type.*;
+import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
 import com.sun.tools.javac.comp.Resolve.InapplicableMethodException;
 import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode;
 import com.sun.tools.javac.tree.JCTree;
@@ -39,6 +40,7 @@
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
 
 import static com.sun.tools.javac.code.TypeTags.*;
 
@@ -120,8 +122,8 @@
      *  Throw a NoInstanceException if this not possible.
      */
    void maximizeInst(UndetVar that, Warner warn) throws InferenceException {
-        List<Type> hibounds = Type.filter(that.hibounds, boundFilter);
-        if (that.eq.isEmpty()) {
+        List<Type> hibounds = Type.filter(that.getBounds(InferenceBound.UPPER), boundFilter);
+        if (that.getBounds(InferenceBound.EQ).isEmpty()) {
             if (hibounds.isEmpty())
                 that.inst = syms.objectType;
             else if (hibounds.tail.isEmpty())
@@ -129,7 +131,7 @@
             else
                 that.inst = types.glb(hibounds);
         } else {
-            that.inst = that.eq.head;
+            that.inst = that.getBounds(InferenceBound.EQ).head;
         }
         if (that.inst == null ||
             that.inst.isErroneous())
@@ -149,8 +151,8 @@
      *  Throw a NoInstanceException if this not possible.
      */
     void minimizeInst(UndetVar that, Warner warn) throws InferenceException {
-        List<Type> lobounds = Type.filter(that.lobounds, boundFilter);
-        if (that.eq.isEmpty()) {
+        List<Type> lobounds = Type.filter(that.getBounds(InferenceBound.LOWER), boundFilter);
+        if (that.getBounds(InferenceBound.EQ).isEmpty()) {
             if (lobounds.isEmpty()) {
                 //do nothing - the inference variable is under-constrained
                 return;
@@ -164,7 +166,7 @@
                         .setMessage("no.unique.minimal.instance.exists",
                                     that.qtype, lobounds);
         } else {
-            that.inst = that.eq.head;
+            that.inst = that.getBounds(InferenceBound.EQ).head;
         }
     }
 
@@ -201,7 +203,8 @@
             boolean stuck = true;
             for (Type t : inferenceContext.undetvars) {
                 UndetVar uv = (UndetVar)t;
-                if (uv.inst == null && (uv.eq.nonEmpty() || !inferenceContext.free(uv.hibounds))) {
+                if (uv.inst == null && (uv.getBounds(InferenceBound.EQ).nonEmpty() ||
+                        !inferenceContext.free(uv.getBounds(InferenceBound.UPPER)))) {
                     maximizeInst((UndetVar)t, warn);
                     stuck = false;
                 }
@@ -219,7 +222,7 @@
                 //variables in remaining upper bounds and continue
                 for (Type t : inferenceContext.undetvars) {
                     UndetVar uv = (UndetVar)t;
-                    uv.hibounds = inferenceContext.asInstTypes(uv.hibounds, types);
+                    uv.substBounds(inferenceContext.inferenceVars(), inferenceContext.instTypes(), types);
                 }
             }
         }
@@ -235,7 +238,7 @@
             UndetVar uv = (UndetVar)t;
             if (uv.inst == null) {
                 TypeSymbol fresh_tvar = new TypeSymbol(Flags.SYNTHETIC, uv.qtype.tsym.name, null, uv.qtype.tsym.owner);
-                fresh_tvar.type = new TypeVar(fresh_tvar, types.makeCompoundType(uv.hibounds), null);
+                fresh_tvar.type = new TypeVar(fresh_tvar, types.makeCompoundType(uv.getBounds(InferenceBound.UPPER)), null);
                 todo.append(uv);
                 uv.inst = fresh_tvar.type;
             }
@@ -267,7 +270,7 @@
                                   boolean useVarargs,
                                   Warner warn) throws InferenceException {
         //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
-        final InferenceContext inferenceContext = new InferenceContext(tvars, types);
+        final InferenceContext inferenceContext = new InferenceContext(tvars, this);
         inferenceException.clear();
 
         try {
@@ -286,7 +289,7 @@
             List<Type> restvars = inferenceContext.restvars();
 
             if (!restvars.isEmpty()) {
-                if (resultInfo != null) {
+                if (resultInfo != null && !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
                     instantiateUninferred(env.tree.pos(), inferenceContext, mt, resultInfo, warn);
                     checkWithinBounds(inferenceContext, warn);
                     mt = (MethodType)inferenceContext.asInstType(mt, types);
@@ -332,34 +335,58 @@
     /** check that type parameters are within their bounds.
      */
     void checkWithinBounds(InferenceContext inferenceContext,
-                           Warner warn)
-        throws InferenceException {
-        List<Type> tvars = inferenceContext.inferenceVars();
+                           Warner warn) throws InferenceException {
+        //step 1 - check compatibility of instantiated type w.r.t. initial bounds
         for (Type t : inferenceContext.undetvars) {
             UndetVar uv = (UndetVar)t;
-            uv.hibounds = inferenceContext.asInstTypes(uv.hibounds, types);
-            uv.lobounds = inferenceContext.asInstTypes(uv.lobounds, types);
-            uv.eq = inferenceContext.asInstTypes(uv.eq, types);
+            uv.substBounds(inferenceContext.inferenceVars(), inferenceContext.instTypes(), types);
             checkCompatibleUpperBounds(uv, inferenceContext.inferenceVars());
-            if (!inferenceContext.restvars().contains(tvars.head)) {
+            if (!inferenceContext.restvars().contains(uv.qtype)) {
                 Type inst = inferenceContext.asInstType(t, types);
-                for (Type u : uv.hibounds) {
+                for (Type u : uv.getBounds(InferenceBound.UPPER)) {
                     if (!types.isSubtypeUnchecked(inst, inferenceContext.asFree(u, types), warn)) {
                         reportBoundError(uv, BoundErrorKind.UPPER);
                     }
                 }
-                for (Type l : uv.lobounds) {
-                    if (!types.isSubtypeUnchecked(inferenceContext.asFree(l, types), inst, warn)) {
+                for (Type l : uv.getBounds(InferenceBound.LOWER)) {
+                    Assert.check(!inferenceContext.free(l));
+                    if (!types.isSubtypeUnchecked(l, inst, warn)) {
                         reportBoundError(uv, BoundErrorKind.LOWER);
                     }
                 }
-                for (Type e : uv.eq) {
-                    if (!types.isSameType(inst, inferenceContext.asFree(e, types))) {
+                for (Type e : uv.getBounds(InferenceBound.EQ)) {
+                    Assert.check(!inferenceContext.free(e));
+                    if (!types.isSameType(inst, e)) {
                         reportBoundError(uv, BoundErrorKind.EQ);
                     }
                 }
             }
-            tvars = tvars.tail;
+        }
+
+        //step 2 - check that eq bounds are consistent w.r.t. eq/lower bounds
+        for (Type t : inferenceContext.undetvars) {
+            UndetVar uv = (UndetVar)t;
+            //check eq bounds consistency
+            Type eq = null;
+            for (Type e : uv.getBounds(InferenceBound.EQ)) {
+                Assert.check(!inferenceContext.free(e));
+                if (eq != null && !types.isSameType(e, eq)) {
+                    reportBoundError(uv, BoundErrorKind.EQ);
+                }
+                eq = e;
+                for (Type l : uv.getBounds(InferenceBound.LOWER)) {
+                    Assert.check(!inferenceContext.free(l));
+                    if (!types.isSubtypeUnchecked(l, e, warn)) {
+                        reportBoundError(uv, BoundErrorKind.BAD_EQ_LOWER);
+                    }
+                }
+                for (Type u : uv.getBounds(InferenceBound.UPPER)) {
+                    if (inferenceContext.free(u)) continue;
+                    if (!types.isSubtypeUnchecked(e, u, warn)) {
+                        reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER);
+                    }
+                }
+            }
         }
     }
 
@@ -367,7 +394,7 @@
         // VGJ: sort of inlined maximizeInst() below.  Adding
         // bounds can cause lobounds that are above hibounds.
         ListBuffer<Type> hiboundsNoVars = ListBuffer.lb();
-        for (Type t : Type.filter(uv.hibounds, boundFilter)) {
+        for (Type t : Type.filter(uv.getBounds(InferenceBound.UPPER), boundFilter)) {
             if (!t.containsAny(tvars)) {
                 hiboundsNoVars.append(t);
             }
@@ -388,25 +415,43 @@
         BAD_UPPER() {
             @Override
             InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
-                return ex.setMessage("incompatible.upper.bounds", uv.qtype, uv.hibounds);
+                return ex.setMessage("incompatible.upper.bounds", uv.qtype,
+                        uv.getBounds(InferenceBound.UPPER));
+            }
+        },
+        BAD_EQ_UPPER() {
+            @Override
+            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
+                return ex.setMessage("incompatible.eq.upper.bounds", uv.qtype,
+                        uv.getBounds(InferenceBound.EQ), uv.getBounds(InferenceBound.UPPER));
+            }
+        },
+        BAD_EQ_LOWER() {
+            @Override
+            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
+                return ex.setMessage("incompatible.eq.lower.bounds", uv.qtype,
+                        uv.getBounds(InferenceBound.EQ), uv.getBounds(InferenceBound.LOWER));
             }
         },
         UPPER() {
             @Override
             InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
-                return ex.setMessage("inferred.do.not.conform.to.upper.bounds", uv.inst, uv.hibounds);
+                return ex.setMessage("inferred.do.not.conform.to.upper.bounds", uv.inst,
+                        uv.getBounds(InferenceBound.UPPER));
             }
         },
         LOWER() {
             @Override
             InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
-                return ex.setMessage("inferred.do.not.conform.to.lower.bounds", uv.inst, uv.lobounds);
+                return ex.setMessage("inferred.do.not.conform.to.lower.bounds", uv.inst,
+                        uv.getBounds(InferenceBound.LOWER));
             }
         },
         EQ() {
             @Override
             InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
-                return ex.setMessage("inferred.do.not.conform.to.eq.bounds", uv.inst, uv.eq);
+                return ex.setMessage("inferred.do.not.conform.to.eq.bounds", uv.inst,
+                        uv.getBounds(InferenceBound.EQ));
             }
         };
 
@@ -480,9 +525,9 @@
      * Mapping that turns inference variables into undet vars
      * (used by inference context)
      */
-    static Mapping fromTypeVarFun = new Mapping("fromTypeVarFun") {
+    Mapping fromTypeVarFun = new Mapping("fromTypeVarFun") {
         public Type apply(Type t) {
-            if (t.tag == TYPEVAR) return new UndetVar(t);
+            if (t.tag == TYPEVAR) return new UndetVar((TypeVar)t, types);
             else return t.map(this);
         }
     };
@@ -517,13 +562,9 @@
 
         List<FreeTypeListener> freetypeListeners = List.nil();
 
-        public InferenceContext(List<Type> inferencevars, Types types) {
-            this.undetvars = Type.map(inferencevars, fromTypeVarFun);
+        public InferenceContext(List<Type> inferencevars, Infer infer) {
+            this.undetvars = Type.map(inferencevars, infer.fromTypeVarFun);
             this.inferencevars = inferencevars;
-            for (Type t : this.undetvars) {
-                UndetVar uv = (UndetVar)t;
-                uv.hibounds = types.getBounds((TypeVar)uv.qtype);
-            }
         }
 
         /**
@@ -669,5 +710,5 @@
         }
     }
 
-    final InferenceContext emptyContext = new InferenceContext(List.<Type>nil(), types);
+    final InferenceContext emptyContext = new InferenceContext(List.<Type>nil(), this);
 }
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Tue Sep 25 11:55:34 2012 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Tue Sep 25 11:56:46 2012 +0100
@@ -737,7 +737,7 @@
         return attr.new ResultInfo(VAL, to, checkContext) {
             @Override
             protected Type check(DiagnosticPosition pos, Type found) {
-                return super.check(pos, chk.checkNonVoid(pos, types.capture(types.upperBound(found))));
+                return super.check(pos, chk.checkNonVoid(pos, types.capture(types.upperBound(found.baseType()))));
             }
         };
     }
--- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Sep 25 11:55:34 2012 +0100
+++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Sep 25 11:56:46 2012 +0100
@@ -1652,6 +1652,18 @@
 compiler.misc.incompatible.upper.bounds=\
     inference variable {0} has incompatible upper bounds {1}
 
+# 0: type, 1: list of type, 2: list of type
+compiler.misc.incompatible.eq.upper.bounds=\
+    inference variable {0} has incompatible bounds\n\
+    equality constraints: {1}\n\
+    upper bounds: {2}
+
+# 0: type, 1: list of type, 2: list of type
+compiler.misc.incompatible.eq.lower.bounds=\
+    inference variable {0} has incompatible bounds\n\
+    equality constraints: {1}\n\
+    lower bounds: {2}
+
 # 0: list of type, 1: type, 2: type
 compiler.misc.infer.no.conforming.instance.exists=\
     no instance(s) of type variable(s) {0} exist so that {1} conforms to {2}
--- a/test/tools/javac/6758789/T6758789b.out	Tue Sep 25 11:55:34 2012 +0100
+++ b/test/tools/javac/6758789/T6758789b.out	Tue Sep 25 11:56:46 2012 +0100
@@ -1,4 +1,4 @@
-T6758789b.java:16:11: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T6758789a.Foo, T6758789a.Foo<java.lang.Object>
+T6758789b.java:16:11: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T6758789a.Foo, T6758789a.Foo<X>
 T6758789b.java:16:10: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, T6758789a.Foo<X>, T6758789a.Foo, kindname.class, T6758789a
 - compiler.err.warnings.and.werror
 1 error
--- a/test/tools/javac/diags/examples.not-yet.txt	Tue Sep 25 11:55:34 2012 +0100
+++ b/test/tools/javac/diags/examples.not-yet.txt	Tue Sep 25 11:56:46 2012 +0100
@@ -65,6 +65,7 @@
 compiler.misc.kindname.type.variable
 compiler.misc.kindname.type.variable.bound
 compiler.misc.kindname.value
+compiler.misc.incompatible.eq.lower.bounds              # cannot happen?
 compiler.misc.no.unique.minimal.instance.exists
 compiler.misc.resume.abort                              # prompt for a response
 compiler.misc.source.unavailable                        # DiagnosticSource
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/IncompatibleEqUpperBounds.java	Tue Sep 25 11:56:46 2012 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+//key: compiler.err.cant.apply.symbol.1
+//key: compiler.misc.incompatible.eq.upper.bounds
+
+import java.util.List;
+
+class IncompatibleEqUpperBounds {
+    <S, T extends List<S>> void m(List<? super S> s1, T s2) { }
+
+    void test(List<Integer> li, List<String> ls) {
+        m(li, ls);
+    }
+}
--- a/test/tools/javac/generics/7015430/T7015430.out	Tue Sep 25 11:55:34 2012 +0100
+++ b/test/tools/javac/generics/7015430/T7015430.out	Tue Sep 25 11:56:46 2012 +0100
@@ -1,14 +1,14 @@
-T7015430.java:41:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception>
+T7015430.java:41:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
 T7015430.java:41:14: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
 T7015430.java:50:42: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
 T7015430.java:50:41: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:68:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception>
+T7015430.java:68:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
 T7015430.java:68:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
 T7015430.java:77:40: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
 T7015430.java:77:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
 T7015430.java:104:41: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
 T7015430.java:104:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:113:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception>
+T7015430.java:113:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
 T7015430.java:113:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
 T7015430.java:41:14: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
 T7015430.java:68:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
--- a/test/tools/javac/generics/7151802/T7151802.out	Tue Sep 25 11:55:34 2012 +0100
+++ b/test/tools/javac/generics/7151802/T7151802.out	Tue Sep 25 11:56:46 2012 +0100
@@ -1,5 +1,5 @@
 T7151802.java:14:31: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get1, Z, T7151802.Foo, kindname.class, T7151802
-T7151802.java:22:31: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo<java.lang.Object>
+T7151802.java:22:31: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo<Z>
 T7151802.java:22:30: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get3, T7151802.Foo<Z>, T7151802.Foo, kindname.class, T7151802
 T7151802.java:30:36: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get5, compiler.misc.no.args, compiler.misc.no.args, kindname.class, T7151802
 T7151802.java:38:32: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo<java.lang.String>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/inference/7177306/T7177306a.java	Tue Sep 25 11:56:46 2012 +0100
@@ -0,0 +1,19 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 7177306
+ * @summary Regression: unchecked method call does not erase return type
+ * @compile/fail/ref=T7177306a.out -Werror -Xlint:unchecked -XDrawDiagnostics T7177306a.java
+ */
+
+import java.util.List;
+
+class T7177306a<A> {
+
+    public static void test(List l) {
+        T7177306a<Object> to = m(l);
+    }
+
+    public static <E> T7177306a<String> m(List<E> le) {
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/inference/7177306/T7177306a.out	Tue Sep 25 11:56:46 2012 +0100
@@ -0,0 +1,6 @@
+T7177306a.java:13:34: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.util.List, java.util.List<E>
+T7177306a.java:13:33: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, java.util.List<E>, java.util.List, kindname.class, T7177306a
+T7177306a.java:13:33: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7177306a, T7177306a<java.lang.Object>
+- compiler.err.warnings.and.werror
+1 error
+3 warnings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/inference/7177306/T7177306b.java	Tue Sep 25 11:56:46 2012 +0100
@@ -0,0 +1,18 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 7177306
+ * @summary Regression: unchecked method call does not erase return type
+ * @compile/fail/ref=T7177306b.out -Werror -Xlint:unchecked -XDrawDiagnostics T7177306b.java
+ */
+
+import java.util.List;
+
+class T7177306b {
+
+    <T, S extends List<T>> List<T> m(List<? super T> arg1, S arg2, Class<Object> arg3) { return arg2; }
+
+    void test(List<Integer> li, List<String> ls, Class c) {
+        m(li, ls, c);
+        // should fail, because of bounds T <: Integer, S :> List<String>
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/inference/7177306/T7177306b.out	Tue Sep 25 11:56:46 2012 +0100
@@ -0,0 +1,2 @@
+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)
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/inference/7177306/T7177306c.java	Tue Sep 25 11:56:46 2012 +0100
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7177306
+ * @summary Regression: unchecked method call does not erase return type
+ */
+public class T7177306c {
+
+    static <T> T m(T t) { return (T)"Null"; }
+
+    public static void main(String[] args) {
+        if (m("NonNullConst") != "Null") {
+            throw new AssertionError("should not get there!");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/inference/7177306/T7177306d.java	Tue Sep 25 11:56:46 2012 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7177306
+ * @summary Regression: unchecked method call does not erase return type
+ */
+import java.util.List;
+
+public class T7177306d {
+
+    static int assertionCount = 0;
+
+    static void assertTrue(boolean cond) {
+        if (!cond) {
+            throw new AssertionError();
+        }
+        assertionCount++;
+    }
+
+    static <T, S extends List<T>> void m(List<? super T> arg1, S arg2, Class<Object> arg3) { assertTrue(false); }
+    static void m(Object o1, Object o2, Object o3) { assertTrue(true); }
+
+    static void test(List<Integer> li, List<String> ls, Class c) {
+        m(li, ls, c);
+    }
+
+    public static void main(String[] args) {
+        test(null, null, null);
+        assertTrue(assertionCount == 1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/inference/7177306/T7177306e.java	Tue Sep 25 11:56:46 2012 +0100
@@ -0,0 +1,17 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 7177306
+ * @summary Regression: unchecked method call does not erase return type
+ * @compile/fail/ref=T7177306e.out -XDrawDiagnostics T7177306e.java
+ */
+
+import java.util.List;
+
+class T7177306e {
+
+    <Z, U extends List<Z>> void m(List<U> lu) { }
+
+    void test(List<List<?>> llw) {
+       m(llw);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/inference/7177306/T7177306e.out	Tue Sep 25 11:56:46 2012 +0100
@@ -0,0 +1,2 @@
+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, ?>)
+1 error