Mercurial > hg > openjdk > lambda > langtools
changeset 2295:42b3c5e92461
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
author | mcimadamore |
---|---|
date | Fri, 05 Jul 2013 11:05:02 +0100 |
parents | bfbedbfc522a |
children | 49654c9c705b |
files | src/share/classes/com/sun/tools/javac/code/Type.java src/share/classes/com/sun/tools/javac/comp/Infer.java test/tools/javac/generics/inference/8019824/T8019824.java test/tools/javac/generics/inference/8019824/T8019824.out |
diffstat | 4 files changed, 48 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/code/Type.java Fri Jul 05 11:04:22 2013 +0100 +++ b/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<Type> 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<Type> 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); }
--- a/src/share/classes/com/sun/tools/javac/comp/Infer.java Fri Jul 05 11:04:22 2013 +0100 +++ b/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<Type> 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<Type> varsToSolve = List.from(nodeToSolve.data); - inferenceContext.save(); + List<Type> 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<Type> save() { ListBuffer<Type> 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<Type> 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; + } } /**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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<? extends Foo<?, ?>> cls) { + Foo<?, ?> foo = make(cls); + } + + <A, B, C extends Foo<A, B>> Foo<A, B> make(Class<C> cls) { return null; } + + interface Foo<A, B> {} +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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<C>, java.lang.Class<compiler.misc.type.captureof: 1, ? extends T8019824.Foo<?,?>>, kindname.class, T8019824, (compiler.misc.incompatible.eq.upper.bounds: C, compiler.misc.type.captureof: 1, ? extends T8019824.Foo<?,?>, T8019824.Foo<java.lang.Object,B>) +1 error