From 3f9fdcf0f44aa97af68dae2a2d19a5d68f3d3bc0 Mon Sep 17 00:00:00 2001 From: mcimadamore Date: Fri, 5 Jul 2013 11:05:02 +0100 Subject: [PATCH] 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 --- .../com/sun/tools/javac/code/Type.java | 11 ++++-- .../com/sun/tools/javac/comp/Infer.java | 34 +++++++++++++------ .../generics/inference/8019824/T8019824.java | 15 ++++++++ .../generics/inference/8019824/T8019824.out | 2 ++ 4 files changed, 48 insertions(+), 14 deletions(-) create mode 100644 test/tools/javac/generics/inference/8019824/T8019824.java create mode 100644 test/tools/javac/generics/inference/8019824/T8019824.out 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 b69b421d..daa0aa0f 100644 --- a/src/share/classes/com/sun/tools/javac/code/Type.java +++ b/src/share/classes/com/sun/tools/javac/code/Type.java @@ -1514,9 +1514,14 @@ public abstract class Type implements TypeMirror { 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 @@ public abstract class Type implements TypeMirror { 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 --git a/src/share/classes/com/sun/tools/javac/comp/Infer.java b/src/share/classes/com/sun/tools/javac/comp/Infer.java index c5f4b271..e4242908 100644 --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java @@ -418,6 +418,7 @@ public class Infer { 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 @@ public class Infer { } finally { mlistener.detach(); + if (mlistener.rounds == MAX_INCORPORATION_STEPS) { + inferenceContext.rollback(saved_undet); + } } } //where @@ -645,7 +649,7 @@ public class Infer { 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 @@ public class Infer { 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 @@ public class Infer { 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 @@ public class Infer { 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 @@ public class Infer { } 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 @@ public class Infer { /** * 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 @@ public class Infer { 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 --git a/test/tools/javac/generics/inference/8019824/T8019824.java b/test/tools/javac/generics/inference/8019824/T8019824.java new file mode 100644 index 00000000..30f0effd --- /dev/null +++ b/test/tools/javac/generics/inference/8019824/T8019824.java @@ -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 --git a/test/tools/javac/generics/inference/8019824/T8019824.out b/test/tools/javac/generics/inference/8019824/T8019824.out new file mode 100644 index 00000000..28a2584d --- /dev/null +++ b/test/tools/javac/generics/inference/8019824/T8019824.out @@ -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 -- GitLab