zompinc/sync-method-generator

Unable to compile to net48 or netstandard2 because of #nullable

Closed this issue · 9 comments

If I write the following code into a project that compiles to either net48 or netstandard2.0..

using System.Threading.Tasks;

namespace ClassLibrary1
{
    public partial class Class1
    {
        [Zomp.SyncMethodGenerator.CreateSyncVersion]
        public async Task FooAsync() => await Task.Delay(100);
    }
}

It'll generate the following code..

// <auto-generated/>
#nullable enable
namespace ClassLibrary1
{
    public partial class Class1
    {
        public void Foo() => global::System.Threading.Thread.Sleep(100);
    }
}

Which will produce the compiler error

1>....\ClassLibrary1\Zomp.SyncMethodGenerator\Zomp.SyncMethodGenerator.SyncMethodSourceGenerator\ClassLibrary1.Class1.FooAsync.g.cs(2,2,2,10): error CS8370: Feature 'nullable reference types' is not available in C# 7.3. Please use language version 8.0 or greater.
1>Done building project "ClassLibrary1.csproj" -- FAILED.

The #enable line should probably be omitted unless the project is compiling to C# 8.0 or later

Sandbox test project targets net48. How is your project different?

I see. That line should be omitted if your langversion is less than 8. Perhaps in other cases too. One issue to upvote and keep an eye on is this: dotnet/roslyn#49555

Can you confirm what your langversion is or perhaps attach a sample zipped project / solution?

Thanks

@persn, Please confirm that the problem goes away in 1.2.24. Thanks.

Can you confirm what your langversion is

I use the one that defaults with the TargetFramework, I don't override the LangVersion, so for net48 and netstandard2.0 it would be C# 7.3 I think?

Please confirm that the problem goes away in 1.2.24. Thanks.

It looks like the original problem has been resolved. However I see another one related to nullable reference types. I can create a new issue if you wish but I'll type it out here anyway.

This time the code is written in net6 so nullable is technically supported however we haven't rewritten our large code base to be compatible with this feature. If I declare a variable and assigns it to null for later assignment I get a compiler warning, which for us will be a compiler error since we have werror enabled. In the following code which works fine for us, however in the generated file it produces issues at string foo = null; because of the #nullable.

using System;
using System.Threading.Tasks;

namespace ClassLibrary1
{
    public partial class Class1
    {
        [Zomp.SyncMethodGenerator.CreateSyncVersion]
        public async Task FooAsync()
        {
            string foo = null;

            // Assume we have some code that reassigns variable foo
            Console.WriteLine(foo);

            await Task.Delay(100);
        }
    }
}
warning CS8600: Converting null literal or possible null value to non-nullable type.

@virzak

It is an interesting problem @persn told about. Why do we need to have #nullable enable at the top of g.cs at all? In general, it is very diffuclt to determine if async code is nullable enable of disable whatever the langversion is in use:

#nullable enable
using System;
using System.Threading.Tasks;

namespace ClassLibrary1
{
    public partial class Class1
    {
        [Zomp.SyncMethodGenerator.CreateSyncVersion]
        public async Task FooAsync()
        {
#nullable disable
            string foo = null;
#nullable enable
            // Assume we have some code that reassigns variable foo
            Console.WriteLine(foo);

            await Task.Delay(100);
        }

#nullable disable
    }
}

I'll look into removing #nullable enable altogether this week. It has been there from the beginning and I don't remember why. I think this has to do with net48 which enables nullable by default. In the meantime, lets upvote dotnet/roslyn#49555

@persn and @lsoft

You can use [CreateSyncVersion(OmitNullableDirective = true)]

Version 1.3.8-beta is on nuget.

Once you confirm that the naming and usage is good, we'll take it out of beta.

It seems to work great