Javac and local records capturing

Tagir Valeev amaembo at gmail.com
Tue Dec 24 09:45:22 UTC 2019


Hello!

I'm playing with javac 14-ea+28-1366 and local records. Looks like it
doesn't prevent capturing of outer context. E.g.:

class X {
  public static void main(String[] args) {
    int x = 2;
    record Y() {
      void test() {
        System.out.println(x);
      }
    }
    new Y().test();
  }
}

javac happily compiles this program and it prints 2. I think it should
be rejected as it captures a local variable from the outer context.

Also, it looks like capturing compile-time constant should be ok. E.g.
if we add `final ` before `int x = 2`, then it should be accepted.
Unfortunately spec draft is silent about whether it's ok to capture
compile-time constant local variable in the record.

Finally, this code breaks the compiler:

class X {
  public static void main(String[] args) {
    int x = 2;
    record Y() {
      static final int y = x;
    }
    new Y();
  }
}

Javac output is the following:

Note: Test.java uses preview language features.
Note: Recompile with -Xlint:preview for details.
An exception has occurred in the compiler (14-ea). Please file a bug
against the Java compiler via the Java bug reporting page
(http://bugreport.java.com) after checking the Bug Database
(http://bugs
.java.com) for duplicates. Include your program, the following
diagnostic, and the parameters passed to the Java compiler in your
report. Thank you.
java.lang.NullPointerException
        at jdk.compiler/com.sun.tools.javac.jvm.Code.emitop0(Code.java:568)
        at jdk.compiler/com.sun.tools.javac.jvm.Items$SelfItem.load(Items.java:369)
        at jdk.compiler/com.sun.tools.javac.jvm.Gen.visitIdent(Gen.java:2257)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCIdent.accept(JCTree.java:2411)
        at jdk.compiler/com.sun.tools.javac.jvm.Gen.genExpr(Gen.java:864)
        at jdk.compiler/com.sun.tools.javac.jvm.Gen.visitAssign(Gen.java:1998)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCAssign.accept(JCTree.java:1981)
        at jdk.compiler/com.sun.tools.javac.jvm.Gen.genExpr(Gen.java:864)
        at jdk.compiler/com.sun.tools.javac.jvm.Gen.visitExec(Gen.java:1723)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCExpressionStatement.accept(JCTree.java:1524)
        at jdk.compiler/com.sun.tools.javac.jvm.Gen.genDef(Gen.java:597)
        at jdk.compiler/com.sun.tools.javac.jvm.Gen.genStat(Gen.java:632)
        at jdk.compiler/com.sun.tools.javac.jvm.Gen.genStat(Gen.java:618)
        at jdk.compiler/com.sun.tools.javac.jvm.Gen.genStats(Gen.java:669)
        at jdk.compiler/com.sun.tools.javac.jvm.Gen.visitBlock(Gen.java:1084)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:1039)
        at jdk.compiler/com.sun.tools.javac.jvm.Gen.genDef(Gen.java:597)
        at jdk.compiler/com.sun.tools.javac.jvm.Gen.genStat(Gen.java:632)
        at jdk.compiler/com.sun.tools.javac.jvm.Gen.genMethod(Gen.java:954)
        at jdk.compiler/com.sun.tools.javac.jvm.Gen.visitMethodDef(Gen.java:917)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:885)
        at jdk.compiler/com.sun.tools.javac.jvm.Gen.genDef(Gen.java:597)
        at jdk.compiler/com.sun.tools.javac.jvm.Gen.genClass(Gen.java:2395)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.genCode(JavaCompiler.java:756)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1646)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1614)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:972)
        at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:316)
        at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:176)
        at jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:57)
        at jdk.compiler/com.sun.tools.javac.Main.main(Main.java:43)

With best regards,
Tagir Valeev


More information about the amber-dev mailing list