Roslyn fails to infer correct nullability with 'default' values and/or unused parameters
- Dominant language
- C#
- Stars
- 20.7k
- Forks
- 4.3k
- PR merge metrics
- PR metrics pending
Description
**Version Used**:
Visual Studio 2026
Version: Insiders [11222.16]
**Steps to Reproduce**:
Compile and run the following code:
```csharp
#nullable enable
using System;
using System.Collections.Generic;
InferenceTest.Test();
public class InferenceTest
{
private static void Foo(T obj, List list, Action? action = null)
{
list.Add(obj);
}
public static void Test()
{
List list = new List();
Foo(obj: default, list: list); // no warnings here
foreach (var s in list)
{
Console.WriteLine(s.Length); // crash here
}
}
}
```
**Diagnostic Id**:
[CS8620](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/nullable-warnings?f1url=%3FappId%3Droslyn%26k%3Dk(CS8620)#mismatch-in-nullability-declaration) - Argument cannot be used for parameter due to differences in the nullability of reference types.
**Expected Behavior**:
There's a warning about nullability mismatch somewhere in the `Foo(obj: default, list: list)` call
Either `default` value is not acceptable if the type argument is non-nullable, or the `list` parameter doesn't match the target nullability if the type argument is nullable
**Actual Behavior**:
No warnings at all in the code above. It crashes at runtime with a `NullReferenceException` as it puts nullable elements in a collection of non-nullable strings.
**Notes**:
The compiler correctly reports
```
Argument of type 'List' cannot be used for parameter 'list' of type 'List' in 'void InferenceTest.Foo(string? obj, List list, Action? action = null)' due to differences in the nullability of reference types.
```
in all of the following cases:
- the call is changed to use `null` instead of `default`
- the redundant parameter `action` is removed from `Foo`
- an actual argument is provided for the `action` parameter:
```csharp
#nullable enable
using System;
using System.Collections.Generic;
public class InferenceTest
{
private static void Foo1(T obj, List list, Action? action = null) { list.Add(obj); }
private static void Foo2(T obj, List list) { list.Add(obj); }
public static void Test()
{
List list = new List();
Foo1(default, list); // missing warning
Foo1(null, list); // correct CS8620 warning
Foo1(default, list, _ => { }); // correct CS8620 warning
Foo2(default, list); // correct CS8620 warning
}
}
```
Contributor guide
Assessment
This issue has not been assessed yet.