RFR: 8315134: javac inference seems to be capturing types incorrectly
Maurizio Cimadamore
mcimadamore at openjdk.org
Tue Aug 29 10:40:10 UTC 2023
On Tue, 29 Aug 2023 03:20:52 GMT, Vicente Romero <vromero at openjdk.org> wrote:
> this code:
>
>
> import java.util.*;
>
> public class Test {
> private static <T> void arrayMethod(List<? super T>[] args) {
> listMethod(Arrays.asList(args));
> }
>
> private static <T> void listMethod(List<List<? super T>> list) {}
> }
>
>
> is being rejected by the compiler. This code should be accepted according to the spec. The compiler is doing a capture conversion that is not mentioned in the spec while reducing subtyping constraints during type inference. This fix is syncing the compiler with the spec.
>
> TIA
Note that this issue was already known:
https://bugs.openjdk.org/browse/JDK-8206142?jql=text%20~%20%22capture%20incorporation%22
IIRC we had some issues with that patch, or were concerned about compatibility impact. This is discussed in this thread:
https://mail.openjdk.org/pipermail/compiler-dev/2018-July/012217.html
Note that there's a related JLS issue that is still not resolved:
https://bugs.openjdk.org/browse/JDK-8016196
Applying capture is too strict (as this bug shows), but not applying capture could result in other problems. Consider a type declaration such as this:
Foo<X> extends Sup<Foo<X>>
Now, let's say you run the following subtyping test:
Foo<?> <: Sup<Foo<?>>
If you don't capture, when you "lift" `Foo` in the LHS to `Sup` what do you do? Do we just replace a wildcard for `X` in `Sup<Foo<X>>` ? If we do, we end up like this:
Sup<Foo<?>> <: Sup<Foo<?>>
-> true
But this is unsound.
-------------
PR Comment: https://git.openjdk.org/jdk/pull/15463#issuecomment-1697187102
More information about the compiler-dev
mailing list