question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ReturnMissingNullable should ignore @DoNotCall and always throwing methods

See original GitHub issue

Sometimes we have methods that we need to implement due to an interface requiring them, but we do not want to support them and make them always throw, for example when implementing immutable collections. ReturnMissingNullable wants to add @Nullable in such cases if the interface method is known to be nullable, but this is useless. It would be nice if ReturnMissingNullable would ignore such cases.

Concrete example:

public class Test {

  abstract interface MyNavigableSet<E> extends NavigableSet<E> {

    /**
     * @throws UnsupportedOperationException Always.
     * @deprecated Unsupported operation.
     */
    @Deprecated
    @DoNotCall
    @Override
    /** Always throws. */
    E pollFirst();
  }

  abstract class MySet<E> implements MyNavigableSet<E> {

    @Override
    public E pollFirst() {
      throw new UnsupportedOperationException();
    }

    @Override
    public E pollLast() {
      throw new UnsupportedOperationException();
    }
  }
}

ReturnMissingNullable from Error Prone 2.11.0 warns about all 3 methods:

    [javac] Test.java:16: warning: [ReturnMissingNullable] Method returns a definitely null value but is not annotated @Nullable
    [javac]     E pollFirst();
    [javac]       ^
    [javac]     (see https://errorprone.info/bugpattern/ReturnMissingNullable)
    [javac]   Did you mean '@Nullable @Deprecated'?
    [javac] Test.java:22: warning: [ReturnMissingNullable] Method returns a definitely null value but is not annotated @Nullable
    [javac]     public E pollFirst() {
    [javac]              ^
    [javac]     (see https://errorprone.info/bugpattern/ReturnMissingNullable)
    [javac]   Did you mean '@Nullable @Override'?
    [javac] Test.java:27: warning: [ReturnMissingNullable] Method returns a definitely null value but is not annotated @Nullable
    [javac]     public E pollLast() {
    [javac]              ^
    [javac]     (see https://errorprone.info/bugpattern/ReturnMissingNullable)
    [javac]   Did you mean '@Nullable @Override'?

Concrete suggestions:

  1. ReturnMissingNullable should ignore all methods marked @DoNotCall or if the method implements a @DoNotCall method from an interface.
  2. ReturnMissingNullable should ignore all methods that can be detected to always throw. At least cases where the method body consists of a single throw should be possible, I guess.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
PhilippWendlercommented, Jan 27, 2022

Interesting. I don’t think we have any stubs like this. (And if there were, I would like to find them.)

For the above mentioned smaller project of us, using Conservative=false found two SortedMap.comparator() implementations were return null; was used as the correct implementation but which missed the annotation. Apart from this no other additional findings. So I would tend to use this flag for this project once the current issue is resolved. (I want this project to be fully nullness-annotated, and I think we are close already.)

0reactions
cpovirkcommented, Jan 27, 2022

The type-variable case turns out to be more interesting. Nearly all the findings from it are correct, but there are some patterns that lead to false positives. For example:

static <T> T clone(T t) {
  if (t == null) {
    return null;
  }
  ...
}

Here, the output is null only if the input is. The best way to annotate such a method would be to say that it both accepts and returns “plain T,” not “@Nullable T.” That way, tools can know that, if you pass a non-null input, you’ll get a non-null output.

I want to look more into the type-variable case someday. For now, I’m going to leave it disabled in the conservative mode, and people can turn it on as desired.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Resolve nullable warnings | Microsoft Learn
Several compiler warnings indicate code that isn't null-safe. Learn how to address those warnings by making your code more resilient.
Read more >
Avoiding NullPointerException in Java - Stack Overflow
The method returns the object passed into it and throws a NullPointerException if the object is null. This means that the returned value...
Read more >
@Nullable and @NotNull | IntelliJ IDEA Documentation
Method calls that can return null. Variables (fields, local variables, and parameters), that can be null. Methods with the @Nullable annotation ...
Read more >
Using nullability in GraphQL
A field can either be nullable or non-null, and this tells you whether or not you could receive a null value when you...
Read more >
Understanding null safety - Dart
Code should be safe by default. If you write new Dart code and don't use any explicitly unsafe features, it never throws a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found