diff --git a/src/share/classes/com/sun/tools/javac/code/Type.java b/src/share/classes/com/sun/tools/javac/code/Type.java index bda5d843148bec912eee1783fd80354b014309f1..a67cd0f958394f76624c15314c673bec95aaea8a 100644 --- a/src/share/classes/com/sun/tools/javac/code/Type.java +++ b/src/share/classes/com/sun/tools/javac/code/Type.java @@ -365,6 +365,16 @@ public class Type implements PrimitiveType { return false; } + public static List filter(List ts, Filter tf) { + ListBuffer buf = ListBuffer.lb(); + for (Type t : ts) { + if (tf.accepts(t)) { + buf.append(t); + } + } + return buf.toList(); + } + public boolean isSuperBound() { return false; } public boolean isExtendsBound() { return false; } public boolean isUnbound() { return false; } diff --git a/src/share/classes/com/sun/tools/javac/comp/Check.java b/src/share/classes/com/sun/tools/javac/comp/Check.java index 05a1f6b5f5b246e8d222d839c9782322efaf3eec..d9abfe2b49943979791362fec879cb86524d5d34 100644 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -800,7 +800,8 @@ public class Check { Type actual = types.subst(args.head, type.tsym.type.getTypeArguments(), tvars_buf.toList()); - if (!checkExtends(actual, (TypeVar)tvars.head)) { + if (!checkExtends(actual, (TypeVar)tvars.head) && + !tvars.head.getUpperBound().isErroneous()) { return args.head; } args = args.tail; @@ -808,11 +809,15 @@ public class Check { } args = type.getTypeArguments(); + tvars = tvars_buf.toList(); for (Type arg : types.capture(type).getTypeArguments()) { - if (arg.tag == TYPEVAR && arg.getUpperBound().isErroneous()) { + if (arg.tag == TYPEVAR && + arg.getUpperBound().isErroneous() && + !tvars.head.getUpperBound().isErroneous()) { return args.head; } + tvars = tvars.tail; } return null; diff --git a/src/share/classes/com/sun/tools/javac/comp/Infer.java b/src/share/classes/com/sun/tools/javac/comp/Infer.java index 48b1afff7be463f5d6893858e4d2b91742ebec7b..66e44903941a3aed8d84fec9d490745d50ce9f6a 100644 --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java @@ -205,19 +205,20 @@ public class Infer { * Throw a NoInstanceException if this not possible. */ void maximizeInst(UndetVar that, Warner warn) throws NoInstanceException { + List hibounds = Type.filter(that.hibounds, errorFilter); if (that.inst == null) { - if (that.hibounds.isEmpty()) + if (hibounds.isEmpty()) that.inst = syms.objectType; - else if (that.hibounds.tail.isEmpty()) - that.inst = that.hibounds.head; + else if (hibounds.tail.isEmpty()) + that.inst = hibounds.head; else - that.inst = types.glb(that.hibounds); + that.inst = types.glb(hibounds); } if (that.inst == null || that.inst.isErroneous()) throw ambiguousNoInstanceException .setMessage("no.unique.maximal.instance.exists", - that.qtype, that.hibounds); + that.qtype, hibounds); } //where private boolean isSubClass(Type t, final List ts) { @@ -241,37 +242,46 @@ public class Infer { return true; } + private Filter errorFilter = new Filter() { + @Override + public boolean accepts(Type t) { + return !t.isErroneous(); + } + }; + /** Instantiate undetermined type variable to the lub of all its lower bounds. * Throw a NoInstanceException if this not possible. */ void minimizeInst(UndetVar that, Warner warn) throws NoInstanceException { + List lobounds = Type.filter(that.lobounds, errorFilter); if (that.inst == null) { - if (that.lobounds.isEmpty()) + if (lobounds.isEmpty()) that.inst = syms.botType; - else if (that.lobounds.tail.isEmpty()) - that.inst = that.lobounds.head.isPrimitive() ? syms.errType : that.lobounds.head; + else if (lobounds.tail.isEmpty()) + that.inst = lobounds.head.isPrimitive() ? syms.errType : lobounds.head; else { - that.inst = types.lub(that.lobounds); + that.inst = types.lub(lobounds); } if (that.inst == null || that.inst.tag == ERROR) throw ambiguousNoInstanceException .setMessage("no.unique.minimal.instance.exists", - that.qtype, that.lobounds); + that.qtype, lobounds); // VGJ: sort of inlined maximizeInst() below. Adding // bounds can cause lobounds that are above hibounds. - if (that.hibounds.isEmpty()) + List hibounds = Type.filter(that.hibounds, errorFilter); + if (hibounds.isEmpty()) return; Type hb = null; - if (that.hibounds.tail.isEmpty()) - hb = that.hibounds.head; - else for (List bs = that.hibounds; + if (hibounds.tail.isEmpty()) + hb = hibounds.head; + else for (List bs = hibounds; bs.nonEmpty() && hb == null; bs = bs.tail) { - if (isSubClass(bs.head, that.hibounds)) + if (isSubClass(bs.head, hibounds)) hb = types.fromUnknownFun.apply(bs.head); } if (hb == null || - !types.isSubtypeUnchecked(hb, that.hibounds, warn) || + !types.isSubtypeUnchecked(hb, hibounds, warn) || !types.isSubtypeUnchecked(that.inst, hb, warn)) throw ambiguousNoInstanceException; } @@ -528,7 +538,8 @@ public class Infer { for (List tvs = tvars, args = arguments; tvs.nonEmpty(); tvs = tvs.tail, args = args.tail) { - if (args.head instanceof UndetVar) continue; + if (args.head instanceof UndetVar || + tvars.head.getUpperBound().isErroneous()) continue; List bounds = types.subst(types.getBounds((TypeVar)tvs.head), tvars, arguments); if (!types.isSubtypeUnchecked(args.head, bounds, warn)) throw invalidInstanceException diff --git a/test/tools/javac/generics/inference/6943278/T6943278.java b/test/tools/javac/generics/inference/6943278/T6943278.java new file mode 100644 index 0000000000000000000000000000000000000000..69e2e50fb92150dea704d8c5b815190ffef308d7 --- /dev/null +++ b/test/tools/javac/generics/inference/6943278/T6943278.java @@ -0,0 +1,12 @@ +/** + * @test /nodynamiccopyright/ + * @bug 6943278 + * @summary spurious error message for inference and type-variable with erroneous bound + * @compile/fail/ref=T6943278.out -XDrawDiagnostics -Xlint:unchecked T6943278.java + */ +class T6943278 { + T6943278 m() { return null;} + T6943278 m(X x) { return null;} + T6943278 f1 = m(); + T6943278 f2 = m(""); +} diff --git a/test/tools/javac/generics/inference/6943278/T6943278.out b/test/tools/javac/generics/inference/6943278/T6943278.out new file mode 100644 index 0000000000000000000000000000000000000000..d3bc5b016f9dc69f8fdfbab8894959217048c02f --- /dev/null +++ b/test/tools/javac/generics/inference/6943278/T6943278.out @@ -0,0 +1,3 @@ +T6943278.java:7:35: compiler.err.cant.resolve: kindname.class, NonExistentInterface, , +T6943278.java:9:25: compiler.err.cant.resolve.location: kindname.class, NonExistentInterface, , , kindname.class, T6943278 +2 errors