Merge
authorlana
Wed, 18 Apr 2012 10:22:32 -0700
changeset 12469 972000107ea5
parent 12361 f151d5833912 (current diff)
parent 12468 1100643c0209 (diff)
child 12470 5875a9028f2c
Merge
langtools/test/tools/javac/diags/examples/InferredDoNotConformToBounds.java
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java	Wed Apr 18 10:22:32 2012 -0700
@@ -1147,29 +1147,6 @@
         }
 
         /**
-         * Kind of type-constraint derived during type inference
-         */
-        public enum ConstraintKind {
-            /**
-             * upper bound constraint (a type variable must be instantiated
-             * with a type T, where T is a subtype of all the types specified by
-             * its EXTENDS constraints).
-             */
-            EXTENDS,
-            /**
-             * lower bound constraint (a type variable must be instantiated
-             * with a type T, where T is a supertype of all the types specified by
-             * its SUPER constraints).
-             */
-            SUPER,
-            /**
-             * equality constraint (a type variable must be instantiated to the type
-             * specified by its EQUAL constraint.
-             */
-            EQUAL;
-        }
-
-        /**
          * Get the type-constraints of a given kind for a given type-variable of
          * this ForAll type. Subclasses should override in order to return more
          * accurate sets of constraints.
@@ -1178,7 +1155,7 @@
          * @param ck the constraint kind to be retrieved
          * @return the list of types specified by the selected constraint
          */
-        public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
+        public List<Type> undetvars() {
             return List.nil();
         }
 
@@ -1220,6 +1197,7 @@
     public static class UndetVar extends DelegatedType {
         public List<Type> lobounds = List.nil();
         public List<Type> hibounds = List.nil();
+        public List<Type> eq = List.nil();
         public Type inst = null;
 
         @Override
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Wed Apr 18 10:22:32 2012 -0700
@@ -326,11 +326,6 @@
             else if (t.tag == TYPEVAR) {
                 return isSubtypeUnchecked(t.getUpperBound(), s, warn);
             }
-            else if (s.tag == UNDETVAR) {
-                UndetVar uv = (UndetVar)s;
-                if (uv.inst != null)
-                    return isSubtypeUnchecked(t, uv.inst, warn);
-            }
             else if (!s.isRaw()) {
                 Type t2 = asSuper(t, s.tsym);
                 if (t2 != null && t2.isRaw()) {
@@ -515,9 +510,6 @@
                     return false;
                 }
 
-                if (t.inst != null)
-                    return isSubtypeNoCapture(t.inst, s); // TODO: ", warn"?
-
                 t.hibounds = t.hibounds.prepend(s);
                 return true;
             }
@@ -586,8 +578,6 @@
                 undet.qtype == s ||
                 s.tag == ERROR ||
                 s.tag == BOT) return true;
-            if (undet.inst != null)
-                return isSubtype(s, undet.inst);
             undet.lobounds = undet.lobounds.prepend(s);
             return true;
         }
@@ -733,18 +723,8 @@
                 if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN)
                     return true;
 
-                if (t.inst != null)
-                    return visit(t.inst, s);
-
-                t.inst = fromUnknownFun.apply(s);
-                for (List<Type> l = t.lobounds; l.nonEmpty(); l = l.tail) {
-                    if (!isSubtype(l.head, t.inst))
-                        return false;
-                }
-                for (List<Type> l = t.hibounds; l.nonEmpty(); l = l.tail) {
-                    if (!isSubtype(t.inst, l.head))
-                        return false;
-                }
+                t.eq = t.eq.prepend(s);
+
                 return true;
             }
 
@@ -779,23 +759,11 @@
                     case UNBOUND: //similar to ? extends Object
                     case EXTENDS: {
                         Type bound = upperBound(s);
-                        // We should check the new upper bound against any of the
-                        // undetvar's lower bounds.
-                        for (Type t2 : undetvar.lobounds) {
-                            if (!isSubtype(t2, bound))
-                                return false;
-                        }
                         undetvar.hibounds = undetvar.hibounds.prepend(bound);
                         break;
                     }
                     case SUPER: {
                         Type bound = lowerBound(s);
-                        // We should check the new lower bound against any of the
-                        // undetvar's lower bounds.
-                        for (Type t2 : undetvar.hibounds) {
-                            if (!isSubtype(bound, t2))
-                                return false;
-                        }
                         undetvar.lobounds = undetvar.lobounds.prepend(bound);
                         break;
                     }
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java	Wed Apr 18 10:22:32 2012 -0700
@@ -32,7 +32,6 @@
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Type.*;
-import com.sun.tools.javac.code.Type.ForAll.ConstraintKind;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.comp.Resolve.InapplicableMethodException;
 import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode;
@@ -122,84 +121,21 @@
 
     /** A mapping that turns type variables into undetermined type variables.
      */
