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

Fix handling of java.lang.Void and enable a couple more Error Prone checks #586

Merged
merged 6 commits into from
Apr 6, 2022

Conversation

msridhar
Copy link
Collaborator

@msridhar msridhar commented Apr 5, 2022

We now require the developer to write @Nullable on usages of java.lang.Void, consistent with JSpecify (see jspecify/jspecify#51).

This issue was discovered while enabling two new Error Prone checks,
TypeToString and SymbolToString.

@coveralls
Copy link

coveralls commented Apr 5, 2022

Pull Request Test Coverage Report for Build #814

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • 39 unchanged lines in 2 files lost coverage.
  • Overall coverage increased (+0.02%) to 92.075%

Files with Coverage Reduction New Missed Lines %
../nullaway/src/main/java/com/uber/nullaway/dataflow/AccessPath.java 1 95.11%
../nullaway/src/main/java/com/uber/nullaway/NullAway.java 38 93.05%
Totals Coverage Status
Change from base Build #812: 0.02%
Covered Lines: 4775
Relevant Lines: 5186

💛 - Coveralls

@@ -72,6 +72,8 @@ subprojects { project ->
check("StringSplitter", CheckSeverity.OFF)
check("WildcardImport", CheckSeverity.ERROR)
check("MissingBraces", CheckSeverity.ERROR)
check("TypeToString", CheckSeverity.ERROR)
check("SymbolToString", CheckSeverity.ERROR)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, these are all suggestion-level, so even with -Werror, we don't get them by default...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup. I found these just browsing through the available checks one day a while back

@@ -178,6 +179,8 @@
// Unmatched, used for when we only want full checker suppressions to work
static final String CORE_CHECK_NAME = "NullAway.<core>";

private static final Supplier<Type> JAVA_LANG_VOID = Suppliers.typeFromString("java.lang.Void");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's also Suppliers.VOID_TYPE, which looking at the implementation may be more efficient. (Uses state.getSymtab().voidType.)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, or is that the non-boxed variant? In that case, nevermind.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is Suppliers#JAVA_LANG_VOID_TYPE which I think does what we want. Thanks for the tip!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed that one 🤦. Nice!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the end I realized we really meant to be checking for the unboxed type! 🙂 And there is an isPrimitiveOrVoid() method for doing that.

@msridhar msridhar marked this pull request as ready for review April 5, 2022 20:43
@msridhar msridhar enabled auto-merge (squash) April 5, 2022 20:51
@msridhar
Copy link
Collaborator Author

msridhar commented Apr 5, 2022

We now report an error for this code in NullAwayNegativeCases:

static Void testVoidType() {
return null;
}

I think this is just wrong and we messed up before. In fact, since the return type is java.lang.Void, this method can only return null (since there are no other values assignable to Void), so the return should be annotated @Nullable. Do you agree @lazaroclapp?

@lazaroclapp
Copy link
Collaborator

I think this is just wrong and we messed up before. In fact, since the return type is java.lang.Void, this method can only return null (since there are no other values assignable to Void), so the return should be annotated @Nullable. Do you agree @lazaroclapp?

Arguably Void == @Nullable Void as @NonNull Void is an empty/error/bottom type... but I wonder how much would need to change in NullAway for there to be a "default-nullable" type/class, vs just saying that if you are returning Void, you must explicitly say @Nullable Void...

@lazaroclapp
Copy link
Collaborator

lazaroclapp commented Apr 5, 2022

@msridhar JSpecify currently says "No special treatment" for Void. So that's good enough for me. @Nullable Void it is. (jspecify/jspecify#51)

Is this technically the first NullAway question, unrelated to direct efforts to support JSpecify, that is settled by referring to the standard? 😉

@msridhar
Copy link
Collaborator Author

msridhar commented Apr 5, 2022

Is this technically the first NullAway question, unrelated to direct efforts to support JSpecify, that is settled by referring to the standard? 😉

First time! So cool to have a standard 😄

@msridhar msridhar changed the title Enable a couple more Error Prone checks Fix handling of java.lang.Void and enable a couple more Error Prone checks Apr 5, 2022
@msridhar msridhar requested a review from lazaroclapp April 5, 2022 22:23
@msridhar
Copy link
Collaborator Author

msridhar commented Apr 5, 2022

Asking for a new review @lazaroclapp since the main purpose of this PR has changed 🙂 We should note this change in the release notes, as after updating to the next release, users will have to add @Nullable to any java.lang.Void return type

@msridhar msridhar disabled auto-merge April 5, 2022 22:25
Copy link
Collaborator

@lazaroclapp lazaroclapp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@msridhar msridhar merged commit c9d89bf into master Apr 6, 2022
@msridhar msridhar deleted the more-ep-checks branch April 6, 2022 01:19
msridhar added a commit that referenced this pull request May 7, 2022
This reverts the user-visible change from #586.  We have found use cases involving generics and method overriding where requiring writing of `@Nullable Void` currently requires adding some ugly error suppressions.  We need to think through those cases more carefully before requiring `@Nullable` on `Void`.

To be clear, this restored handling of `Void` is unsound.  We treat a `Void` return type as `@Nullable Void` when checking `return` statements (so they are allowed to return `null`), but at call sites of methods with a `Void` return type, we assume the method will return a `@NonNull` value.  Also, if an overriding method has return type `Void`, we treat it as `@NonNull Void`, which leads to unsound checking of method subtyping.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants