dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
19.02k stars 4.03k forks source link

Roslyn tracks nullability of struct fields in parameters but not fields #47596

Open TessenR opened 4 years ago

TessenR commented 4 years ago

Version Used:

Branch master (9 Sep 2020)
Latest commit 85ca92f by msftbot[bot]:
Merge pull request #47534 from mavasani/BulkConfigure

Account for bulk configuration editorconfig entries for computing eff…

Steps to Reproduce:

Compile the following code

#nullable enable

struct S<T> { internal T GenericField; }

class Program<T> where T: class
{
  S<T?> field;
  void F(S<T?> parameter)
  {
    S<T> x1 = parameter;
    x1.GenericField.ToString();

    S<T> x2 = field;
    x2.GenericField.ToString();
  }
}

Expected Behavior: Either both x1.GenericField and x2.GenericField have a warning or neither of them

Actual Behavior: CS8602: Dereference of a possibly null reference. is reported for x1 but not x2

Notes Roslyn forces slots for fields of structs in parameters in the InheritNullableStateOfTrackableStruct call in the EnterParameter method. Therefore it's able to track the field's state in the assignment from parameter to x1. Since there's no such call for fields Roslyn doesn't have a value slot in the assignment x2 = field and incorrectly assumes the default state in x2.GenericField

jaredpar commented 3 years ago

In both cases here we are properly getting a warning on the conversion from S<T?> to S<T> but the state tracking of the result is indeed different.