-    Mapping fromTypeVarFun = new Mapping("fromTypeVarFun") {
-            public Type apply(Type t) {
-                if (t.tag == TYPEVAR) return new UndetVar(t);
-                else return t.map(this);
-            }
-        };
-
-    /** A mapping that returns its type argument with every UndetVar replaced
-     *  by its `inst' field. Throws a NoInstanceException
-     *  if this not possible because an `inst' field is null.
-     *  Note: mutually referring undertvars will be left uninstantiated
-     *  (that is, they will be replaced by the underlying type-variable).
-     */
-
-    Mapping getInstFun = new Mapping("getInstFun") {
-            public Type apply(Type t) {
-                switch (t.tag) {
-                    case UNKNOWN:
-                        throw ambiguousNoInstanceException
-                            .setMessage("undetermined.type");
-                    case UNDETVAR:
-                        UndetVar that = (UndetVar) t;
-                        if (that.inst == null)
-                            throw ambiguousNoInstanceException
-                                .setMessage("type.variable.has.undetermined.type",
-                                            that.qtype);
-                        return isConstraintCyclic(that) ?
-                            that.qtype :
-                            apply(that.inst);
-                        default:
-                            return t.map(this);
+    List<Type> makeUndetvars(List<Type> tvars) {
+        List<Type> undetvars = Type.map(tvars, fromTypeVarFun);
+        for (Type t : undetvars) {
+            UndetVar uv = (UndetVar)t;
+            uv.hibounds = types.getBounds((TypeVar)uv.qtype);
+        }
+        return undetvars;
+    }
+    //where
+            Mapping fromTypeVarFun = new Mapping("fromTypeVarFun") {
+                public Type apply(Type t) {
+                    if (t.tag == TYPEVAR) return new UndetVar(t);
+                    else return t.map(this);
                 }
-            }
-
-            private boolean isConstraintCyclic(UndetVar uv) {
-                Types.UnaryVisitor<Boolean> constraintScanner =
-                        new Types.UnaryVisitor<Boolean>() {
-
-                    List<Type> seen = List.nil();
-
-                    Boolean visit(List<Type> ts) {
-                        for (Type t : ts) {
-                            if (visit(t)) return true;
-                        }
-                        return false;
-                    }
-
-                    public Boolean visitType(Type t, Void ignored) {
-                        return false;
-                    }
-
-                    @Override
-                    public Boolean visitClassType(ClassType t, Void ignored) {
-                        if (t.isCompound()) {
-                            return visit(types.supertype(t)) ||
-                                    visit(types.interfaces(t));
-                        } else {
-                            return visit(t.getTypeArguments());
-                        }
-                    }
-                    @Override
-                    public Boolean visitWildcardType(WildcardType t, Void ignored) {
-                        return visit(t.type);
-                    }
-
-                    @Override
-                    public Boolean visitUndetVar(UndetVar t, Void ignored) {
-                        if (seen.contains(t)) {
-                            return true;
-                        } else {
-                            seen = seen.prepend(t);
-                            return visit(t.inst);
-                        }
-                    }
-                };
-                return constraintScanner.visit(uv);
-            }
-        };
+            };
 
 /***************************************************************************
  * Mini/Maximization of UndetVars
@@ -210,13 +146,15 @@
      */
     void maximizeInst(UndetVar that, Warner warn) throws NoInstanceException {
         List<Type> hibounds = Type.filter(that.hibounds, errorFilter);
-        if (that.inst == null) {
+        if (that.eq.isEmpty()) {
             if (hibounds.isEmpty())
                 that.inst = syms.objectType;
             else if (hibounds.tail.isEmpty())
                 that.inst = hibounds.head;
             else
                 that.inst = types.glb(hibounds);
+        } else {
+            that.inst = that.eq.head;
         }
         if (that.inst == null ||
             that.inst.isErroneous())
@@ -224,27 +162,6 @@
                 .setMessage("no.unique.maximal.instance.exists",
                             that.qtype, hibounds);
     }
-    //where
-        private boolean isSubClass(Type t, final List<Type> ts) {
-            t = t.baseType();
-            if (t.tag == TYPEVAR) {
-                List<Type> bounds = types.getBounds((TypeVar)t);
-                for (Type s : ts) {
-                    if (!types.isSameType(t, s.baseType())) {
-                        for (Type bound : bounds) {
-                            if (!isSubClass(bound, List.of(s.baseType())))
-                                return false;
-                        }
-                    }
-                }
-            } else {
-                for (Type s : ts) {
-                    if (!t.tsym.isSubClass(s.baseType().tsym, types))
-                        return false;
-                }
-            }
-            return true;
-        }
 
     private Filter<Type> errorFilter = new Filter<Type>() {
         @Override
@@ -258,7 +175,7 @@
      */
     void minimizeInst(UndetVar that, Warner warn) throws NoInstanceException {
         List<Type> lobounds = Type.filter(that.lobounds, errorFilter);
-        if (that.inst == null) {
+        if (that.eq.isEmpty()) {
             if (lobounds.isEmpty())
                 that.inst = syms.botType;
             else if (lobounds.tail.isEmpty())
@@ -270,21 +187,8 @@
                     throw ambiguousNoInstanceException
                         .setMessage("no.unique.minimal.instance.exists",
                                     that.qtype, lobounds);
-            // VGJ: sort of inlined maximizeInst() below.  Adding
-            // bounds can cause lobounds that are above hibounds.
-            List<Type> hibounds = Type.filter(that.hibounds, errorFilter);
-            Type hb = null;
-            if (hibounds.isEmpty())
-                hb = syms.objectType;
-            else if (hibounds.tail.isEmpty())
-                hb = hibounds.head;
-            else
-                hb = types.glb(hibounds);
-            if (hb == null ||
-                hb.isErroneous())
-                throw ambiguousNoInstanceException
-                        .setMessage("incompatible.upper.bounds",
-                                    that.qtype, hibounds);
+        } else {
+            that.inst = that.eq.head;
         }
     }
 
@@ -313,21 +217,7 @@
     public Type instantiateExpr(ForAll that,
                                 Type to,
                                 Warner warn) throws InferenceException {
-        List<Type> undetvars = Type.map(that.tvars, fromTypeVarFun);
-        for (List<Type> l = undetvars; l.nonEmpty(); l = l.tail) {
-            UndetVar uv = (UndetVar) l.head;
-            TypeVar tv = (TypeVar)uv.qtype;
-            ListBuffer<Type> hibounds = new ListBuffer<Type>();
-            for (Type t : that.getConstraints(tv, ConstraintKind.EXTENDS)) {
-                hibounds.append(types.subst(t, that.tvars, undetvars));
-            }
-
-            List<Type> inst = that.getConstraints(tv, ConstraintKind.EQUAL);
-            if (inst.nonEmpty() && inst.head.tag != BOT) {
-                uv.inst = inst.head;
-            }
-            uv.hibounds = hibounds.toList();
-        }
+        List<Type> undetvars = that.undetvars();
         Type qtype1 = types.subst(that.qtype, that.tvars, undetvars);
         if (!types.isSubtype(qtype1,
                 qtype1.tag == UNDETVAR ? types.boxedTypeOrType(to) : to)) {
@@ -335,41 +225,72 @@
                 .setMessage("infer.no.conforming.instance.exists",
                             that.tvars, that.qtype, to);
         }
-        for (List<Type> l = undetvars; l.nonEmpty(); l = l.tail)
-            maximizeInst((UndetVar) l.head, warn);
-        // System.out.println(" = " + qtype1.map(getInstFun));//DEBUG
 
-        // check bounds
-        List<Type> targs = Type.map(undetvars, getInstFun);
-        if (Type.containsAny(targs, that.tvars)) {
-            //replace uninferred type-vars
-            targs = types.subst(targs,
+        List<Type> insttypes;
+        while (true) {
+            boolean stuck = true;
+            insttypes = List.nil();
+            for (Type t : undetvars) {
+                UndetVar uv = (UndetVar)t;
+                if (uv.inst == null && (uv.eq.nonEmpty() || !Type.containsAny(uv.hibounds, that.tvars))) {
+                    maximizeInst((UndetVar)t, warn);
+                    stuck = false;
+                }
+                insttypes = insttypes.append(uv.inst == null ? uv.qtype : uv.inst);
+            }
+            if (!Type.containsAny(insttypes, that.tvars)) {
+                //all variables have been instantiated - exit
+                break;
+            } else if (stuck) {
+                //some variables could not be instantiated because of cycles in
+                //upper bounds - provide a (possibly recursive) default instantiation
+                insttypes = types.subst(insttypes,
                     that.tvars,
                     instantiateAsUninferredVars(undetvars, that.tvars));
+                break;
+            } else {
+                //some variables have been instantiated - replace newly instantiated
+                //variables in remaining upper bounds and continue
+                for (Type t : undetvars) {
+                    UndetVar uv = (UndetVar)t;
+                    uv.hibounds = types.subst(uv.hibounds, that.tvars, insttypes);
+                }
+            }
         }
-        return that.inst(targs, types);
+        return that.inst(insttypes, types);
     }
-    //where
+
+    /**
+     * Infer cyclic inference variables as described in 15.12.2.8.
+     */
     private List<Type> instantiateAsUninferredVars(List<Type> undetvars, List<Type> tvars) {
         Assert.check(undetvars.length() == tvars.length());
-        ListBuffer<Type> new_targs = ListBuffer.lb();
-        //step 1 - create synthetic captured vars
+        ListBuffer<Type> insttypes = ListBuffer.lb();
+        ListBuffer<Type> todo = ListBuffer.lb();
+        //step 1 - create fresh tvars
         for (Type t : undetvars) {
             UndetVar uv = (UndetVar)t;
-            Type newArg = new CapturedType(t.tsym.name, t.tsym, uv.inst, syms.botType, null);
-            new_targs = new_targs.append(newArg);
+            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);
+                todo.append(uv);
+                uv.inst = fresh_tvar.type;
+            }
+            insttypes.append(uv.inst);
         }
-        //step 2 - replace synthetic vars in their bounds
+        //step 2 - replace fresh tvars in their bounds
         List<Type> formals = tvars;
-        for (Type t : new_targs.toList()) {
-            CapturedType ct = (CapturedType)t;
-            ct.bound = types.subst(ct.bound, tvars, new_targs.toList());
-            WildcardType wt = new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass);
-            wt.bound = (TypeVar)formals.head;
-            ct.wildcard = wt;
+        for (Type t : todo) {
+            UndetVar uv = (UndetVar)t;
+            TypeVar ct = (TypeVar)uv.inst;
+            ct.bound = types.glb(types.subst(types.getBounds(ct), tvars, insttypes.toList()));
+            if (ct.bound.isErroneous()) {
+                //report inference error if glb fails
+                reportBoundError(uv, BoundErrorKind.BAD_UPPER);
+            }
             formals = formals.tail;
         }
-        return new_targs.toList();
+        return insttypes.toList();
     }
 
     /** Instantiate method type `mt' by finding instantiations of
@@ -384,7 +305,7 @@
                                   final boolean useVarargs,
                                   final Warner warn) throws InferenceException {
         //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
-        List<Type> undetvars = Type.map(tvars, fromTypeVarFun);
+        final List<Type> undetvars =  makeUndetvars(tvars);
 
         final List<Type> capturedArgs =
                 rs.checkRawArgumentsAcceptable(env, undetvars, argtypes, mt.getParameterTypes(),
@@ -419,7 +340,7 @@
                 undettypes.append(uv.inst);
             }
         }
-        checkWithinBounds(tvars, undettypes.toList(), warn);
+        checkWithinBounds(tvars, undetvars, insttypes.toList(), warn);
 
         mt = (MethodType)types.subst(mt, tvars, insttypes.toList());
 
@@ -430,18 +351,8 @@
             final List<Type> all_tvars = tvars; //this is the wrong tvars
             return new UninferredMethodType(env.tree.pos(), msym, mt, restvars.toList()) {
                 @Override
-                List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
-                    for (Type t : restundet.toList()) {
-                        UndetVar uv = (UndetVar)t;
-                        if (uv.qtype == tv) {
-                            switch (ck) {
-                                case EXTENDS: return uv.hibounds.appendList(types.subst(types.getBounds(tv), all_tvars, inferredTypes));
-                                case SUPER: return uv.lobounds;
-                                case EQUAL: return uv.inst != null ? List.of(uv.inst) : List.<Type>nil();
-                            }
-                        }
-                    }
-                    return List.nil();
+                List<Type> undetvars() {
+                    return restundet.toList();
                 }
                 @Override
                 void instantiateReturnType(Type restype, List<Type> inferred, Types types) throws NoInstanceException {
@@ -453,7 +364,7 @@
                     warn.clear();
                     checkArgumentsAcceptable(env, capturedArgs, owntype.getParameterTypes(), allowBoxing, useVarargs, warn);
                     // check that inferred bounds conform to their bounds
-                    checkWithinBounds(all_tvars,
+                    checkWithinBounds(all_tvars, undetvars,
                            types.subst(inferredTypes, tvars, inferred), warn);
                     qtype = chk.checkMethod(owntype, msym, env, TreeInfo.args(env.tree), capturedArgs, useVarargs, warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED));
                 }
@@ -525,7 +436,7 @@
 
             abstract void instantiateReturnType(Type restype, List<Type> inferred, Types types);
 
-            abstract List<Type> getConstraints(TypeVar tv, ConstraintKind ck);
+            abstract List<Type> undetvars();
 
             class UninferredReturnType extends ForAll {
                 public UninferredReturnType(List<Type> tvars, Type restype) {
@@ -541,8 +452,8 @@
                     return UninferredMethodType.this.qtype.getReturnType();
                 }
                 @Override
-                public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
-                    return UninferredMethodType.this.getConstraints(tv, ck);
+                public List<Type> undetvars() {
+                    return UninferredMethodType.this.undetvars();
                 }
             }
         }
@@ -559,43 +470,94 @@
             }
         }
 
-    /** Try to instantiate argument type `that' to given type `to'.
-     *  If this fails, try to insantiate `that' to `to' where
-     *  every occurrence of a type variable in `tvars' is replaced
-     *  by an unknown type.
+    /** check that type parameters are within their bounds.
      */
-    private Type instantiateArg(ForAll that,
-                                Type to,
-                                List<Type> tvars,
-                                Warner warn) throws InferenceException {
-        List<Type> targs;
-        try {
-            return instantiateExpr(that, to, warn);
-        } catch (NoInstanceException ex) {
-            Type to1 = to;
-            for (List<Type> l = tvars; l.nonEmpty(); l = l.tail)
-                to1 = types.subst(to1, List.of(l.head), List.of(syms.unknownType));
-            return instantiateExpr(that, to1, warn);
+    void checkWithinBounds(List<Type> tvars,
+                           List<Type> undetvars,
+                           List<Type> arguments,
+                           Warner warn)
+        throws InvalidInstanceException {
+        List<Type> args = arguments;
+        for (Type t : undetvars) {
+            UndetVar uv = (UndetVar)t;
+            uv.hibounds = types.subst(uv.hibounds, tvars, arguments);
+            uv.lobounds = types.subst(uv.lobounds, tvars, arguments);
+            uv.eq = types.subst(uv.eq, tvars, arguments);
+            checkCompatibleUpperBounds(uv, tvars);
+            if (args.head.tag != TYPEVAR || !args.head.containsAny(tvars)) {
+                Type inst = args.head;
+                for (Type u : uv.hibounds) {
+                    if (!types.isSubtypeUnchecked(inst, types.subst(u, tvars, undetvars), warn)) {
+                        reportBoundError(uv, BoundErrorKind.UPPER);
+                    }
+                }
+                for (Type l : uv.lobounds) {
+                    if (!types.isSubtypeUnchecked(types.subst(l, tvars, undetvars), inst, warn)) {
+                        reportBoundError(uv, BoundErrorKind.LOWER);
+                    }
+                }
+                for (Type e : uv.eq) {
+                    if (!types.isSameType(inst, types.subst(e, tvars, undetvars))) {
+                        reportBoundError(uv, BoundErrorKind.EQ);
+                    }
+                }
+            }
+            args = args.tail;
         }
     }
 
-    /** check that type parameters are within their bounds.
-     */
-    void checkWithinBounds(List<Type> tvars,
-                                   List<Type> arguments,
-                                   Warner warn)
-        throws InvalidInstanceException {
-        for (List<Type> tvs = tvars, args = arguments;
-             tvs.nonEmpty();
-             tvs = tvs.tail, args = args.tail) {
-            if (args.head instanceof UndetVar ||
-                    tvars.head.getUpperBound().isErroneous()) continue;
-            List<Type> bounds = types.subst(types.getBounds((TypeVar)tvs.head), tvars, arguments);
-            if (!types.isSubtypeUnchecked(args.head, bounds, warn))
-                throw invalidInstanceException
-                    .setMessage("inferred.do.not.conform.to.bounds",
-                                args.head, bounds);
+    void checkCompatibleUpperBounds(UndetVar uv, List<Type> tvars) {
+        // 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, errorFilter)) {
+            if (!t.containsAny(tvars)) {
+                hiboundsNoVars.append(t);
+            }
         }
+        List<Type> hibounds = hiboundsNoVars.toList();
+        Type hb = null;
+        if (hibounds.isEmpty())
+            hb = syms.objectType;
+        else if (hibounds.tail.isEmpty())
+            hb = hibounds.head;
+        else
+            hb = types.glb(hibounds);
+        if (hb == null || hb.isErroneous())
+            reportBoundError(uv, BoundErrorKind.BAD_UPPER);
+    }
+
+    enum BoundErrorKind {
+        BAD_UPPER() {
+            @Override
+            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
+                return ex.setMessage("incompatible.upper.bounds", uv.qtype, uv.hibounds);
+            }
+        },
+        UPPER() {
+            @Override
+            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
+                return ex.setMessage("inferred.do.not.conform.to.upper.bounds", uv.inst, uv.hibounds);
+            }
+        },
+        LOWER() {
+            @Override
+            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
+                return ex.setMessage("inferred.do.not.conform.to.lower.bounds", uv.inst, uv.lobounds);
+            }
+        },
+        EQ() {
+            @Override
+            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
+                return ex.setMessage("inferred.do.not.conform.to.eq.bounds", uv.inst, uv.eq);
+            }
+        };
+
+        abstract InapplicableMethodException setMessage(InferenceException ex, UndetVar uv);
+    }
+    //where
+    void reportBoundError(UndetVar uv, BoundErrorKind bk) {
+        throw bk.setMessage(uv.inst == null ? ambiguousNoInstanceException : invalidInstanceException, uv);
     }
 
     /**
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Wed Apr 18 10:22:32 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -1798,92 +1798,126 @@
      */
     @SuppressWarnings("fallthrough")
     List<JCStatement> blockStatements() {
-//todo: skip to anchor on error(?)
-        int lastErrPos = -1;
+        //todo: skip to anchor on error(?)
         ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
         while (true) {
-            int pos = token.pos;
-            switch (token.kind) {
-            case RBRACE: case CASE: case DEFAULT: case EOF:
+            List<JCStatement> stat = blockStatement();
+            if (stat.isEmpty()) {
                 return stats.toList();
-            case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
-            case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
-            case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
-                stats.append(parseStatement());
+            } else {
+                if (token.pos <= endPosTable.errorEndPos) {
+                    skip(false, true, true, true);
+                }
+                stats.addAll(stat);
+            }
+        }
+    }
+
+    /*
+     * This method parses a statement treating it as a block, relaxing the
+     * JLS restrictions, allows us to parse more faulty code, doing so
+     * enables us to provide better and accurate diagnostics to the user.
+     */
+    JCStatement parseStatementAsBlock() {
+        int pos = token.pos;
+        List<JCStatement> stats = blockStatement();
+        if (stats.isEmpty()) {
+            JCErroneous e = F.at(pos).Erroneous();
+            error(e, "illegal.start.of.stmt");
+            return F.at(pos).Exec(e);
+        } else {
+            JCStatement first = stats.head;
+            String error = null;
+            switch (first.getTag()) {
+            case CLASSDEF:
+                error = "class.not.allowed";
                 break;
-            case MONKEYS_AT:
-            case FINAL: {
-                String dc = token.comment(CommentStyle.JAVADOC);
-                JCModifiers mods = modifiersOpt();
-                if (token.kind == INTERFACE ||
-                    token.kind == CLASS ||
-                    allowEnums && token.kind == ENUM) {
-                    stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
-                } else {
-                    JCExpression t = parseType();
-                    stats.appendList(variableDeclarators(mods, t,
-                                                         new ListBuffer<JCStatement>()));
-                    // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
-                    storeEnd(stats.elems.last(), token.endPos);
-                    accept(SEMI);
-                }
-                break;
-            }
-            case ABSTRACT: case STRICTFP: {
-                String dc = token.comment(CommentStyle.JAVADOC);
-                JCModifiers mods = modifiersOpt();
-                stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
+            case VARDEF:
+                error = "variable.not.allowed";
                 break;
             }
-            case INTERFACE:
-            case CLASS:
-                String dc = token.comment(CommentStyle.JAVADOC);
-                stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
-                break;
-            case ENUM:
-            case ASSERT:
-                if (allowEnums && token.kind == ENUM) {
-                    error(token.pos, "local.enum");
-                    dc = token.comment(CommentStyle.JAVADOC);
-                    stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
-                    break;
-                } else if (allowAsserts && token.kind == ASSERT) {
-                    stats.append(parseStatement());
-                    break;
-                }
-                /* fall through to default */
-            default:
-                Token prevToken = token;
-                JCExpression t = term(EXPR | TYPE);
-                if (token.kind == COLON && t.hasTag(IDENT)) {
-                    nextToken();
-                    JCStatement stat = parseStatement();
-                    stats.append(F.at(pos).Labelled(prevToken.name(), stat));
-                } else if ((lastmode & TYPE) != 0 &&
-                           (token.kind == IDENTIFIER ||
-                            token.kind == ASSERT ||
-                            token.kind == ENUM)) {
-                    pos = token.pos;
-                    JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
-                    F.at(pos);
-                    stats.appendList(variableDeclarators(mods, t,
-                                                         new ListBuffer<JCStatement>()));
-                    // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
-                    storeEnd(stats.elems.last(), token.endPos);
-                    accept(SEMI);
-                } else {
-                    // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
-                    stats.append(to(F.at(pos).Exec(checkExprStat(t))));
-                    accept(SEMI);
-                }
+            if (error != null) {
+                error(first, error);
+                List<JCBlock> blist = List.of(F.at(first.pos).Block(0, stats));
+                return toP(F.at(pos).Exec(F.at(first.pos).Erroneous(blist)));
+            }
+            return first;
+        }
+    }
+
+    @SuppressWarnings("fallthrough")
+    List<JCStatement> blockStatement() {
+        //todo: skip to anchor on error(?)
+        int pos = token.pos;
+        switch (token.kind) {
+        case RBRACE: case CASE: case DEFAULT: case EOF:
+            return List.nil();
+        case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
+        case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
+        case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
+            return List.of(parseStatement());
+        case MONKEYS_AT:
+        case FINAL: {
+            String dc = token.comment(CommentStyle.JAVADOC);
+            JCModifiers mods = modifiersOpt();
+            if (token.kind == INTERFACE ||
+                token.kind == CLASS ||
+                allowEnums && token.kind == ENUM) {
+                return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
+            } else {
+                JCExpression t = parseType();
+                ListBuffer<JCStatement> stats =
+                        variableDeclarators(mods, t, new ListBuffer<JCStatement>());
+                // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
+                storeEnd(stats.elems.last(), token.endPos);
+                accept(SEMI);
+                return stats.toList();
             }
-
-            // error recovery
-            if (token.pos == lastErrPos)
+        }
+        case ABSTRACT: case STRICTFP: {
+            String dc = token.comment(CommentStyle.JAVADOC);
+            JCModifiers mods = modifiersOpt();
+            return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
+        }
+        case INTERFACE:
+        case CLASS:
+            String dc = token.comment(CommentStyle.JAVADOC);
+            return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
+        case ENUM:
+        case ASSERT:
+            if (allowEnums && token.kind == ENUM) {
+                error(token.pos, "local.enum");
+                dc = token.comment(CommentStyle.JAVADOC);
+                return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
+            } else if (allowAsserts && token.kind == ASSERT) {
+                return List.of(parseStatement());
+            }
+            /* fall through to default */
+        default:
+            Token prevToken = token;
+            JCExpression t = term(EXPR | TYPE);
+            if (token.kind == COLON && t.hasTag(IDENT)) {
+                nextToken();
+                JCStatement stat = parseStatement();
+                return List.<JCStatement>of(F.at(pos).Labelled(prevToken.name(), stat));
+            } else if ((lastmode & TYPE) != 0 &&
+                       (token.kind == IDENTIFIER ||
+                        token.kind == ASSERT ||
+                        token.kind == ENUM)) {
+                pos = token.pos;
+                JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
+                F.at(pos);
+                ListBuffer<JCStatement> stats =
+                        variableDeclarators(mods, t, new ListBuffer<JCStatement>());
+                // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
+                storeEnd(stats.elems.last(), token.endPos);
+                accept(SEMI);
                 return stats.toList();
-            if (token.pos <= endPosTable.errorEndPos) {
-                skip(false, true, true, true);
-                lastErrPos = token.pos;
+            } else {
+                // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
+                JCExpressionStatement expr = to(F.at(pos).Exec(checkExprStat(t)));
+                accept(SEMI);
+                return List.<JCStatement>of(expr);
             }
         }
     }
@@ -1917,11 +1951,11 @@
         case IF: {
             nextToken();
             JCExpression cond = parExpression();
-            JCStatement thenpart = parseStatement();
+            JCStatement thenpart = parseStatementAsBlock();
             JCStatement elsepart = null;
             if (token.kind == ELSE) {
                 nextToken();
-                elsepart = parseStatement();
+                elsepart = parseStatementAsBlock();
             }
             return F.at(pos).If(cond, thenpart, elsepart);
         }
@@ -1938,7 +1972,7 @@
                 accept(COLON);
                 JCExpression expr = parseExpression();
                 accept(RPAREN);
-                JCStatement body = parseStatement();
+                JCStatement body = parseStatementAsBlock();
                 return F.at(pos).ForeachLoop(var, expr, body);
             } else {
                 accept(SEMI);
@@ -1946,19 +1980,19 @@
                 accept(SEMI);
                 List<JCExpressionStatement> steps = token.kind == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate();
                 accept(RPAREN);
-                JCStatement body = parseStatement();
+                JCStatement body = parseStatementAsBlock();
                 return F.at(pos).ForLoop(inits, cond, steps, body);
             }
         }
         case WHILE: {
             nextToken();
             JCExpression cond = parExpression();
-            JCStatement body = parseStatement();
+            JCStatement body = parseStatementAsBlock();
             return F.at(pos).WhileLoop(cond, body);
         }
         case DO: {
             nextToken();
-            JCStatement body = parseStatement();
+            JCStatement body = parseStatementAsBlock();
             accept(WHILE);
             JCExpression cond = parExpression();
             JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Apr 18 10:22:32 2012 -0700
@@ -196,6 +196,9 @@
 compiler.err.clash.with.pkg.of.same.name=\
     {0} {1} clashes with package of same name
 
+compiler.err.class.not.allowed=\
+    class, interface or enum declaration not allowed here
+
 compiler.err.const.expr.req=\
     constant expression required
 
@@ -385,6 +388,9 @@
 compiler.err.illegal.start.of.expr=\
     illegal start of expression
 
+compiler.err.illegal.start.of.stmt=\
+    illegal start of statement
+
 compiler.err.illegal.start.of.type=\
     illegal start of type
 
@@ -446,6 +452,9 @@
 compiler.err.varargs.and.old.array.syntax=\
     legacy array notation not allowed on variable-arity parameter
 
+compiler.err.variable.not.allowed=\
+    variable declaration not allowed here
+
 # 0: name
 compiler.err.label.already.in.use=\
     label {0} already in use
@@ -1574,9 +1583,6 @@
     cannot infer type arguments for {0}\n\
     reason: {1}
 
-compiler.misc.type.variable.has.undetermined.type=\
-    type variable {0} has undetermined type
-
 # 0: type, 1: list of type
 compiler.misc.no.unique.maximal.instance.exists=\
     no unique maximal instance exists for type variable {0} with upper bounds {1}
@@ -1604,10 +1610,22 @@
     no instance(s) of type variable(s) {0} exist so that argument type {1} conforms to vararg element type {2}
 
 # 0: type, 1: list of type
-compiler.misc.inferred.do.not.conform.to.bounds=\
-    inferred type does not conform to declared bound(s)\n\
+compiler.misc.inferred.do.not.conform.to.upper.bounds=\
+    inferred type does not conform to upper bound(s)\n\
     inferred: {0}\n\
-    bound(s): {1}
+    upper bound(s): {1}
+
+# 0: type, 1: list of type
+compiler.misc.inferred.do.not.conform.to.lower.bounds=\
+    inferred type does not conform to lower bound(s)\n\
+    inferred: {0}\n\
+    lower bound(s): {1}
+
+# 0: type, 1: list of type
+compiler.misc.inferred.do.not.conform.to.eq.bounds=\
+    inferred type does not conform to equality constraint(s)\n\
+    inferred: {0}\n\
+    equality constraints(s): {1}
 
 # 0: symbol
 compiler.misc.diamond=\
@@ -2033,9 +2051,16 @@
 
 # compact where clause for type variable: contains the kindname ({2}) and location ({3})
 # in which the typevar has been declared
+# 0: type, 1: list of type, 2: symbol kind, 3: symbol
 compiler.misc.where.typevar.1=\
     {0} declared in {2} {3}
 
+# where clause for fresh type variable: contains upper bound(s) ('extends {1}').
+# Since a fresh type-variable is synthetic - there's no location/kindname here.
+# 0: type, 1: list of type
+compiler.misc.where.fresh.typevar=\
+    {0} extends {1}
+
 # where clause for type variable: contains all the upper bound(s) ('extends {1}')
 # of this intersection type
 # 0: type, 1: list of type
--- a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java	Wed Apr 18 10:22:32 2012 -0700
@@ -540,13 +540,22 @@
                                          bounds.head.tag == NONE ||
                                          bounds.head.tag == ERROR;
 
-
-                JCDiagnostic d = diags.fragment("where.typevar" +
+                if ((t.tsym.flags() & SYNTHETIC) == 0) {
+                    //this is a true typevar
+                    JCDiagnostic d = diags.fragment("where.typevar" +
                         (boundErroneous ? ".1" : ""), t, bounds,
                         Kinds.kindName(t.tsym.location()), t.tsym.location());
-                whereClauses.get(WhereClauseKind.TYPEVAR).put(t, d);
-                symbolPreprocessor.visit(t.tsym.location(), null);
-                visit(bounds);
+                    whereClauses.get(WhereClauseKind.TYPEVAR).put(t, d);
+                    symbolPreprocessor.visit(t.tsym.location(), null);
+                    visit(bounds);
+                } else {
+                    Assert.check(!boundErroneous);
+                    //this is a fresh (synthetic) tvar
+                    JCDiagnostic d = diags.fragment("where.fresh.typevar", t, bounds);
+                    whereClauses.get(WhereClauseKind.TYPEVAR).put(t, d);
+                    visit(bounds);
+                }
+
             }
             return null;
         }
--- a/langtools/test/tools/javac/Diagnostics/6722234/T6722234b_1.out	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/test/tools/javac/Diagnostics/6722234/T6722234b_1.out	Wed Apr 18 10:22:32 2012 -0700
@@ -1,2 +1,2 @@
-T6722234b.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, List<T>,List<T>, List<compiler.misc.type.captureof: 1, ? extends T6722234b>,List<compiler.misc.type.captureof: 2, ? extends T6722234b>, kindname.class, T6722234b, (compiler.misc.infer.no.conforming.assignment.exists: T, List<compiler.misc.type.captureof: 2, ? extends T6722234b>, List<T>)
+T6722234b.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, List<T>,List<T>, List<compiler.misc.type.captureof: 1, ? extends T6722234b>,List<compiler.misc.type.captureof: 2, ? extends T6722234b>, kindname.class, T6722234b, (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.type.captureof: 2, ? extends T6722234b, compiler.misc.type.captureof: 2, ? extends T6722234b,compiler.misc.type.captureof: 1, ? extends T6722234b)
 1 error
--- a/langtools/test/tools/javac/Diagnostics/6722234/T6722234b_2.out	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/test/tools/javac/Diagnostics/6722234/T6722234b_2.out	Wed Apr 18 10:22:32 2012 -0700
@@ -1,4 +1,4 @@
-T6722234b.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, List<T>,List<T>, List<compiler.misc.captured.type: 1>,List<compiler.misc.captured.type: 2>, kindname.class, T6722234b, (compiler.misc.infer.no.conforming.assignment.exists: T, List<compiler.misc.captured.type: 2>, List<T>)
+T6722234b.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, List<T>,List<T>, List<compiler.misc.captured.type: 1>,List<compiler.misc.captured.type: 2>, kindname.class, T6722234b, (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.captured.type: 2, compiler.misc.captured.type: 2,compiler.misc.captured.type: 1)
 - compiler.misc.where.description.typevar: T,{(compiler.misc.where.typevar: T, Object, kindname.method, <T>m(List<T>,List<T>))}
 - compiler.misc.where.description.captured.1: compiler.misc.captured.type: 1,compiler.misc.captured.type: 2,{(compiler.misc.where.captured.1: compiler.misc.captured.type: 1, T6722234b, compiler.misc.type.null, ? extends T6722234b),(compiler.misc.where.captured.1: compiler.misc.captured.type: 2, T6722234b, compiler.misc.type.null, ? extends T6722234b)}
 1 error
--- a/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out	Wed Apr 18 10:22:32 2012 -0700
@@ -1,4 +1,4 @@
-T6799605.java:17:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.inferred.do.not.conform.to.bounds: compiler.misc.type.captureof: 1, ?, T6799605<compiler.misc.type.captureof: 1, ?>))}
-T6799605.java:18:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.no.conforming.assignment.exists: T, T6799605<compiler.misc.type.captureof: 2, ?>, T6799605<T>)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch))}
-T6799605.java:19:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,T6799605<compiler.misc.type.captureof: 3, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.no.conforming.assignment.exists: T, T6799605<compiler.misc.type.captureof: 2, ?>, T6799605<T>)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch))}
+T6799605.java:17:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.inferred.do.not.conform.to.upper.bounds: compiler.misc.type.captureof: 1, ?, T6799605<compiler.misc.type.captureof: 1, ?>))}
+T6799605.java:18:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.type.captureof: 2, ?, compiler.misc.type.captureof: 2, ?,compiler.misc.type.captureof: 1, ?)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch))}
+T6799605.java:19:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,T6799605<compiler.misc.type.captureof: 3, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.type.captureof: 3, ?, compiler.misc.type.captureof: 3, ?,compiler.misc.type.captureof: 2, ?,compiler.misc.type.captureof: 1, ?)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch))}
 3 errors
