Mercurial > hg > openjdk > lambda > langtools
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
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