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

Treat Void return type as @Nullable Void when checking return statements #595

Merged
merged 2 commits into from
May 7, 2022

Conversation

msridhar
Copy link
Collaborator

@msridhar msridhar commented 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.

@msridhar msridhar requested a review from lazaroclapp May 7, 2022 00:13
@msridhar
Copy link
Collaborator Author

msridhar commented May 7, 2022

@lazaroclapp should we open an issue with the reduced code example you found?

@@ -728,6 +728,12 @@ private Description checkReturnExpression(
// check for unboxing
return returnType.isPrimitive() ? doUnboxingCheck(state, retExpr) : Description.NO_MATCH;
}
if (ASTHelpers.isSameType(returnType, Suppliers.JAVA_LANG_VOID_TYPE.get(state), state)) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is restoring precisely the behavior we had before #586; we only special-cased Void for return types.

@coveralls
Copy link

coveralls commented May 7, 2022

Pull Request Test Coverage Report for Build #844

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • 39 unchanged lines in 1 file lost coverage.
  • Overall coverage increased (+0.003%) to 92.091%

Files with Coverage Reduction New Missed Lines %
../nullaway/src/main/java/com/uber/nullaway/NullAway.java 39 93.07%
Totals Coverage Status
Change from base Build #843: 0.003%
Covered Lines: 4797
Relevant Lines: 5209

💛 - Coveralls

@lazaroclapp
Copy link
Collaborator

@lazaroclapp should we open an issue with the reduced code example you found?

Might need some more careful rephrasing, but: #597

@msridhar msridhar changed the title Treat Void return type as @Nullable Void Treat Void return type as @Nullable Void when checking return statements May 7, 2022
@msridhar msridhar merged commit 4ca7d09 into master May 7, 2022
@msridhar msridhar deleted the Void-nullable branch May 7, 2022 19:53
lazaroclapp added a commit that referenced this pull request Jun 20, 2022
This is a follow up on #595. See that PR for some of the soundness
caveats related to method overriding and the nullability of Void
in our current implementation.

This does, however, avoid some otherwise awkward suppressions,
as shown in #608.

There are two correct ways of hadling Void:

a) Having it default to `@Nullable` as a type, which requires us
   adding a "default nullability" for some types/classes and explictly
   contradicts JSpecify (jspecify/jspecify#51)
b) Supporting generics, and requiring explictly annotating `@Nullable Void`.
   This will probably also require third-party libraries which we consider
   annotated (such as CF), to adopt this convention.

I believe (b) is the way forward long-term, which means that, for now,
this hack might be the best we can do without generics support. Once
NullAway supports generics, both this change and #595 should be reverted.
lazaroclapp added a commit that referenced this pull request Jun 21, 2022
This is a follow up on #595. See that PR for some of the soundness
caveats related to method overriding and the nullability of Void
in our current implementation.

This does, however, avoid some otherwise awkward suppressions,
as shown in #608.

There are two correct ways of hadling Void:

a) Having it default to `@Nullable` as a type, which requires us
   adding a "default nullability" for some types/classes and explictly
   contradicts JSpecify (jspecify/jspecify#51)
b) Supporting generics, and requiring explictly annotating `@Nullable Void`.
   This will probably also require third-party libraries which we consider
   annotated (such as CF), to adopt this convention.

I believe (b) is the way forward long-term, which means that, for now,
this hack might be the best we can do without generics support. Once
NullAway supports generics, both this change and #595 should be reverted.
lazaroclapp added a commit that referenced this pull request Jun 21, 2022
This is a follow up on #595. See that PR for some of the soundness
caveats related to method overriding and the nullability of Void
in our current implementation.

This does, however, avoid some otherwise awkward suppressions,
as shown in #608.

There are two correct ways of handling Void:

a) Having it default to `@Nullable` as a type, which requires us
   adding a "default nullability" for some types/classes and explicitly
   contradicts JSpecify (jspecify/jspecify#51)
b) Supporting generics, and requiring explicitly annotating `@Nullable Void`.
   This will probably also require third-party libraries which we consider
   annotated (such as CF), to adopt this convention.

I believe (b) is the way forward long-term, which means that, for now,
this hack might be the best we can do without generics support. Once
NullAway supports generics, both this change and #595 should be reverted.
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.

3 participants