[PATCH] 8074570: Javac does not get membership right when it comes to erased supertypes
bsrbnd
bsrbnd at gmail.com
Wed Aug 19 17:33:30 UTC 2015
Hi,
As explained in issue 8074570 the following code doesn't compile
because javac looses all type parameters when it comes to an erased
supertype:
interface Sup<X> {
boolean m(X x);
}
interface Sub<X> extends Sup<String> {
boolean m(String s);
}
class Test {
void test() {
Sub s = new Sub() { // new Sub<Void> compiles..
@Override
public boolean m(String o) {return true;}
};
}
}
In this example, when all type parameters are erased, interface "Sup"
defines abstract method "boolean m(Object x)" which is not overriden
in our anonymous class.
If you give a type parameter to "Sub" (for example: new Sub<Void>()
{...}), all compiles fine because type parameters are not erased.
The problem occures in Types.memberType(Type, Symbol) when javac
searches for an implementation of Sup<X>.m(X x).
The call to Types.asOuterSuper(Type, Symbol) erases type parameters.
The following patch replaces undefined type parameters with Object
parameters instead of erasing them in Types.supertype(Type) and
Types.interfaces(Type).
I'm not sure if this is very clean, but it seems that it corrects the problem.
It is also possible that this fix is too global and could be made more
locally to avoid side effects.
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
@@ -2211,6 +2211,23 @@
public List<Type> erasureRecursive(List<Type> ts) {
return erasure.visit(ts, true);
}
+
+ private List<Type> erasureWithObjects(List<Type> ts, List<Type> formals) {
+ Type[] objectParams = new Type[formals.length()];
+ for (int i=0; i<formals.length(); i++) {
+ objectParams[i] = syms.objectType;
+ }
+ List<Type> subt = subst(ts, formals, List.from(objectParams));
+ return subt;
+ }
+ private Type erasureWithObjects(Type t, List<Type> formals) {
+ Type[] objectParams = new Type[formals.length()];
+ for (int i=0; i<formals.length(); i++) {
+ objectParams[i] = syms.objectType;
+ }
+ Type subt = subst(t, formals, List.from(objectParams));
+ return subt;
+ }
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="makeIntersectionType">
@@ -2281,7 +2298,7 @@
List<Type> actuals = classBound(t).allparams();
List<Type> formals = t.tsym.type.allparams();
if (t.hasErasedSupertypes()) {
- t.supertype_field = erasureRecursive(supertype);
+ t.supertype_field =
erasureWithObjects(supertype, formals);
} else if (formals.nonEmpty()) {
t.supertype_field = subst(supertype,
formals, actuals);
}
@@ -2362,7 +2379,7 @@
List<Type> actuals = t.allparams();
List<Type> formals = t.tsym.type.allparams();
if (t.hasErasedSupertypes()) {
- t.interfaces_field = erasureRecursive(interfaces);
+ t.interfaces_field =
erasureWithObjects(interfaces, formals);
} else if (formals.nonEmpty()) {
t.interfaces_field = subst(interfaces,
formals, actuals);
}
Regards,
bsrbnd
More information about the compiler-dev
mailing list