JDK 10/11 RFR of JDK-8189146: Have use of "var" in 9 and earlier source versions issue a warning

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Jan 10 00:39:51 UTC 2018


Thanks for the update. This is close, but compared to the existing 
golden file, as you noticed, there are missing warnings, esp. when 'var' 
is used as an array element type.

I believe the issue is with this code:

if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && elemType.hasTag(IDENT)) {
2998             Name typeName = ((JCIdent)elemType).name;
2999             if (isRestrictedLocalVarTypeName(typeName, pos)) {
3000                 if (type.hasTag(TYPEARRAY)) {
3001                     //error - 'var' and arrays
3002                     reportSyntaxError(pos, "var.not.allowed.array");
3003                 } else {
3004                     startPos = TreeInfo.getStartPos(mods);
3005                     if (startPos == Position.NOPOS)
3006                         startPos = TreeInfo.getStartPos(type);
3007                     //implicit type
3008                     type = null;
3009                 }
3010             }
3011         }


Here, if LVTI is disabled, the 'isRestrictedLocalVarTypeName' call would 
not even take place, hence the missing warnings. I suggest to shuffle as 
follows:

if (elemType.hasTag(IDENT)) {
2998             Name typeName = ((JCIdent)elemType).name;
2999             if (isRestrictedLocalVarTypeName(typeName, pos)) {
3000                 if (type.hasTag(TYPEARRAY)) {
3001                     //error - 'var' and arrays
3002                     reportSyntaxError(pos, "var.not.allowed.array");
3003                 } else {
3004                     startPos = TreeInfo.getStartPos(mods);
3005                     if (startPos == Position.NOPOS)
3006                         startPos = TreeInfo.getStartPos(type);
3007                     //implicit type
3008                     type = null;
3009                 }
3010             }
3011         }


This should be more or less equivalent, behavior-wise 
(isRestrictedLocalVarTypeName returns 'false' if lvti is disabled, so 
that makes it equivalent to what was there before), but it will execute 
the test regardless of whether LVTI is disabled or not, which is what 
you want.

There is another 'special' case where the parser reject 'var' and that 
is with the compound case (e.g. 'var x, y = ...'), but I think that's a 
corner^3 case and we can live w/o the warning there. But if you want to 
get there, this is the code to tweak:

boolean implicit = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && head.vartype == null;
2960         vdefs.append(head);
2961         while (token.kind == COMMA) {
2962             if (implicit) {
2963                 reportSyntaxError(pos, "var.not.allowed.compound");
2964             }
2965             // All but last of multiple declarators subsume a comma
2966             storeEnd((JCTree)vdefs.last(), token.endPos);
2967             nextToken();
2968             vdefs.append(variableDeclarator(mods, type, reqInit, dc, localDecl));
2969         }


Again, the name of the game is to make sure that we issue the warning 
regardless of whether lvti is enable or not. This should do:

2960         vdefs.append(head);
2961         while (token.kind == COMMA) {
2962             if (isRestrictedLocalVarTypeName
(type)) {
2963                 reportSyntaxError(pos, "var.not.allowed.compound");
2964             }
2965             // All but last of multiple declarators subsume a comma
2966             storeEnd((JCTree)vdefs.last(), token.endPos);
2967             nextToken();
2968             vdefs.append(variableDeclarator(mods, type, reqInit, dc, localDecl));
2969         }

I'm less sure about this last one, so take it for a spin and see what 
happens.

Maurizio

