Javac type inference issue

Attila Kelemen attila.kelemen85 at gmail.com
Sun Aug 27 14:06:16 UTC 2023


>
>
> In case of a capture, the inference does not try to replace the capture by
> its bound. It's a limitation of the inference which tend to choose the most
> speciifc type where here, it has to use a less specific type.
>
>
I don't quite understand the step by step "reasoning"  of the type inferer
here, because naively this is what I would do if I was employed as a full
time type inferer :). (I'm copying here my code again with some variable
renaming for easier reference) Suppose I'm a compiler, and I see this:

```
<T1> void arrayMethod(List<? super T1>[] args) {
    listMethod(Arrays.asList(args));
}
<T2> void listMethod(List<List<? super T2>> list) { }
```

1. I look at `arrayMethod` and see 2 type variables to infer. One for
`listMethod` (let's call it #L), and one for `Arrays.asList` (let's call it
#A).
2. The first thing I see is that `Arrays.asList` returns `List<#A>`, and it
is assigned to `List<List<? super #L>>`. This is easy to satisfy with #A =
List<? super #L> (and this is actually the only possibility).
3. Then I go the next part, and see that args is of course `List<? super
T1>[]` which must be assigned to `#A[]`, which is again easy to satisfy
with #A = List<? super T1> (which is the only possibility again).
4. So, now I have to satisfy all equalities `#A = List<? super #L>` and `#A
= List<? super T1>`, which implies that `List<? super #L> = List<? super
T1>`, which is easy to satisfy by the choice #L = T1 (again, this is the
only choice).
5. So, now I have resolved both variables:` #L = T1`, and `#A = List<?
super T1>`, and indeed I can validate that this choice will satisfy every
constraint.

I'm just puzzled here, because sometimes the type inferer can solve much
more difficult problems, and this seems trivial compared to those.



> My bad, I should have written List<? super List<? super T>>.
>
>
Surprisingly (to me), that would compile without explicitly specifying the
type arguments (though of course that is not a type declaration that is
acceptable for me). What surprises me here is that I would think that this
would make the job of the type inferer harder, since now it is more
difficult to find the correct types, since there are more options. Without
the outer "? super" the inferer would be forced to make the correct type
assignment (since there is always only one possibility). That is, when you
write `List<? super List<? super T>`, now you get another fresh type
variable to satisfy. Namely, you have to pick a type of `? super List<?
super T>`. While in the other case your only option for this was `List<?
super T>` (which is the only correct choice even in the `? super` variant.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/compiler-dev/attachments/20230827/4e2ed08b/attachment.htm>


More information about the compiler-dev mailing list