--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Thu Aug 19 11:54:25 2010 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Mon Aug 23 16:59:30 2010 +0100
@@ -960,7 +960,7 @@
return true;
if (s.tag == TYPEVAR) {
- if (isCastable(s.getUpperBound(), t, Warner.noWarnings)) {
+ if (isCastable(t, s.getUpperBound(), Warner.noWarnings)) {
warnStack.head.warnUnchecked();
return true;
} else {
@@ -1030,7 +1030,12 @@
&& !disjointTypes(aHigh.allparams(), lowSub.allparams())
&& !disjointTypes(aLow.allparams(), highSub.allparams())
&& !disjointTypes(aLow.allparams(), lowSub.allparams())) {
- if (upcast ? giveWarning(a, b) :
+ if (s.isInterface() &&
+ !t.isInterface() &&
+ t.isFinal() &&
+ !isSubtype(t, s)) {
+ return false;
+ } else if (upcast ? giveWarning(a, b) :
giveWarning(b, a))
warnStack.head.warnUnchecked();
return true;
@@ -1230,18 +1235,23 @@
if (t == s) return false;
if (t.tag == TYPEVAR) {
TypeVar tv = (TypeVar) t;
- if (s.tag == TYPEVAR)
- s = s.getUpperBound();
return !isCastable(tv.bound,
- s,
+ relaxBound(s),
Warner.noWarnings);
}
if (s.tag != WILDCARD)
s = upperBound(s);
- if (s.tag == TYPEVAR)
- s = s.getUpperBound();
-
- return !isSubtype(t, s);
+
+ return !isSubtype(t, relaxBound(s));
+ }
+
+ private Type relaxBound(Type t) {
+ if (t.tag == TYPEVAR) {
+ while (t.tag == TYPEVAR)
+ t = t.getUpperBound();
+ t = rewriteQuantifiers(t, true, true);
+ }
+ return t;
}
// </editor-fold>
@@ -3280,7 +3290,7 @@
* quantifiers) only
*/
private Type rewriteQuantifiers(Type t, boolean high, boolean rewriteTypeVars) {
- return new Rewriter(high, rewriteTypeVars).rewrite(t);
+ return new Rewriter(high, rewriteTypeVars).visit(t);
}
class Rewriter extends UnaryVisitor<Type> {
@@ -3293,25 +3303,21 @@
this.rewriteTypeVars = rewriteTypeVars;
}
- Type rewrite(Type t) {
- ListBuffer<Type> from = new ListBuffer<Type>();
- ListBuffer<Type> to = new ListBuffer<Type>();
- adaptSelf(t, from, to);
+ @Override
+ public Type visitClassType(ClassType t, Void s) {
ListBuffer<Type> rewritten = new ListBuffer<Type>();
- List<Type> formals = from.toList();
boolean changed = false;
- for (Type arg : to.toList()) {
+ for (Type arg : t.allparams()) {
Type bound = visit(arg);
if (arg != bound) {
changed = true;
- bound = high ? makeExtendsWildcard(bound, (TypeVar)formals.head)
- : makeSuperWildcard(bound, (TypeVar)formals.head);
}
rewritten.append(bound);
- formals = formals.tail;
}
if (changed)
- return subst(t.tsym.type, from.toList(), rewritten.toList());
+ return subst(t.tsym.type,
+ t.tsym.type.allparams(),
+ rewritten.toList());
else
return t;
}
@@ -3322,13 +3328,22 @@
@Override
public Type visitCapturedType(CapturedType t, Void s) {
- return visitWildcardType(t.wildcard, null);
+ Type bound = visitWildcardType(t.wildcard, null);
+ return (bound.contains(t)) ?
+ (high ? syms.objectType : syms.botType) :
+ bound;
}
@Override
public Type visitTypeVar(TypeVar t, Void s) {
- if (rewriteTypeVars)
- return high ? t.bound : syms.botType;
+ if (rewriteTypeVars) {
+ Type bound = high ?
+ (t.bound.contains(t) ?
+ syms.objectType :
+ visit(t.bound)) :
+ syms.botType;
+ return rewriteAsWildcardType(bound, t);
+ }
else
return t;
}
@@ -3338,11 +3353,31 @@
Type bound = high ? t.getExtendsBound() :
t.getSuperBound();
if (bound == null)
- bound = high ? syms.objectType : syms.botType;
- return bound;
+ bound = high ? syms.objectType : syms.botType;
+ return rewriteAsWildcardType(visit(bound), t.bound);
+ }
+
+ private Type rewriteAsWildcardType(Type bound, TypeVar formal) {
+ return high ?
+ makeExtendsWildcard(B(bound), formal) :
+ makeSuperWildcard(B(bound), formal);
+ }
+
+ Type B(Type t) {
+ while (t.tag == WILDCARD) {
+ WildcardType w = (WildcardType)t;
+ t = high ?
+ w.getExtendsBound() :
+ w.getSuperBound();
+ if (t == null) {
+ t = high ? syms.objectType : syms.botType;
+ }
+ }
+ return t;
}
}
+
/**
* Create a wildcard with the given upper (extends) bound; create
* an unbounded wildcard if bound is Object.