Argument state after call for AllowNull parameters #4102
-
Related to dotnet/roslyn#48605 In order to reduce nullable warnings down to the most "actionable" subset, we modified analysis such that arguments to parameters with non-nullable types would update the argument's flow state to not-null after the call. This also achieved a goal of increasing uniformity between e.g. string? s = null;
M(s); // warning
s.ToString(); // no warning
void M(string s) { } For by-value parameters this ended up interacting with string? s = null;
M(s); // no warning
s.ToString(); // no warning..?
void M([AllowNull] string s) { } Arguably this is an intended consequence and enables users to write AssertNotNull-type methods which only return if the argument is not-null. However, C# 8 users ended up needing namespace Newtonsoft.Json
{
public abstract class JsonConverter<T>
{
// note: caller might pass a maybe-null argument here and have its state quietly updated to not-null
public abstract void WriteJson(JsonWriter writer, [AllowNull]T value, JsonSerializer serializer);
}
} We also decided that a non-nullable reference type string? s = null;
M(ref s); // no warning
s.ToString(); // no warning
void M([AllowNull] ref string s) { } We may wish to adjust the heuristic for whether to update the argument state to not-null. One way we could do this is by saying that:
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
We recently met and discussed how to alleviate issues we've found with the
DiscussionAllowNull/DisallowNull and MaybeNull/NotNull were initially designed with an emphasis on the respective concepts of "input state" and "output state" of members and parameters. However, we found that in the absence of Instead, we think the better mental model is to say that an input parameter usually only has an input state. By default there is no "output state" being applied to the argument. Instead, we say that if a safety warning is given for the argument (due to failing to convert to the parameter type), the argument's state should be updated to not-null. In this model, This proposal addresses the main pain point that was raised, by not updating argument state to not-null in more scenarios: string? s = null;
M(s);
s.ToString(); // new warning
void M([AllowNull] string s) { } However, behavior around string? s = null;
M(ref s);
s.ToString(); // no warning
void M([AllowNull] ref string s) { } This scenario is also unchanged. string? s = null;
AssertNotNull(s);
s.ToString(); // no warning
void AssertNotNull([NotNull] string? s) { } |
Beta Was this translation helpful? Give feedback.
We recently met and discussed how to alleviate issues we've found with the
[AllowNull] string s
parameter scenario. Our proposal is to modify the rules for nullable argument analysis as follows:Discussion
AllowNull/DisallowNull and MaybeNull/NotNull were initially designed with an emphasis on the respective concepts of "input state" and "output state" of members and parameters. However, we found that in the absence of
T?
, developers used[AllowNull]
a stand-in forT?
on input parameters. For example, theJ…