Skip to content

Crash wrt inferring generic return array type #1238

@agrieve

Description

@agrieve

Showed up in Chrome when trying to roll the latest version.

I've failed to create a minimal repro, unfortunately, so hopefully the stack is meaningful.

../../chrome/browser/creator/android/java/src/org/chromium/chrome/browser/creator/CreatorMediator.java:41: error: An unhandled exception was thrown by the Error Prone static analysis plugin.
            WebFeedBridge.followFromId(
                                      ^
     Please report this at https://github.com/google/error-prone/issues/new and include the following:

     error-prone version: 2.41.0
     BugPattern: NullAway
     Stack Trace:
     java.lang.ClassCastException: class com.sun.tools.javac.code.Type$TypeVar cannot be cast to class com.sun.tools.javac.code.Type$ArrayType (com.sun.tools.javac.code.Type$TypeVar and com.sun.tools.javac.code.Type$ArrayType are in module jdk.compiler of loader 'app')
  	at com.uber.nullaway.generics.CheckIdenticalNullabilityVisitor.visitArrayType(CheckIdenticalNullabilityVisitor.java:94)
  	at com.uber.nullaway.generics.CheckIdenticalNullabilityVisitor.visitArrayType(CheckIdenticalNullabilityVisitor.java:16)
  	at jdk.compiler/com.sun.tools.javac.code.Type$ArrayType.accept(Type.java:1375)
  	at com.uber.nullaway.generics.GenericsChecks.identicalTypeParameterNullability(GenericsChecks.java:615)
  	at com.uber.nullaway.generics.GenericsChecks.subtypeParameterNullability(GenericsChecks.java:647)
  	at com.uber.nullaway.generics.GenericsChecks.compareGenericTypeParameterNullabilityForCall(GenericsChecks.java:809)
  	at com.uber.nullaway.NullAway.handleInvocation(NullAway.java:1938)
  	at com.uber.nullaway.NullAway.matchMethodInvocation(NullAway.java:418)
  	at com.google.errorprone.scanner.ErrorProneScanner.processMatchers(ErrorProneScanner.java:509)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitMethodInvocation(ErrorProneScanner.java:824)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitMethodInvocation(ErrorProneScanner.java:170)
  	at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1873)
  	at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:92)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
  	at jdk.compiler/com.sun.source.util.TreeScanner.visitExpressionStatement(TreeScanner.java:504)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitExpressionStatement(ErrorProneScanner.java:711)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitExpressionStatement(ErrorProneScanner.java:170)
  	at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCExpressionStatement.accept(JCTree.java:1652)
  	at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:92)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
  	at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:110)
  	at jdk.compiler/com.sun.source.util.TreeScanner.visitBlock(TreeScanner.java:271)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitBlock(ErrorProneScanner.java:591)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitBlock(ErrorProneScanner.java:170)
  	at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:1145)
  	at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:92)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
  	at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:95)
  	at jdk.compiler/com.sun.source.util.TreeScanner.visitMethod(TreeScanner.java:223)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitMethod(ErrorProneScanner.java:818)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitMethod(ErrorProneScanner.java:170)
  	at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:989)
  	at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:92)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
  	at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:95)
  	at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:110)
  	at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:118)
  	at jdk.compiler/com.sun.source.util.TreeScanner.visitClass(TreeScanner.java:202)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitClass(ErrorProneScanner.java:619)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitClass(ErrorProneScanner.java:170)
  	at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:896)
  	at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:92)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
  	at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:110)
  	at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:118)
  	at jdk.compiler/com.sun.source.util.TreeScanner.visitCompilationUnit(TreeScanner.java:151)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitCompilationUnit(ErrorProneScanner.java:631)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitCompilationUnit(ErrorProneScanner.java:170)
  	at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCCompilationUnit.accept(JCTree.java:625)
  	at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:66)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:58)
  	at com.google.errorprone.scanner.ErrorProneScannerTransformer.apply(ErrorProneScannerTransformer.java:43)
  	at com.google.errorprone.ErrorProneAnalyzer.finished(ErrorProneAnalyzer.java:231)
  	at jdk.compiler/com.sun.tools.javac.api.MultiTaskListener.finished(MultiTaskListener.java:133)
  	at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1432)
  	at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1379)
  	at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:964)
  	at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:319)
  	at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:178)
  	at jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:66)
  	at jdk.compiler/com.sun.tools.javac.Main.main(Main.java:52)
1 error

The code in question is here (although I may soon change it to work around this)

Changing from:

            WebFeedBridge.followFromId(
                    mCreatorModel.get(CreatorProperties.WEB_FEED_ID_KEY),

to:

            byte[] bytes = mCreatorModel.get(CreatorProperties.WEB_FEED_ID_KEY);
            WebFeedBridge.followFromId(
                    bytes,

fixes it.

Here's my failed attempt at a repro in case you can spot what might be off:
Bar.java:

import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.NullUnmarked;
import org.chromium.build.annotations.Nullable;

@NullMarked
public class Bar {
    interface Callback<T> {
      void onResult(T thin);
    }

    static class KeyBase {}
    static class KeyType<T extends @Nullable Object> extends KeyBase {}
    static class KeySubtype<T extends @Nullable Object> extends KeyType<T> {}
    static class KeyTypeB extends KeyBase {}
    static class ReadableTransformingObjectPropertyKey<
                    T extends @Nullable Object, V extends @Nullable Object>
            extends KeyBase {}

    @SuppressWarnings({"unchecked", "NullAway"}) // Can't check container != null when T is @NonNull
    @NullUnmarked // https://github.com/uber/NullAway/issues/1075
    public <T extends @Nullable Object> T get(KeyType<T> key) {
      return null;
    }

    @SuppressWarnings({"unchecked", "NullAway"}) // Can't check container != null when T is @NonNull
    @NullUnmarked // https://github.com/uber/NullAway/issues/1075
    public <T extends @Nullable Object, V extends @Nullable Object> V get(
            ReadableTransformingObjectPropertyKey<T, V> key) {
      return null;
    }

    public boolean get(KeyTypeB key) {
      return false;
    }


    public <T extends @Nullable Object> void set(KeyType<T> key, T value) {
    }

    static void followFromId(byte @Nullable [] webFeedId, boolean b, Callback<String> r) {
    }
}

Foo.java

import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.NullUnmarked;
import org.chromium.build.annotations.Nullable;

@NullMarked
class Foo {
    private static final Bar.KeySubtype<byte[]> KEY = new Bar.KeySubtype<>();
    private static final Bar.KeyType<String> KEY2 = new Bar.KeyType<>();

    Bar b = new Bar();


    private void followClickHandler() {
        if (some()) {
          Bar.followFromId(b.get(KEY), /* isDurable= */ true, (foo) -> {
            b.set(KEY, null);
            b.get(KEY2);
          });
        } else {
          some();
        }
    }
    private static boolean some() {
      return false;
    }
}

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions