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