File: Semantics\UsingDeclarationTests.cs
Web Access
Project: src\src\Compilers\CSharp\Test\Semantic\Microsoft.CodeAnalysis.CSharp.Semantic.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Semantic.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.CSharp.UnitTests;
using Roslyn.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.CSharp.Semantic.UnitTests.Semantics
{
    /// <summary>
    /// Tests related to binding (but not lowering) using declarations (i.e. using var x = ...).
    /// </summary>
    public class UsingDeclarationTests : CompilingTestBase
    {
        [Fact]
        public void UsingVariableIsNotReportedAsUnused()
        {
            var source = @"
using System;
class C
{
    static void Main()
    {
        using var x = (IDisposable)null;
    }
}
";
            CreateCompilation(source).VerifyDiagnostics();
        }
 
        [Fact]
        public void DisallowGoToForwardAcrossUsingDeclarations()
        {
            var source = @"
using System;
class C
{
    static void Main()
    {
        goto label1;
        using var x = (IDisposable)null;
 
        label1:
        return;
    }
}
";
            CreateCompilation(source).VerifyDiagnostics(
                // (7,9): error CS8641: A goto target within the same block can not cross a using declaration.
                //         goto label1;
                Diagnostic(ErrorCode.ERR_GoToForwardJumpOverUsingVar, "goto label1;").WithLocation(7, 9),
                // (8,9): warning CS0162: Unreachable code detected
                //         using var x = (IDisposable)null;
                Diagnostic(ErrorCode.WRN_UnreachableCode, "using").WithLocation(8, 9)
                );
        }
 
        [Fact]
        public void DisallowGoToForwardAcrossUsingDeclarationsFromLowerBlock()
        {
            var source = @"
using System;
class C
{
    static void Main()
    {   
        {
            goto label1;
        }
        using var x = (IDisposable)null;
 
        label1:
        return;
    }
}
";
            CreateCompilation(source).VerifyDiagnostics(
                // (7,9): error CS8641: A goto target within the same block can not cross a using declaration.
                //         goto label1;
                Diagnostic(ErrorCode.ERR_GoToForwardJumpOverUsingVar, "goto label1;").WithLocation(8, 13),
                // (8,9): warning CS0162: Unreachable code detected
                //         using var x = (IDisposable)null;
                Diagnostic(ErrorCode.WRN_UnreachableCode, "using").WithLocation(10, 9)
                );
        }
 
        [Fact]
        public void DisallowGoToForwardAcrossMultipleUsingDeclarationsGivesOnlyOneDiagnostic()
        {
            var source = @"
using System;
class C
{
    static void Main()
    {
        goto label1;
        using var x = (IDisposable)null;
        using var y = (IDisposable)null;
 
        label1:
        return;
    }
}
";
            CreateCompilation(source).VerifyDiagnostics(
                // (7,9): error CS8641: A goto target within the same block can not cross a using declaration.
                //         goto label1;
                Diagnostic(ErrorCode.ERR_GoToForwardJumpOverUsingVar, "goto label1;").WithLocation(7, 9),
                // (8,9): warning CS0162: Unreachable code detected
                //         using var x = (IDisposable)null;
                Diagnostic(ErrorCode.WRN_UnreachableCode, "using").WithLocation(8, 9)
                );
        }
 
        [Fact]
        public void DisallowMultipleGoToForwardAcrossMultipleUsingDeclarations()
        {
            var source = @"
using System;
class C
{
    static void Main()
    {
        goto label1;
        using var x = (IDisposable)null;
        goto label2;
        using var y = (IDisposable)null;
 
        label1:
        label2:
        return;
    }
}
";
            CreateCompilation(source).VerifyDiagnostics(
                // (7,9): error CS8641: A goto target within the same block can not cross a using declaration.
                //         goto label1;
                Diagnostic(ErrorCode.ERR_GoToForwardJumpOverUsingVar, "goto label1;").WithLocation(7, 9),
                // (8,9): warning CS0162: Unreachable code detected
                //         using var x = (IDisposable)null;
                Diagnostic(ErrorCode.WRN_UnreachableCode, "using").WithLocation(8, 9),
                // (9,9): error CS8641: A goto target can not be after any using declarations.
                //         goto label2;
                Diagnostic(ErrorCode.ERR_GoToForwardJumpOverUsingVar, "goto label2;").WithLocation(9, 9)
                );
        }
 
        [Fact]
        public void DisallowGoToBackwardsAcrossUsingDeclarationsWhenLabelIsInTheSameScope()
        {
            var source = @"
using System;
class C
{
    static void Main()
    {
        label1:
        using var x = (IDisposable)null;
 
        goto label1;
    }
}
";
            CreateCompilation(source).VerifyDiagnostics(
                // (10,9): error CS8641: A goto target within the same block can not cross a using declaration.
                //         goto label1;
                Diagnostic(ErrorCode.ERR_GoToBackwardJumpOverUsingVar, "goto label1;").WithLocation(10, 9)
                );
        }
 
        [Fact]
        public void DisallowGoToBackwardsAcrossUsingDeclarationsWithMultipleLabels()
        {
            var source = @"
using System;
class C
{
    static void Main()
    {
        label1: 
        label2:
        label3:
        using var x = (IDisposable)null;
 
        goto label3; // disallowed
    }
}
";
            CreateCompilation(source).VerifyDiagnostics(
                // (7,9): warning CS0164: This label has not been referenced
                //         label1: 
                Diagnostic(ErrorCode.WRN_UnreferencedLabel, "label1").WithLocation(7, 9),
                // (8,9): warning CS0164: This label has not been referenced
                //         label2:
                Diagnostic(ErrorCode.WRN_UnreferencedLabel, "label2").WithLocation(8, 9),
                // (10,9): error CS8641: A goto target within the same block can not cross a using declaration.
                //         goto label3; // disallowed
                Diagnostic(ErrorCode.ERR_GoToBackwardJumpOverUsingVar, "goto label3;").WithLocation(12, 9)
                );
        }
 
        [Fact]
        public void DisallowGoToAcrossUsingDeclarationsComplexTest()
        {
            var source = @"
using System;
#pragma warning disable 162 // disable unreachable code warnings
class C
{
    static void Main()
    {
        label1:
        {
            label2:
            using var a = (IDisposable)null;
            goto label1; // allowed
            
            goto label2; // disallowed 1
        }
 
        label3:
        using var b = (IDisposable)null;
        {
            goto label3; // disallowed 2
        }
    
        {
            goto label4; // allowed
            goto label5; // disallowed 3
            label4:
            using var c = (IDisposable)null;
            label5:
            using var d = (IDisposable)null;
        }
        
        using var e = (IDisposable)null;
        label6:
        {
            {
                goto label6; //allowed
                label7:
                {
                    label8:
                    using var f = (IDisposable)null;      
                    goto label7; // allowed
                    {
                        using var g = (IDisposable)null;
                        goto label7; //allowed
                        goto label8; // disallowed 4
                    }
                }
            }
        }
    }
}
";
            CreateCompilation(source).VerifyDiagnostics(
                // (14,13): error CS8642: A goto cannot jump to a location before a using declaration within the same block.
                //             goto label2; // disallowed 1
                Diagnostic(ErrorCode.ERR_GoToBackwardJumpOverUsingVar, "goto label2;").WithLocation(14, 13),
                // (20,13): error CS8642: A goto cannot jump to a location before a using declaration within the same block.
                //             goto label3; // disallowed 2
                Diagnostic(ErrorCode.ERR_GoToBackwardJumpOverUsingVar, "goto label3;").WithLocation(20, 13),
                // (25,13): error CS8641: A goto cannot jump to a location after a using declaration.
                //             goto label5; // disallowed 3
                Diagnostic(ErrorCode.ERR_GoToForwardJumpOverUsingVar, "goto label5;").WithLocation(25, 13),
                // (45,25): error CS8642: A goto cannot jump to a location before a using declaration within the same block.
                //                         goto label8; // disallowed 4
                Diagnostic(ErrorCode.ERR_GoToBackwardJumpOverUsingVar, "goto label8;").WithLocation(45, 25)
                );
        }
 
        [Fact]
        public void AllowGoToAroundUsingDeclarations()
        {
            var source = @"
using System;
class C
{
    static void Main()
    {
        goto label1;
        label1:
        using var x = (IDisposable)null;
        goto label2;
        label2:
        return;
    }
}
";
            CreateCompilation(source).VerifyDiagnostics();
        }
 
        [Fact]
        public void AllowGoToBackwardsAcrossUsingDeclarationsWhenLabelIsInHigherScope()
        {
            var source = @"
using System;
class C
{
    static void Main()
    {
        label1:
        {
            using var x = (IDisposable)null;
            goto label1;
        }
    }
}
";
            CreateCompilation(source).VerifyDiagnostics();
        }
 
        [Fact]
        public void AllowGoToForwardsAcrossUsingDeclarationsInALowerBlock()
        {
            var source = @"
using System;
class C
{
    static void Main()
    {
        goto label1;
        {
            using var x = (IDisposable)null;
        }
        label1: ;
    }
}
";
            CreateCompilation(source).VerifyDiagnostics(
                // (8,9): warning CS0162: Unreachable code detected
                //         using var x = (IDisposable)null;
                Diagnostic(ErrorCode.WRN_UnreachableCode, "using").WithLocation(9, 13)
                );
        }
 
        [Fact]
        public void AllowGoToBackwardsAcrossUsingDeclarationsInALowerBlock()
        {
            var source = @"
using System;
class C
{
    static void Main()
    {
        label1:
        {
            using var x = (IDisposable)null;
        }
        goto label1;
    }
}
";
            CreateCompilation(source).VerifyDiagnostics();
        }
 
        [Fact]
        public void UsingVariableCanBeInitializedWithExistingDisposable()
        {
            var source = @"
using System;
class C2 : IDisposable
{
    public void Dispose()
    {
        Console.Write(""Disposed; ""); 
    }
}
class C
{
    static void Main()
    {
        var x = new C2();
        using var x2 = x;
        using var x3 = x2;
        x = null;
    }
}
";
            var compilation = CreateCompilation(source, options: TestOptions.DebugExe).VerifyDiagnostics();
            CompileAndVerify(compilation, expectedOutput: "Disposed; Disposed; ");
        }
 
        [Fact]
        public void UsingVariableCanBeInitializedWithExistingDisposableInASingleStatement()
        {
            var source = @"
using System;
class C2 : IDisposable
{
    public void Dispose()
    {
        Console.Write(""Disposed; ""); 
    }
}
class C
{
    static void Main()
    {
        using C2 x = new C2(), x2 = x;
    }
}
";
            var compilation = CreateCompilation(source, options: TestOptions.DebugExe).VerifyDiagnostics();
            CompileAndVerify(compilation, expectedOutput: "Disposed; Disposed; ");
        }
 
        [Fact]
        public void UsingVariableCanBeInitializedWithExistingRefStructDisposable()
        {
            var source = @"
using System;
ref struct C2
{
    public void Dispose()
    {
        Console.Write(""Disposed; ""); 
    }
}
class C
{
    static void Main()
    {
        var x = new C2();
        using var x2 = x;
        using var x3 = x2;
    }
}
";
            var compilation = CreateCompilation(source, options: TestOptions.DebugExe).VerifyDiagnostics();
            CompileAndVerify(compilation, expectedOutput: "Disposed; Disposed; ");
        }
 
        [Fact]
        public void UsingVariableCannotBeReAssigned()
        {
            var source = @"
using System;
class C
{
    static void Main()
    {
        using var x = (IDisposable)null;
        x = null;
    }
}
";
            CreateCompilation(source).VerifyDiagnostics(
                // (8,9): error CS1656: Cannot assign to 'x' because it is a 'using variable'
                //         x = null;
                Diagnostic(ErrorCode.ERR_AssgReadonlyLocalCause, "x").WithArguments("x", "using variable").WithLocation(8, 9)
                );
        }
 
        [Fact]
        public void UsingVariableCannotBeUsedAsOutVariable()
        {
            var source = @"
using System;
class C
{
    static void Consume(out IDisposable x) 
    {
        x = null;
    }
 
    static void Main()
    {
        using var x = (IDisposable)null;
        Consume(out x);
    }
}
";
            CreateCompilation(source).VerifyDiagnostics(
                // (13,21): error CS1657: Cannot use 'x' as a ref or out value because it is a 'using variable'
                //         Consume(out x);
                Diagnostic(ErrorCode.ERR_RefReadonlyLocalCause, "x").WithArguments("x", "using variable").WithLocation(13, 21)
                );
        }
 
        [Fact]
        public void UsingVariableMustHaveInitializer()
        {
            var source = @"
using System;
class C
{
    static void Main()
    {
        using IDisposable x;
    }
}
";
            CreateCompilation(source).VerifyDiagnostics(
                // (7,27): error CS0210: You must provide an initializer in a fixed or using statement declaration
                //         using IDisposable x;
                Diagnostic(ErrorCode.ERR_FixedMustInit, "x").WithLocation(7, 27)
                );
        }
 
        [Fact]
        public void UsingVariableFromExistingVariable()
        {
            var source = @"
using System;
class C
{
    static void Main()
    {
        var x = (IDisposable)null;
        using var x2 = x;
    }
}
";
            CreateCompilation(source).VerifyDiagnostics();
        }
 
        [Fact]
        public void UsingVariableFromExpression()
        {
            var source = @"
using System;
class C
{
    static IDisposable GetDisposable()
    {
        return null;
    }
 
    static void Main()
    {
        using IDisposable x = GetDisposable();
    }
}
";
            CreateCompilation(source).VerifyDiagnostics();
        }
 
        [Fact]
        public void UsingVariableFromAwaitExpression()
        {
            var source = @"
using System;
using System.Threading.Tasks;
class C
{
    static Task<IDisposable> GetDisposable()
    {
        return Task.FromResult<IDisposable>(null);
    }
 
    static async Task Main()
    {
        using IDisposable x = await GetDisposable();
    }
}
";
            CreateCompilation(source).VerifyDiagnostics();
        }
 
        [Fact]
        public void UsingVariableInSwitchCase_01()
        {
            var source = @"
using System;
class C1 : IDisposable
{
    public void Dispose() { }
}
class C2
{
    public static void Main()
    {
        int x = 5;
        switch (x)
        {
            case 5:
                using C1 o1 = new C1();
                break;
        }
    }
}";
            CreateCompilation(source).VerifyDiagnostics(
                // (15,21): error CS8389: A using variable cannot be used directly within a switch section (consider using braces). 
                //                     using C1 o1 = new C1();
                Diagnostic(ErrorCode.ERR_UsingVarInSwitchCase, "using C1 o1 = new C1();").WithLocation(15, 17)
            );
        }
 
        [Fact, WorkItem(63570, "https://github.com/dotnet/roslyn/issues/63570")]
        public void UsingVariableInSwitchCase_02()
        {
            var source = """
                using System;
                StringSplitOptions temp = StringSplitOptions.RemoveEmptyEntries;
                switch (temp)
                {
                    case StringSplitOptions.None:
                        Console.WriteLine("None");
                        break;
                
                    case StringSplitOptions.RemoveEmptyEntries:
                    {
                        using var streamReader = new C1();
                        goto case StringSplitOptions.None;
                    }
                
                    default:
                        break;
                }
                
                class C1 : IDisposable
                {
                    public void Dispose()
                    {
                        Console.WriteLine("Disposed");
                    }
                }
                """;
 
            var verifier = CompileAndVerify(source, expectedOutput: """
                Disposed
                None
                """);
 
            verifier.VerifyDiagnostics();
 
            verifier.VerifyIL("<top-level-statements-entry-point>", """
                {
                  // Code size       39 (0x27)
                  .maxstack  2
                  .locals init (System.StringSplitOptions V_0, //temp
                                C1 V_1) //streamReader
                  IL_0000:  ldc.i4.1
                  IL_0001:  stloc.0
                  IL_0002:  ldloc.0
                  IL_0003:  brfalse.s  IL_000a
                  IL_0005:  ldloc.0
                  IL_0006:  ldc.i4.1
                  IL_0007:  beq.s      IL_0015
                  IL_0009:  ret
                  IL_000a:  ldstr      "None"
                  IL_000f:  call       "void System.Console.WriteLine(string)"
                  IL_0014:  ret
                  IL_0015:  newobj     "C1..ctor()"
                  IL_001a:  stloc.1
                  .try
                  {
                    IL_001b:  leave.s    IL_000a
                  }
                  finally
                  {
                    IL_001d:  ldloc.1
                    IL_001e:  brfalse.s  IL_0026
                    IL_0020:  ldloc.1
                    IL_0021:  callvirt   "void System.IDisposable.Dispose()"
                    IL_0026:  endfinally
                  }
                }
                """);
        }
 
        [Fact, WorkItem(63570, "https://github.com/dotnet/roslyn/issues/63570")]
        public void UsingVariableInSwitchCase_03()
        {
            var source = """
                using System;
                StringSplitOptions temp = StringSplitOptions.RemoveEmptyEntries;
                switch (temp)
                {
                    case StringSplitOptions.None:
                        goto case StringSplitOptions.RemoveEmptyEntries;
                
                    case StringSplitOptions.RemoveEmptyEntries:
                    {
                        using var streamReader = new C1();
                        goto case StringSplitOptions.None;
                    }
                }
                
                class C1 : IDisposable
                {
                    public void Dispose()
                    {
                        Console.WriteLine("Disposed");
                    }
                }
                """;
 
            var verifier = CompileAndVerify(source);
            verifier.VerifyDiagnostics();
        }
 
        [Fact, WorkItem(63570, "https://github.com/dotnet/roslyn/issues/63570")]
        public void UsingVariableInSwitchCase_04()
        {
            var source = """
                using System;
                StringSplitOptions temp = StringSplitOptions.RemoveEmptyEntries;
                switch (temp)
                {
                    case StringSplitOptions.RemoveEmptyEntries:
                    {
                        using var streamReader = new C1();
                        goto default;
                    }
 
                    default:
                        Console.WriteLine("Default");
                        break;
                }
                
                class C1 : IDisposable
                {
                    public void Dispose()
                    {
                        Console.WriteLine("Disposed");
                    }
                }
                """;
 
            var verifier = CompileAndVerify(source, expectedOutput: """
                Disposed
                Default
                """);
            verifier.VerifyDiagnostics();
        }
 
        [Fact, WorkItem(63570, "https://github.com/dotnet/roslyn/issues/63570")]
        public void UsingVariableInSwitchCase_05()
        {
            var source = """
                using System;
                StringSplitOptions temp = StringSplitOptions.RemoveEmptyEntries;
                switch (temp)
                {
                    default:
                        Console.WriteLine("Default");
                        break;
 
                    case StringSplitOptions.RemoveEmptyEntries:
                    {
                        using var streamReader = new C1();
                        goto default;
                    }
                }
                
                class C1 : IDisposable
                {
                    public void Dispose()
                    {
                        Console.WriteLine("Disposed");
                    }
                }
                """;
 
            var verifier = CompileAndVerify(source, expectedOutput: """
                Disposed
                Default
                """);
            verifier.VerifyDiagnostics();
        }
 
        [Fact]
        public void UsingVariableDiagnosticsInDeclarationAreOnlyEmittedOnce()
        {
            var source = @"
using System;
class C1 : IDisposable
{
    public void Dispose() { }
}
class C2
{
    public static void Main()
    {
        using var c1 = new C1(), c2 = new C2();
    }
}";
            CreateCompilation(source).VerifyDiagnostics(
              // (11,15): error CS0819: Implicitly-typed variables cannot have multiple declarators
              //         using var c1 = new C1(), c2 = new C2();
              Diagnostic(ErrorCode.ERR_ImplicitlyTypedVariableMultipleDeclarator, "var c1 = new C1(), c2 = new C2()").WithLocation(11, 15)
            );
        }
 
        [Fact]
        public void UsingDeclarationWithAwaitsInAsync()
        {
            var source = @"
using System;
using System.Threading.Tasks;
class C2 : IDisposable
{
    public string ID { get; set; }
    public void Dispose()
    {
        Console.Write($""Dispose {ID}; "");
    }
}
class C
{
    static async Task<IDisposable> GetDisposable(string id)
    {
        await Task.Yield();
        return new C2(){ ID = id };
    }
 
    static async Task Main()
    {
        using IDisposable x = await GetDisposable(""c1"");
        await Task.Yield();
        Console.Write(""after c1; "");
        using IDisposable y = await GetDisposable(""c2"");
        Console.Write(""after c2; "");
    }
}
";
            var compilation = CreateCompilationWithTasksExtensions(source, options: TestOptions.DebugExe).VerifyDiagnostics();
 
            CompileAndVerify(compilation, expectedOutput: "after c1; after c2; Dispose c2; Dispose c1; ");
        }
 
        [Fact]
        public void UsingDeclarationsWithLangVer7_3()
        {
            var source = @"
using System;
class C
{
    static void Main()
    {
        using IDisposable x = null;
    }
}
";
            var expected = new[]
            {
                // (7,9): error CS8652: The feature 'using declarations' is not available in C# 7.3. Please use language version 8.0 or greater.
                //         using IDisposable x = null;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "using").WithArguments("using declarations", "8.0").WithLocation(7, 9)
            };
 
            CreateCompilation(source, parseOptions: TestOptions.Regular7_3).VerifyDiagnostics(expected);
 
            CreateCompilation(source, parseOptions: TestOptions.Regular8).VerifyDiagnostics();
        }
 
        [Fact]
        public void AwaitUsingDeclarationsWithLangVer7_3()
        {
            var source = @"
using System;
using System.Threading.Tasks;
class C
{
    static async Task Main()
    {
        await using IAsyncDisposable x = null;
    }
}
";
            var expected = new[]
            {
                // 0.cs(8,9): error CS8370: Feature 'pattern-based disposal' is not available in C# 7.3. Please use language version 8.0 or greater.
                //         await using IAsyncDisposable x = null;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "await using IAsyncDisposable x = null;").WithArguments("pattern-based disposal", "8.0").WithLocation(8, 9),
                // 0.cs(8,15): error CS8370: Feature 'using declarations' is not available in C# 7.3. Please use language version 8.0 or greater.
                //         await using IAsyncDisposable x = null;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "using").WithArguments("using declarations", "8.0").WithLocation(8, 15)
            };
 
            CreateCompilationWithTasksExtensions(new[] { source, IAsyncDisposableDefinition }, parseOptions: TestOptions.Regular7_3).VerifyDiagnostics(expected);
 
            CreateCompilationWithTasksExtensions(new[] { source, IAsyncDisposableDefinition }, parseOptions: TestOptions.Regular8).VerifyDiagnostics();
        }
 
        [Fact]
        public void UsingDeclarationsWithObsoleteTypes()
        {
            var source = @"
using System;
 
[Obsolete]
class C1 : IDisposable
{
    [Obsolete]
    public void Dispose()  
    {
    }
}
 
class C2 : IDisposable
{
    [Obsolete]
    public void Dispose()  
    {
    }
}
 
ref struct S3
{
    [Obsolete]
    public void Dispose()
    {
    }
}
 
class C4
{
    static void Main()
    {
        // c1 is obsolete
        using C1 c1 = new C1();
 
        // no warning, we don't warn on dispose being obsolete because it comes through interface
        using C2 c2 = new C2();
    
        // warning, we're calling the pattern based obsolete method for the ref struct
        using S3 S3 = new S3();
    }
}
";
            CreateCompilation(source).VerifyDiagnostics(
                // (34,15): warning CS0612: 'C1' is obsolete
                //         using C1 c1 = new C1();
                Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "C1").WithArguments("C1").WithLocation(34, 15),
                // (34,27): warning CS0612: 'C1' is obsolete
                //         using C1 c1 = new C1();
                Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "C1").WithArguments("C1").WithLocation(34, 27),
                // (40,15): warning CS0612: 'S3.Dispose()' is obsolete
                //         using S3 S3 = new S3();
                Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "using S3 S3 = new S3();").WithArguments("S3.Dispose()").WithLocation(40, 9)
                );
        }
 
        [Fact]
        [WorkItem(36413, "https://github.com/dotnet/roslyn/issues/36413")]
        public void UsingDeclarationsWithInvalidModifiers()
        {
            var source = @"
using System;
class C
{
    static void Main()
    {
        using public readonly var x = (IDisposable)null;
    }
}
";
            CreateCompilation(source, parseOptions: TestOptions.Regular8).VerifyDiagnostics(
                // (7,15): error CS9229: Modifiers cannot be placed on using declarations
                //         using public readonly var x = (IDisposable)null;
                Diagnostic(ErrorCode.ERR_NoModifiersOnUsing, "public").WithLocation(7, 15),
                // (7,22): error CS9229: Modifiers cannot be placed on using declarations
                //         using public readonly var x = (IDisposable)null;
                Diagnostic(ErrorCode.ERR_NoModifiersOnUsing, "readonly").WithLocation(7, 22)
                );
        }
    }
}