6969184: poor error recovery after symbol not found

Generic type-well formedness check should ignore erroneous symbols

Reviewed-by: jjg
This commit is contained in:
Maurizio Cimadamore 2011-02-03 09:37:28 +00:00
parent 6ded62c828
commit 536bd08692
3 changed files with 68 additions and 3 deletions
langtools
src/share/classes/com/sun/tools/javac/comp
test/tools/javac/generics/6969184

@ -807,8 +807,9 @@ public class Check {
Type actual = types.subst(args.head,
type.tsym.type.getTypeArguments(),
tvars_buf.toList());
if (!checkExtends(actual, (TypeVar)tvars.head) &&
!tvars.head.getUpperBound().isErroneous()) {
if (!isTypeArgErroneous(actual) &&
!tvars.head.getUpperBound().isErroneous() &&
!checkExtends(actual, (TypeVar)tvars.head)) {
return args.head;
}
args = args.tail;
@ -821,14 +822,39 @@ public class Check {
for (Type arg : types.capture(type).getTypeArguments()) {
if (arg.tag == TYPEVAR &&
arg.getUpperBound().isErroneous() &&
!tvars.head.getUpperBound().isErroneous()) {
!tvars.head.getUpperBound().isErroneous() &&
!isTypeArgErroneous(args.head)) {
return args.head;
}
tvars = tvars.tail;
args = args.tail;
}
return null;
}
//where
boolean isTypeArgErroneous(Type t) {
return isTypeArgErroneous.visit(t);
}
Types.UnaryVisitor<Boolean> isTypeArgErroneous = new Types.UnaryVisitor<Boolean>() {
public Boolean visitType(Type t, Void s) {
return t.isErroneous();
}
@Override
public Boolean visitTypeVar(TypeVar t, Void s) {
return visit(t.getUpperBound());
}
@Override
public Boolean visitCapturedType(CapturedType t, Void s) {
return visit(t.getUpperBound()) ||
visit(t.getLowerBound());
}
@Override
public Boolean visitWildcardType(WildcardType t, Void s) {
return visit(t.type);
}
};
/** Check that given modifiers are legal for given symbol and
* return modifiers together with any implicit modififiers for that symbol.

@ -0,0 +1,29 @@
/*
* @test /nodynamiccopyright/
* @bug 6956758
*
* @summary poor error recovery after symbol not found
* @author Maurizio Cimadamore
* @compile/fail/ref=T6969184.out -XDrawDiagnostics T6969184.java
*
*/
class T6969184 {
static class C1<X> {
void m1(C1<? extends NonExistentClass> n) {}
void m2(C1<? super NonExistentClass> n) {}
void m3(C1<?> n) {}
}
static class C2<X extends NonExistentBound> {
void m1(C2<? extends NonExistentClass> n) {}
void m2(C2<? super NonExistentClass> n) {}
void m3(C2<?> n) {}
}
static class C3<X extends NonExistentBound1 & NonExistentBound2> {
void m1(C3<? extends NonExistentClass> n) {}
void m2(C3<? super NonExistentClass> n) {}
void m3(C3<?> n) {}
}
}

@ -0,0 +1,10 @@
T6969184.java:13:30: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, T6969184.C1<X>, null)
T6969184.java:14:28: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, T6969184.C1<X>, null)
T6969184.java:18:31: compiler.err.cant.resolve.location: kindname.class, NonExistentBound, , , (compiler.misc.location: kindname.class, T6969184, null)
T6969184.java:19:30: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, T6969184.C2<X>, null)
T6969184.java:20:28: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, T6969184.C2<X>, null)
T6969184.java:24:31: compiler.err.cant.resolve.location: kindname.class, NonExistentBound1, , , (compiler.misc.location: kindname.class, T6969184, null)
T6969184.java:24:51: compiler.err.cant.resolve.location: kindname.class, NonExistentBound2, , , (compiler.misc.location: kindname.class, T6969184, null)
T6969184.java:25:30: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, T6969184.C3<X>, null)
T6969184.java:26:28: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, T6969184.C3<X>, null)
9 errors