The .NET SDK supports installation into older versions of Visual Studio. For example 17.0 installs the 6.0.100 SDK by default but loading 6.0.200, 6.0.300 is supported. While this is supported it means that there is a bit of a mismatch in which compiler is used:
- When building from Visual Studio or
msbuild the C# compiler installed with Visual Studio is used.
- When building from the CLI via
dotnet build the compiler installed with the SDK is used.
This means that analyzers and generators can experience two different compiler versions based on how the build is invoked. An analyzer / generator that depends on a new version of the Roslyn APIs can get into a situation where dotnet build succeeds but msbuild fails because the compiler with Visual Studio is too old. That ends up resulting in errors like the following:
`##[warning]CSC(0,0): Warning CS8032: An instance of analyzer Microsoft.CodeAnalysis.MakeFieldReadonly.MakeFieldReadonlyDiagnosticAnalyzer cannot be created from C:\hostedtoolcache\windows\dotnet\sdk\6.0.300\Sdks\Microsoft.NET.Sdk\codestyle\cs\Microsoft.CodeAnalysis.CodeStyle.dll : Could not load file or assembly 'Microsoft.CodeAnalysis, Version=4.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified..
CSC : warning CS8032: An instance of analyzer Microsoft.CodeAnalysis.MakeFieldReadonly.MakeFieldReadonlyDiagnosticAnalyzer cannot be created from C:\hostedtoolcache\windows\dotnet\sdk\6.0.300\Sdks\Microsoft.NET.Sdk\codestyle\cs\Microsoft.CodeAnalysis.CodeStyle.dll : Could not load file or assembly 'Microsoft.CodeAnalysis, Version=4.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.. [f:\a\1\s\src\XX\XX.csproj]
This situation has existed for a while but this error is becoming more common for a variety of reasons:
- Source generator APIs are new and hence depend on much newer versions of the compiler
- Code style analyzers are effectively shipping in lock step with the language now and that requires them to use latest compiler APIs.
- There are more scenarios where customers are taking advantage of mismatched VS and .NET SDK versions
Given that we should address this scenario and I believe we should do so in two ways:
- The compiler needs a declarative diagnostic here. I believe our analyzer loader should just scan the reference table of any analyzer we load and if it depends on a newer version of the compiler then we issue a proactive diagonstic and do not load the analyzer.
- The diagnostic should be a warning not an error. The reason is that when a customer gets into this situation there is often nothing they can do. Using an error means the build is fundamentally blocked until they can find the MSBuild logic to remove an analyzer, which then degrades the
dotnet build scenario. Using a warning means the customer is alerted to the problem and the build can continue.
Examples of customers hitting this:
The .NET SDK supports installation into older versions of Visual Studio. For example 17.0 installs the 6.0.100 SDK by default but loading 6.0.200, 6.0.300 is supported. While this is supported it means that there is a bit of a mismatch in which compiler is used:
msbuildthe C# compiler installed with Visual Studio is used.dotnet buildthe compiler installed with the SDK is used.This means that analyzers and generators can experience two different compiler versions based on how the build is invoked. An analyzer / generator that depends on a new version of the Roslyn APIs can get into a situation where
dotnet buildsucceeds butmsbuildfails because the compiler with Visual Studio is too old. That ends up resulting in errors like the following:This situation has existed for a while but this error is becoming more common for a variety of reasons:
Given that we should address this scenario and I believe we should do so in two ways:
dotnet buildscenario. Using a warning means the customer is alerted to the problem and the build can continue.Examples of customers hitting this: