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