Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

False alarm when using "return null" and type is known to support nulls #3614

Closed
vlsi opened this issue Aug 31, 2020 · 3 comments · Fixed by #3823
Closed

False alarm when using "return null" and type is known to support nulls #3614

vlsi opened this issue Aug 31, 2020 · 3 comments · Fixed by #3823

Comments

@vlsi
Copy link
Contributor

vlsi commented Aug 31, 2020

Sample code:

  public static @PolyNull Boolean not(@PolyNull Boolean b) {
    return (b == null) ? null : !b;
  }

Error:

SqlFunctions.java:2571: error: [return.type.incompatible] incompatible types in return.
    return (b == null) ? null : !b;
                       ^
  type of expression: @Initialized @Nullable Boolean
  method return type: @Initialized @PolyNull Boolean

Could checker be a bit smarter, so it could see that {{b == null}} implies {{@polynull}} is in {{@nullable}} mode, so it should be perfectly valid to return {{null}}.

I understand I can rewrite the method like {{return (b == null) ? b : !b;}}, however, it would be nice if checker could figure out that automatically.

Another example might involve regular generics without Poly annotations:

  public <T> static T of(T a) {
    return a == null ? null : a;
  }

It would be nice if checker could figure out return null is reachable only in the case T is nullable.

Another example:

  /** Converts a JDBC array to a list. */
  public static @PolyNull List arrayToList(final java.sql.@PolyNull Array a) {
    if (a == null) {
      return null; // <- error here
    }
    ...
@vlsi
Copy link
Contributor Author

vlsi commented Sep 1, 2020

One more sample which does not have a nice workaround except castNonNull

  public static @PolyNull Integer plus(@PolyNull Integer b0, @PolyNull Integer b1) {
    return (b0 == null || b1 == null) ? null : (b0 + b1);
  }

@mernst
Copy link
Member

mernst commented Sep 6, 2020

The not and plus examples may be related to #3622, because rewriting them as if statements causes the Nullness Checker to accept them.

@mernst
Copy link
Member

mernst commented Sep 10, 2020

Followup: the fix for #3622 does not resolve this issue.
There are test cases checked into the repository in file Issue3614.java.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants