RFR: 8372635: Lambdas do not copy over SYNTHETIC flag for local variables
Chen Liang
liach at openjdk.org
Tue Dec 9 21:52:11 UTC 2025
On Tue, 9 Dec 2025 20:02:18 GMT, Vicente Romero <vromero at openjdk.org> wrote:
>> Consider case like:
>>
>> Object o = ...;
>>
>> //synthetic variable for the instanceof's expression
>> boolean b = o.toString() instanceof String str && str.isEmpty();
>>
>> Runnable r = () -> {
>> //synthetic variable for the instanceof's expression
>> boolean b = o.toString() instanceof String str && str.isEmpty();
>> };
>>
>>
>> There are synthetic variables generated for `o.toString()`, to ensure the method is invoked only once for each `instanceof`. These variables are marked as synthetic in `TransPatterns` (and then consequently omitted in `LocalVariableTable`), but when the flag is lost for the variable in the lambda.
>>
>> This PR proposes to keep the flag, as suggested in the bug.
>
> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java line 1155:
>
>> 1153: break;
>> 1154: case LOCAL_VAR:
>> 1155: ret = new VarSymbol(sym.flags() & (SYNTHETIC | FINAL), sym.name, sym.type, translatedSym);
>
> this will effectively make synthetic all local variables, should we do this starting from source 27?, what about the parameter being generated below? should it be synthetic too?
This only preserves the SYNTHETIC or FINAL flags of the original sym. I don't think it makes all local vars synthetic, but we should check if these two are the only flags we want to propagate. Or should we switch to a blacklist where we explicitly remove the unwanted flags?
Also this flag processing should probably be shared by LOCAL_VAR and PARAM.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/28724#discussion_r2604484669
More information about the compiler-dev
mailing list