RFR: JDK-8207320: Wrong type order for intersection lambdas with multiple abstract methods

Vicente Romero vicente.romero at oracle.com
Wed Aug 15 20:50:36 UTC 2018



On 08/15/2018 04:33 PM, Maurizio Cimadamore wrote:
>
> This looks good!
>
> I wonder if we can get to a similar issue with intersection types 
> inferred for a captured var from a lambda. This is possible e.g. if 
> the variable being captured is declared with 'var', I think. Then, I 
> believe we will end up in a very similar case - where the signature of 
> the indy says one thing, and the static type of the dynamic argument 
> being passed to it has an incompatible type.
>
> But maybe that can't happen - as the type of the captured arguments is 
> inferred from the argument expressions themselves. So perhaps there 
> can't be a mismatch (here the problem was that the method handle had a 
> receiver of type R1 and the receiver expression turned out with a 
> different receiver type R2).
>
> I'll keep thinking about this case for a while, to see if something 
> pops up, but in the meantime this fix looks good to go.

:)

>
> P.S.
> If I recall correctly, the coerce method does not generate a cast 
> unless necessary, right?
right only if necessary
>
> Maurizio

going for it, thanks for your comments,
Vicente

>
> On 15/08/18 20:35, Vicente Romero wrote:
>> Hi Maurizio,
>>
>> Thanks for your comments. I have uploaded another iteration [3]. I 
>> also added another regression test. All Tier1 tests passed.
>>
>> Vicente
>>
>> [3] http://cr.openjdk.java.net/~vromero/8207320/webrev.01/jdk.dev.patch
>>
>> On 08/15/2018 11:44 AM, Maurizio Cimadamore wrote:
>>>
>>> Hi,
>>> I agree that there's a bug somewhere in javac's code generation - 
>>> but I believe this fix is too wide, as it touches how erasure of all 
>>> cast expression is performed. I think this issue has only to do with 
>>> the synthetic receiver parameter of a method reference, which seems 
>>> to be captured incorrectly. That is, the lambda translation 
>>> machinery knows well that the receiver ought to be AB (in fact 
>>> that's what ends up in the metafactory protocol), but when the 
>>> receiver argument is captured, no cast is emitted.
>>>
>>> I think this could be just matter of generating the right checkcast 
>>> at the right time.
>>>
>>> More specifically, in LambdaToMethod, I see this (method 
>>> visitReference):
>>>
>>>             case BOUND:             /** Expr :: instMethod */
>>>                 init = tree.getQualifierExpression();
>>>
>>> Now, since this will simply get the (erased) qualifier expression 
>>> and pass it to the indy as its dynamic argument, we have to handle 
>>> cases where there's a disconnect between the erased type of the 
>>> qualifier expression and the expected receiver type 
>>> (tree.sym.owner.type). I think you need a call to transTypes.coerce 
>>> (as done in other places) at that point, to ensure the receiver arg 
>>> conforms with what the MH expects.
>>>
>>> Maurizio
>>>
>>>
>>> On 15/08/18 16:04, Vicente Romero wrote:
>>>> Please review the fix for [1] at [2]. The fix is modifying the way 
>>>> intersection types are erased. Javac erases an intersection type to 
>>>> its first component, but it is not always the right choice. This 
>>>> patch fixes that issue. As an additional information please check 
>>>> Dan's comments in the bug entry,
>>>>
>>>> Thanks,
>>>> Vicente
>>>>
>>>> [1] https://bugs.openjdk.java.net/browse/JDK-8207320
>>>> [2] http://cr.openjdk.java.net/~vromero/8207320/webrev.00/jdk.dev.patch
>>>
>>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20180815/68db6735/attachment.html>


More information about the compiler-dev mailing list