On 09/01/18 22:29, joe darcy wrote:
> Hi Maurizio,
>
>
> On 1/9/2018 10:49 AM, Maurizio Cimadamore wrote:
>> Hi Joe,
>> I'm a bit unsure about having a retroactive warning in JDK 10 - e.g. 
>> I'm not sure how useful that would be, but I get the spirit of what 
>> you're getting at.
>
> I think this kind of warning allows a smoother cross-release transition.
>
>>
>> In terms of code, I think your warning should go inside the 
>> isRestrictedLocalVarTypeName(Name), which is called in a few places 
>> (not just the one you have touched). For instance, I don't think your 
>> patch will cover this case:
>>
>> List<var> l = null;
>>
>> So, the code for isRestrictedLocalVarTypeName(Name) is currently:
>>
>> return allowLocalVariableTypeInference && name == names.var;
>>
>> I think it should be updated to:
>>
>> if (name == names.var) {
>>             if (allowLocalVariableTypeInference) {
>>                 return true;
>>             } else {
>>                 warning(pos, "var.not.allowed", name);
>>             }
>>         }
>>         return false;
>>
>>
>> Of course you need to enhance the method to take an extra position 
>> argument (pos).
>>
>>
>
> Webrev updated as suggested:
>
>     http://cr.openjdk.java.net/~darcy/8189146.1/
>
> That does emit more warnings than the earlier iteration in ParserTest, 
> 17 rather than 6. As a review aid, the 17 expanded non-raw warnings 
> are listed below. Under release 10, there are 24 errors generated for 
> the file, including different error messages.
>
> Thanks,
>
> -Joe
>
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:14: 
> warning: as of release 10, 'var' is a restricted local variable type 
> and cannot be used for type declarations
> class ParserTest<var> {
>                  ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:16: 
> warning: as of release 10, 'var' is a restricted local variable type 
> and cannot be used for type declarations
>         static class var { } //illegal
>                      ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:20: 
> warning: as of release 10, 'var' is a restricted local variable type 
> and cannot be used for type declarations
>         interface var { } //illegal
>                   ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:24: 
> warning: as of release 10, 'var' is a restricted local variable type 
> and cannot be used for type declarations
>         enum var { } //illegal
>              ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:28: 
> warning: as of release 10, 'var' is a restricted local variable type 
> and cannot be used for type declarations
>         @interface var { } //illegal
>                    ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:36: 
> warning: as of release 10, 'var' is a restricted local variable type 
> and cannot be used for type declarations
>     static class var extends RuntimeException { } //illegal
>                  ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:38: 
> warning: as of release 10, 'var' is a restricted local variable type 
> and cannot be used for type declarations
>     var x = null; //illegal
>     ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:54: 
> warning: as of release 10, 'var' is a restricted local variable type 
> and cannot be used for type declarations
>     var m() { //illegal
>     ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:58: 
> warning: as of release 10, 'var' is a restricted local variable type 
> and cannot be used for type declarations
>     void test2(var x) { //error
>                ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:59: 
> warning: as of release 10, 'var' is a restricted local variable type 
> and cannot be used for type declarations
>         List<var> l1; //error
>              ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:60: 
> warning: as of release 10, 'var' is a restricted local variable type 
> and cannot be used for type declarations
>         List<? extends var> l2; //error
>                        ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:61: 
> warning: as of release 10, 'var' is a restricted local variable type 
> and cannot be used for type declarations
>         List<? super var> l3; //error
>                      ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:63: 
> warning: as of release 10, 'var' is a restricted local variable type 
> and cannot be used for type declarations
>             Function<var, String> f = (var x2) -> ""; //error
>                      ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:63: 
> warning: as of release 10, 'var' is a restricted local variable type 
> and cannot be used for type declarations
>             Function<var, String> f = (var x2) -> ""; //error
>                                        ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:64: 
> warning: as of release 10, 'var' is a restricted local variable type 
> and cannot be used for type declarations
>         } catch (var ex) { } //error
>                  ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:68: 
> warning: as of release 10, 'var' is a restricted local variable type 
> and cannot be used for type declarations
>         boolean b1 = o instanceof var; //error
>                                   ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:69: 
> warning: as of release 10, 'var' is a restricted local variable type 
> and cannot be used for type declarations
>         Object o2 = (var)o; //error
>                      ^
> 17 warnings
>



More information about the compiler-dev mailing list