dotnet / dotnet/roslyn

Roslyn fails to infer correct nullability with 'default' values and/or unused parameters

Open
#81,501 3 comments 0 reactions 1 assignee Claimed by @RikkiGibson View on GitHub
Area-Compilers Feature - Nullable Reference Types
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.