RFR: 8269121: Type inference bug with method references

Vicente Romero vromero at openjdk.java.net
Wed Sep 8 15:38:10 UTC 2021

On Wed, 8 Sep 2021 09:38:50 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:

>> Please review this PR which is making a change to how javac generates the arguments for the lambda metafactory. There are cases like the one described in the JIRA bug entry for which the generated arguments won't be valid and the generated code will fail at execution. The problem arises when the erasure of the lambda method is incompatible with the erasure of the function descriptor. This can happen when at least one of the arguments of the lambda method has an intersection type, in case that the erasure of the intersection type is not compatible with the corresponding argument of the function descriptor. This fix's proposal is to analyze all the components of the intersection and select the first that is compatible with its corresponding argument in the function descriptor.
>> TIA
> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java line 1091:
>> 1089:     }
>> 1090: 
>> 1091:     private MethodType typeToMethodType(Type mt, MethodType interfaceMethodType) {
> It is nice that we can put all the complexity in this method. I wonder if we could somehow make this more general - e.g. instead of detecting whether there is an intersection type - simply compare the erased signature of the function descriptor with the erased signature of the lambda method, and see if the two are compatible. I believe that, maybe, a resolution check might work (e.g. try to pass the erased parameter to the erased function descriptor and see if we get a resolution error or not). In `Lower` we do something similar - see `Lower::lookupMethod`.
> Another option could be to always use the erased function descriptor type, and then add the required casts inside the lambda method implementation body (in most cases there would be no casts) - e.g. do not rely on the conversions handled by the lambda metafactory, but generate code that is more 1-1 with what the metafactory expects (and fix it up on the javac side). But doing this might change signature for some of the lambda bodies - which, if we take into account serializable lambdas, could be problematic.

I think I prefer the second option, but I'm wondering if there are really cases when we need to insert any cast. It seem that at least at the place where we are making the changes all the needed casts in the lambda body has already being inserted. What do you think?


PR: https://git.openjdk.java.net/jdk/pull/5406

More information about the compiler-dev mailing list