7126754: Generics compilation failure casting List<? extends Set...> to List<Set...>
Summary: Problems with Types.rewriteQuantifiers not preserving variance
Reviewed-by: jjg
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Tue Jan 03 17:18:10 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Wed Jan 11 18:23:24 2012 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -3600,39 +3600,44 @@
@Override
public Type visitCapturedType(CapturedType t, Void s) {
- Type bound = visitWildcardType(t.wildcard, null);
- return (bound.contains(t)) ?
- erasure(bound) :
- bound;
+ Type w_bound = t.wildcard.type;
+ Type bound = w_bound.contains(t) ?
+ erasure(w_bound) :
+ visit(w_bound);
+ return rewriteAsWildcardType(visit(bound), t.wildcard.bound, t.wildcard.kind);
}
@Override
public Type visitTypeVar(TypeVar t, Void s) {
if (rewriteTypeVars) {
- Type bound = high ?
- (t.bound.contains(t) ?
+ Type bound = t.bound.contains(t) ?
erasure(t.bound) :
- visit(t.bound)) :
- syms.botType;
- return rewriteAsWildcardType(bound, t);
+ visit(t.bound);
+ return rewriteAsWildcardType(bound, t, EXTENDS);
+ } else {
+ return t;
}
- else
- return t;
}
@Override
public Type visitWildcardType(WildcardType t, Void s) {
- Type bound = high ? t.getExtendsBound() :
- t.getSuperBound();
- if (bound == null)
- bound = high ? syms.objectType : syms.botType;
- return rewriteAsWildcardType(visit(bound), t.bound);
+ Type bound2 = visit(t.type);
+ return t.type == bound2 ? t : rewriteAsWildcardType(bound2, t.bound, t.kind);
}
- private Type rewriteAsWildcardType(Type bound, TypeVar formal) {
- return high ?
- makeExtendsWildcard(B(bound), formal) :
- makeSuperWildcard(B(bound), formal);
+ private Type rewriteAsWildcardType(Type bound, TypeVar formal, BoundKind bk) {
+ switch (bk) {
+ case EXTENDS: return high ?
+ makeExtendsWildcard(B(bound), formal) :
+ makeExtendsWildcard(syms.objectType, formal);
+ case SUPER: return high ?
+ makeSuperWildcard(syms.botType, formal) :
+ makeSuperWildcard(B(bound), formal);
+ case UNBOUND: return makeExtendsWildcard(syms.objectType, formal);
+ default:
+ Assert.error("Invalid bound kind " + bk);
+ return null;
+ }
}
Type B(Type t) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/7126754/T7126754.java Wed Jan 11 18:23:24 2012 +0000
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @author mcimadamore
+ * @bug 7005671
+ * @summary Generics compilation failure casting List<? extends Set...> to List<Set...>
+ * @compile/fail/ref=T7126754.out -Xlint:unchecked -Werror -XDrawDiagnostics T7126754.java
+ */
+
+import java.util.List;
+
+class T7126754 {
+ List<? extends List<? extends String>> c = null;
+ List<List<? extends String>> d = (List<List<? extends String>>)c;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/7126754/T7126754.out Wed Jan 11 18:23:24 2012 +0000
@@ -0,0 +1,4 @@
+T7126754.java:13:68: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), java.util.List<compiler.misc.type.captureof: 1, ? extends java.util.List<? extends java.lang.String>>, java.util.List<java.util.List<? extends java.lang.String>>
+- compiler.err.warnings.and.werror
+1 error
+1 warning