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

Generic-typed fields include erroneous non-null check #1320

Closed
kennknowles opened this issue May 15, 2022 · 7 comments
Closed

Generic-typed fields include erroneous non-null check #1320

kennknowles opened this issue May 15, 2022 · 7 comments
Assignees
Labels
Component: value P3 type=enhancement Make an existing feature better

Comments

@kennknowles
Copy link

Discovered during apache/beam#16721 here is a summary example:

@AutoValue
public abstract class ValueInSingleWindow<T> {
  T getValue();
  ... other fields ...
}

It is valid to create ValueInSingleWindow<@Nullable String> in the usual way via ValueInSingleWindow.<@Nullable String>of(null, ...).

However, autovalue creates a check that the value is non-null, rejecting type-safe code.

@eamonnmcmanus
Copy link
Member

eamonnmcmanus commented May 15, 2022

Do you have a suggestion for what you think should happen? The generated code can't know whether T is @Nullable.

Perhaps we could say that if there is a @Nullable bound (class ValueInSingleWindow<T extends @Nullable Object>) then we treat T as @Nullable, under the assumption that static checking will eliminate incorrect null values. That use of bounds would be consistent with Checker Framework and JSpecify. In those systems, ValueInSingleWindow<@Nullable String> is not allowed if the declaration is class ValueInSingleWindow<T> without the @Nullable bound.

@kennknowles
Copy link
Author

T is a type parameter that can be instantiated either to either nullable or non-nullable types. Autovalue isn't capable of knowing, indeed, so must treat all values as a black box.

@kennknowles
Copy link
Author

You clearly have a good analysis, however the default is not what you think. From that page:

The Nullness type system is an example.

class MyClass<T> == class MyClass<T extends @Nullable Object>
class MyClass<T extends Object> == class MyClass<T extends @NonNull Object>

The rationale for this choice is:

The “<T>” in MyClass<T> means “fully unconstrained”, and the rules maintain that, without the need for a programmer to change existing code.
The “Object” in MyClass<T extends Object> is treated exactly like every other occurrence of Object in the program — it would be confusing for different occurrences of Object to mean different annotated types.

So a bare type variable <T> can be instantiated to any type at all, including nullable types.

@eamonnmcmanus
Copy link
Member

Oh dear. That's an inconsistency between Checker Framework and JSpecify, then. Regardless, <T extends @Nullable Object> does mean that T can be a @Nullable type in both systems. So people could at least write that if they ran into this issue.

@kennknowles
Copy link
Author

Yea, that's a helpful workaround. Glad we had this exchange!

@eamonnmcmanus
Copy link
Member

To be clear, they can't currently employ that workaround, because AutoValue doesn't currently have logic to treat T foo() as @Nullable if <T extends @Nullable Object>. I do think we should add that logic, and I plan to do so fairly soon. (Unfortunately the compiler treatment of type annotations isn't always very reliable, but I think this case will probably work.)

@rkraneis
Copy link

rkraneis commented Mar 8, 2023

Hi @eamonnmcmanus, any news on the planned implementation?

copybara-service bot pushed a commit that referenced this issue Mar 8, 2023
…a type variable with a `@Nullable` bound, like `<T extends @nullable Object>`.

Fixes #1320.

RELNOTES=An AutoValue or AutoBuilder property is now allowed to be null if its type is a type variable with a `@Nullable` bound, like `<T extends @nullable Object>`.
PiperOrigin-RevId: 515104184
copybara-service bot pushed a commit that referenced this issue Mar 9, 2023
…ullable` bound.

For example `<T extends @nullable Object>`.

Fixes #1320.

RELNOTES=An AutoValue or AutoBuilder property is now allowed to be null if its type is a type variable with a `@Nullable` bound, like `<T extends @nullable Object>`.
PiperOrigin-RevId: 515104184
copybara-service bot pushed a commit that referenced this issue Mar 9, 2023
…ullable` bound.

For example `<T extends @nullable Object>`.

Fixes #1320.

RELNOTES=An AutoValue or AutoBuilder property is now allowed to be null if its type is a type variable with a `@Nullable` bound, like `<T extends @nullable Object>`.
PiperOrigin-RevId: 515104184
copybara-service bot pushed a commit that referenced this issue Mar 9, 2023
…ullable` bound.

For example `<T extends @nullable Object>`.

Fixes #1320.

RELNOTES=An AutoValue or AutoBuilder property is now allowed to be null if its type is a type variable with a `@Nullable` bound, like `<T extends @nullable Object>`.
PiperOrigin-RevId: 515104184
copybara-service bot pushed a commit that referenced this issue Mar 13, 2023
…ullable` bound.

For example `<T extends @nullable Object>`.

Fixes #1320.

RELNOTES=An AutoValue or AutoBuilder property is now allowed to be null if its type is a type variable with a `@Nullable` bound, like `<T extends @nullable Object>`.
PiperOrigin-RevId: 515104184
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: value P3 type=enhancement Make an existing feature better
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants