dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.44k stars 10.02k forks source link

CS8669 when using runtime compilation and the project has nullable enabled #53967

Open sandermvanvliet-stack opened 9 months ago

sandermvanvliet-stack commented 9 months ago

I have an interesting case where I have Razor runtime compilation enabled and the view is in a project that has <Nullable>enable</Nullable> in the project file.

What I'm seeing

Given a view like this:

@using MyModel

@functions 
{
    public void StatusIndicator(bool success, string? reason)
    {
       // Omitted for brevity
    }
}

<div>
    <p>@{ StatusIndicator(Model.Success, Model.Reason); }</p>
</div>

where MyModel is:

public class MyModel
{
    public bool Success { get; set; }
    public string? Reason { get; set; }
}

Project file is like this:

<Project>
    <PropertyGroup>
        <TargetFramework>net6.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
    </PropertyGroup>
</Project>

When enabling Razor runtime compilation and navigating to the route that uses this view I get the error:

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.

(click for full stack trace)

When disabling Razor runtime compilation and navigating to the route that uses this view it will be rendered normally.

Suspicions

For (I think..) both runtime and build compilation, the view is passed through the Razor source generator exactly in the same way so should amount to the same code. By catching the exception (see above) I've managed to pull out the runtime generated code and using the EmitCompilerGeneratedFiles MSBuild property in the project I've also managed to capture the build time generated code.

Comparing the two I can see some slight differences (namespace name and file paths) but otherwise they're similar.

My suspicion is that:

As it's not part of the actual project, the setting for Nullable isn't taken from that project which leads to this result that the compilation thinks that Nullable is not enabled (where it is enabled in the actual project).

Versions

Visual Studio Version 17.8.3

dotnet --info:

.NET SDK (reflecting any global.json):
 Version:   6.0.413
 Commit:    10710f7d8e

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.22631
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\6.0.413\

Host:
  Version:      8.0.0
  Architecture: x64
  Commit:       5535e31a71

.NET SDKs installed:
  6.0.300 [C:\Program Files\dotnet\sdk]
  6.0.405 [C:\Program Files\dotnet\sdk]
  6.0.408 [C:\Program Files\dotnet\sdk]
  6.0.413 [C:\Program Files\dotnet\sdk]
  7.0.115 [C:\Program Files\dotnet\sdk]
  8.0.100 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 5.0.14 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.16 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.25 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.14 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.16 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.25 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.13 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.16 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.25 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 7.0.14 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 7.0.15 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation Version 6.0.5

chsienki commented 9 months ago

@sandermvanvliet-stack thanks for the detailed analysis! That certainly seems like a plausible explanation for what is happening.

@jaredpar @danroth27 Runtime compilation lives in aspnetcore, but I guess we're the closest to its owners. Do we want to track issues for it here, or over there?

danroth27 commented 9 months ago

@jaredpar @danroth27 Runtime compilation lives in aspnetcore, but I guess we're the closest to its owners. Do we want to track issues for it here, or over there?

Let's track the issue in the repo where the corresponding code lives. If this is an issue with runtime compilation and not the compiler, then it should move to the aspnetcore repo.

sandermvanvliet commented 8 months ago

If there is any additional info needed give me a shout 👍