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

Vicente Romero vicente.romero at oracle.com
Mon Jul 30 22:36:28 UTC 2018



On 07/30/2018 01:20 PM, Maurizio Cimadamore wrote:
>
>
> 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.

got it, then I guess we have no option but waiting for the spec issue to 
be fixed

>
> Maurizio

Vicente

>>
>>>
>>> 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