Home > OS >  Getting warning when forgiving null through Nulllable.Value property on value type
Getting warning when forgiving null through Nulllable.Value property on value type

Time:04-21

I've tried to reproduce a null-forgiving code applied to a value type, but it does not generate any warning: dotnetfiddle.net. In actual code, I'm getting a warning. I'm actually compiling with .NET Core 6.0.

I'm getting multiple compile-time warnings on a code base, some of them related to null-forgiving code. I'm trying to use either SomeNullableValue.Value or SomeNullableValue!, but the compiler complains I'm possibly passing null argument to a function in both ways.

The case I'm dealing with now is an enum that is initially null, but is assigned later in the same control flow; in this case, it is Ast.ContStmtTarget? t, where Ast.ContStmtTarget is an enum:

NextToken();
Ast.ContStmtTarget? t = null;
if (CurrentToken.Type == Token.Keyword) {
    switch (CurrentToken.StringValue) {
        case "do": t = Ast.ContStmtTarget.Do; break;
        case "for": t = Ast.ContStmtTarget.For; break;
        case "loop": t = Ast.ContStmtTarget.Loop; break;
        case "while": t = Ast.ContStmtTarget.While; break;
    }
}
if (!t.HasValue) {
    FatalError(0x80A0400, GetTokenSpan());
}
r = new Ast.ContStmt(t.Value);

The compiler is outputting warning in the last line, r = ...;, with the column pointing to t.Value. Also, the Ast.ContStmt constructor takes a non-nullable value (the enum).

...\Parser.cs(1410,38): warning CS8629: Nullable value type may be null.

I've put compilable project on GitHub (dotnet build):

CodePudding user response:

compiler is warning you that you can reach that line with t == null. Does FatalError return? I assume it throws but the compiler doesnt know that

do

if (!t.HasValue) {
    FatalError(0x80A0400, GetTokenSpan());
} else{
   r = new Ast.ContStmt(t.Value);
}

CodePudding user response:

You can mark FatalError with DoesNotReturnAttribute to help compiler determine that code after if is unreachable in case !t.HasValue otherwise compiler can't verify that code will not actually be called:

[DoesNotReturn]
private void FatalError(int msgId, Span? span, Dictionary<string, object>? vars = null) {
    throw new SyntaxException(Program.Collect(new Problem(msgId, false, vars, span.Value)));
}
  • Related