Community
Participate
Working Groups
I ran into this problem using AspectJ 1.8, but it can also be reproduced by calling ECJ directly, so it's not introduced by AspectJ's usage of ECJ. Consider the following class: public class WildcardCapture { public Object convertFails(Class<?> clazz, String value) { return Enum.valueOf(clazz.asSubclass(Enum.class), value); } public Object convertCompiles(Class<?> clazz, String value) { return Enum.valueOf(clazz.<Enum>asSubclass(Enum.class), value); } public Object convertCompiles2(Class<?> clazz, String value) { Class<? extends Enum> enumType = clazz.asSubclass(Enum.class); return Enum.valueOf(enumType, value); } } The first method fails to compile, the other two have no problem (by either specifying a second type the generic type, or extracting the variable). Using the most recent deployment of ECJ in Maven Central, I get: $ java -jar ~/.m2/repository/org/eclipse/jdt/core/compiler/ecj/P20140317-1600/ecj-P20140317-1600.jar -1.8 -deprecation WildcardCapture.java ---------- 1. ERROR in /home/pavageau/devs/aspectj/wildcard-capture/src/main/java/WildcardCapture.java (at line 3) return Enum.valueOf(clazz.asSubclass(Enum.class), value); ^^^^^^^ The method valueOf(Class<T>, String) in the type Enum is not applicable for the arguments (Class<capture#2-of ? extends Enum>, String) ---------- 2. WARNING in /home/pavageau/devs/aspectj/wildcard-capture/src/main/java/WildcardCapture.java (at line 7) return Enum.valueOf(clazz.<Enum>asSubclass(Enum.class), value); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Type safety: Unchecked invocation valueOf(Class<capture#4-of ? extends Enum>, String) of the generic method valueOf(Class<T>, String) of type Enum ---------- 3. WARNING in /home/pavageau/devs/aspectj/wildcard-capture/src/main/java/WildcardCapture.java (at line 7) return Enum.valueOf(clazz.<Enum>asSubclass(Enum.class), value); ^^^^ Enum is a raw type. References to generic type Enum<E> should be parameterized ---------- 4. WARNING in /home/pavageau/devs/aspectj/wildcard-capture/src/main/java/WildcardCapture.java (at line 11) Class<? extends Enum> enumType = clazz.asSubclass(Enum.class); ^^^^ Enum is a raw type. References to generic type Enum<E> should be parameterized ---------- 5. WARNING in /home/pavageau/devs/aspectj/wildcard-capture/src/main/java/WildcardCapture.java (at line 12) return Enum.valueOf(enumType, value); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Type safety: Unchecked invocation valueOf(Class<capture#7-of ? extends Enum>, String) of the generic method valueOf(Class<T>, String) of type Enum ---------- 5 problems (1 error, 4 warnings) Note that this compiles fine using javac from Oracle JDK 6, 7 or 8, and AspectJ 1.6 and 1.7 also compile it (with matching versions of ECJ embeded).
Thanks for taking a look Stephan,
In fact, it's type inference that correctly fails due to this constraint: ⟨java.lang.Enum <: java.lang.Enum<T#0>⟩ Next, if I disable our javac bug-compatibility flag SIMULATE_BUG_JDK_8026527 all three variants are rejected (as per JLS). If instead, I flip the detail of the former, ARGUMENT_CONSTRAINTS_ARE_SOFT, all three variants are accepted. Ergo: we could resolve either way, but each of these bug compatibility flags has already been fine tuned for best similarity with buggy javac. I have no hope that we can improve here, before javac has cleaned up that cluster of known bugs. Note, that at -1.7 all compilers are known to illegally admit constraints like the above. Hence, it comes to no surprise that ecj -1.7, too, accepts the program -- erroneously.
Targetting for 4.5 M3. While ATM ownership is left unchanged, Stephan is under time constraint during this window, so I will likely take this over or assign to someone else to load balance later on.
This is simply a variant of the issue discussed at https://bugs.eclipse.org/bugs/show_bug.cgi?id=430987#c13 Is Class<? extends Enum#RAW> asSubclass(Class<Enum#RAW>) a poly expression ? I think not since it does not mention in its return type any type variables. But to reach past the jlO substitutions, we reach into the generic method and get misled. But the fix at that bug does not cover this case as I am just checking for return type being raw and Class<? extends Enum#RAW> is not raw in itself. I'll see how I can extend that.
(In reply to Srikanth Sankaran from comment #4) > This is simply a variant of the issue discussed at > https://bugs.eclipse.org/bugs/show_bug.cgi?id=430987#c13 > > Is Class<? extends Enum#RAW> asSubclass(Class<Enum#RAW>) a poly expression ? > > I think not since it does not mention in its return type any type variables. > > But to reach past the jlO substitutions, we reach into the generic method and > get misled. Rereading the definition: The method to be invoked, as determined by the following subsections, is generic (§8.4.4) and has a return type that mentions at least one of the method's type parameters looks straightforward enough that we should reach into the generic method (not just because we could find jlO instantiations in the PGMB that would mask type variable mention) by definition. But javac must either be making exceptions when type arguments are seen to be raw types or using some form of unofficial soft constraints.
Bug went away with the fix for bug 444334. Released a junit here: http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=736a3352edee05c04aa96eb4323328cfa8fdbdd5 *** This bug has been marked as a duplicate of bug 444334 ***
Verified for 4.5 M3 using I20141027-2000 build