RFR JDK-8206142: type inference: javac is incorrectly applying capture conversion during incorporation

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Mon Jul 30 20:20:18 UTC 2018



On 30/07/18 19:00, Vicente Romero wrote:
>
>
> On 07/30/2018 07:25 AM, Maurizio Cimadamore wrote:
>> Hi Vicente,
>> while I agree that the program in JDK-8206142 exposes an issues with 
>> a spurious capture being performed by javac, and, while I agree that, 
>> in that case, we can do without the capyure (both the source and the 
>> target of the test are some B<...>), in the more general case where 
>> source and target are at different heights, you need to recurse to 
>> supertype and, hence, you need capture.
>>
>> So, I'm afraid that with this we will potentially introduce 
>> compatibility issues, w/o fully resolving the underlying issue, which 
>> is described by this spec issue which Dan filed while ago:
>>
>> https://bugs.openjdk.java.net/browse/JDK-8016196
>>
>> Maybe we should wait on this one?
>
> not sure here, it could be a good idea to wait but usually these spec 
> issues take some time to be sorted out, so we could pause now and push 
> this fix later if more users complain about this issue.
Right. But the point I was trying to make is that, if you never capture 
(as in this patch), when you have a subtyping test like this:

A<? super T> <: B<M>

where

A<X> <: B<C<? extends X>>

you end up with the following, non-sensical subtyping assertion:

B<C<? extends ? super T> <: B<M>

So, javac always applies capture conversion (even at risk of 
incompatibilities like the one in this issue) in order to remain on a 
safe path, from a type-wellformedness perspective.

Maurizio
>
>>
>> Maurizio
>
> Vicente
>
>>
>>
>>
>> On 23/07/18 14:22, Vicente Romero wrote:
>>>
>>>
>>> On 07/21/2018 09:49 AM, B. Blaser wrote:
>>>> Hi Vicente,
>>>>
>>>> On 20 July 2018 at 22:27, Vicente Romero 
>>>> <vicente.romero at oracle.com> wrote:
>>>>> Hi all,
>>>>>
>>>>> Please review the patch to fix [1] at [2]. The fix is putting 
>>>>> javac in sync
>>>>> with the spec by not applying capture conversion during 
>>>>> incorporation.
>>>>>
>>>>> Thanks,
>>>>> Vicente
>>>>>
>>>>> [1] https://bugs.openjdk.java.net/browse/JDK-8206142
>>>>> [2] 
>>>>> http://cr.openjdk.java.net/~vromero/8206142/webrev.00/jdk.dev.patch
>>>> It's hard to measure the potential side-effects of this fix,
>>>
>>> yes, I'm also worried about the possible side effects. I agree that 
>>> more discussion will be needed,
>>>
>>>>   but it
>>>> seems good to me even if you'll probably need another review.
>>>> Maybe, I'd rewrite it as next to avoid creating a new method?
>>>>
>>>> Thanks,
>>>> Bernard
>>>
>>> Thanks,
>>> Vicente
>>>
>>>>
>>>>
>>>> diff -r b0fcf59be391
>>>> src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
>>>> --- 
>>>> a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
>>>>         Fri Jul 20 14:48:41 2018 -0700
>>>> +++ 
>>>> b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
>>>>         Sat Jul 21 14:33:05 2018 +0200
>>>> @@ -1003,24 +1003,24 @@
>>>>        * Is t an unchecked subtype of s?
>>>>        */
>>>>       public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) {
>>>> -        boolean result = isSubtypeUncheckedInternal(t, s, true, 
>>>> warn);
>>>> +        boolean result = isSubtypeUnchecked(t, s, true, warn);
>>>>           if (result) {
>>>>               checkUnsafeVarargsConversion(t, s, warn);
>>>>           }
>>>>           return result;
>>>>       }
>>>>       //where
>>>> -        private boolean isSubtypeUncheckedInternal(Type t, Type s,
>>>> boolean capture, Warner warn) {
>>>> +        public boolean isSubtypeUnchecked(Type t, Type s, boolean
>>>> capture, Warner warn) {
>>>>               if (t.hasTag(ARRAY) && s.hasTag(ARRAY)) {
>>>>                   if (((ArrayType)t).elemtype.isPrimitive()) {
>>>>                       return isSameType(elemtype(t), elemtype(s));
>>>>                   } else {
>>>> -                    return isSubtypeUncheckedInternal(elemtype(t),
>>>> elemtype(s), false, warn);
>>>> +                    return isSubtypeUnchecked(elemtype(t),
>>>> elemtype(s), false, warn);
>>>>                   }
>>>>               } else if (isSubtype(t, s, capture)) {
>>>>                   return true;
>>>>               } else if (t.hasTag(TYPEVAR)) {
>>>> -                return isSubtypeUncheckedInternal(t.getUpperBound(),
>>>> s, false, warn);
>>>> +                return isSubtypeUnchecked(t.getUpperBound(), s, 
>>>> false, warn);
>>>>               } else if (!s.isRaw()) {
>>>>                   Type t2 = asSuper(t, s.tsym);
>>>>                   if (t2 != null && t2.isRaw()) {
>>>> diff -r b0fcf59be391
>>>> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
>>>> --- 
>>>> a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
>>>>         Fri Jul 20 14:48:41 2018 -0700
>>>> +++ 
>>>> b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
>>>>         Sat Jul 21 14:33:05 2018 +0200
>>>> @@ -1180,7 +1180,7 @@
>>>>           IS_SUBTYPE() {
>>>>               @Override
>>>>               boolean apply(Type op1, Type op2, Warner warn, Types 
>>>> types) {
>>>> -                return types.isSubtypeUnchecked(op1, op2, warn);
>>>> +                return types.isSubtypeUnchecked(op1, op2, false, 
>>>> warn);
>>>>               }
>>>>           },
>>>>           IS_SAME_TYPE() {
>>>
>>
>



More information about the compiler-dev mailing list