Possible regression involving inferred generic types
Vicente-Arturo Romero-Zaldivar
vicente.romero at oracle.com
Wed Nov 6 02:50:25 PST 2013
On 04/11/13 21:18, Jeremy Manson wrote:
> Thanks, guys. I think there is a lot of value in documenting this
> sort of thing. Since it was the very first incompatibility we
> encountered in our source base when trying to compile with JDK8, I
> would expect that there is rather a lot of it in the wild.
Thanks to you guys for the detailed report,
Vicente.
>
> Jeremy
>
>
> On Mon, Nov 4, 2013 at 10:53 AM, Alex Buckley <alex.buckley at oracle.com
> <mailto:alex.buckley at oracle.com>> wrote:
>
> Hi Vicente,
>
> Thanks for identifying the JBS issue which describes the change.
>
> If javac in JDK7 compiled this illegal code, and javac in JDK8
> rejects this illegal code, then the JBS issue should be documented
> as a source compatibility issue in the JDK8 Release Notes. As
> examples, see the "Tools" items in the JDK7 Release Notes at [1].
> This is exactly the place to identify changes in javac made for
> solid conformance reasons which will nevertheless confuse legions
> of programmers.
>
> So, please take over JDK-7115044, add the label
> "release-note=yes", and add a comment showing ReproOne.java with a
> brief description.
>
> Alex
>
> [1]
> http://www.oracle.com/technetwork/java/javase/compatibility-417013.html#jdk7
>
>
>
> On 11/4/2013 7:10 AM, Vicente-Arturo Romero-Zaldivar wrote:
>
> Hi Liam,
>
> I have been investigating the issue you reported. The fix that
> changed
> javac's behavior is deep in current javac 8 repo, see [1], the
> original
> bug entry can be seen at [2].
>
> From my understanding of the spec and also based on Alex's
> answer at
> [3], I think that the fact that the code compiles in 7 is a
> bug and thus
> 8 can be considered correct. For this reason I don't think
> that there is
> a compatibility issue here.
>
> I have modified the code of ReproOne.java to:
>
> --------------------------------------------------------------------------------
>
> import java.util.List;
>
> class ReproOne {
>
> static class Baz<T> {
> public static List<Baz<Object>> getElements(Baz<Object>
> transcoder) {
> return null;
> }
> }
>
> private static void bar(Baz arg) {
> Baz element = Baz.getElements(arg).get(0);
> }
> }
> -----------------------------------------------------------------------------------
>
>
> Which probably shows more clearly the fact that after erasing
> the return
> value of getElements() to "java.util.List" the type of get(0)
> is Object
> and thus not assignable to a variable of type Baz.
>
> Thanks,
> Vicente.
>
> [1] http://hg.openjdk.java.net/jdk8/tl/langtools/rev/48ee63caaa93
> [2] https://bugs.openjdk.java.net/browse/JDK-7144506
> [3]
> http://mail.openjdk.java.net/pipermail/compiler-dev/2013-October/007726.html
>
>
> On 17/10/13 01:48, cushon wrote:
>
> Forwarded from compiler-dev at Alex Buckley's suggestion.
> Original
> thread:
> http://mail.openjdk.java.net/pipermail/compiler-dev/2013-October/007726.html
>
>
>
> I found some cases where javac 8 behaviour diverges from
> javac 7, and I'm
> interested in knowing whether this is a bug or an
> intentional change.
>
> The following programs do not compile with the jdk8 javac.
> (I tried
> b111 and
> 954dd199d6ff). All of the programs compile with the jdk7
> javac.
>
> -------------------------------------------------------------------------------
>
> import java.util.List;
>
> class ReproOne {
>
> static class Baz<T> {
> public static List<Baz<Object>> getElements(Baz<Object>
> transcoder) {
> return null;
> }
> }
>
> private static void bar(Baz arg) {
> for (Baz element : Baz.getElements(arg)) {}
> }
> }
> -------------------------------------------------------------------------------
>
> abstract class ReproTwo<T> {
>
> class Bar<E> {}
>
> T get(Bar<? extends T> arg1, Bar arg2) {
> return circularGet(arg2, arg2);
> }
>
> abstract T circularGet(final Bar<? extends T> arg1,
> final Bar<?>
> arg2);
> }
> -------------------------------------------------------------------------------
>
> abstract class ReproThree<T, V> {
>
> class Binding<E> {}
> class ProviderBinding<E> extends Binding<E> {}
>
> abstract V visitOther(Binding<? extends T> binding);
>
> public V visitTwo(ProviderBinding<? extends T>
> providerBinding) {
> return visitOther((Binding) providerBinding);
> }
> }
> -------------------------------------------------------------------------------
>
>
> javac output:
>
> ReproOne.java:12: error: incompatible types: Object cannot be
> converted to
> Baz
> for (Baz element : Baz.getElements(arg)) {}
> ^
>
> ReproTwo.java:6: error: incompatible types: Object cannot
> be converted
> to T
> return circularGet(arg2, arg2);
> ^
> where T is a type-variable:
> T extends Object declared in class ReproTwo
>
> ReproThree.java:10: error: incompatible types: Object
> cannot be converted
> to V
> return visitOther((Binding) providerBinding);
> ^
> where V is a type-variable:
> V extends Object declared in class ReproThree
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20131106/f702646a/attachment-0001.html
More information about the compiler-dev
mailing list