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

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Aug 15 20:33:12 UTC 2018


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?

Maurizio

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/01b8dd29/attachment.html>


More information about the compiler-dev mailing list