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.12k stars 4.04k forks source link

Seemingly spurious CS8620 when doing type inference after recent VS update #50311

Open madelson opened 3 years ago

madelson commented 3 years ago

Version Used:

Visual Studio 16.8.3 compiling against netstandard2.0 with LangVersion 8.0 on Windows 10.

Steps to Reproduce:

private class Foo<T> { }

private static void Bar<T>(Action<Foo<T>>? action = null) => Baz(action: action); // error here

private static void Baz<T>(Action<Foo<T>>? action = null, T x = default!) { }

Error:

CS8620  Argument of type 'Action<Foo<T>>' cannot be used for parameter 'action' of type 'Action<Foo<T?>>' in 'void Baz<T?>(Action<Foo<T?>>? action = null, T? x = default(T?))' due to differences in the nullability of reference types.

Expected Behavior:

This used to compile without error, so I would expect it to continue to.

Actual Behavior:

Fails with the error above.

RikkiGibson commented 3 years ago

Still present in 16.9. Somehow, the type argument to Baz is inferred to be T?. SharpLab

RikkiGibson commented 3 years ago

A few things are probably interacting to produce this behavior:

  1. When the parameter default value is translated into a ConstantValue on the parameter symbol, the nullability suppression on the default value is lost.
  2. A default argument is bound at the call site based on the parameter default ConstantValue. This default is then included in the nullable type argument reinference process.

Perhaps we can fix this bug by making it so implicit default arguments don't "participate" in nullable type argument reinference.