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