--- a/langtools/test/tools/javac/cast/7123100/T7123100a.out	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/test/tools/javac/cast/7123100/T7123100a.out	Wed Apr 18 10:22:32 2012 -0700
@@ -1,4 +1,4 @@
-T7123100a.java:14:19: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), compiler.misc.type.captureof: 1, ?, Z
+T7123100a.java:14:19: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), E, Z
 - compiler.err.warnings.and.werror
 1 error
 1 warning
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/ClassVersionChecker.java	Wed Apr 18 10:22:32 2012 -0700
@@ -0,0 +1,149 @@
+/*
+ * 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 7157626
+ * @summary Test major version for all legal combinations for -source and -target
+ * @author sgoel
+ *
+ */
+
+import java.io.*;
+import java.nio.*;
+import java.util.*;
+import java.util.regex.*;
+
+public class ClassVersionChecker {
+
+    int errors;
+    String[] jdk = {"","1.2","1.3","1.4","1.5","1.6","1.7","1.8"};
+    File javaFile = null;
+
+    public static void main(String[] args) throws Throwable {
+        new ClassVersionChecker().run();
+    }
+
+    void run() throws Exception {
+        writeTestFile();
+        /* Rules applicable for -source and -target combinations
+         * 1. If both empty, version num is for 1.7
+         * 2. If source is not empty and target is empty, version is based on source
+         * 3. If both non-empty, version is based on target
+         */
+
+        /* -source (0=>empty,1=>1.2,...) X -target (0=>empty,1=>1.2,...)
+         * ver[0][0] => no -source or -target was given
+         * -1 => invalid combinations
+         */
+        int[][] ver =
+                {{51, -1, -1, -1, -1, -1, -1, -1},
+                 {48, 46, 47, 48, 49, 50, 51, 51},
+                 {48, 46, 47, 48, 49, 50, 51, 51},
+                 {48, -1, -1, 48, 49, 50, 51, 51},
+                 {51, -1, -1, -1, 49, 50, 51, 51},
+                 {51, -1, -1, -1, -1, 50, 51, 51},
+                 {51, -1, -1, -1, -1, -1, 51, 51},
+                 {51, -1, -1, -1, -1, -1, -1, 51}};
+
+        // Loop to run all possible combinations of source/target values
+        for (int i = 0; i< ver.length; i++) {
+            for (int j = 0 ; j< ver[i].length; j++) {
+                if(ver[i][j] != -1) {
+                    logMsg("Index values for i = " + i + " j = " + j);
+                    logMsg("Running for src = " + jdk[i] + " target = "+jdk[j] +" expected = " + ver[i][j]);
+                    test(i,j, ver[i][j]);
+                }
+            }
+        }
+
+        if (errors > 0)
+            throw new Exception(errors + " errors found");
+    }
+
+    void test (int i, int j, int expected) {
+        File classFile = compileTestFile(i, j, javaFile);
+        short majorVer = getMajorVersion(classFile);
+        checkVersion(majorVer, expected);
+    }
+
+    void writeTestFile() throws IOException {
+        javaFile = new File("Test.java");
+        try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(javaFile)));) {
+            out.println("class Test { ");
+            out.println("  public void foo() { }");
+            out.println("}");
+        } catch (IOException ioe) {
+            error("IOException while creating Test.java" + ioe);
+        }
+    }
+
+    File compileTestFile(int i , int j, File f) {
+        int rc = -1;
+        // Src and target are empty
+        if (i == 0 && j == 0 ) {
+            rc = compile("-g", f.getPath());
+        } else if( j == 0 ) {  // target is empty
+            rc = compile("-source", jdk[i], "-g", f.getPath());
+        } else {
+            rc = compile("-source", jdk[i], "-target", jdk[j], "-g", f.getPath());
+        }
+        if (rc != 0)
+            throw new Error("compilation failed. rc=" + rc);
+        String path = f.getPath();
+        return new File(path.substring(0, path.length() - 5) + ".class");
+    }
+
+    int compile(String... args) {
+        return com.sun.tools.javac.Main.compile(args);
+    }
+
+    void logMsg (String str) {
+        System.out.println(str);
+    }
+
+    short getMajorVersion(File f) {
+        List<String> args = new ArrayList<String>();
+        short majorVer = 0;
+        try(DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(f)));) {
+            in.readInt();
+            in.readShort();
+            majorVer = in.readShort();
+            System.out.println("major version:" +  majorVer);
+        } catch (IOException e) {
+            error("IOException while reading Test.class" + e);
+        }
+        return majorVer;
+    }
+
+    void checkVersion(short majorVer, int expected) {
+        if (majorVer != expected ) {
+            error("versions did not match, Expected: " + expected + "Got: " + majorVer);
+        }
+    }
+
+    void error(String msg) {
+       System.out.println("error: " + msg);
+       errors++;
+    }
+}
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt	Wed Apr 18 10:22:32 2012 -0700
@@ -78,7 +78,6 @@
 compiler.misc.type.captureof.1
 compiler.misc.type.none
 compiler.misc.type.req.exact
