6559182: Cast from a raw type with non-generic supertype to a raw type fails unexpectedly
Javac doesn't conform to JLS 4.8 - all the supertypes of a raw type must be erased Reviewed-by: jjg
This commit is contained in:
parent
e63129f7b5
commit
38763bd637
@ -640,6 +640,10 @@ public class Type implements PrimitiveType {
|
||||
return typarams_field;
|
||||
}
|
||||
|
||||
public boolean hasErasedSupertypes() {
|
||||
return isRaw();
|
||||
}
|
||||
|
||||
public Type getEnclosingType() {
|
||||
return outer_field;
|
||||
}
|
||||
@ -711,6 +715,17 @@ public class Type implements PrimitiveType {
|
||||
}
|
||||
}
|
||||
|
||||
public static class ErasedClassType extends ClassType {
|
||||
public ErasedClassType(Type outer, TypeSymbol tsym) {
|
||||
super(outer, List.<Type>nil(), tsym);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasErasedSupertypes() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ArrayType extends Type
|
||||
implements javax.lang.model.type.ArrayType {
|
||||
|
||||
|
@ -1499,47 +1499,68 @@ public class Types {
|
||||
* type parameters in t are deleted.
|
||||
*/
|
||||
public Type erasure(Type t) {
|
||||
return erasure(t, false);
|
||||
}
|
||||
//where
|
||||
private Type erasure(Type t, boolean recurse) {
|
||||
if (t.tag <= lastBaseTag)
|
||||
return t; /* fast special case */
|
||||
else
|
||||
return erasure.visit(t);
|
||||
return erasure.visit(t, recurse);
|
||||
}
|
||||
// where
|
||||
private UnaryVisitor<Type> erasure = new UnaryVisitor<Type>() {
|
||||
public Type visitType(Type t, Void ignored) {
|
||||
private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() {
|
||||
public Type visitType(Type t, Boolean recurse) {
|
||||
if (t.tag <= lastBaseTag)
|
||||
return t; /*fast special case*/
|
||||
else
|
||||
return t.map(erasureFun);
|
||||
return t.map(recurse ? erasureRecFun : erasureFun);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type visitWildcardType(WildcardType t, Void ignored) {
|
||||
return erasure(upperBound(t));
|
||||
public Type visitWildcardType(WildcardType t, Boolean recurse) {
|
||||
return erasure(upperBound(t), recurse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type visitClassType(ClassType t, Void ignored) {
|
||||
return t.tsym.erasure(Types.this);
|
||||
public Type visitClassType(ClassType t, Boolean recurse) {
|
||||
Type erased = t.tsym.erasure(Types.this);
|
||||
if (recurse) {
|
||||
erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym);
|
||||
}
|
||||
return erased;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type visitTypeVar(TypeVar t, Void ignored) {
|
||||
return erasure(t.bound);
|
||||
public Type visitTypeVar(TypeVar t, Boolean recurse) {
|
||||
return erasure(t.bound, recurse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type visitErrorType(ErrorType t, Void ignored) {
|
||||
public Type visitErrorType(ErrorType t, Boolean recurse) {
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
private Mapping erasureFun = new Mapping ("erasure") {
|
||||
public Type apply(Type t) { return erasure(t); }
|
||||
};
|
||||
|
||||
private Mapping erasureRecFun = new Mapping ("erasureRecursive") {
|
||||
public Type apply(Type t) { return erasureRecursive(t); }
|
||||
};
|
||||
|
||||
public List<Type> erasure(List<Type> ts) {
|
||||
return Type.map(ts, erasureFun);
|
||||
}
|
||||
|
||||
public Type erasureRecursive(Type t) {
|
||||
return erasure(t, true);
|
||||
}
|
||||
|
||||
public List<Type> erasureRecursive(List<Type> ts) {
|
||||
return Type.map(ts, erasureRecFun);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="makeCompoundType">
|
||||
@ -1626,15 +1647,14 @@ public class Types {
|
||||
if (t.supertype_field == null) {
|
||||
List<Type> actuals = classBound(t).allparams();
|
||||
List<Type> formals = t.tsym.type.allparams();
|
||||
if (actuals.isEmpty()) {
|
||||
if (formals.isEmpty())
|
||||
// Should not happen. See comments below in interfaces
|
||||
t.supertype_field = supertype;
|
||||
else
|
||||
t.supertype_field = erasure(supertype);
|
||||
} else {
|
||||
if (t.hasErasedSupertypes()) {
|
||||
t.supertype_field = erasureRecursive(supertype);
|
||||
} else if (formals.nonEmpty()) {
|
||||
t.supertype_field = subst(supertype, formals, actuals);
|
||||
}
|
||||
else {
|
||||
t.supertype_field = supertype;
|
||||
}
|
||||
}
|
||||
}
|
||||
return t.supertype_field;
|
||||
@ -1708,18 +1728,15 @@ public class Types {
|
||||
assert t != t.tsym.type : t.toString();
|
||||
List<Type> actuals = t.allparams();
|
||||
List<Type> formals = t.tsym.type.allparams();
|
||||
if (actuals.isEmpty()) {
|
||||
if (formals.isEmpty()) {
|
||||
// In this case t is not generic (nor raw).
|
||||
// So this should not happen.
|
||||
t.interfaces_field = interfaces;
|
||||
} else {
|
||||
t.interfaces_field = erasure(interfaces);
|
||||
}
|
||||
} else {
|
||||
if (t.hasErasedSupertypes()) {
|
||||
t.interfaces_field = erasureRecursive(interfaces);
|
||||
} else if (formals.nonEmpty()) {
|
||||
t.interfaces_field =
|
||||
upperBounds(subst(interfaces, formals, actuals));
|
||||
}
|
||||
else {
|
||||
t.interfaces_field = interfaces;
|
||||
}
|
||||
}
|
||||
}
|
||||
return t.interfaces_field;
|
||||
|
45
langtools/test/tools/javac/generics/Casting5.java
Normal file
45
langtools/test/tools/javac/generics/Casting5.java
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2004 Sun Microsystems, Inc. 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6559182
|
||||
* @summary Cast from a raw type with non-generic supertype to a raw type fails unexpectedly
|
||||
* @author Maurizio Cimadamore
|
||||
*
|
||||
* @compile Casting5.java
|
||||
*/
|
||||
|
||||
class Casting5 {
|
||||
static interface Super<P> {}
|
||||
static class Y implements Super<Integer>{}
|
||||
static interface X extends Super<Double>{}
|
||||
static class S<L> extends Y {}
|
||||
static interface T<L> extends X {}
|
||||
|
||||
public static void main(String... args) {
|
||||
S s = null; // same if I use S<Byte>
|
||||
T t = null; // same if I use T<Byte>
|
||||
t = (T) s;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user