@MonotonicNonNull should allow null-assignment within constructors
Example:
@NullMarked
class Foo {
@MonotonicNonNull Object mBar;
@Nullable Object maybeNull() {
return null;
}
Foo() {
mBar = maybeNull();
}
}
Yields:
Foo.java:13: warning: [NullAway] assigning @Nullable expression to @NonNull field
mBar = maybeNull();
^
IIUC, @MonotonicNonNull means a field should never go from non-null -> null. If the field is not already considered non-null in the constructor, and a nullable assignment is made to it, then I don't think there should be a warning, as this is really no different from the field just remaining null.
You are correct, we should allow such assignments to @MonotonicNonNull fields in the constructor.
Getting back to this issue, and at this point I think it's not worth fixing. The tricky issue is that to allow a write of @Nullable to a @MonotonicNonNull field, we must prove that before the write, the field is definitely null (otherwise we are allowing a violation of the basic monotonicity rule). Even in a constructor, checking this can be tricky, as it requires reasoning about previous writes from initializer expressions, instance initializer blocks, and previous calls from within the constructor. E.g., consider:
@NullMarked
class Foo {
@MonotonicNonNull Object mBar;
@Nullable Object maybeNull() {
[...]
}
Foo() {
// should be allowed
mBar = maybeNull();
// should be disallowed! the previous write _may_ have put a non-null value into the field
mBar = maybeNull();
}
}
We don't have any good tracking of when fields are definitely null. And given that this issue leads to false positives, rather than false negatives, I think we're better off asking users to suppress.
Thanks for reporting @agrieve. I'm open to re-visiting if I missed something.