-compiler.misc.type.variable.has.undetermined.type
 compiler.misc.unable.to.access.file                     # ClassFile
 compiler.misc.undecl.type.var                           # ClassReader
 compiler.misc.unicode.str.not.supported                 # ClassReader
--- a/langtools/test/tools/javac/diags/examples/CantApplyDiamond1.java	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples/CantApplyDiamond1.java	Wed Apr 18 10:22:32 2012 -0700
@@ -23,7 +23,7 @@
 
 // key: compiler.err.prob.found.req.1
 // key: compiler.misc.cant.apply.diamond.1
-// key: compiler.misc.infer.no.conforming.instance.exists
+// key: compiler.misc.no.conforming.assignment.exists
 // key: compiler.misc.diamond
 
 class CantApplyDiamond1<X> {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/IllegalStartOfStmt.java	Wed Apr 18 10:22:32 2012 -0700
@@ -0,0 +1,31 @@
+/*
+ * 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.illegal.start.of.stmt
+// key: compiler.err.expected3
+
+class IllegalStartOfStmt {
+    void m() {
+        if (true) }
+    }
+}
--- a/langtools/test/tools/javac/diags/examples/IncompatibleTypes1.java	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples/IncompatibleTypes1.java	Wed Apr 18 10:22:32 2012 -0700
@@ -25,9 +25,9 @@
 // key: compiler.err.prob.found.req.1
 
 class IncompatibleTypes1<V> {
-    <T extends Integer & Runnable> IncompatibleTypes1<T> m() {
+    <T> IncompatibleTypes1<Integer> m() {
         return null;
     }
 
-    IncompatibleTypes1<? super String> o = m();
+    IncompatibleTypes1<? extends String> o = m();
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/InferNoConformingAssignment.java	Wed Apr 18 10:22:32 2012 -0700
@@ -0,0 +1,33 @@
+/*
+ * 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.infer.no.conforming.assignment.exists
+
+import java.util.*;
+
+class InferNoConformingAssignment {
+    <X extends Number> List<X> m(String s) { return null; }
+    { this.m(1); }
+}
+
--- a/langtools/test/tools/javac/diags/examples/InferredDoNotConformToBounds.java	Wed Jul 05 18:08:21 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2010, 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.misc.inferred.do.not.conform.to.bounds
-// key: compiler.err.cant.apply.diamond.1
-// key: compiler.misc.diamond
-
-class InferredDoNotConformToBounds {
-   static class SuperFoo<X> {}
-   static class Foo<X extends Number> extends SuperFoo<X> {
-       Foo(X x) {}
-   }
-
-   SuperFoo<String> sf1 = new Foo<>("");
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/InferredDoNotConformToEq.java	Wed Apr 18 10:22:32 2012 -0700
@@ -0,0 +1,32 @@
+/*
+ * 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.inferred.do.not.conform.to.eq.bounds
+
+import java.util.*;
+
+class InferredDoNotConformToEq {
+    <X> void m(List<X> lx1, List<X> lx2) {}
+    { this.m(Arrays.asList(""), Arrays.asList(1)); }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/InferredDoNotConformToLower.java	Wed Apr 18 10:22:32 2012 -0700
@@ -0,0 +1,33 @@
+/*
+ * 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.misc.invalid.inferred.types
+// key: compiler.err.prob.found.req.1
+// key: compiler.misc.inferred.do.not.conform.to.lower.bounds
+
+import java.util.*;
+
+class InferredDoNotConformToLower {
+    <X extends Number> List<X> m() { return null; }
+    { List<? super String> lss = this.m(); }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/InferredDoNotConformToUpper.java	Wed Apr 18 10:22:32 2012 -0700
@@ -0,0 +1,32 @@
+/*
+ * 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.inferred.do.not.conform.to.upper.bounds
+
+import java.util.*;
+
+class InferredDoNotConformToUpper {
+    <X> void m(X x, List<? super X> lx) {}
+    { this.m("", Arrays.asList(1)); }
+}
--- a/langtools/test/tools/javac/diags/examples/InvalidInferredTypes.java	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples/InvalidInferredTypes.java	Wed Apr 18 10:22:32 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -23,17 +23,15 @@
 
 // key: compiler.err.prob.found.req.1
 // key: compiler.misc.invalid.inferred.types
-// key: compiler.misc.inferred.do.not.conform.to.bounds
+// key: compiler.misc.inferred.do.not.conform.to.upper.bounds
 
 import java.util.*;
 
 class InvalidInferredTypes {
 
-    <T extends List<? super T>> T makeList() {
-        return null;
-    }
+    <S extends String> List<S> m() { return null; }
 
-    public void test() {
-        List<? super String> l = makeList();
+    void test() {
+        List<Integer> li = m();
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotAllowedClass.java	Wed Apr 18 10:22:32 2012 -0700
@@ -0,0 +1,31 @@
+/*
+ * 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.class.not.allowed
+
+class NotAllowedClass {
+    void t1() {
+        if (true)
+            class X {}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotAllowedVariable.java	Wed Apr 18 10:22:32 2012 -0700
@@ -0,0 +1,31 @@
+/*
+ * 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.variable.not.allowed
+
+class NotAllowedVariable {
+    void t1() {
+        if (true)
+            int x = 0;
+    }
+}
--- a/langtools/test/tools/javac/diags/examples/WhereCaptured.java	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples/WhereCaptured.java	Wed Apr 18 10:22:32 2012 -0700
@@ -26,7 +26,7 @@
 // key: compiler.misc.where.description.typevar
 // key: compiler.misc.where.typevar
 // key: compiler.err.cant.apply.symbol.1
-// key: compiler.misc.infer.no.conforming.assignment.exists
+// key: compiler.misc.inferred.do.not.conform.to.eq.bounds
 // key: compiler.misc.captured.type
 // options: -XDdiags=where,simpleNames
 // run: simple
--- a/langtools/test/tools/javac/diags/examples/WhereCaptured1.java	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples/WhereCaptured1.java	Wed Apr 18 10:22:32 2012 -0700
@@ -26,7 +26,7 @@
 // key: compiler.misc.where.description.typevar
 // key: compiler.misc.where.typevar
 // key: compiler.err.cant.apply.symbol.1
-// key: compiler.misc.infer.no.conforming.assignment.exists
+// key: compiler.misc.inferred.do.not.conform.to.eq.bounds
 // key: compiler.misc.captured.type
 // key: compiler.misc.type.null
 // options: -XDdiags=where,simpleNames
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/WhereFreshTvar.java	Wed Apr 18 10:22:32 2012 -0700
@@ -0,0 +1,39 @@
+/*
+ * 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.misc.where.fresh.typevar
+// key: compiler.misc.where.description.typevar.1
+// key: compiler.misc.where.typevar
+// key: compiler.misc.invalid.inferred.types
+// key: compiler.err.prob.found.req.1
+// key: compiler.misc.inferred.do.not.conform.to.upper.bounds
+// options: -XDdiags=where,simpleNames
+// run: simple
+
+import java.util.*;
+
+class WhereFreshTvar {
+    <T extends List<T>> T m() {}
+
+    { List<String> ls = m(); }
+}
--- a/langtools/test/tools/javac/generics/diamond/neg/Neg06.out	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/test/tools/javac/generics/diamond/neg/Neg06.out	Wed Apr 18 10:22:32 2012 -0700
@@ -1,2 +1,2 @@
-Neg06.java:16:37: compiler.err.prob.found.req.1: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.infer.no.conforming.instance.exists: X, Neg06.CFoo<X>, Neg06.CSuperFoo<java.lang.String>))
+Neg06.java:16:37: compiler.err.prob.found.req.1: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number))
 1 error
--- a/langtools/test/tools/javac/generics/diamond/neg/Neg07.out	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/test/tools/javac/generics/diamond/neg/Neg07.out	Wed Apr 18 10:22:32 2012 -0700
@@ -1,2 +1,2 @@
-Neg07.java:17:27: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg07.Foo), (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.String, java.lang.Number)
+Neg07.java:17:27: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg07.Foo), (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number)
 1 error
--- a/langtools/test/tools/javac/generics/inference/6315770/T6315770.out	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/test/tools/javac/generics/inference/6315770/T6315770.out	Wed Apr 18 10:22:32 2012 -0700
@@ -1,3 +1,3 @@
 T6315770.java:16:42: compiler.err.prob.found.req.1: (compiler.misc.undetermined.type: <T>T6315770<T>, (compiler.misc.no.unique.maximal.instance.exists: T, java.lang.String,java.lang.Integer,java.lang.Runnable))
-T6315770.java:17:40: compiler.err.prob.found.req.1: (compiler.misc.infer.no.conforming.instance.exists: T, T6315770<T>, T6315770<? super java.lang.String>)
+T6315770.java:17:40: compiler.err.prob.found.req.1: (compiler.misc.invalid.inferred.types: T, (compiler.misc.inferred.do.not.conform.to.lower.bounds: java.lang.Integer&java.lang.Runnable, java.lang.String))
 2 errors
--- a/langtools/test/tools/javac/generics/inference/6611449/T6611449.out	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/test/tools/javac/generics/inference/6611449/T6611449.out	Wed Apr 18 10:22:32 2012 -0700
@@ -1,5 +1,5 @@
-T6611449.java:18:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T,T), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T), (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.Integer, S))}
-T6611449.java:19:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T,T), (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.Integer, S)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T), (compiler.misc.infer.arg.length.mismatch))}
-T6611449.java:20:9: compiler.err.cant.apply.symbol.1: kindname.method, m1, T, int, kindname.class, T6611449<S>, (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.Integer, S)
-T6611449.java:21:9: compiler.err.cant.apply.symbol.1: kindname.method, m2, T,T, int,int, kindname.class, T6611449<S>, (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.Integer, S)
+T6611449.java:18:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T,T), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T), (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, S))}
+T6611449.java:19:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T,T), (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, S)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T), (compiler.misc.infer.arg.length.mismatch))}
+T6611449.java:20:9: compiler.err.cant.apply.symbol.1: kindname.method, m1, T, int, kindname.class, T6611449<S>, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, S)
+T6611449.java:21:9: compiler.err.cant.apply.symbol.1: kindname.method, m2, T,T, int,int, kindname.class, T6611449<S>, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, S)
 4 errors
--- a/langtools/test/tools/javac/generics/inference/6638712/T6638712b.out	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712b.out	Wed Apr 18 10:22:32 2012 -0700
@@ -1,2 +1,2 @@
-T6638712b.java:14:21: compiler.err.prob.found.req.1: (compiler.misc.infer.no.conforming.instance.exists: T, T, java.lang.String)
+T6638712b.java:14:21: compiler.err.prob.found.req.1: (compiler.misc.invalid.inferred.types: T, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, java.lang.String,java.lang.Object))
 1 error
--- a/langtools/test/tools/javac/generics/inference/6638712/T6638712d.out	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712d.out	Wed Apr 18 10:22:32 2012 -0700
@@ -1,2 +1,2 @@
-T6638712d.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, U,java.util.List<java.util.List<U>>, int,java.util.List<java.util.List<java.lang.String>>, kindname.class, T6638712d, (compiler.misc.no.conforming.assignment.exists: int, java.lang.String)
+T6638712d.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, U,java.util.List<java.util.List<U>>, int,java.util.List<java.util.List<java.lang.String>>, kindname.class, T6638712d, (compiler.misc.inferred.do.not.conform.to.lower.bounds: java.lang.String, java.lang.Integer)
 1 error
--- a/langtools/test/tools/javac/generics/inference/6638712/T6638712e.out	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712e.out	Wed Apr 18 10:22:32 2012 -0700
@@ -1,2 +1,2 @@
-T6638712e.java:17:27: compiler.err.prob.found.req.1: (compiler.misc.infer.no.conforming.instance.exists: X, T6638712e.Foo<X,java.lang.String>, T6638712e.Foo<java.lang.Object,java.lang.String>)
+T6638712e.java:17:27: compiler.err.prob.found.req.1: (compiler.misc.invalid.inferred.types: X, (compiler.misc.no.conforming.assignment.exists: T6638712e.Foo<java.lang.Boolean,java.lang.Boolean>, T6638712e.Foo<? super java.lang.Object,? extends java.lang.Boolean>))
 1 error
--- a/langtools/test/tools/javac/generics/inference/6650759/T6650759m.out	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/test/tools/javac/generics/inference/6650759/T6650759m.out	Wed Apr 18 10:22:32 2012 -0700
@@ -1,2 +1,2 @@
-T6650759m.java:43:36: compiler.err.prob.found.req: java.util.List<? super java.lang.Integer>, java.util.List<? super java.lang.String>
+T6650759m.java:43:36: compiler.err.prob.found.req.1: (compiler.misc.invalid.inferred.types: Z, (compiler.misc.inferred.do.not.conform.to.lower.bounds: java.lang.Integer, java.lang.String))
 1 error
--- a/langtools/test/tools/javac/generics/inference/7086601/T7086601a.out	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/test/tools/javac/generics/inference/7086601/T7086601a.out	Wed Apr 18 10:22:32 2012 -0700
@@ -1,5 +1,5 @@
-T7086601a.java:20:9: compiler.err.cant.apply.symbols: kindname.method, m1, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m1(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m1(java.lang.Iterable<? super S>,java.lang.Iterable<? super S>), (compiler.misc.incompatible.upper.bounds: S, java.lang.Integer,java.lang.String))}
-T7086601a.java:24:9: compiler.err.cant.apply.symbols: kindname.method, m2, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,java.lang.Iterable<java.lang.Double>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m2(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m2(java.lang.Iterable<? super S>,java.lang.Iterable<? super S>,java.lang.Iterable<? super S>), (compiler.misc.incompatible.upper.bounds: S, java.lang.Double,java.lang.Integer,java.lang.String))}
-T7086601a.java:28:9: compiler.err.cant.apply.symbols: kindname.method, m3, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m3(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m3(java.lang.Iterable<? super S>...), (compiler.misc.incompatible.upper.bounds: S, java.lang.Integer,java.lang.String))}
-T7086601a.java:32:9: compiler.err.cant.apply.symbols: kindname.method, m3, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,java.lang.Iterable<java.lang.Double>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m3(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m3(java.lang.Iterable<? super S>...), (compiler.misc.incompatible.upper.bounds: S, java.lang.Double,java.lang.Integer,java.lang.String))}
+T7086601a.java:20:9: compiler.err.cant.apply.symbols: kindname.method, m1, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m1(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m1(java.lang.Iterable<? super S>,java.lang.Iterable<? super S>), (compiler.misc.incompatible.upper.bounds: S, java.lang.Integer,java.lang.String,java.lang.Object))}
+T7086601a.java:24:9: compiler.err.cant.apply.symbols: kindname.method, m2, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,java.lang.Iterable<java.lang.Double>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m2(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m2(java.lang.Iterable<? super S>,java.lang.Iterable<? super S>,java.lang.Iterable<? super S>), (compiler.misc.incompatible.upper.bounds: S, java.lang.Double,java.lang.Integer,java.lang.String,java.lang.Object))}
+T7086601a.java:28:9: compiler.err.cant.apply.symbols: kindname.method, m3, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m3(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m3(java.lang.Iterable<? super S>...), (compiler.misc.incompatible.upper.bounds: S, java.lang.Integer,java.lang.String,java.lang.Object))}
+T7086601a.java:32:9: compiler.err.cant.apply.symbols: kindname.method, m3, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,java.lang.Iterable<java.lang.Double>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m3(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m3(java.lang.Iterable<? super S>...), (compiler.misc.incompatible.upper.bounds: S, java.lang.Double,java.lang.Integer,java.lang.String,java.lang.Object))}
 4 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/7154127/T7154127.java	Wed Apr 18 10:22:32 2012 -0700
@@ -0,0 +1,21 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 7154127
+ * @summary Inference cleanup: remove bound check analysis from visitors in Types.java
+ * @compile/fail/ref=T7154127.out -XDrawDiagnostics T7154127.java
+ */
+class T7154127 {
+
+    static class B<V> {}
+
+    static class D extends B<E> {}
+    static class E extends B<D> {}
+
+    static class Triple<U,V,W> { }
+
+    static <T, Y extends B<U>, U extends B<Y>> Triple<T, Y, U> m() { return null; }
+
+    void test() {
+       Triple<B, ? extends D, ? extends E> t = m();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/7154127/T7154127.out	Wed Apr 18 10:22:32 2012 -0700
@@ -0,0 +1,2 @@
+T7154127.java:19:49: compiler.err.prob.found.req.1: (compiler.misc.invalid.inferred.types: T,Y,U, (compiler.misc.inferred.do.not.conform.to.upper.bounds: Y, T7154127.D,T7154127.B<U>))
+1 error
--- a/langtools/test/tools/javac/parser/JavacParserTest.java	Wed Jul 05 18:08:21 2017 +0200
+++ b/langtools/test/tools/javac/parser/JavacParserTest.java	Wed Apr 18 10:22:32 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -596,8 +596,8 @@
     public void testVariableInIfThen3() throws IOException {
 
         String code = "package t; class Test { "+
-                "private static void t(String name) { " +
-                "if (name != null) abstract } }";
+                "private static void t() { " +
+                "if (true) abstract class F {} }}";
         DiagnosticCollector<JavaFileObject> coll =
                 new DiagnosticCollector<JavaFileObject>();
         JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null,
@@ -612,7 +612,51 @@
         }
 
         assertEquals("testVariableInIfThen3",
-                Arrays.<String>asList("compiler.err.illegal.start.of.expr"),
+                Arrays.<String>asList("compiler.err.class.not.allowed"), codes);
+    }
+
+    public void testVariableInIfThen4() throws IOException {
+
+        String code = "package t; class Test { "+
+                "private static void t(String name) { " +
+                "if (name != null) interface X {} } }";
+        DiagnosticCollector<JavaFileObject> coll =
+                new DiagnosticCollector<JavaFileObject>();
+        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null,
+                null, Arrays.asList(new MyFileObject(code)));
+
+        ct.parse();
+
+        List<String> codes = new LinkedList<String>();
+
+        for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) {
+            codes.add(d.getCode());
+        }
+
+        assertEquals("testVariableInIfThen4",
+                Arrays.<String>asList("compiler.err.class.not.allowed"), codes);
+    }
+
+    public void testVariableInIfThen5() throws IOException {
+
+        String code = "package t; class Test { "+
+                "private static void t() { " +
+                "if (true) } }";
+        DiagnosticCollector<JavaFileObject> coll =
+                new DiagnosticCollector<JavaFileObject>();
+        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null,
+                null, Arrays.asList(new MyFileObject(code)));
+
+        ct.parse();
+
+        List<String> codes = new LinkedList<String>();
+
+        for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) {
+            codes.add(d.getCode());
+        }
+
+        assertEquals("testVariableInIfThen5",
+                Arrays.<String>asList("compiler.err.illegal.start.of.stmt"),
                 codes);
     }
 
@@ -808,8 +852,6 @@
         testPositionBrokenSource126732b();
 
         // Fails, these tests yet to be addressed
-        testVariableInIfThen1();
-        testVariableInIfThen2();
         testPositionForEnumModifiers();
         testStartPositionEnumConstantInit();
     }
@@ -821,7 +863,11 @@
         testPreferredPositionForBinaryOp();
         testStartPositionForMethodWithoutModifiers();
         testVarPos();
+        testVariableInIfThen1();
+        testVariableInIfThen2();
         testVariableInIfThen3();
+        testVariableInIfThen4();
+        testVariableInIfThen5();
         testMissingExponent();
         testTryResourcePos();
         testOperatorMissingError();