提交 3f9fdcf0 编写于 作者: M mcimadamore

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
上级 e8ff3561
...@@ -1514,9 +1514,14 @@ public abstract class Type implements TypeMirror { ...@@ -1514,9 +1514,14 @@ public abstract class Type implements TypeMirror {
return buf.toList(); 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 */ /** add a bound of a given kind - this might trigger listener notification */
public void addBound(InferenceBound ib, Type bound, Types types) { 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); List<Type> prevBounds = bounds.get(ib);
for (Type b : prevBounds) { for (Type b : prevBounds) {
//check for redundancy - use strict version of isSameType on tvars //check for redundancy - use strict version of isSameType on tvars
...@@ -1527,12 +1532,12 @@ public abstract class Type implements TypeMirror { ...@@ -1527,12 +1532,12 @@ public abstract class Type implements TypeMirror {
notifyChange(EnumSet.of(ib)); notifyChange(EnumSet.of(ib));
} }
//where //where
Type.Mapping toTypeVarMap = new Mapping("toTypeVarMap") { Type.Mapping boundMap = new Mapping("boundMap") {
@Override @Override
public Type apply(Type t) { public Type apply(Type t) {
if (t.hasTag(UNDETVAR)) { if (t.hasTag(UNDETVAR)) {
UndetVar uv = (UndetVar)t; UndetVar uv = (UndetVar)t;
return uv.qtype; return uv.inst != null ? uv.inst : uv.qtype;
} else { } else {
return t.map(this); return t.map(this);
} }
......
...@@ -418,6 +418,7 @@ public class Infer { ...@@ -418,6 +418,7 @@ public class Infer {
void checkWithinBounds(InferenceContext inferenceContext, void checkWithinBounds(InferenceContext inferenceContext,
Warner warn) throws InferenceException { Warner warn) throws InferenceException {
MultiUndetVarListener mlistener = new MultiUndetVarListener(inferenceContext.undetvars); MultiUndetVarListener mlistener = new MultiUndetVarListener(inferenceContext.undetvars);
List<Type> saved_undet = inferenceContext.save();
try { try {
while (true) { while (true) {
mlistener.reset(); mlistener.reset();
...@@ -443,6 +444,9 @@ public class Infer { ...@@ -443,6 +444,9 @@ public class Infer {
} }
finally { finally {
mlistener.detach(); mlistener.detach();
if (mlistener.rounds == MAX_INCORPORATION_STEPS) {
inferenceContext.rollback(saved_undet);
}
} }
} }
//where //where
...@@ -645,7 +649,7 @@ public class Infer { ...@@ -645,7 +649,7 @@ public class Infer {
UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
//alpha <: beta //alpha <: beta
//0. set beta :> alpha //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 //1. copy alpha's lower to beta's
for (Type l : uv.getBounds(InferenceBound.LOWER)) { for (Type l : uv.getBounds(InferenceBound.LOWER)) {
uv2.addBound(InferenceBound.LOWER, inferenceContext.asInstType(l), infer.types); uv2.addBound(InferenceBound.LOWER, inferenceContext.asInstType(l), infer.types);
...@@ -670,7 +674,7 @@ public class Infer { ...@@ -670,7 +674,7 @@ public class Infer {
UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
//alpha :> beta //alpha :> beta
//0. set beta <: alpha //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 //1. copy alpha's upper to beta's
for (Type u : uv.getBounds(InferenceBound.UPPER)) { for (Type u : uv.getBounds(InferenceBound.UPPER)) {
uv2.addBound(InferenceBound.UPPER, inferenceContext.asInstType(u), infer.types); uv2.addBound(InferenceBound.UPPER, inferenceContext.asInstType(u), infer.types);
...@@ -695,7 +699,7 @@ public class Infer { ...@@ -695,7 +699,7 @@ public class Infer {
UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
//alpha == beta //alpha == beta
//0. set beta == alpha //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 //1. copy all alpha's bounds to beta's
for (InferenceBound ib : InferenceBound.values()) { for (InferenceBound ib : InferenceBound.values()) {
for (Type b2 : uv.getBounds(ib)) { for (Type b2 : uv.getBounds(ib)) {
...@@ -1090,7 +1094,7 @@ public class Infer { ...@@ -1090,7 +1094,7 @@ public class Infer {
while (!sstrategy.done()) { while (!sstrategy.done()) {
InferenceGraph.Node nodeToSolve = sstrategy.pickNode(inferenceGraph); InferenceGraph.Node nodeToSolve = sstrategy.pickNode(inferenceGraph);
List<Type> varsToSolve = List.from(nodeToSolve.data); List<Type> varsToSolve = List.from(nodeToSolve.data);
inferenceContext.save(); List<Type> saved_undet = inferenceContext.save();
try { try {
//repeat until all variables are solved //repeat until all variables are solved
outer: while (Type.containsAny(inferenceContext.restvars(), varsToSolve)) { outer: while (Type.containsAny(inferenceContext.restvars(), varsToSolve)) {
...@@ -1107,7 +1111,7 @@ public class Infer { ...@@ -1107,7 +1111,7 @@ public class Infer {
} }
catch (InferenceException ex) { catch (InferenceException ex) {
//did we fail because of interdependent ivars? //did we fail because of interdependent ivars?
inferenceContext.rollback(); inferenceContext.rollback(saved_undet);
instantiateAsUninferredVars(varsToSolve, inferenceContext); instantiateAsUninferredVars(varsToSolve, inferenceContext);
checkWithinBounds(inferenceContext, warn); checkWithinBounds(inferenceContext, warn);
} }
...@@ -1502,7 +1506,7 @@ public class Infer { ...@@ -1502,7 +1506,7 @@ public class Infer {
/** /**
* Save the state of this inference context * Save the state of this inference context
*/ */
void save() { List<Type> save() {
ListBuffer<Type> buf = ListBuffer.lb(); ListBuffer<Type> buf = ListBuffer.lb();
for (Type t : undetvars) { for (Type t : undetvars) {
UndetVar uv = (UndetVar)t; UndetVar uv = (UndetVar)t;
...@@ -1515,16 +1519,24 @@ public class Infer { ...@@ -1515,16 +1519,24 @@ public class Infer {
uv2.inst = uv.inst; uv2.inst = uv.inst;
buf.add(uv2); buf.add(uv2);
} }
saved_undet = buf.toList(); return buf.toList();
} }
/** /**
* Restore the state of this inference context to the previous known checkpoint * Restore the state of this inference context to the previous known checkpoint
*/ */
void rollback() { void rollback(List<Type> saved_undet) {
Assert.check(saved_undet != null && saved_undet.length() == undetvars.length()); Assert.check(saved_undet != null && saved_undet.length() == undetvars.length());
undetvars = saved_undet; //restore bounds (note: we need to preserve the old instances)
saved_undet = null; 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;
}
} }
/** /**
......
/**
* @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> {}
}
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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册