Compiler NPE in local-methods branch with recursive lambda

Jake Wharton jakewharton at gmail.com
Tue Nov 26 20:41:32 UTC 2019


Whoops. Sent the version with the predicate-capturing 'if' already removed!
The full reproducer is:

interface Node {
  List<Node> getNodes();

  static boolean any(Node root, Predicate<Node> predicate) {
    boolean hasMatch(Node node) {
      if (predicate.test(node)) return true;
      return node.getNodes().stream().anyMatch(n -> hasMatch(n));
    }
    return hasMatch(root);
  }
}

On Tue, Nov 26, 2019 at 3:39 PM Jake Wharton <jakewharton at gmail.com> wrote:

> With hg revision 4a43a5fc2c4a, given the following pared-down input:
>
> interface Node {
>   List<Node> getNodes();
>
>   static boolean any(Node root, Predicate<Node> predicate) {
>     boolean hasMatch(Node node) {
>       return node.getNodes().stream().anyMatch(n -> hasMatch(n));
>     }
>     return hasMatch(root);
>   }
> }
>
> Compilation causes:
>
> java.lang.NullPointerException
> at jdk.compiler/com.sun.tools.javac.jvm.Code.emitop0(Code.java:570)
> at
> jdk.compiler/com.sun.tools.javac.jvm.Items$LocalItem.load(Items.java:399)
> at jdk.compiler/com.sun.tools.javac.jvm.Gen.genArgs(Gen.java:885)
> at jdk.compiler/com.sun.tools.javac.jvm.Gen.visitApply(Gen.java:1851)
> at
> jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1736)
> at jdk.compiler/com.sun.tools.javac.jvm.Gen.genExpr(Gen.java:860)
> at jdk.compiler/com.sun.tools.javac.jvm.Gen.visitReturn(Gen.java:1814)
> at
> jdk.compiler/com.sun.tools.javac.tree.JCTree$JCReturn.accept(JCTree.java:1648)
> 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:1080)
> at
> jdk.compiler/com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:1029)
> 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:950)
> at jdk.compiler/com.sun.tools.javac.jvm.Gen.visitMethodDef(Gen.java:913)
> at
> jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:875)
> 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:2391)
> at
> jdk.compiler/com.sun.tools.javac.main.JavaCompiler.genCode(JavaCompiler.java:757)
> at
> jdk.compiler/com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1677)
> at
> jdk.compiler/com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1645)
> at
> jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:973)
> at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:318)
> 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)
>
> The problem seems to be a combination of the fact that the local method
> captures 'predicate' and recursively invokes itself from a lambda. Removing
> the 'if' will result in successful compilation. Replacing the stream with a
> for-each will result in successful compilation.
>


More information about the amber-dev mailing list