Does JLS tell if this program is legal?
Dan Smith
daniel.smith at oracle.com
Thu May 23 14:52:21 UTC 2024
> On May 23, 2024, at 3:19 AM, Stephan Herrmann <stephan.herrmann at berlin.de> wrote:
>
> Thanks, Dan,
>
> Am 22.05.24 um 02:13 schrieb Dan Smith:
>>> On May 21, 2024, at 12:49 PM, Stephan Herrmann <stephan.herrmann at berlin.de> wrote:
>>>
>>> * Super<Inner<?>> is a supertype of T / One<?> (directly)
>> Note that "is a supertype" here isn't true though:
>> Is One<?> <: Super<Inner<?>>
>> Is One<CAP> <: Super<Inner<?>>
>> Is Super<Inner<CAP>> <: Super<Inner<?>>
>> Is Inner<CAP> = Inner<?>
>> false
>
> Wow, another corner I hadn't yet looked at. :) I had assumed that capture applies only when something is being accessed / evaluated. Going from a type to its supertype didn't look like evaluation to me.
>
> But now looking at §4.10.2 I see it speaking of capture indeed.
>
> So that would change my analysis
> from Super<Inner<?>> is a supertype of T / One<?>
> to Super<Inner<CAP>> is a supertype of T / One<?>
>
> and we continue:
> * S1 = Inner<X>
> * T1 = Inner<CAP>
> * new constraint formula created: ⟨Inner<X> = Inner<CAP>⟩
>
> This, too, reduces to false, and again I would be without an explanation how 'accept' could be correct.
No, I'm not saying you should use capture to find a supertype.
I'm saying your proposed supertype, Super<Inner<?>>, is demonstrably not a supertype of One<?>, by following the normal subtyping rules. And, it turns out, neither is Super<Inner<CAP>>.
(So what *is* the supertype? Well, yeah, that's the spec bug. It's not defined.)
>
>> This is related to
>> https://bugs.openjdk.org/browse/JDK-8016196
>> Unfortunately, JLS doesn't specify a way to map from subtypes to supertypes when wildcards are involved. (It's one of those unexplained corners of the type system.)
>
> Isn't that given by that sentence I discovered just now?
> "Given a generic class or interface C with type parameters F1,...,Fn (n > 0), the direct supertypes of the parameterized type C<R1,...,Rn> where at least one of the Ri (1 ≤ i ≤ n) is a wildcard type argument, are the direct supertypes of the parameterized type C<X1,...,Xn> which is the result of applying capture conversion to C<R1,...,Rn> (§5.1.10)."
That is a thing the spec says, but... it's not true. Clearly, following normal subtyping rules, One<?> is not a subtype Super<Inner<X>> for any type variable X.
>> I've got a solution in my mind that involves the upward projection operation we introduced in 4.10.5: capture, find the supertype, then project away the capture variable. But there are details to work out.
>
> If I apply this strategy in ecj I get these pairs of supertypes of One<?> , Y
> * One<?>, One<X>
> * Super<? extends Inner<?>>, Super<Inner<X>>
>
> In both pairs we find a wildcard as a direct type argument and hence NO new constraint would be generated in §18.3.1.
>
> Is that what you have in mind?
Right. It is true, per the subtyping rules, that
One<?> <: Super<? extends Inner<?>>
> Does javac already implement this application of projection?
No, I don't believe so. The bug remains, it's something that needs to be addressed sometime.
More information about the compiler-dev
mailing list