# HG changeset patch # User mcimadamore # Date 1373018702 -3600 # Node ID 3c4c6457ec5b76b527d61d2ef1dcf04a41686239 # Parent 99f42bd11bc2a9947fb67c37080c23cdee032972 8019824: very long error messages on inference error Summary: Inference error messages shows several spurious captured variables generated during an inference loop Reviewed-by: jjg, vromero diff -r 99f42bd11bc2 -r 3c4c6457ec5b langtools/src/share/classes/com/sun/tools/javac/code/Type.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Fri Jul 05 11:04:22 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Fri Jul 05 11:05:02 2013 +0100 @@ -1514,9 +1514,14 @@ return buf.toList(); } + /** internal method used to override an undetvar bounds */ + public void setBounds(InferenceBound ib, List newBounds) { + bounds.put(ib, newBounds); + } + /** add a bound of a given kind - this might trigger listener notification */ public void addBound(InferenceBound ib, Type bound, Types types) { - Type bound2 = toTypeVarMap.apply(bound); + Type bound2 = boundMap.apply(bound); List prevBounds = bounds.get(ib); for (Type b : prevBounds) { //check for redundancy - use strict version of isSameType on tvars @@ -1527,12 +1532,12 @@ notifyChange(EnumSet.of(ib)); } //where - Type.Mapping toTypeVarMap = new Mapping("toTypeVarMap") { + Type.Mapping boundMap = new Mapping("boundMap") { @Override public Type apply(Type t) { if (t.hasTag(UNDETVAR)) { UndetVar uv = (UndetVar)t; - return uv.qtype; + return uv.inst != null ? uv.inst : uv.qtype; } else { return t.map(this); } diff -r 99f42bd11bc2 -r 3c4c6457ec5b langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Fri Jul 05 11:04:22 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Fri Jul 05 11:05:02 2013 +0100 @@ -418,6 +418,7 @@ void checkWithinBounds(InferenceContext inferenceContext, Warner warn) throws InferenceException { MultiUndetVarListener mlistener = new MultiUndetVarListener(inferenceContext.undetvars); + List saved_undet = inferenceContext.save(); try { while (true) { mlistener.reset(); @@ -443,6 +444,9 @@ } finally { mlistener.detach(); + if (mlistener.rounds == MAX_INCORPORATION_STEPS) { + inferenceContext.rollback(saved_undet); + } } } //where @@ -645,7 +649,7 @@ UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); //alpha <: beta //0. set beta :> alpha - uv2.addBound(InferenceBound.LOWER, uv.qtype, infer.types); + uv2.addBound(InferenceBound.LOWER, uv, infer.types); //1. copy alpha's lower to beta's for (Type l : uv.getBounds(InferenceBound.LOWER)) { uv2.addBound(InferenceBound.LOWER, inferenceContext.asInstType(l), infer.types); @@ -670,7 +674,7 @@ UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); //alpha :> beta //0. set beta <: alpha - uv2.addBound(InferenceBound.UPPER, uv.qtype, infer.types); + uv2.addBound(InferenceBound.UPPER, uv, infer.types); //1. copy alpha's upper to beta's for (Type u : uv.getBounds(InferenceBound.UPPER)) { uv2.addBound(InferenceBound.UPPER, inferenceContext.asInstType(u), infer.types); @@ -695,7 +699,7 @@ UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); //alpha == beta //0. set beta == alpha - uv2.addBound(InferenceBound.EQ, uv.qtype, infer.types); + uv2.addBound(InferenceBound.EQ, uv, infer.types); //1. copy all alpha's bounds to beta's for (InferenceBound ib : InferenceBound.values()) { for (Type b2 : uv.getBounds(ib)) { @@ -1090,7 +1094,7 @@ while (!sstrategy.done()) { InferenceGraph.Node nodeToSolve = sstrategy.pickNode(inferenceGraph); List varsToSolve = List.from(nodeToSolve.data); - inferenceContext.save(); + List saved_undet = inferenceContext.save(); try { //repeat until all variables are solved outer: while (Type.containsAny(inferenceContext.restvars(), varsToSolve)) { @@ -1107,7 +1111,7 @@ } catch (InferenceException ex) { //did we fail because of interdependent ivars? - inferenceContext.rollback(); + inferenceContext.rollback(saved_undet); instantiateAsUninferredVars(varsToSolve, inferenceContext); checkWithinBounds(inferenceContext, warn); } @@ -1502,7 +1506,7 @@ /** * Save the state of this inference context */ - void save() { + List save() { ListBuffer buf = ListBuffer.lb(); for (Type t : undetvars) { UndetVar uv = (UndetVar)t; @@ -1515,16 +1519,24 @@ uv2.inst = uv.inst; buf.add(uv2); } - saved_undet = buf.toList(); + return buf.toList(); } /** * Restore the state of this inference context to the previous known checkpoint */ - void rollback() { - Assert.check(saved_undet != null && saved_undet.length() == undetvars.length()); - undetvars = saved_undet; - saved_undet = null; + void rollback(List saved_undet) { + Assert.check(saved_undet != null && saved_undet.length() == undetvars.length()); + //restore bounds (note: we need to preserve the old instances) + for (Type t : undetvars) { + UndetVar uv = (UndetVar)t; + UndetVar uv_saved = (UndetVar)saved_undet.head; + for (InferenceBound ib : InferenceBound.values()) { + uv.setBounds(ib, uv_saved.getBounds(ib)); + } + uv.inst = uv_saved.inst; + saved_undet = saved_undet.tail; + } } /** diff -r 99f42bd11bc2 -r 3c4c6457ec5b langtools/test/tools/javac/generics/inference/8019824/T8019824.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/generics/inference/8019824/T8019824.java Fri Jul 05 11:05:02 2013 +0100 @@ -0,0 +1,15 @@ +/** + * @test /nodynamiccopyright/ + * @bug 8019824 + * @summary very long error messages on inference error + * @compile/fail/ref=T8019824.out -XDrawDiagnostics T8019824.java + */ +class T8019824 { + void test(Class> cls) { + Foo foo = make(cls); + } + + > Foo make(Class cls) { return null; } + + interface Foo {} +} diff -r 99f42bd11bc2 -r 3c4c6457ec5b langtools/test/tools/javac/generics/inference/8019824/T8019824.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/generics/inference/8019824/T8019824.out Fri Jul 05 11:05:02 2013 +0100 @@ -0,0 +1,2 @@ +T8019824.java:9:25: compiler.err.cant.apply.symbol: kindname.method, make, java.lang.Class, java.lang.Class>, kindname.class, T8019824, (compiler.misc.incompatible.eq.upper.bounds: C, compiler.misc.type.captureof: 1, ? extends T8019824.Foo, T8019824.Foo) +1 error