File: Semantics\LocalFunctionTests.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.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using Xunit;
 
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
    public class LocalFunctionsTestBase : CSharpTestBase
    {
        internal static readonly CSharpParseOptions DefaultParseOptions = TestOptions.Regular;
 
        internal static void VerifyDiagnostics(string source, params DiagnosticDescription[] expected)
        {
            var comp = CreateCompilationWithMscorlib461AndCSharp(source, options: TestOptions.ReleaseDll, parseOptions: DefaultParseOptions);
            comp.VerifyDiagnostics(expected);
        }
    }
 
    [CompilerTrait(CompilerFeature.LocalFunctions)]
    public class LocalFunctionTests : LocalFunctionsTestBase
    {
        [Fact, WorkItem(29656, "https://github.com/dotnet/roslyn/issues/29656")]
        public void RefReturningAsyncLocalFunction()
        {
            var source = @"
public class C
{
    async ref System.Threading.Tasks.Task M() { }
 
    public void M2()
    {
        _ = local();
 
        async ref System.Threading.Tasks.Task local() { }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (4,11): error CS1073: Unexpected token 'ref'
                //     async ref System.Threading.Tasks.Task M() { }
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(4, 11),
                // (4,43): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
                //     async ref System.Threading.Tasks.Task M() { }
                Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "M").WithLocation(4, 43),
                // (10,15): error CS1073: Unexpected token 'ref'
                //         async ref System.Threading.Tasks.Task local() { }
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(10, 15),
                // (10,47): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
                //         async ref System.Threading.Tasks.Task local() { }
                Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "local").WithLocation(10, 47)
                );
        }
 
        [ConditionalFact(typeof(DesktopOnly))]
        public void LocalFunctionResetsLockScopeFlag()
        {
            var source = @"
using System;
using System.Threading.Tasks;
 
class C
{
    static void Main()
    {
        lock (new Object())
        {
            async Task localFunc()
            {
                Console.Write(""localFunc"");
                await Task.Yield();
            }
 
            localFunc();
        }
    }
}
";
 
            var comp = CreateCompilationWithMscorlib46(source, options: TestOptions.ReleaseExe);
            CompileAndVerify(comp, expectedOutput: "localFunc");
        }
 
        [ConditionalFact(typeof(DesktopOnly))]
        public void LocalFunctionResetsTryCatchFinallyScopeFlags()
        {
            var source = @"
using System;
using System.Collections.Generic;
 
class C
{
    static void Main()
    {
        try
        {
            IEnumerable<int> localFunc()
            {
                yield return 1;
            }
 
            foreach (int i in localFunc())
            {
                Console.Write(i);
            }
 
            throw new Exception();
        }
        catch (Exception)
        {
            IEnumerable<int> localFunc()
            {
                yield return 2;
            }
 
            foreach (int i in localFunc())
            {
                Console.Write(i);
            }
        }
        finally
        {
            IEnumerable<int> localFunc()
            {
                yield return 3;
            }
 
            foreach (int i in localFunc())
            {
                Console.Write(i);
            }
        }
    }
}
";
 
            var comp = CreateCompilationWithMscorlib46(source, options: TestOptions.ReleaseExe);
            CompileAndVerify(comp, expectedOutput: "123");
        }
 
        [ConditionalFact(typeof(DesktopOnly))]
        public void LocalFunctionDoesNotOverwriteInnerLockScopeFlag()
        {
            var source = @"
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
 
class C
{
    void M(List<Task> listOfTasks)
    {
        lock (new Object())
        {
            async Task localFunc()
            {
                lock (new Object())
                {
                    await Task.Yield();
                }
            }
 
            listOfTasks.Add(localFunc());
        }
    }
}
";
 
            var comp = CreateCompilationWithMscorlib46(source);
            comp.VerifyDiagnostics(
                // (16,21): error CS1996: Cannot await in the body of a lock statement
                //                     await Task.Yield();
                Diagnostic(ErrorCode.ERR_BadAwaitInLock, "await Task.Yield()").WithLocation(16, 21));
        }
 
        [ConditionalFact(typeof(DesktopOnly))]
        public void LocalFunctionDoesNotOverwriteInnerTryCatchFinallyScopeFlags()
        {
            var source = @"
using System;
using System.Collections.Generic;
 
class C
{
    void M()
    {
        try
        {
            IEnumerable<int> localFunc()
            {
                try
                {
                    yield return 1;
                }
                catch (Exception) {}
            }
 
            localFunc();
        }
        catch (Exception)
        {
            IEnumerable<int> localFunc()
            {
                try {}
                catch (Exception)
                {
                    yield return 2;
                }
            }
 
            localFunc();
        }
        finally
        {
            IEnumerable<int> localFunc()
            {
                try {}
                finally
                {
                    yield return 3;
                }
            }
 
            localFunc();
        }
    }
}
";
 
            var comp = CreateCompilationWithMscorlib46(source);
            comp.VerifyDiagnostics(
                // (15,21): error CS1626: Cannot yield a value in the body of a try block with a catch clause
                //                     yield return 1;
                Diagnostic(ErrorCode.ERR_BadYieldInTryOfCatch, "yield").WithLocation(15, 21),
                // (29,21): error CS1631: Cannot yield a value in the body of a catch clause
                //                     yield return 2;
                Diagnostic(ErrorCode.ERR_BadYieldInCatch, "yield").WithLocation(29, 21),
                // (42,21): error CS1625: Cannot yield in the body of a finally clause
                //                     yield return 3;
                Diagnostic(ErrorCode.ERR_BadYieldInFinally, "yield").WithLocation(42, 21));
        }
 
        [ConditionalFact(typeof(DesktopOnly))]
        public void RethrowingExceptionsInCatchInsideLocalFuncIsAllowed()
        {
            var source = @"
using System;
 
class C
{
    static void Main()
    {
        try
        {
            throw new Exception();
        }
        catch (Exception)
        {
            void localFunc()
            {
                try
                {
                    throw new Exception();
                }
                catch (Exception)
                {
                    Console.Write(""localFunc"");
                    throw;
                }
            }
 
            try
            {
                localFunc();
            }
            catch (Exception)
            {
                Console.Write(""_thrown"");
            }
        }
    }
}
";
 
            var comp = CreateCompilationWithMscorlib46(source, options: TestOptions.ReleaseExe);
            CompileAndVerify(comp, expectedOutput: "localFunc_thrown");
        }
 
        [ConditionalFact(typeof(DesktopOnly))]
        public void RethrowingExceptionsInLocalFuncInsideCatchIsNotAllowed()
        {
            var source = @"
using System;
 
class C
{
    static void Main()
    {
        try {}
        catch (Exception)
        {
            void localFunc()
            {
                throw;
            }
 
            localFunc();
        }
    }
}
";
 
            var comp = CreateCompilationWithMscorlib46(source);
            comp.VerifyDiagnostics(
                // (13,17): error CS0156: A throw statement with no arguments is not allowed outside of a catch clause
                //                 throw;
                Diagnostic(ErrorCode.ERR_BadEmptyThrow, "throw").WithLocation(13, 17));
        }
 
        [Fact]
        public void LocalFunctionTypeParametersUseCorrectBinder()
        {
            var text = @"
class C
{
    static void M()
    {
        void local<[X]T>() {}
    }
}";
            var tree = SyntaxFactory.ParseSyntaxTree(text, options: TestOptions.Regular9);
            var comp = CreateCompilation(tree);
            var model = comp.GetSemanticModel(tree, ignoreAccessibility: true);
 
            var newTree = SyntaxFactory.ParseSyntaxTree(text + " ");
            var m = newTree.GetRoot()
                .DescendantNodes().OfType<MethodDeclarationSyntax>().Single();
 
            Assert.True(model.TryGetSpeculativeSemanticModelForMethodBody(m.Body.SpanStart, m, out model));
 
            var x = newTree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Single();
            Assert.Equal("X", x.Identifier.Text);
 
            // If we aren't using the right binder here, the compiler crashes going through the binder factory
            var info = model.GetSymbolInfo(x);
            Assert.Null(info.Symbol);
 
            comp.VerifyDiagnostics(
                // (6,21): error CS0246: The type or namespace name 'XAttribute' could not be found (are you missing a using directive or an assembly reference?)
                //         void local<[X]T>() {}
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "X").WithArguments("XAttribute").WithLocation(6, 21),
                // (6,21): error CS0246: The type or namespace name 'X' could not be found (are you missing a using directive or an assembly reference?)
                //         void local<[X]T>() {}
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "X").WithArguments("X").WithLocation(6, 21),
                // (6,14): warning CS8321: The local function 'local' is declared but never used
                //         void local<[X]T>() {}
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "local").WithArguments("local").WithLocation(6, 14));
        }
 
        [Theory]
        [InlineData("[A] void local() { }")]
        [InlineData("[return: A] void local() { }")]
        [InlineData("void local([A] int i) { }")]
        [InlineData("void local<[A]T>() {}")]
        [InlineData("[A] int x = 123;")]
        public void LocalFunctionAttribute_SpeculativeSemanticModel(string statement)
        {
            string text = $@"
using System;
class A : Attribute {{}}
 
class C
{{
    static void M()
    {{
        {statement}
    }}
}}";
            var tree = SyntaxFactory.ParseSyntaxTree(text);
            var comp = (Compilation)CreateCompilation(tree);
            var model = comp.GetSemanticModel(tree);
            var a = tree.GetRoot().DescendantNodes()
                .OfType<IdentifierNameSyntax>().ElementAt(2);
            Assert.Equal("A", a.Identifier.Text);
            var attrInfo = model.GetSymbolInfo(a);
            var attrType = comp.GlobalNamespace.GetTypeMember("A");
            var attrCtor = attrType.GetMember(".ctor");
            Assert.Equal(attrCtor, attrInfo.Symbol);
 
            // Assert that this is also true for the speculative semantic model
            var newTree = SyntaxFactory.ParseSyntaxTree(text + " ");
            var m = newTree.GetRoot()
                .DescendantNodes().OfType<MethodDeclarationSyntax>().Single();
 
            Assert.True(model.TryGetSpeculativeSemanticModelForMethodBody(m.Body.SpanStart, m, out model));
 
            a = newTree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().ElementAt(2);
            Assert.Equal("A", a.Identifier.Text);
 
            var info = model.GetSymbolInfo(a);
            Assert.Equal(attrCtor, info.Symbol);
        }
 
        [Theory]
        [InlineData(@"[Attr(42, Name = ""hello"")] void local() { }")]
        [InlineData(@"[return: Attr(42, Name = ""hello"")] void local() { }")]
        [InlineData(@"void local([Attr(42, Name = ""hello"")] int i) { }")]
        [InlineData(@"void local<[Attr(42, Name = ""hello"")]T>() {}")]
        [InlineData(@"[Attr(42, Name = ""hello"")] int x = 123;")]
        public void LocalFunctionAttribute_Argument_SemanticModel(string statement)
        {
            var text = $@"
class Attr
{{
    public Attr(int id) {{ }}
    public string Name {{ get; set; }}
}}
 
class C
{{
    static void M()
    {{
        {statement}
    }}
}}";
            var tree = SyntaxFactory.ParseSyntaxTree(text, options: TestOptions.Regular9);
            var comp = CreateCompilation(tree);
            var model = comp.GetSemanticModel(tree, ignoreAccessibility: true);
            validate(model, tree);
 
            var newTree = SyntaxFactory.ParseSyntaxTree(text + " ", options: TestOptions.Regular9);
            var mMethod = (MethodDeclarationSyntax)newTree.FindNodeOrTokenByKind(SyntaxKind.MethodDeclaration, occurrence: 1).AsNode();
 
            Assert.True(model.TryGetSpeculativeSemanticModelForMethodBody(mMethod.Body.SpanStart, mMethod, out var newModel));
            validate(newModel, newTree);
 
            static void validate(SemanticModel model, SyntaxTree tree)
            {
                var attributeSyntax = tree.GetRoot().DescendantNodes().OfType<AttributeSyntax>().Single();
                var attrArgs = attributeSyntax.ArgumentList.Arguments;
 
                var attrArg0 = attrArgs[0].Expression;
                Assert.Null(model.GetSymbolInfo(attrArg0).Symbol);
 
                var argType0 = model.GetTypeInfo(attrArg0).Type;
                Assert.Equal(SpecialType.System_Int32, argType0.SpecialType);
 
                var attrArg1 = attrArgs[1].Expression;
                Assert.Null(model.GetSymbolInfo(attrArg1).Symbol);
 
                var argType1 = model.GetTypeInfo(attrArg1).Type;
                Assert.Equal(SpecialType.System_String, argType1.SpecialType);
            }
        }
 
        [Fact]
        public void LocalFunctionAttribute_OnFunction()
        {
            const string text = @"
using System;
class A : Attribute { }
 
class C
{
    void M()
    {
        [A]
        void local() { }
    }
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (10,14): warning CS8321: The local function 'local' is declared but never used
                //         void local() { }
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "local").WithArguments("local").WithLocation(10, 14));
 
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);
 
            var localFunction = tree.GetRoot().DescendantNodes()
                .OfType<LocalFunctionStatementSyntax>()
                .Single();
 
            var attributeList = localFunction.AttributeLists.Single();
            Assert.Null(attributeList.Target);
 
            var attribute = attributeList.Attributes.Single();
            Assert.Equal("A", ((SimpleNameSyntax)attribute.Name).Identifier.ValueText);
 
            var symbol = (IMethodSymbol)model.GetDeclaredSymbol(localFunction);
            Assert.NotNull(symbol);
 
            var attributes = symbol.GetAttributes().As<CSharpAttributeData>();
            Assert.Equal(new[] { "A" }, GetAttributeNames(attributes));
 
            var returnAttributes = symbol.GetReturnTypeAttributes();
            Assert.Empty(returnAttributes);
        }
 
        [Fact]
        public void LocalFunctionAttribute_OnFunction_Argument()
        {
            const string text = @"
using System;
class A : Attribute
{
    internal A(int i) { }
}
 
class C
{
    void M()
    {
        [A(42)]
        void local() { }
    }
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (13,14): warning CS8321: The local function 'local' is declared but never used
                //         void local() { }
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "local").WithArguments("local").WithLocation(13, 14));
 
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);
 
            var localFunction = tree.GetRoot().DescendantNodes()
                .OfType<LocalFunctionStatementSyntax>()
                .Single();
 
            var attributeList = localFunction.AttributeLists.Single();
            Assert.Null(attributeList.Target);
 
            var attribute = attributeList.Attributes.Single();
            Assert.Equal("A", ((SimpleNameSyntax)attribute.Name).Identifier.ValueText);
 
            var symbol = (IMethodSymbol)model.GetDeclaredSymbol(localFunction);
            Assert.NotNull(symbol);
 
            var attributes = symbol.GetAttributes();
            var attributeData = attributes.Single();
            var aAttribute = comp.GetTypeByMetadataName("A");
            Assert.Equal(aAttribute, attributeData.AttributeClass.GetSymbol());
            Assert.Equal(aAttribute.InstanceConstructors.Single(), attributeData.AttributeConstructor.GetSymbol());
            Assert.Equal(42, attributeData.ConstructorArguments.Single().Value);
 
            var returnAttributes = symbol.GetReturnTypeAttributes();
            Assert.Empty(returnAttributes);
        }
 
        [Fact]
        public void LocalFunctionAttribute_OnFunction_LocalArgument()
        {
            const string text = @"
using System;
class A : Attribute
{
    internal A(string s) { }
}
 
class C
{
    void M()
    {
#pragma warning disable 0219 // Unreferenced local variable
        string s1 = ""hello"";
        const string s2 = ""world"";
 
#pragma warning disable 8321 // Unreferenced local function
        [A(s1)] // 1
        void local1() { }
 
        [A(nameof(s1))]
        void local2() { }
 
        [A(s2)]
        void local3() { }
 
        [A(s1.ToString())] // 2
        void local4() { }
 
        static string local5() => ""hello"";
 
        [A(local5())] // 3
        void local6() { }
    }
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (17,12): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
                //         [A(s1)] // 1
                Diagnostic(ErrorCode.ERR_BadAttributeArgument, "s1").WithLocation(17, 12),
                // (26,12): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
                //         [A(s1.ToString())] // 2
                Diagnostic(ErrorCode.ERR_BadAttributeArgument, "s1.ToString()").WithLocation(26, 12),
                // (31,12): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
                //         [A(local5())] // 3
                Diagnostic(ErrorCode.ERR_BadAttributeArgument, "local5()").WithLocation(31, 12));
 
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);
 
            var arg1 = (AttributeArgumentSyntax)tree.FindNodeOrTokenByKind(SyntaxKind.AttributeArgument, occurrence: 1).AsNode();
            Assert.Equal("System.String s1", model.GetSymbolInfo(arg1.Expression).Symbol.ToTestDisplayString());
            Assert.Equal(SpecialType.System_String, model.GetTypeInfo(arg1.Expression).Type.SpecialType);
 
            var arg2 = (AttributeArgumentSyntax)tree.FindNodeOrTokenByKind(SyntaxKind.AttributeArgument, occurrence: 2).AsNode();
            Assert.Null(model.GetSymbolInfo(arg2.Expression).Symbol);
            Assert.Equal(SpecialType.System_String, model.GetTypeInfo(arg2.Expression).Type.SpecialType);
 
            var arg3 = (AttributeArgumentSyntax)tree.FindNodeOrTokenByKind(SyntaxKind.AttributeArgument, occurrence: 3).AsNode();
            Assert.Equal("System.String s2", model.GetSymbolInfo(arg3.Expression).Symbol.ToTestDisplayString());
            Assert.Equal(SpecialType.System_String, model.GetTypeInfo(arg3.Expression).Type.SpecialType);
        }
 
        [Fact]
        public void LocalFunctionAttribute_OnFunction_DeclarationPattern()
        {
            const string text = @"
using System;
class A : Attribute
{
    internal A(bool b) { }
}
 
class C
{
    void M()
    {
#pragma warning disable 8321 // Unreferenced local function
        [A(42 is int i)] // 1
        void local1()
        {
            _ = i.ToString(); // 2
        }
 
        _ = i.ToString(); // 3
    }
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (13,12): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
                //         [A(42 is int i)] // 1
                Diagnostic(ErrorCode.ERR_BadAttributeArgument, "42 is int i").WithLocation(13, 12),
                // (16,17): error CS0103: The name 'i' does not exist in the current context
                //             _ = i.ToString(); // 2
                Diagnostic(ErrorCode.ERR_NameNotInContext, "i").WithArguments("i").WithLocation(16, 17),
                // (19,13): error CS0103: The name 'i' does not exist in the current context
                //         _ = i.ToString(); // 3
                Diagnostic(ErrorCode.ERR_NameNotInContext, "i").WithArguments("i").WithLocation(19, 13));
 
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);
 
            var arg = (AttributeArgumentSyntax)tree.FindNodeOrTokenByKind(SyntaxKind.AttributeArgument, occurrence: 1).AsNode();
            Assert.Null(model.GetSymbolInfo(arg.Expression).Symbol);
            Assert.Equal(SpecialType.System_Boolean, model.GetTypeInfo(arg.Expression).Type.SpecialType);
 
            var decl = (DeclarationPatternSyntax)tree.FindNodeOrTokenByKind(SyntaxKind.DeclarationPattern, occurrence: 1).AsNode();
            Assert.Equal("System.Int32 i", model.GetDeclaredSymbol(decl.Designation).ToTestDisplayString());
        }
 
        [Fact]
        public void LocalFunctionAttribute_OnFunction_OutVarInCall()
        {
            const string text = @"
using System;
class A : Attribute
{
    internal A(bool b) { }
}
 
class C
{
    void M1()
    {
#pragma warning disable 8321 // Unreferenced local function
        [A(M2(out var i))] // 1
        void local1()
        {
            _ = i.ToString(); // 2
        }
 
        _ = i.ToString(); // 3
    }
 
    static bool M2(out int x)
    {
        x = 0;
        return false;
    }
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (13,12): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
                //         [A(M2(out var i))] // 1
                Diagnostic(ErrorCode.ERR_BadAttributeArgument, "M2(out var i)").WithLocation(13, 12),
                // (16,17): error CS0103: The name 'i' does not exist in the current context
                //             _ = i.ToString(); // 2
                Diagnostic(ErrorCode.ERR_NameNotInContext, "i").WithArguments("i").WithLocation(16, 17),
                // (19,13): error CS0103: The name 'i' does not exist in the current context
                //         _ = i.ToString(); // 3
                Diagnostic(ErrorCode.ERR_NameNotInContext, "i").WithArguments("i").WithLocation(19, 13));
 
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);
 
            var arg = (AttributeArgumentSyntax)tree.FindNodeOrTokenByKind(SyntaxKind.AttributeArgument, occurrence: 1).AsNode();
            Assert.Equal("System.Boolean C.M2(out System.Int32 x)", model.GetSymbolInfo(arg.Expression).Symbol.ToTestDisplayString());
            Assert.Equal(SpecialType.System_Boolean, model.GetTypeInfo(arg.Expression).Type.SpecialType);
 
            var decl = (DeclarationExpressionSyntax)tree.FindNodeOrTokenByKind(SyntaxKind.DeclarationExpression, occurrence: 1).AsNode();
            Assert.Equal("System.Int32 i", model.GetDeclaredSymbol(decl.Designation).ToTestDisplayString());
        }
 
        [Fact]
        public void LocalFunctionAttribute_OutParam()
        {
            const string text = @"
using System;
class A : Attribute
{
    internal A(out string s) { s = ""a""; }
}
 
class C
{
    void M()
    {
#pragma warning disable 8321, 0168 // Unreferenced local
        string s;
 
        [A(out s)]
        void local1() { }
 
        [A(out var s)]
        void local2() { }
    }
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (15,12): error CS1041: Identifier expected; 'out' is a keyword
                //         [A(out s)]
                Diagnostic(ErrorCode.ERR_IdentifierExpectedKW, "out").WithArguments("", "out").WithLocation(15, 12),
                // (15,16): error CS1620: Argument 1 must be passed with the 'out' keyword
                //         [A(out s)]
                Diagnostic(ErrorCode.ERR_BadArgRef, "s").WithArguments("1", "out").WithLocation(15, 16),
                // (18,10): error CS1729: 'A' does not contain a constructor that takes 2 arguments
                //         [A(out var s)]
                Diagnostic(ErrorCode.ERR_BadCtorArgCount, "A(out var s)").WithArguments("A", "2").WithLocation(18, 10),
                // (18,12): error CS1041: Identifier expected; 'out' is a keyword
                //         [A(out var s)]
                Diagnostic(ErrorCode.ERR_IdentifierExpectedKW, "out").WithArguments("", "out").WithLocation(18, 12),
                // (18,16): error CS0103: The name 'var' does not exist in the current context
                //         [A(out var s)]
                Diagnostic(ErrorCode.ERR_NameNotInContext, "var").WithArguments("var").WithLocation(18, 16),
                // (18,20): error CS1003: Syntax error, ',' expected
                //         [A(out var s)]
                Diagnostic(ErrorCode.ERR_SyntaxError, "s").WithArguments(",").WithLocation(18, 20));
        }
 
        [Fact]
        public void LocalFunctionAttribute_Return()
        {
            const string text = @"
using System;
class A : Attribute { }
 
class C
{
    void M()
    {
        [return: A]
        int local() => 42;
    }
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (10,13): warning CS8321: The local function 'local' is declared but never used
                //         int local() => 42;
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "local").WithArguments("local").WithLocation(10, 13));
 
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);
 
            var localFunction = tree.GetRoot().DescendantNodes()
                .OfType<LocalFunctionStatementSyntax>()
                .Single();
 
            var attributeList = localFunction.AttributeLists.Single();
            Assert.Equal(SyntaxKind.ReturnKeyword, attributeList.Target.Identifier.Kind());
 
            var attribute = attributeList.Attributes.Single();
            Assert.Equal("A", ((SimpleNameSyntax)attribute.Name).Identifier.ValueText);
 
            var symbol = (IMethodSymbol)model.GetDeclaredSymbol(localFunction);
            Assert.NotNull(symbol);
 
            var returnAttributes = symbol.GetReturnTypeAttributes();
            var attributeData = returnAttributes.Single();
            var aAttribute = comp.GetTypeByMetadataName("A");
            Assert.Equal(aAttribute, attributeData.AttributeClass.GetSymbol());
            Assert.Equal(aAttribute.InstanceConstructors.Single(), attributeData.AttributeConstructor.GetSymbol());
 
            var attributes = symbol.GetAttributes();
            Assert.Empty(attributes);
        }
 
        [Fact]
        public void LocalFunctionAttribute_Parameter()
        {
            var source = @"
using System;
class A : Attribute { }
 
class C
{
    void M()
    {
        int local([A] int i) => i;
    }
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                    // (9,13): warning CS8321: The local function 'local' is declared but never used
                    //         int local([A] int i) => i;
                    Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "local").WithArguments("local").WithLocation(9, 13));
 
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);
 
            var localFunction = tree.GetRoot().DescendantNodes().OfType<LocalFunctionStatementSyntax>().Single();
            var parameter = localFunction.ParameterList.Parameters.Single();
            var paramSymbol = model.GetDeclaredSymbol(parameter);
 
            var attrs = paramSymbol.GetAttributes();
            var attr = attrs.Single();
            Assert.Equal(comp.GetTypeByMetadataName("A"), attr.AttributeClass.GetSymbol());
        }
 
        [Fact]
        public void LocalFunctionAttribute_LangVersionError()
        {
            const string text = @"
using System;
class A : Attribute { }
 
class C
{
    void M()
    {
#pragma warning disable 8321 // Unreferenced local function
        [A]
        void local1() { }
 
        [return: A]
        void local2() { }
 
        void local3([A] int i) { }
 
        void local4<[A] T>() { }
    }
}
";
 
            var comp = CreateCompilation(text, parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (10,9): error CS8400: Feature 'local function attributes' is not available in C# 8.0. Please use language version 9.0 or greater.
                //         [A]
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "[A]").WithArguments("local function attributes", "9.0").WithLocation(10, 9),
                // (13,9): error CS8400: Feature 'local function attributes' is not available in C# 8.0. Please use language version 9.0 or greater.
                //         [return: A]
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "[return: A]").WithArguments("local function attributes", "9.0").WithLocation(13, 9),
                // (16,21): error CS8400: Feature 'local function attributes' is not available in C# 8.0. Please use language version 9.0 or greater.
                //         void local3([A] int i) { }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "[A]").WithArguments("local function attributes", "9.0").WithLocation(16, 21),
                // (18,21): error CS8400: Feature 'local function attributes' is not available in C# 8.0. Please use language version 9.0 or greater.
                //         void local4<[A] T>() { }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "[A]").WithArguments("local function attributes", "9.0").WithLocation(18, 21));
 
            comp = CreateCompilation(text, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void LocalFunctionAttribute_BadAttributeLocation()
        {
            const string text = @"
using System;
 
[AttributeUsage(AttributeTargets.Property)]
class PropAttribute : Attribute { }
 
[AttributeUsage(AttributeTargets.Method)]
class MethodAttribute : Attribute { }
 
[AttributeUsage(AttributeTargets.ReturnValue)]
class ReturnAttribute : Attribute { }
 
[AttributeUsage(AttributeTargets.Parameter)]
class ParamAttribute : Attribute { }
 
[AttributeUsage(AttributeTargets.GenericParameter)]
class TypeParamAttribute : Attribute { }
 
public class C {
    public void M() {
#pragma warning disable 8321 // Unreferenced local function
        [Prop] // 1
        [Return] // 2
        [Method]
        [return: Prop] // 3
        [return: Return]
        [return: Method] // 4
        void local<
            [Param] // 5
            [TypeParam]
            T>(
            [Param]
            [TypeParam] // 6
            T t) { }
    }
}
";
 
            var comp = CreateCompilation(text, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (22,10): error CS0592: Attribute 'Prop' is not valid on this declaration type. It is only valid on 'property, indexer' declarations.
                //         [Prop] // 1
                Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "Prop").WithArguments("Prop", "property, indexer").WithLocation(22, 10),
                // (23,10): error CS0592: Attribute 'Return' is not valid on this declaration type. It is only valid on 'return' declarations.
                //         [Return] // 2
                Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "Return").WithArguments("Return", "return").WithLocation(23, 10),
                // (25,18): error CS0592: Attribute 'Prop' is not valid on this declaration type. It is only valid on 'property, indexer' declarations.
                //         [return: Prop] // 3
                Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "Prop").WithArguments("Prop", "property, indexer").WithLocation(25, 18),
                // (27,18): error CS0592: Attribute 'Method' is not valid on this declaration type. It is only valid on 'method' declarations.
                //         [return: Method] // 4
                Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "Method").WithArguments("Method", "method").WithLocation(27, 18),
                // (29,14): error CS0592: Attribute 'Param' is not valid on this declaration type. It is only valid on 'parameter' declarations.
                //             [Param] // 5
                Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "Param").WithArguments("Param", "parameter").WithLocation(29, 14),
                // (33,14): error CS0592: Attribute 'TypeParam' is not valid on this declaration type. It is only valid on 'type parameter' declarations.
                //             [TypeParam] // 6
                Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "TypeParam").WithArguments("TypeParam", "type parameter").WithLocation(33, 14));
 
            var tree = comp.SyntaxTrees.Single();
            var localFunction = tree.GetRoot().DescendantNodes().OfType<LocalFunctionStatementSyntax>().Single();
            var model = comp.GetSemanticModel(tree);
 
            var symbol = (IMethodSymbol)model.GetDeclaredSymbol(localFunction);
            Assert.NotNull(symbol);
 
            var attributes = symbol.GetAttributes();
            Assert.Equal(3, attributes.Length);
            Assert.Equal(comp.GetTypeByMetadataName("PropAttribute"), attributes[0].AttributeClass.GetSymbol());
            Assert.Equal(comp.GetTypeByMetadataName("ReturnAttribute"), attributes[1].AttributeClass.GetSymbol());
            Assert.Equal(comp.GetTypeByMetadataName("MethodAttribute"), attributes[2].AttributeClass.GetSymbol());
 
            var returnAttributes = symbol.GetReturnTypeAttributes();
            Assert.Equal(3, returnAttributes.Length);
            Assert.Equal(comp.GetTypeByMetadataName("PropAttribute"), returnAttributes[0].AttributeClass.GetSymbol());
            Assert.Equal(comp.GetTypeByMetadataName("ReturnAttribute"), returnAttributes[1].AttributeClass.GetSymbol());
            Assert.Equal(comp.GetTypeByMetadataName("MethodAttribute"), returnAttributes[2].AttributeClass.GetSymbol());
        }
 
        [Fact]
        public void LocalFunctionAttribute_AttributeSemanticModel()
        {
            const string text = @"
using System;
class A : Attribute { }
 
class C
{
    void M()
    {
        local1();
        local2();
        local3(0);
        local4<object>();
 
        [A]
        void local1() { }
 
        [return: A]
        void local2() { }
 
        void local3([A] int i) { }
 
        void local4<[A] T>() { }
    }
}
";
 
            var comp = CreateCompilation(text, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics();
 
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);
 
            var attributeSyntaxes = tree.GetRoot().DescendantNodes().OfType<AttributeSyntax>().ToList();
            Assert.Equal(4, attributeSyntaxes.Count);
 
            var attributeConstructor = comp.GetTypeByMetadataName("A").InstanceConstructors.Single();
            foreach (var attributeSyntax in attributeSyntaxes)
            {
                var symbol = model.GetSymbolInfo(attributeSyntax).Symbol.GetSymbol<MethodSymbol>();
                Assert.Equal(attributeConstructor, symbol);
            }
        }
 
        [Fact]
        public void StatementAttributeSemanticModel()
        {
            const string text = @"
using System;
 
class A : Attribute { }
 
class C
{
    void M()
    {
#pragma warning disable 219 // The variable '{0}' is assigned but its value is never used
        [A] int i = 0;
    }
}
";
            var comp = CreateCompilation(text);
 
            comp.VerifyDiagnostics(
                // (11,9): error CS7014: Attributes are not valid in this context.
                //         [A] int i = 0;
                Diagnostic(ErrorCode.ERR_AttributesNotAllowed, "[A]").WithLocation(11, 9));
 
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);
 
            var attrSyntax = tree.GetRoot().DescendantNodes().OfType<AttributeSyntax>().Single();
            var attrConstructor = (IMethodSymbol)model.GetSymbolInfo(attrSyntax).Symbol;
 
            Assert.Equal(MethodKind.Constructor, attrConstructor.MethodKind);
            Assert.Equal("A", attrConstructor.ContainingType.Name);
        }
 
        [Fact]
        public void LocalFunctionNoBody()
        {
            const string text = @"
class C
{
    void M()
    {
        local1();
 
        void local1();
    }
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (8,14): error CS8112: Local function 'local1()' must either have a body or be marked 'static extern'.
                //         void local1();
                Diagnostic(ErrorCode.ERR_LocalFunctionMissingBody, "local1").WithArguments("local1()").WithLocation(8, 14));
        }
 
        [Fact]
        public void LocalFunctionExtern()
        {
            const string text = @"
using System.Runtime.InteropServices;
 
class C
{
    void M()
    {
#pragma warning disable 8321 // Unreferenced local function
 
        [DllImport(""a"")] extern void local1(); // 1, 2
        [DllImport(""a"")] extern void local2() { } // 3, 4
        [DllImport(""a"")] extern int local3() => 0; // 5, 6
 
        static void local4(); // 7
        static void local5() { }
        static int local6() => 0;
 
        [DllImport(""a"")] static extern void local7();
        [DllImport(""a"")] static extern void local8() { } // 8
        [DllImport(""a"")] static extern int local9() => 0; // 9
 
        [DllImport(""a"")] extern static void local10();
        [DllImport(""a"")] extern static void local11() { } // 10
        [DllImport(""a"")] extern static int local12() => 0; // 11
    }
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (10,10): error CS0601: The DllImport attribute must be specified on a method marked 'static' and 'extern'
                //         [DllImport("a")] extern void local1(); // 1, 2
                Diagnostic(ErrorCode.ERR_DllImportOnInvalidMethod, "DllImport").WithLocation(10, 10),
                // (10,38): error CS8112: Local function 'local1()' must either have a body or be marked 'static extern'.
                //         [DllImport("a")] extern void local1(); // 1, 2
                Diagnostic(ErrorCode.ERR_LocalFunctionMissingBody, "local1").WithArguments("local1()").WithLocation(10, 38),
                // (11,10): error CS0601: The DllImport attribute must be specified on a method marked 'static' and 'extern'
                //         [DllImport("a")] extern void local2() { } // 3, 4
                Diagnostic(ErrorCode.ERR_DllImportOnInvalidMethod, "DllImport").WithLocation(11, 10),
                // (11,38): error CS0179: 'local2()' cannot be extern and declare a body
                //         [DllImport("a")] extern void local2() { } // 3, 4
                Diagnostic(ErrorCode.ERR_ExternHasBody, "local2").WithArguments("local2()").WithLocation(11, 38),
                // (12,10): error CS0601: The DllImport attribute must be specified on a method marked 'static' and 'extern'
                //         [DllImport("a")] extern int local3() => 0; // 5, 6
                Diagnostic(ErrorCode.ERR_DllImportOnInvalidMethod, "DllImport").WithLocation(12, 10),
                // (12,37): error CS0179: 'local3()' cannot be extern and declare a body
                //         [DllImport("a")] extern int local3() => 0; // 5, 6
                Diagnostic(ErrorCode.ERR_ExternHasBody, "local3").WithArguments("local3()").WithLocation(12, 37),
                // (14,21): error CS8112: Local function 'local4()' must either have a body or be marked 'static extern'.
                //         static void local4(); // 7
                Diagnostic(ErrorCode.ERR_LocalFunctionMissingBody, "local4").WithArguments("local4()").WithLocation(14, 21),
                // (19,45): error CS0179: 'local8()' cannot be extern and declare a body
                //         [DllImport("a")] static extern void local8() { } // 8
                Diagnostic(ErrorCode.ERR_ExternHasBody, "local8").WithArguments("local8()").WithLocation(19, 45),
                // (20,44): error CS0179: 'local9()' cannot be extern and declare a body
                //         [DllImport("a")] static extern int local9() => 0; // 9
                Diagnostic(ErrorCode.ERR_ExternHasBody, "local9").WithArguments("local9()").WithLocation(20, 44),
                // (23,45): error CS0179: 'local11()' cannot be extern and declare a body
                //         [DllImport("a")] extern static void local11() { } // 10
                Diagnostic(ErrorCode.ERR_ExternHasBody, "local11").WithArguments("local11()").WithLocation(23, 45),
                // (24,44): error CS0179: 'local12()' cannot be extern and declare a body
                //         [DllImport("a")] extern static int local12() => 0; // 11
                Diagnostic(ErrorCode.ERR_ExternHasBody, "local12").WithArguments("local12()").WithLocation(24, 44));
        }
 
        [Fact]
        public void LocalFunctionExtern_Generic()
        {
            var source = @"
using System;
using System.Runtime.InteropServices;
 
class C
{
#pragma warning disable 8321 // Unreferenced local function
 
    void M()
    {
        [DllImport(""a"")] extern static void local1();
        [DllImport(""a"")] extern static void local2<T>(); // 1
 
        void local3()
        {
            [DllImport(""a"")] extern static void local1();
            [DllImport(""a"")] extern static void local2<T2>(); // 2
        }
 
        void local4<T4>()
        {
            [DllImport(""a"")] extern static void local1(); // 3
            [DllImport(""a"")] extern static void local2<T2>(); // 4
        }
 
        Action a = () =>
        {
            [DllImport(""a"")] extern static void local1();
            [DllImport(""a"")] extern static void local2<T>(); // 5
 
            void local3()
            {
                [DllImport(""a"")] extern static void local1();
                [DllImport(""a"")] extern static void local2<T2>(); // 6
            }
 
            void local4<T4>()
            {
                [DllImport(""a"")] extern static void local1(); // 7
                [DllImport(""a"")] extern static void local2<T2>(); // 8
            }
        };
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (12,10): error CS7042: The DllImport attribute cannot be applied to a method that is generic or contained in a generic method or type.
                //         [DllImport("a")] extern static void local2<T>(); // 1
                Diagnostic(ErrorCode.ERR_DllImportOnGenericMethod, "DllImport").WithLocation(12, 10),
                // (17,14): error CS7042: The DllImport attribute cannot be applied to a method that is generic or contained in a generic method or type.
                //             [DllImport("a")] extern static void local2<T2>(); // 2
                Diagnostic(ErrorCode.ERR_DllImportOnGenericMethod, "DllImport").WithLocation(17, 14),
                // (22,14): error CS7042: The DllImport attribute cannot be applied to a method that is generic or contained in a generic method or type.
                //             [DllImport("a")] extern static void local1(); // 3
                Diagnostic(ErrorCode.ERR_DllImportOnGenericMethod, "DllImport").WithLocation(22, 14),
                // (23,14): error CS7042: The DllImport attribute cannot be applied to a method that is generic or contained in a generic method or type.
                //             [DllImport("a")] extern static void local2<T2>(); // 4
                Diagnostic(ErrorCode.ERR_DllImportOnGenericMethod, "DllImport").WithLocation(23, 14),
                // (29,14): error CS7042: The DllImport attribute cannot be applied to a method that is generic or contained in a generic method or type.
                //             [DllImport("a")] extern static void local2<T>(); // 5
                Diagnostic(ErrorCode.ERR_DllImportOnGenericMethod, "DllImport").WithLocation(29, 14),
                // (34,18): error CS7042: The DllImport attribute cannot be applied to a method that is generic or contained in a generic method or type.
                //                 [DllImport("a")] extern static void local2<T2>(); // 6
                Diagnostic(ErrorCode.ERR_DllImportOnGenericMethod, "DllImport").WithLocation(34, 18),
                // (39,18): error CS7042: The DllImport attribute cannot be applied to a method that is generic or contained in a generic method or type.
                //                 [DllImport("a")] extern static void local1(); // 7
                Diagnostic(ErrorCode.ERR_DllImportOnGenericMethod, "DllImport").WithLocation(39, 18),
                // (40,18): error CS7042: The DllImport attribute cannot be applied to a method that is generic or contained in a generic method or type.
                //                 [DllImport("a")] extern static void local2<T2>(); // 8
                Diagnostic(ErrorCode.ERR_DllImportOnGenericMethod, "DllImport").WithLocation(40, 18));
        }
 
        [Theory]
        [InlineData("<CT>", "", "")]
        [InlineData("", "<MT>", "")]
        [InlineData("", "", "<LT>")]
        public void LocalFunctionExtern_Generic_GenericMembers(string classTypeParams, string methodTypeParams, string localFunctionTypeParams)
        {
            var source = $@"
using System;
using System.Runtime.InteropServices;
 
class C{classTypeParams}
{{
#pragma warning disable 8321 // Unreferenced local function
 
    void M{methodTypeParams}()
    {{
        void localOuter{localFunctionTypeParams}()
        {{
            [DllImport(""a"")] extern static void local1(); // 1
            [DllImport(""a"")] extern static void local2<T>(); // 2
 
            void local3()
            {{
                [DllImport(""a"")] extern static void local1(); // 3
                [DllImport(""a"")] extern static void local2<T2>(); // 4
            }}
 
            void local4<T4>()
            {{
                [DllImport(""a"")] extern static void local1(); // 5
                [DllImport(""a"")] extern static void local2<T2>(); // 6
            }}
 
            Action a = () =>
            {{
                [DllImport(""a"")] extern static void local1(); // 7
                [DllImport(""a"")] extern static void local2<T>(); // 8
 
                void local3()
                {{
                    [DllImport(""a"")] extern static void local1(); // 9
                    [DllImport(""a"")] extern static void local2<T2>(); // 10
                }}
 
                void local4<T4>()
                {{
                    [DllImport(""a"")] extern static void local1(); // 11
                    [DllImport(""a"")] extern static void local2<T2>(); // 12
                }}
            }};
        }}
    }}
}}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (13,14): error CS7042: The DllImport attribute cannot be applied to a method that is generic or contained in a generic method or type.
                //             [DllImport("a")] extern static void local1(); // 1
                Diagnostic(ErrorCode.ERR_DllImportOnGenericMethod, "DllImport").WithLocation(13, 14),
                // (14,14): error CS7042: The DllImport attribute cannot be applied to a method that is generic or contained in a generic method or type.
                //             [DllImport("a")] extern static void local2<T>(); // 2
                Diagnostic(ErrorCode.ERR_DllImportOnGenericMethod, "DllImport").WithLocation(14, 14),
                // (18,18): error CS7042: The DllImport attribute cannot be applied to a method that is generic or contained in a generic method or type.
                //                 [DllImport("a")] extern static void local1(); // 3
                Diagnostic(ErrorCode.ERR_DllImportOnGenericMethod, "DllImport").WithLocation(18, 18),
                // (19,18): error CS7042: The DllImport attribute cannot be applied to a method that is generic or contained in a generic method or type.
                //                 [DllImport("a")] extern static void local2<T2>(); // 4
                Diagnostic(ErrorCode.ERR_DllImportOnGenericMethod, "DllImport").WithLocation(19, 18),
                // (24,18): error CS7042: The DllImport attribute cannot be applied to a method that is generic or contained in a generic method or type.
                //                 [DllImport("a")] extern static void local1(); // 5
                Diagnostic(ErrorCode.ERR_DllImportOnGenericMethod, "DllImport").WithLocation(24, 18),
                // (25,18): error CS7042: The DllImport attribute cannot be applied to a method that is generic or contained in a generic method or type.
                //                 [DllImport("a")] extern static void local2<T2>(); // 6
                Diagnostic(ErrorCode.ERR_DllImportOnGenericMethod, "DllImport").WithLocation(25, 18),
                // (30,18): error CS7042: The DllImport attribute cannot be applied to a method that is generic or contained in a generic method or type.
                //                 [DllImport("a")] extern static void local1(); // 7
                Diagnostic(ErrorCode.ERR_DllImportOnGenericMethod, "DllImport").WithLocation(30, 18),
                // (31,18): error CS7042: The DllImport attribute cannot be applied to a method that is generic or contained in a generic method or type.
                //                 [DllImport("a")] extern static void local2<T>(); // 8
                Diagnostic(ErrorCode.ERR_DllImportOnGenericMethod, "DllImport").WithLocation(31, 18),
                // (35,22): error CS7042: The DllImport attribute cannot be applied to a method that is generic or contained in a generic method or type.
                //                     [DllImport("a")] extern static void local1(); // 9
                Diagnostic(ErrorCode.ERR_DllImportOnGenericMethod, "DllImport").WithLocation(35, 22),
                // (36,22): error CS7042: The DllImport attribute cannot be applied to a method that is generic or contained in a generic method or type.
                //                     [DllImport("a")] extern static void local2<T2>(); // 10
                Diagnostic(ErrorCode.ERR_DllImportOnGenericMethod, "DllImport").WithLocation(36, 22),
                // (41,22): error CS7042: The DllImport attribute cannot be applied to a method that is generic or contained in a generic method or type.
                //                     [DllImport("a")] extern static void local1(); // 11
                Diagnostic(ErrorCode.ERR_DllImportOnGenericMethod, "DllImport").WithLocation(41, 22),
                // (42,22): error CS7042: The DllImport attribute cannot be applied to a method that is generic or contained in a generic method or type.
                //                     [DllImport("a")] extern static void local2<T2>(); // 12
                Diagnostic(ErrorCode.ERR_DllImportOnGenericMethod, "DllImport").WithLocation(42, 22));
        }
 
        [Fact]
        public void LocalFunctionExtern_NoImplementationWarning_Attribute()
        {
            const string text = @"
using System.Runtime.InteropServices;
 
class Attr : System.Attribute { }
 
class C
{
    void M()
    {
#pragma warning disable 8321 // Unreferenced local function
 
        static extern void local1(); // 1
        static extern void local2() { } // 2
 
        [DllImport(""a"")]
        static extern void local3();
 
        [Attr]
        static extern void local4();
    }
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (12,28): warning CS0626: Method, operator, or accessor 'local1()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation.
                //         static extern void local1(); // 1
                Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "local1").WithArguments("local1()").WithLocation(12, 28),
                // (13,28): error CS0179: 'local2()' cannot be extern and declare a body
                //         static extern void local2() { } // 2
                Diagnostic(ErrorCode.ERR_ExternHasBody, "local2").WithArguments("local2()").WithLocation(13, 28));
        }
 
        [Fact]
        public void LocalFunctionExtern_Errors()
        {
            const string text = @"
class C
{
#pragma warning disable 8321 // Unreferenced local function
 
    void M1()
    {
        void local1(); // 1
        static extern void local1(); // 2, 3
    }
 
    void M2()
    {
        void local1(); // 4
        static extern void local1() { } // 5
    }
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (8,14): error CS8112: Local function 'local1()' must either have a body or be marked 'static extern'.
                //         void local1(); // 1
                Diagnostic(ErrorCode.ERR_LocalFunctionMissingBody, "local1").WithArguments("local1()").WithLocation(8, 14),
                // (9,28): error CS0128: A local variable or function named 'local1' is already defined in this scope
                //         static extern void local1(); // 2, 3
                Diagnostic(ErrorCode.ERR_LocalDuplicate, "local1").WithArguments("local1").WithLocation(9, 28),
                // (9,28): warning CS0626: Method, operator, or accessor 'local1()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation.
                //         static extern void local1(); // 2, 3
                Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "local1").WithArguments("local1()").WithLocation(9, 28),
                // (14,14): error CS8112: Local function 'local1()' must either have a body or be marked 'static extern'.
                //         void local1(); // 4
                Diagnostic(ErrorCode.ERR_LocalFunctionMissingBody, "local1").WithArguments("local1()").WithLocation(14, 14),
                // (15,28): error CS0128: A local variable or function named 'local1' is already defined in this scope
                //         static extern void local1() { } // 5
                Diagnostic(ErrorCode.ERR_LocalDuplicate, "local1").WithArguments("local1").WithLocation(15, 28));
        }
 
        [Fact]
        public void ComImport_Class()
        {
            const string text = @"
using System;
using System.Runtime.InteropServices;
 
[ComImport, Guid(""00020813-0000-0000-c000-000000000046"")]
class C
{
    void M() // 1
    {
#pragma warning disable 8321 // Unreferenced local function
        void local1() { }
    }
}
";
            var comp = CreateCompilation(text);
            comp.VerifyDiagnostics(
                // (8,10): error CS0423: Since 'C' has the ComImport attribute, 'C.M()' must be extern or abstract
                //     void M() // 1
                Diagnostic(ErrorCode.ERR_ComImportWithImpl, "M").WithArguments("C.M()", "C").WithLocation(8, 10));
        }
 
        [Fact]
        public void UnsafeLocal()
        {
            var source = @"
class C
{
    void M()
    {
        var bytesA = local();
 
        unsafe byte[] local()
        {
            var bytes = new byte[sizeof(int)];
            fixed (byte* ptr = &bytes[0])
            {
                *(int*)ptr = sizeof(int);
            }
            return bytes;
        }
    }
}";
 
            var comp = CreateCompilation(source);
            Assert.Empty(comp.GetDeclarationDiagnostics());
            comp.VerifyDiagnostics(
                // (8,23): error CS0227: Unsafe code may only appear if compiling with /unsafe
                //         unsafe byte[] local()
                Diagnostic(ErrorCode.ERR_IllegalUnsafe, "local").WithLocation(8, 23)
                );
 
            var compWithUnsafe = CreateCompilation(source, options: TestOptions.UnsafeDebugDll);
            compWithUnsafe.VerifyDiagnostics();
        }
 
        [Fact]
        public void LocalInUnsafeStruct()
        {
            var source = @"
unsafe struct C
{
    void A()
    {
        var bytesA = local();
        var bytesB = B();
 
        byte[] local()
        {
            var bytes = new byte[sizeof(int)];
            fixed (byte* ptr = &bytes[0])
            {
                *(int*)ptr = sizeof(int);
            }
            return bytes;
        }
    }
 
    byte[] B()
    {
        var bytes = new byte[sizeof(long)];
        fixed (byte* ptr = &bytes[0])
        {
            *(long*)ptr = sizeof(long);
        }
        return bytes;
    }
}";
            // no need to declare local function `local` or method `B` as unsafe
            var compWithUnsafe = CreateCompilation(source, options: TestOptions.UnsafeDebugDll);
            compWithUnsafe.VerifyDiagnostics();
        }
 
        [Fact]
        public void LocalInUnsafeBlock()
        {
            var source = @"
struct C
{
    void A()
    {
        unsafe
        {
            var bytesA = local();
 
            byte[] local()
            {
                var bytes = new byte[sizeof(int)];
                fixed (byte* ptr = &bytes[0])
                {
                    *(int*)ptr = sizeof(int);
                }
                return bytes;
            }
        }
    }
}";
            // no need to declare local function `local` as unsafe
            var compWithUnsafe = CreateCompilation(source, options: TestOptions.UnsafeDebugDll);
            compWithUnsafe.VerifyDiagnostics();
        }
 
        [Fact]
        public void ConstraintBinding()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        void Local<T, U>()
            where T : U
            where U : class
        { }
 
        Local<object, object>();
    }
}");
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void ConstraintBinding2()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        void Local<T, U>(T t)
            where T : U
            where U : t
        { }
 
        Local<object, object>(null);
    }
}");
            comp.VerifyDiagnostics(
                // (8,23): error CS0246: The type or namespace name 't' could not be found (are you missing a using directive or an assembly reference?)
                //             where U : t
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "t").WithArguments("t").WithLocation(8, 23),
                // (11,9): error CS0311: The type 'object' cannot be used as type parameter 'U' in the generic type or method 'Local<T, U>(T)'. There is no implicit reference conversion from 'object' to 't'.
                //         Local<object, object>(null);
                Diagnostic(ErrorCode.ERR_GenericConstraintNotSatisfiedRefType, "Local<object, object>").WithArguments("Local<T, U>(T)", "t", "U", "object").WithLocation(11, 9));
        }
 
        [Fact]
        [WorkItem(17014, "https://github.com/dotnet/roslyn/pull/17014")]
        public void RecursiveLocalFuncsAsParameterTypes()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        int L(L2 l2) => 0;
        int L2(L l1) => 0;
    }
}");
            comp.VerifyDiagnostics(
                // (6,15): error CS0246: The type or namespace name 'L2' could not be found (are you missing a using directive or an assembly reference?)
                //         int L(L2 l2) => 0;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "L2").WithArguments("L2").WithLocation(6, 15),
                // (7,16): error CS0246: The type or namespace name 'L' could not be found (are you missing a using directive or an assembly reference?)
                //         int L2(L l1) => 0;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "L").WithArguments("L").WithLocation(7, 16),
                // (6,13): warning CS8321: The local function 'L' is declared but never used
                //         int L(L2 l2) => 0;
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "L").WithArguments("L").WithLocation(6, 13),
                // (7,13): warning CS8321: The local function 'L2' is declared but never used
                //         int L2(L l1) => 0;
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "L2").WithArguments("L2").WithLocation(7, 13));
        }
 
        [Fact]
        [WorkItem(16451, "https://github.com/dotnet/roslyn/issues/16451")]
        public void BadGenericConstraint()
        {
            var comp = CreateCompilation(@"
class C
{
    public void M<T>(T value) where T : class, object { }
}");
            comp.VerifyDiagnostics(
                // (4,48): error CS0702: Constraint cannot be special class 'object'
                //     public void M<T>(T value) where T : class, object { }
                Diagnostic(ErrorCode.ERR_SpecialTypeAsBound, "object").WithArguments("object").WithLocation(4, 48)
                );
        }
 
        [Fact]
        [WorkItem(16451, "https://github.com/dotnet/roslyn/issues/16451")]
        public void RecursiveDefaultParameter()
        {
            var comp = CreateCompilation(@"
class C
{
    public static void Main()
    {
        int Local(int j = Local()) => 0;
        Local();
    }
}");
            comp.VerifyDiagnostics(
                // (6,27): error CS1736: Default parameter value for 'j' must be a compile-time constant
                //         int Local(int j = Local()) => 0;
                Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "Local()").WithArguments("j").WithLocation(6, 27));
            comp.DeclarationDiagnostics.Verify();
        }
 
        [Fact]
        [WorkItem(16451, "https://github.com/dotnet/roslyn/issues/16451")]
        public void RecursiveDefaultParameter2()
        {
            var comp = CreateCompilation(@"
using System;
class C
{
    void M()
    {
        int Local(Action a = Local) => 0;
        Local();
    }
}");
            comp.VerifyDiagnostics(
                // (7,30): error CS1736: Default parameter value for 'a' must be a compile-time constant
                //         int Local(Action a = Local) => 0;
                Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "Local").WithArguments("a").WithLocation(7, 30));
            comp.DeclarationDiagnostics.Verify();
        }
 
        [Fact]
        [WorkItem(16451, "https://github.com/dotnet/roslyn/issues/16451")]
        public void MutuallyRecursiveDefaultParameters()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        int Local1(int p = Local2()) => 0;
        int Local2(int p = Local1()) => 0;
        Local1();
        Local2();
    }
}");
            comp.VerifyDiagnostics(
                // (6,28): error CS1736: Default parameter value for 'p' must be a compile-time constant
                //         int Local1(int p = Local2()) => 0;
                Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "Local2()").WithArguments("p").WithLocation(6, 28),
                // (7,28): error CS1736: Default parameter value for 'p' must be a compile-time constant
                //         int Local2(int p = Local1()) => 0;
                Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "Local1()").WithArguments("p").WithLocation(7, 28));
            comp.DeclarationDiagnostics.Verify();
        }
 
        [Fact]
        public void FetchLocalFunctionSymbolThroughLocal()
        {
            var tree = SyntaxFactory.ParseSyntaxTree(@"
using System;
class C
{
    public void M()
    {
        void Local<[A, B, CLSCompliant, D]T>() 
        {
            var x = new object(); 
        }
        Local<int>();
    }
}");
            var comp = CreateCompilation(tree);
            comp.DeclarationDiagnostics.Verify();
 
            comp.VerifyDiagnostics(
                // (7,21): error CS0246: The type or namespace name 'AAttribute' could not be found (are you missing a using directive or an assembly reference?)
                //         void Local<[A, B, CLSCompliant, D]T>() 
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "A").WithArguments("AAttribute").WithLocation(7, 21),
                // (7,21): error CS0246: The type or namespace name 'A' could not be found (are you missing a using directive or an assembly reference?)
                //         void Local<[A, B, CLSCompliant, D]T>() 
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "A").WithArguments("A").WithLocation(7, 21),
                // (7,24): error CS0246: The type or namespace name 'BAttribute' could not be found (are you missing a using directive or an assembly reference?)
                //         void Local<[A, B, CLSCompliant, D]T>() 
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "B").WithArguments("BAttribute").WithLocation(7, 24),
                // (7,24): error CS0246: The type or namespace name 'B' could not be found (are you missing a using directive or an assembly reference?)
                //         void Local<[A, B, CLSCompliant, D]T>() 
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "B").WithArguments("B").WithLocation(7, 24),
                // (7,41): error CS0246: The type or namespace name 'DAttribute' could not be found (are you missing a using directive or an assembly reference?)
                //         void Local<[A, B, CLSCompliant, D]T>() 
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "D").WithArguments("DAttribute").WithLocation(7, 41),
                // (7,41): error CS0246: The type or namespace name 'D' could not be found (are you missing a using directive or an assembly reference?)
                //         void Local<[A, B, CLSCompliant, D]T>() 
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "D").WithArguments("D").WithLocation(7, 41),
                // (7,27): error CS7036: There is no argument given that corresponds to the required parameter 'isCompliant' of 'CLSCompliantAttribute.CLSCompliantAttribute(bool)'
                //         void Local<[A, B, CLSCompliant, D]T>() 
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "CLSCompliant").WithArguments("isCompliant", "System.CLSCompliantAttribute.CLSCompliantAttribute(bool)").WithLocation(7, 27));
 
            var model = comp.GetSemanticModel(tree);
 
            var x = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Where(v => v.Identifier.ValueText == "x").Single();
            var localSymbol = model.GetDeclaredSymbol(x).ContainingSymbol.GetSymbol<LocalFunctionSymbol>();
            var typeParam = localSymbol.TypeParameters.Single();
            var attrs = typeParam.GetAttributes();
 
            Assert.True(attrs[0].AttributeClass.IsErrorType());
            Assert.True(attrs[1].AttributeClass.IsErrorType());
            Assert.False(attrs[2].AttributeClass.IsErrorType());
            Assert.Equal(comp.GlobalNamespace
                             .GetMember<NamespaceSymbol>("System")
                             .GetMember<NamedTypeSymbol>("CLSCompliantAttribute"),
                attrs[2].AttributeClass);
            Assert.True(attrs[3].AttributeClass.IsErrorType());
            comp.DeclarationDiagnostics.Verify();
        }
 
        [Fact]
        public void TypeParameterAttributesInSemanticModel()
        {
            var comp = (Compilation)CreateCompilation(@"
using System;
class C
{
    public void M()
    {
        void Local<[A]T, [CLSCompliant]U>() { }
    }
}", parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (7,21): error CS0246: The type or namespace name 'AAttribute' could not be found (are you missing a using directive or an assembly reference?)
                //         void Local<[A]T, [CLSCompliant]U>() { }
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "A").WithArguments("AAttribute").WithLocation(7, 21),
                // (7,21): error CS0246: The type or namespace name 'A' could not be found (are you missing a using directive or an assembly reference?)
                //         void Local<[A]T, [CLSCompliant]U>() { }
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "A").WithArguments("A").WithLocation(7, 21),
                // (7,27): error CS7036: There is no argument given that corresponds to the required parameter 'isCompliant' of 'CLSCompliantAttribute.CLSCompliantAttribute(bool)'
                //         void Local<[A]T, [CLSCompliant]U>() { }
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "CLSCompliant").WithArguments("isCompliant", "System.CLSCompliantAttribute.CLSCompliantAttribute(bool)").WithLocation(7, 27),
                // (7,14): warning CS8321: The local function 'Local' is declared but never used
                //         void Local<[A]T, [CLSCompliant]U>() { }
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Local").WithArguments("Local").WithLocation(7, 14));
 
            var tree = comp.SyntaxTrees.First();
            var root = tree.GetRoot();
 
            var model = comp.GetSemanticModel(tree);
 
            var a = root.DescendantNodes()
                .OfType<IdentifierNameSyntax>()
                .Where(id => id.Identifier.ValueText == "A")
                .Single();
 
            Assert.Null(model.GetDeclaredSymbol(a));
 
            var aSymbolInfo = model.GetSymbolInfo(a);
            Assert.Equal(0, aSymbolInfo.CandidateSymbols.Length);
            Assert.Null(aSymbolInfo.Symbol);
 
            var aTypeInfo = model.GetTypeInfo(a);
            Assert.Equal(TypeKind.Error, aTypeInfo.Type.TypeKind);
 
            Assert.Null(model.GetAliasInfo(a));
 
            Assert.Empty(model.LookupNamespacesAndTypes(a.SpanStart, name: "A"));
 
            var clsCompliant = root.DescendantNodes()
                .OfType<IdentifierNameSyntax>()
                .Where(id => id.Identifier.ValueText == "CLSCompliant")
                .Single();
            var clsCompliantSymbol = comp.GlobalNamespace
                .GetMember<INamespaceSymbol>("System")
                .GetTypeMember("CLSCompliantAttribute");
 
            Assert.Null(model.GetDeclaredSymbol(clsCompliant));
 
            // This should be null because there is no CLSCompliant ctor with no args
            var clsCompliantSymbolInfo = model.GetSymbolInfo(clsCompliant);
            Assert.Null(clsCompliantSymbolInfo.Symbol);
            Assert.Equal(clsCompliantSymbol.GetMember<IMethodSymbol>(".ctor"),
                clsCompliantSymbolInfo.CandidateSymbols.Single());
            Assert.Equal(CandidateReason.OverloadResolutionFailure, clsCompliantSymbolInfo.CandidateReason);
 
            Assert.Equal(clsCompliantSymbol, model.GetTypeInfo(clsCompliant).Type);
 
            Assert.Null(model.GetAliasInfo(clsCompliant));
 
            Assert.Equal(clsCompliantSymbol,
                model.LookupNamespacesAndTypes(clsCompliant.SpanStart, name: "CLSCompliantAttribute").Single());
            ((CSharpCompilation)comp).DeclarationDiagnostics.Verify();
        }
 
        [Fact]
        public void ParameterAttributesInSemanticModel()
        {
            var comp = (Compilation)CreateCompilation(@"
using System;
class C
{
    public void M()
    {
        void Local([A]int x, [CLSCompliant]int y) { }
    }
}", parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (7,21): error CS0246: The type or namespace name 'AAttribute' could not be found (are you missing a using directive or an assembly reference?)
                //         void Local([A]int x, [CLSCompliant]int y) { }
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "A").WithArguments("AAttribute").WithLocation(7, 21),
                // (7,21): error CS0246: The type or namespace name 'A' could not be found (are you missing a using directive or an assembly reference?)
                //         void Local([A]int x, [CLSCompliant]int y) { }
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "A").WithArguments("A").WithLocation(7, 21),
                // (7,31): error CS7036: There is no argument given that corresponds to the required parameter 'isCompliant' of 'CLSCompliantAttribute.CLSCompliantAttribute(bool)'
                //         void Local([A]int x, [CLSCompliant]int y) { }
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "CLSCompliant").WithArguments("isCompliant", "System.CLSCompliantAttribute.CLSCompliantAttribute(bool)").WithLocation(7, 31),
                // (7,14): warning CS8321: The local function 'Local' is declared but never used
                //         void Local([A]int x, [CLSCompliant]int y) { }
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Local").WithArguments("Local").WithLocation(7, 14));
 
            var tree = comp.SyntaxTrees.First();
            var root = tree.GetRoot();
 
            var model = comp.GetSemanticModel(tree);
 
            var a = root.DescendantNodes()
                .OfType<IdentifierNameSyntax>()
                .Where(id => id.Identifier.ValueText == "A")
                .Single();
 
            Assert.Null(model.GetDeclaredSymbol(a));
 
            var aSymbolInfo = model.GetSymbolInfo(a);
            Assert.Equal(0, aSymbolInfo.CandidateSymbols.Length);
            Assert.Null(aSymbolInfo.Symbol);
 
            var aTypeInfo = model.GetTypeInfo(a);
            Assert.Equal(TypeKind.Error, aTypeInfo.Type.TypeKind);
 
            Assert.Null(model.GetAliasInfo(a));
 
            Assert.Empty(model.LookupNamespacesAndTypes(a.SpanStart, name: "A"));
 
            var clsCompliant = root.DescendantNodes()
                .OfType<IdentifierNameSyntax>()
                .Where(id => id.Identifier.ValueText == "CLSCompliant")
                .Single();
            var clsCompliantSymbol = comp.GlobalNamespace
                .GetMember<INamespaceSymbol>("System")
                .GetTypeMember("CLSCompliantAttribute");
 
            Assert.Null(model.GetDeclaredSymbol(clsCompliant));
 
            // This should be null because there is no CLSCompliant ctor with no args
            var clsCompliantSymbolInfo = model.GetSymbolInfo(clsCompliant);
            Assert.Null(clsCompliantSymbolInfo.Symbol);
            Assert.Equal(clsCompliantSymbol.GetMember<IMethodSymbol>(".ctor"),
                clsCompliantSymbolInfo.CandidateSymbols.Single());
            Assert.Equal(CandidateReason.OverloadResolutionFailure, clsCompliantSymbolInfo.CandidateReason);
 
            Assert.Equal(clsCompliantSymbol, model.GetTypeInfo(clsCompliant).Type);
 
            Assert.Null(model.GetAliasInfo(clsCompliant));
 
            Assert.Equal(clsCompliantSymbol,
                model.LookupNamespacesAndTypes(clsCompliant.SpanStart, name: "CLSCompliantAttribute").Single());
            ((CSharpCompilation)comp).DeclarationDiagnostics.Verify();
        }
 
        [Fact]
        public void LocalFunctionAttribute_TypeParameter_Errors()
        {
            var tree = SyntaxFactory.ParseSyntaxTree(@"
using System;
class C
{
    public void M()
    {
        void Local<[A, B, CLSCompliant, D]T>() { }
        Local<int>();
    }
}", options: TestOptions.Regular9);
            var comp = CreateCompilation(tree);
            comp.DeclarationDiagnostics.Verify();
            comp.VerifyDiagnostics(
                // (7,21): error CS0246: The type or namespace name 'AAttribute' could not be found (are you missing a using directive or an assembly reference?)
                //         void Local<[A, B, CLSCompliant, D]T>() { }
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "A").WithArguments("AAttribute").WithLocation(7, 21),
                // (7,21): error CS0246: The type or namespace name 'A' could not be found (are you missing a using directive or an assembly reference?)
                //         void Local<[A, B, CLSCompliant, D]T>() { }
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "A").WithArguments("A").WithLocation(7, 21),
                // (7,24): error CS0246: The type or namespace name 'BAttribute' could not be found (are you missing a using directive or an assembly reference?)
                //         void Local<[A, B, CLSCompliant, D]T>() { }
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "B").WithArguments("BAttribute").WithLocation(7, 24),
                // (7,24): error CS0246: The type or namespace name 'B' could not be found (are you missing a using directive or an assembly reference?)
                //         void Local<[A, B, CLSCompliant, D]T>() { }
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "B").WithArguments("B").WithLocation(7, 24),
                // (7,41): error CS0246: The type or namespace name 'DAttribute' could not be found (are you missing a using directive or an assembly reference?)
                //         void Local<[A, B, CLSCompliant, D]T>() { }
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "D").WithArguments("DAttribute").WithLocation(7, 41),
                // (7,41): error CS0246: The type or namespace name 'D' could not be found (are you missing a using directive or an assembly reference?)
                //         void Local<[A, B, CLSCompliant, D]T>() { }
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "D").WithArguments("D").WithLocation(7, 41),
                // (7,27): error CS7036: There is no argument given that corresponds to the required parameter 'isCompliant' of 'CLSCompliantAttribute.CLSCompliantAttribute(bool)'
                //         void Local<[A, B, CLSCompliant, D]T>() { }
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "CLSCompliant").WithArguments("isCompliant", "System.CLSCompliantAttribute.CLSCompliantAttribute(bool)").WithLocation(7, 27));
 
            var localDecl = tree.FindNodeOrTokenByKind(SyntaxKind.LocalFunctionStatement);
            var model = comp.GetSemanticModel(tree);
            var localSymbol = Assert.IsType<LocalFunctionSymbol>(model.GetDeclaredSymbol(localDecl.AsNode()).GetSymbol());
            var typeParam = localSymbol.TypeParameters.Single();
            var attrs = typeParam.GetAttributes();
 
            Assert.True(attrs[0].AttributeClass.IsErrorType());
            Assert.True(attrs[1].AttributeClass.IsErrorType());
            Assert.False(attrs[2].AttributeClass.IsErrorType());
            Assert.Equal(comp.GlobalNamespace
                             .GetMember<NamespaceSymbol>("System")
                             .GetMember<NamedTypeSymbol>("CLSCompliantAttribute"),
                attrs[2].AttributeClass);
            Assert.True(attrs[3].AttributeClass.IsErrorType());
 
            comp.DeclarationDiagnostics.Verify();
        }
 
        [Fact]
        public void LocalFunctionAttribute_Parameter_Errors()
        {
            var tree = SyntaxFactory.ParseSyntaxTree(@"
using System;
class C
{
    public void M()
    {
        void Local([A, B]int x, [CLSCompliant]string s = """") { }
        Local(0);
    }
}", options: TestOptions.Regular9);
            var comp = CreateCompilation(tree);
            comp.DeclarationDiagnostics.Verify();
            comp.VerifyDiagnostics(
                // (7,21): error CS0246: The type or namespace name 'AAttribute' could not be found (are you missing a using directive or an assembly reference?)
                //         void Local([A, B]int x, [CLSCompliant]string s = "") { }
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "A").WithArguments("AAttribute").WithLocation(7, 21),
                // (7,21): error CS0246: The type or namespace name 'A' could not be found (are you missing a using directive or an assembly reference?)
                //         void Local([A, B]int x, [CLSCompliant]string s = "") { }
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "A").WithArguments("A").WithLocation(7, 21),
                // (7,24): error CS0246: The type or namespace name 'BAttribute' could not be found (are you missing a using directive or an assembly reference?)
                //         void Local([A, B]int x, [CLSCompliant]string s = "") { }
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "B").WithArguments("BAttribute").WithLocation(7, 24),
                // (7,24): error CS0246: The type or namespace name 'B' could not be found (are you missing a using directive or an assembly reference?)
                //         void Local([A, B]int x, [CLSCompliant]string s = "") { }
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "B").WithArguments("B").WithLocation(7, 24),
                // (7,34): error CS7036: There is no argument given that corresponds to the required parameter 'isCompliant' of 'CLSCompliantAttribute.CLSCompliantAttribute(bool)'
                //         void Local([A, B]int x, [CLSCompliant]string s = "") { }
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "CLSCompliant").WithArguments("isCompliant", "System.CLSCompliantAttribute.CLSCompliantAttribute(bool)").WithLocation(7, 34));
 
            var localDecl = tree.FindNodeOrTokenByKind(SyntaxKind.LocalFunctionStatement);
            var model = comp.GetSemanticModel(tree);
            var localSymbol = Assert.IsType<LocalFunctionSymbol>(model.GetDeclaredSymbol(localDecl.AsNode()).GetSymbol());
            var param = localSymbol.Parameters[0];
            var attrs = param.GetAttributes();
 
            Assert.True(attrs[0].AttributeClass.IsErrorType());
            Assert.True(attrs[1].AttributeClass.IsErrorType());
 
            param = localSymbol.Parameters[1];
            attrs = param.GetAttributes();
            Assert.Equal(comp.GlobalNamespace
                             .GetMember<NamespaceSymbol>("System")
                             .GetMember<NamedTypeSymbol>("CLSCompliantAttribute"),
                attrs[0].AttributeClass);
            comp.DeclarationDiagnostics.Verify();
        }
 
        [Fact]
        public void LocalFunctionDisallowedAttributes()
        {
            var source = @"
using System.Runtime.CompilerServices;
 
namespace System.Runtime.CompilerServices
{
    public class IsReadOnlyAttribute : System.Attribute { }
    public class IsUnmanagedAttribute : System.Attribute { }
    public class IsByRefLikeAttribute : System.Attribute { }
    public class NullableContextAttribute : System.Attribute { public NullableContextAttribute(byte b) { } }
}
 
class C
{
    void M()
    {
        local1();
 
        [IsReadOnly] // 1
        [IsUnmanaged] // 2
        [IsByRefLike] // 3
        [Extension] // 4
        [NullableContext(0)] // 5
        void local1()
        {
        }
    }
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (18,10): error CS8335: Do not use 'System.Runtime.CompilerServices.IsReadOnlyAttribute'. This is reserved for compiler usage.
                //         [IsReadOnly] // 1
                Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsReadOnly").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(18, 10),
                // (19,10): error CS8335: Do not use 'System.Runtime.CompilerServices.IsUnmanagedAttribute'. This is reserved for compiler usage.
                //         [IsUnmanaged] // 2
                Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsUnmanaged").WithArguments("System.Runtime.CompilerServices.IsUnmanagedAttribute").WithLocation(19, 10),
                // (20,10): error CS8335: Do not use 'System.Runtime.CompilerServices.IsByRefLikeAttribute'. This is reserved for compiler usage.
                //         [IsByRefLike] // 3
                Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsByRefLike").WithArguments("System.Runtime.CompilerServices.IsByRefLikeAttribute").WithLocation(20, 10),
                // (21,10): error CS1112: Do not use 'System.Runtime.CompilerServices.ExtensionAttribute'. Use the 'this' keyword instead.
                //         [Extension] // 4
                Diagnostic(ErrorCode.ERR_ExplicitExtension, "Extension").WithLocation(21, 10),
                // (22,10): error CS8335: Do not use 'System.Runtime.CompilerServices.NullableContextAttribute'. This is reserved for compiler usage.
                //         [NullableContext(0)] // 5
                Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "NullableContext(0)").WithArguments("System.Runtime.CompilerServices.NullableContextAttribute").WithLocation(22, 10));
        }
 
        [Fact]
        public void LocalFunctionDisallowedSecurityAttributes()
        {
            var source = @"
using System.Security;
 
class C
{
    void M()
    {
        local1();
 
        [SecurityCritical] // 1
        [SecuritySafeCriticalAttribute] // 2
        async void local1() // 3
        {
        }
    }
}
";
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (10,10): error CS4030: Security attribute 'SecurityCritical' cannot be applied to an Async method.
                //         [SecurityCritical] // 1
                Diagnostic(ErrorCode.ERR_SecurityCriticalOrSecuritySafeCriticalOnAsync, "SecurityCritical").WithArguments("SecurityCritical").WithLocation(10, 10),
                // (11,10): error CS4030: Security attribute 'SecuritySafeCriticalAttribute' cannot be applied to an Async method.
                //         [SecuritySafeCriticalAttribute] // 2
                Diagnostic(ErrorCode.ERR_SecurityCriticalOrSecuritySafeCriticalOnAsync, "SecuritySafeCriticalAttribute").WithArguments("SecuritySafeCriticalAttribute").WithLocation(11, 10),
                // (12,20): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
                //         async void local1() // 3
                Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "local1").WithLocation(12, 20));
        }
 
        [Fact]
        public void TypeParameterBindingScope()
        {
            var src = @"
class C
{
    public void M()
    {
        {
            int T = 0; // Should not have error
 
            int Local<T>() => 0; // Should conflict with above
            Local<int>();
            T++;
        }
        {
            int T<T>() => 0;
            T<int>();
        }
        {
            int Local<T, T>() => 0;
            Local<int, int>();
        }
    }
    public void M2<T>()
    {
        {
            int Local<T>() => 0;
            Local<int>();
        }
        {
            int Local1<V>()
            {
                int Local2<V>() => 0;
                return Local2<int>();
            }
            Local1<int>();
        }
        {
            int T() => 0;
            T();
        }
        {
            int Local1<V>()
            {
                int V() => 0;
                return V();
            }
            Local1<int>();
        }
        {
            int Local1<V>()
            {
                int Local2<U>()
                {
                    // Conflicts with method type parameter
                    int T() => 0;
                    return T();
                }
                return Local2<int>();
            }
            Local1<int>();
        }
        {
            int Local1<V>()
            {
                int Local2<U>()
                {
                    // Shadows M.2<T>
                    int Local3<T>() => 0;
                    return Local3<int>();
                }
                return Local2<int>();
            }
            Local1<int>();
        }
    }
    public void V<V>() { }
}
";
            var comp = CreateCompilation(src, parseOptions: TestOptions.Regular7_3);
            comp.VerifyDiagnostics(
                // (9,23): error CS0136: A local or parameter named 'T' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //             int Local<T>() => 0; // Should conflict with above
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "T").WithArguments("T").WithLocation(9, 23),
                // (14,19): error CS0136: A local or parameter named 'T' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //             int T<T>() => 0;
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "T").WithArguments("T").WithLocation(14, 19),
                // (18,26): error CS0692: Duplicate type parameter 'T'
                //             int Local<T, T>() => 0;
                Diagnostic(ErrorCode.ERR_DuplicateTypeParameter, "T").WithArguments("T").WithLocation(18, 26),
                // (25,23): warning CS8387: Type parameter 'T' has the same name as the type parameter from outer method 'C.M2<T>()'
                //             int Local<T>() => 0;
                Diagnostic(ErrorCode.WRN_TypeParameterSameAsOuterMethodTypeParameter, "T").WithArguments("T", "C.M2<T>()").WithLocation(25, 23),
                // (31,28): warning CS8387: Type parameter 'V' has the same name as the type parameter from outer method 'Local1<V>()'
                //                 int Local2<V>() => 0;
                Diagnostic(ErrorCode.WRN_TypeParameterSameAsOuterMethodTypeParameter, "V").WithArguments("V", "Local1<V>()").WithLocation(31, 28),
                // (37,17): error CS0412: 'T': a parameter, local variable, or local function cannot have the same name as a method type parameter
                //             int T() => 0;
                Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "T").WithArguments("T").WithLocation(37, 17),
                // (43,21): error CS0412: 'V': a parameter, local variable, or local function cannot have the same name as a method type parameter
                //                 int V() => 0;
                Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "V").WithArguments("V").WithLocation(43, 21),
                // (54,25): error CS0412: 'T': a parameter, local variable, or local function cannot have the same name as a method type parameter
                //                     int T() => 0;
                Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "T").WithArguments("T").WithLocation(54, 25),
                // (67,32): warning CS8387: Type parameter 'T' has the same name as the type parameter from outer method 'C.M2<T>()'
                //                     int Local3<T>() => 0;
                Diagnostic(ErrorCode.WRN_TypeParameterSameAsOuterMethodTypeParameter, "T").WithArguments("T", "C.M2<T>()").WithLocation(67, 32));
 
            comp = CreateCompilation(src, parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (18,26): error CS0692: Duplicate type parameter 'T'
                //             int Local<T, T>() => 0;
                Diagnostic(ErrorCode.ERR_DuplicateTypeParameter, "T").WithArguments("T").WithLocation(18, 26),
                // (25,23): warning CS8387: Type parameter 'T' has the same name as the type parameter from outer method 'C.M2<T>()'
                //             int Local<T>() => 0;
                Diagnostic(ErrorCode.WRN_TypeParameterSameAsOuterMethodTypeParameter, "T").WithArguments("T", "C.M2<T>()").WithLocation(25, 23),
                // (31,28): warning CS8387: Type parameter 'V' has the same name as the type parameter from outer method 'Local1<V>()'
                //                 int Local2<V>() => 0;
                Diagnostic(ErrorCode.WRN_TypeParameterSameAsOuterMethodTypeParameter, "V").WithArguments("V", "Local1<V>()").WithLocation(31, 28),
                // (37,17): error CS0412: 'T': a parameter, local variable, or local function cannot have the same name as a method type parameter
                //             int T() => 0;
                Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "T").WithArguments("T").WithLocation(37, 17),
                // (43,21): error CS0412: 'V': a parameter, local variable, or local function cannot have the same name as a method type parameter
                //                 int V() => 0;
                Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "V").WithArguments("V").WithLocation(43, 21),
                // (67,32): warning CS8387: Type parameter 'T' has the same name as the type parameter from outer method 'C.M2<T>()'
                //                     int Local3<T>() => 0;
                Diagnostic(ErrorCode.WRN_TypeParameterSameAsOuterMethodTypeParameter, "T").WithArguments("T", "C.M2<T>()").WithLocation(67, 32));
        }
 
        [Fact]
        public void LocalFuncAndTypeParameterOnType()
        {
            var comp = CreateCompilation(@"
class C2<T>
{
    public void M()
    {
        {
            int Local1()
            {
                int Local2<T>() => 0;
                return Local2<int>();
            }
            Local1();
        }
        {
            int Local1()
            {
                int Local2()
                {
                    // Shadows type parameter
                    int T() => 0;
 
                    // Type parameter resolves in type only context
                    T t = default(T); 
 
                    // Ambiguous context chooses local
                    T.M();
 
                    // Call chooses local
                    return T();
                }
                return Local2();
            }
            Local1();
        }
    }
}");
            comp.VerifyDiagnostics(
                // (9,28): warning CS0693: Type parameter 'T' has the same name as the type parameter from outer type 'C2<T>'
                //                 int Local2<T>() => 0;
                Diagnostic(ErrorCode.WRN_TypeParameterSameAsOuterTypeParameter, "T").WithArguments("T", "C2<T>").WithLocation(9, 28),
                // (26,21): error CS0119: 'T()' is a method, which is not valid in the given context
                //                     T.M();
                Diagnostic(ErrorCode.ERR_BadSKunknown, "T").WithArguments("T()", "method").WithLocation(26, 21),
                // (23,23): warning CS0219: The variable 't' is assigned but its value is never used
                //                     T t = default(T); 
                Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "t").WithArguments("t").WithLocation(23, 23));
        }
 
        [Fact]
        public void RefArgsInIteratorLocalFuncs()
        {
            var src = @"
using System;
using System.Collections.Generic;
class C
{
    public void M1()
    {
        IEnumerable<int> Local(ref int a) { yield break; }
        int x = 0;
        Local(ref x);
    }
 
    public void M2()
    {
        Action a = () =>
        {
            IEnumerable<int> Local(ref int x) { yield break; }
            int y = 0;
            Local(ref y);
            return;
        };
        a();
    }
 
    public Func<int> M3() => (() =>
    {
        IEnumerable<int> Local(ref int a) { yield break; }
        int x = 0;
        Local(ref x);
        return 0;
    });
 
    public IEnumerable<int> M4(ref int a)
    {
        yield return new Func<int>(() =>
            {
                IEnumerable<int> Local(ref int b) { yield break; }
                int x = 0;
                Local(ref x);
                return 0;
            })();
    }
}";
            VerifyDiagnostics(src,
                // (8,40): error CS1623: Iterators cannot have ref, in or out parameters
                //         IEnumerable<int> Local(ref int a) { yield break; }
                Diagnostic(ErrorCode.ERR_BadIteratorArgType, "a").WithLocation(8, 40),
                // (17,44): error CS1623: Iterators cannot have ref, in or out parameters
                //             IEnumerable<int> Local(ref int x) { yield break; }
                Diagnostic(ErrorCode.ERR_BadIteratorArgType, "x").WithLocation(17, 44),
                // (27,40): error CS1623: Iterators cannot have ref, in or out parameters
                //         IEnumerable<int> Local(ref int a) { yield break; }
                Diagnostic(ErrorCode.ERR_BadIteratorArgType, "a").WithLocation(27, 40),
                // (33,40): error CS1623: Iterators cannot have ref, in or out parameters
                //     public IEnumerable<int> M4(ref int a)
                Diagnostic(ErrorCode.ERR_BadIteratorArgType, "a").WithLocation(33, 40),
                // (37,48): error CS1623: Iterators cannot have ref, in or out parameters
                //                 IEnumerable<int> Local(ref int b) { yield break; }
                Diagnostic(ErrorCode.ERR_BadIteratorArgType, "b").WithLocation(37, 48));
        }
 
        [Fact]
        public void UnsafeArgsInIteratorLocalFuncs()
        {
            var src = @"
using System;
using System.Collections.Generic;
class C
{
    public unsafe void M1()
    {
        IEnumerable<int> Local(int* a) { yield break; }
        int x = 0;
        Local(&x);
    }
 
    public unsafe void M2()
    {
        Action a = () =>
        {
            IEnumerable<int> Local(int* x) { yield break; }
            int y = 0;
            Local(&y);
            return;
        };
        a();
    }
 
    public unsafe Func<int> M3() => (() =>
    {
        IEnumerable<int> Local(int* a) { yield break; }
        int x = 0;
        Local(&x);
        return 0;
    });
 
    public unsafe IEnumerable<int> M4(int* a)
    {
        yield return new Func<int>(() =>
            {
                IEnumerable<int> Local(int* b) { yield break; }
                int x = 0;
                Local(&x);
                return 0;
            })();
    }
}";
            var comp = CreateCompilation(src, options: TestOptions.UnsafeDebugDll, parseOptions: TestOptions.Regular12.WithFeature("run-nullable-analysis", "never"));
 
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);
            LocalFunctionStatementSyntax declaration = tree.GetRoot().DescendantNodes().OfType<LocalFunctionStatementSyntax>().First();
            var local = model.GetDeclaredSymbol(declaration).GetSymbol<MethodSymbol>();
 
            Assert.True(local.IsIterator);
            Assert.Equal("System.Int32", local.IteratorElementTypeWithAnnotations.ToTestDisplayString());
 
            model.GetOperation(declaration.Body);
 
            Assert.True(local.IsIterator);
            Assert.Equal("System.Int32", local.IteratorElementTypeWithAnnotations.ToTestDisplayString());
 
            comp.VerifyDiagnostics(
                // (8,37): error CS1637: Iterators cannot have pointer type parameters
                //         IEnumerable<int> Local(int* a) { yield break; }
                Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "a").WithLocation(8, 37),
                // (17,41): error CS1637: Iterators cannot have pointer type parameters
                //             IEnumerable<int> Local(int* x) { yield break; }
                Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "x").WithLocation(17, 41),
                // (27,37): error CS1637: Iterators cannot have pointer type parameters
                //         IEnumerable<int> Local(int* a) { yield break; }
                Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "a").WithLocation(27, 37),
                // (37,40): error CS9202: Feature 'ref and unsafe in async and iterator methods' is not available in C# 12.0. Please use language version 13.0 or greater.
                //                 IEnumerable<int> Local(int* b) { yield break; }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion12, "int*").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(37, 40),
                // (39,23): error CS9202: Feature 'ref and unsafe in async and iterator methods' is not available in C# 12.0. Please use language version 13.0 or greater.
                //                 Local(&x);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion12, "&x").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(39, 23),
                // (39,17): error CS9202: Feature 'ref and unsafe in async and iterator methods' is not available in C# 12.0. Please use language version 13.0 or greater.
                //                 Local(&x);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion12, "Local(&x)").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(39, 17),
                // (33,44): error CS1637: Iterators cannot have pointer type parameters
                //     public unsafe IEnumerable<int> M4(int* a)
                Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "a").WithLocation(33, 44),
                // (33,36): error CS9202: Feature 'ref and unsafe in async and iterator methods' is not available in C# 12.0. Please use language version 13.0 or greater.
                //     public unsafe IEnumerable<int> M4(int* a)
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion12, "M4").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(33, 36),
                // (37,45): error CS1637: Iterators cannot have pointer type parameters
                //                 IEnumerable<int> Local(int* b) { yield break; }
                Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "b").WithLocation(37, 45));
 
            var expectedDiagnostics = new[]
            {
                // (8,37): error CS1637: Iterators cannot have pointer type parameters
                //         IEnumerable<int> Local(int* a) { yield break; }
                Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "a").WithLocation(8, 37),
                // (17,41): error CS1637: Iterators cannot have pointer type parameters
                //             IEnumerable<int> Local(int* x) { yield break; }
                Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "x").WithLocation(17, 41),
                // (27,37): error CS1637: Iterators cannot have pointer type parameters
                //         IEnumerable<int> Local(int* a) { yield break; }
                Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "a").WithLocation(27, 37),
                // (33,44): error CS1637: Iterators cannot have pointer type parameters
                //     public unsafe IEnumerable<int> M4(int* a)
                Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "a").WithLocation(33, 44),
                // (37,40): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //                 IEnumerable<int> Local(int* b) { yield break; }
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(37, 40),
                // (37,45): error CS1637: Iterators cannot have pointer type parameters
                //                 IEnumerable<int> Local(int* b) { yield break; }
                Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "b").WithLocation(37, 45),
                // (39,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //                 Local(&x);
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "Local(&x)").WithLocation(39, 17),
                // (39,23): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //                 Local(&x);
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "&x").WithLocation(39, 23)
            };
 
            CreateCompilation(src, options: TestOptions.UnsafeDebugDll, parseOptions: TestOptions.Regular13.WithFeature("run-nullable-analysis", "never")).VerifyDiagnostics(expectedDiagnostics);
            CreateCompilation(src, options: TestOptions.UnsafeDebugDll, parseOptions: TestOptions.RegularPreview.WithFeature("run-nullable-analysis", "never")).VerifyDiagnostics(expectedDiagnostics);
        }
 
        [Fact]
        [WorkItem(13193, "https://github.com/dotnet/roslyn/issues/13193")]
        public void LocalFunctionConflictingName()
        {
            var comp = CreateCompilation(@"
class C
{
    public void M<TLocal>()
    {
        void TLocal() { }
        TLocal();
    }
    public void M(int Local)
    {
        void Local() { }
        Local();
    }
    public void M()
    {
        int local = 0;
 
        void local() { }
        local();
    }
}");
            comp.VerifyDiagnostics(
                // (6,14): error CS0412: 'TLocal': a parameter, local variable, or local function cannot have the same name as a method type parameter
                //         void TLocal() { }
                Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "TLocal").WithArguments("TLocal").WithLocation(6, 14),
                // (11,14): error CS0136: A local or parameter named 'Local' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void Local() { }
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "Local").WithArguments("Local").WithLocation(11, 14),
                // (18,14): error CS0128: A local variable or function named 'local' is already defined in this scope
                //         void local() { }
                Diagnostic(ErrorCode.ERR_LocalDuplicate, "local").WithArguments("local").WithLocation(18, 14),
                // (16,13): warning CS0219: The variable 'local' is assigned but its value is never used
                //         int local = 0;
                Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "local").WithArguments("local").WithLocation(16, 13));
        }
 
        [Fact]
        public void ForgotSemicolonLocalFunctionsMistake()
        {
            var src = """
                class C
                {
                    public void M1()
                    {
                    // forget closing brace
 
                    public void BadLocal1()
                    {
                        this.BadLocal2();
                    }
 
                    public void BadLocal2()
                    {
                    }
 
                    public int P => 0;
                }
                """;
            VerifyDiagnostics(src,
                // (5,6): error CS1513: } expected
                //     {
                Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(4, 6));
        }
 
        [Fact]
        public void VarLocalFunction()
        {
            var src = @"
class C
{
    void M()
    {
        var local() => 0;
        int x = local();
   } 
}";
            VerifyDiagnostics(src,
                // (6,9): error CS0825: The contextual keyword 'var' may only appear within a local variable declaration or in script code
                //         var local() => 0;
                Diagnostic(ErrorCode.ERR_TypeVarNotFound, "var").WithLocation(6, 9));
        }
 
        [Fact]
        public void VarLocalFunction2()
        {
            var comp = CreateCompilation(@"
class C
{
    private class @var
    {
    }
 
    void M()
    {
        var local() => new var();
        var x = local();
   } 
}", parseOptions: DefaultParseOptions);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        [CompilerTrait(CompilerFeature.Params)]
        public void BadParams()
        {
            var source = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        void Params(params int x)
        {
            Console.WriteLine(x);
        }
        Params(2);
    }
}
";
            VerifyDiagnostics(source,
    // (8,21): error CS0225: The params parameter must have a valid collection type
    //         void Params(params int x)
    Diagnostic(ErrorCode.ERR_ParamsMustBeCollection, "params").WithLocation(8, 21)
    );
        }
 
        [Fact]
        public void ParamsArray_Symbol_MultipleParamsArrays()
        {
            var source = """
                int Method1(params int[] xs, params int[] ys, int[] zs) => xs.Length + ys.Length + zs.Length;
                int Method2(params int[] xs, int[] ys, params int[] zs) => xs.Length + ys.Length + zs.Length;
                """;
            var comp = CreateCompilation(source);
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var exprs = tree.GetRoot().DescendantNodes().OfType<LocalFunctionStatementSyntax>().ToImmutableArray();
            var methods = exprs.SelectAsArray(e => (IMethodSymbol)model.GetDeclaredSymbol(e));
            Assert.Equal(2, methods.Length);
            // Method1
            Assert.Equal(3, methods[0].Parameters.Length);
            Assert.True(methods[0].Parameters[0].IsParams);
            Assert.True(methods[0].Parameters[1].IsParams);
            Assert.False(methods[0].Parameters[2].IsParams);
            // Method2
            Assert.Equal(3, methods[1].Parameters.Length);
            Assert.True(methods[1].Parameters[0].IsParams);
            Assert.False(methods[1].Parameters[1].IsParams);
            Assert.True(methods[1].Parameters[2].IsParams);
        }
 
        [Fact]
        public void BadRefWithDefault()
        {
            var source = @"
class Program
{
    static void Main(string[] args)
    {
        void RefOut(ref int x = 2)
        {
            x++;
        }
        int y = 2;
        RefOut(ref y);
    }
}
";
            VerifyDiagnostics(source,
    // (6,21): error CS1741: A ref or out parameter cannot have a default value
    //         void RefOut(ref int x = 2)
    Diagnostic(ErrorCode.ERR_RefOutDefaultValue, "ref").WithLocation(6, 21)
    );
        }
 
        [Fact]
        public void BadDefaultValueType()
        {
            var source = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        void NamedOptional(string x = 2)
        {
            Console.WriteLine(x);
        }
        NamedOptional(""2"");
    }
}
";
            VerifyDiagnostics(source,
    // (8,35): error CS1750: A value of type 'int' cannot be used as a default parameter because there are no standard conversions to type 'string'
    //         void NamedOptional(string x = 2)
    Diagnostic(ErrorCode.ERR_NoConversionForDefaultParam, "x").WithArguments("int", "string").WithLocation(8, 35)
    );
        }
 
        [Fact]
        public void CallerMemberName()
        {
            var comp = CreateCompilationWithMscorlib46(@"
using System;
using System.Runtime.CompilerServices;
class C
{
    static void Main()
    {
        void CallerMemberName([CallerMemberName] string s = null)
        {
            Console.Write(s);
        }
        void LocalFuncName()
        {
            CallerMemberName();
        }
        LocalFuncName();
        Console.Write(' ');
        CallerMemberName();
    }
}", parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void BadCallerMemberName()
        {
            var source = @"
using System;
using System.Runtime.CompilerServices;
 
class Program
{
    static void Main(string[] args)
    {
        void CallerMemberName([CallerMemberName] int s = 2) // 1
        {
            Console.WriteLine(s);
        }
        CallerMemberName(); // 2
    }
}
";
            CreateCompilationWithMscorlib461AndCSharp(source, parseOptions: TestOptions.Regular9).VerifyDiagnostics(
                // (9,32): error CS4019: CallerMemberNameAttribute cannot be applied because there are no standard conversions from type 'string' to type 'int'
                //         void CallerMemberName([CallerMemberName] int s = 2) // 1
                Diagnostic(ErrorCode.ERR_NoConversionForCallerMemberNameParam, "CallerMemberName").WithArguments("string", "int").WithLocation(9, 32),
                // (13,9): error CS0029: Cannot implicitly convert type 'string' to 'int'
                //         CallerMemberName(); // 2
                Diagnostic(ErrorCode.ERR_NoImplicitConv, "CallerMemberName()").WithArguments("string", "int").WithLocation(13, 9));
        }
 
        [WorkItem(10708, "https://github.com/dotnet/roslyn/issues/10708")]
        [CompilerTrait(CompilerFeature.Dynamic, CompilerFeature.Params)]
        [Fact]
        public void DynamicArgumentToParams()
        {
            var src = @"
using System;
class C
{
    static void Main()
    {
        void L1(int x = 0, params int[] ys) => Console.Write(x);
 
        dynamic val = 2;
        L1(val, val);
        L1(ys: val, x: val);
        L1(ys: val);
    }
}";
            VerifyDiagnostics(src,
                // (10,17): error CS8106: Cannot pass argument with dynamic type to params parameter 'ys' of local function 'L1'.
                //         L1(val, val);
                Diagnostic(ErrorCode.ERR_DynamicLocalFunctionParamsParameter, "val").WithArguments("ys", "L1").WithLocation(10, 17),
                // (11,16): error CS8106: Cannot pass argument with dynamic type to params parameter 'ys' of local function 'L1'.
                //         L1(ys: val, x: val);
                Diagnostic(ErrorCode.ERR_DynamicLocalFunctionParamsParameter, "val").WithArguments("ys", "L1").WithLocation(11, 16),
                // (12,16): error CS8106: Cannot pass argument with dynamic type to params parameter 'ys' of local function 'L1'.
                //         L1(ys: val);
                Diagnostic(ErrorCode.ERR_DynamicLocalFunctionParamsParameter, "val").WithArguments("ys", "L1").WithLocation(12, 16));
        }
 
        [Fact]
        [CompilerTrait(CompilerFeature.Dynamic)]
        public void DynamicArgOverload()
        {
            var src = @"
using System;
class C
{
    static void Main()
    {
        void Overload(int i) => Console.Write(i);
        void Overload(string s) => Console.Write(s);
 
        dynamic val = 2;
        Overload(val);
    }
}";
            VerifyDiagnostics(src,
                // (8,14): error CS0128: A local variable named 'Overload' is already defined in this scope
                //         void Overload(string s) => Console.Write(s);
                Diagnostic(ErrorCode.ERR_LocalDuplicate, "Overload").WithArguments("Overload").WithLocation(8, 14),
                // (8,14): warning CS8321: The local function 'Overload' is declared but never used
                //         void Overload(string s) => Console.Write(s);
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Overload").WithArguments("Overload").WithLocation(8, 14));
        }
 
        [Fact]
        [CompilerTrait(CompilerFeature.Dynamic)]
        public void DynamicArgWrongArity()
        {
            var src = @"
using System;
class C
{
    static void Main()
    {
        void Local(int i) => Console.Write(i);
 
        dynamic val = 2;
        Local(val, val);
    }
}";
            VerifyDiagnostics(src,
                // (10,9): error CS1501: No overload for method 'Local' takes 2 arguments
                //         Local(val, val);
                Diagnostic(ErrorCode.ERR_BadArgCount, "Local").WithArguments("Local", "2").WithLocation(10, 9));
        }
 
        [Fact]
        [WorkItem("https://github.com/dotnet/roslyn/issues/71399")]
        [CompilerTrait(CompilerFeature.Dynamic)]
        public void DynamicArgWithRefKind_01()
        {
            var src = @"
class C
{
    static void Main()
    {
        dynamic i = 1;
        
        local1(i);
        local1(ref i);
 
        local2(i);
        local3(i);
        
        void local1(ref int x){ x++; }
        void local2(ref object x){ }
        void local3(ref dynamic x){ x++; }
    }
}";
            VerifyDiagnostics(src,
                // (8,16): error CS1620: Argument 1 must be passed with the 'ref' keyword
                //         local1(i);
                Diagnostic(ErrorCode.ERR_BadArgRef, "i").WithArguments("1", "ref").WithLocation(8, 16),
                // (9,20): error CS1503: Argument 1: cannot convert from 'ref dynamic' to 'ref int'
                //         local1(ref i);
                Diagnostic(ErrorCode.ERR_BadArgType, "i").WithArguments("1", "ref dynamic", "ref int").WithLocation(9, 20),
                // (11,16): error CS1620: Argument 1 must be passed with the 'ref' keyword
                //         local2(i);
                Diagnostic(ErrorCode.ERR_BadArgRef, "i").WithArguments("1", "ref").WithLocation(11, 16),
                // (12,16): error CS1620: Argument 1 must be passed with the 'ref' keyword
                //         local3(i);
                Diagnostic(ErrorCode.ERR_BadArgRef, "i").WithArguments("1", "ref").WithLocation(12, 16)
                );
        }
 
        [Fact]
        [WorkItem("https://github.com/dotnet/roslyn/issues/71399")]
        [CompilerTrait(CompilerFeature.Dynamic)]
        public void DynamicArgWithRefKind_02()
        {
            var src = @"
class C
{
    static void Main()
    {
        dynamic i = 1;
        
        local2(ref i);
        System.Console.Write(i);
        local3(ref i);
        System.Console.Write(i);
        
        void local2(ref object x){ ref dynamic y = ref x; y++; }
        void local3(ref dynamic x){ x++; }
    }
}";
            var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe);
 
            CompileAndVerify(comp, expectedOutput: "23").VerifyDiagnostics();
        }
 
        [WorkItem(3923, "https://github.com/dotnet/roslyn/issues/3923")]
        [Fact]
        public void ExpressionTreeLocalFunctionUsage_01()
        {
            var source = @"
using System;
using System.Linq.Expressions;
class Program
{
    static void Main()
    {
        T Id<T>(T x)
        {
            return x;
        }
        Expression<Func<T>> Local<T>(Expression<Func<T>> f)
        {
            return f;
        }
        Console.Write(Local(() => Id(2)));
        Console.Write(Local<Func<int, int>>(() => Id));
        Console.Write(Local(() => new Func<int, int>(Id)));
        Console.Write(Local(() => nameof(Id)));
    }
}
";
            VerifyDiagnostics(source,
                // (16,35): error CS8096: An expression tree may not contain a reference to a local function
                //         Console.Write(Local(() => Id(2)));
                Diagnostic(ErrorCode.ERR_ExpressionTreeContainsLocalFunction, "Id(2)").WithLocation(16, 35),
                // (17,51): error CS8096: An expression tree may not contain a reference to a local function
                //         Console.Write(Local<Func<int, int>>(() => Id));
                Diagnostic(ErrorCode.ERR_ExpressionTreeContainsLocalFunction, "Id").WithLocation(17, 51),
                // (18,35): error CS8096: An expression tree may not contain a reference to a local function
                //         Console.Write(Local(() => new Func<int, int>(Id)));
                Diagnostic(ErrorCode.ERR_ExpressionTreeContainsLocalFunction, "Id").WithLocation(18, 54)
                );
        }
 
        [Fact]
        public void ExpressionTreeLocalFunctionUsage_02()
        {
            var source = @"
using System;
using System.Linq.Expressions;
class Program
{
    static void Main()
    {
        static T Id<T>(T x)
        {
            return x;
        }
        static Expression<Func<T>> Local<T>(Expression<Func<T>> f)
        {
            return f;
        }
        Console.Write(Local(() => Id(2)));
        Console.Write(Local<Func<int, int>>(() => Id));
        Console.Write(Local(() => new Func<int, int>(Id)));
        Console.Write(Local(() => nameof(Id)));
    }
}
";
            VerifyDiagnostics(source,
                // (16,35): error CS8096: An expression tree may not contain a reference to a local function
                //         Console.Write(Local(() => Id(2)));
                Diagnostic(ErrorCode.ERR_ExpressionTreeContainsLocalFunction, "Id(2)").WithLocation(16, 35),
                // (17,51): error CS8096: An expression tree may not contain a reference to a local function
                //         Console.Write(Local<Func<int, int>>(() => Id));
                Diagnostic(ErrorCode.ERR_ExpressionTreeContainsLocalFunction, "Id").WithLocation(17, 51),
                // (18,35): error CS8096: An expression tree may not contain a reference to a local function
                //         Console.Write(Local(() => new Func<int, int>(Id)));
                Diagnostic(ErrorCode.ERR_ExpressionTreeContainsLocalFunction, "Id").WithLocation(18, 54)
                );
        }
 
        [Fact]
        public void ExpressionTreeLocalFunctionInside()
        {
            var source = @"
using System;
using System.Linq.Expressions;
class Program
{
    static void Main()
    {
        Expression<Func<int, int>> f = x =>
        {
            int Local(int y) => y;
            return Local(x);
        };
        Console.Write(f);
    }
}
";
            VerifyDiagnostics(source,
    // (8,40): error CS0834: A lambda expression with a statement body cannot be converted to an expression tree
    //         Expression<Func<int, int>> f = x =>
    Diagnostic(ErrorCode.ERR_StatementLambdaToExpressionTree, @"x =>
        {
            int Local(int y) => y;
            return Local(x);
        }").WithLocation(8, 40),
    // (11,20): error CS8096: An expression tree may not contain a local function or a reference to a local function
    //             return Local(x);
    Diagnostic(ErrorCode.ERR_ExpressionTreeContainsLocalFunction, "Local(x)").WithLocation(11, 20)
    );
        }
 
        [Fact]
        public void BadScoping()
        {
            var source = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        if (true)
        {
            void Local()
            {
                Console.WriteLine(2);
            }
            Local();
        }
        Local();
 
        Local2();
        void Local2()
        {
            Console.WriteLine(2);
        }
    }
}
";
            VerifyDiagnostics(source,
    // (16,9): error CS0103: The name 'Local' does not exist in the current context
    //         Local();
    Diagnostic(ErrorCode.ERR_NameNotInContext, "Local").WithArguments("Local").WithLocation(16, 9)
    );
        }
 
        [Fact]
        public void NameConflictDuplicate()
        {
            var source = @"
class Program
{
    static void Main(string[] args)
    {
        void Duplicate() { }
        void Duplicate() { }
        Duplicate();
    }
}
";
            VerifyDiagnostics(source,
    // (7,14): error CS0128: A local variable named 'Duplicate' is already defined in this scope
    //         void Duplicate() { }
    Diagnostic(ErrorCode.ERR_LocalDuplicate, "Duplicate").WithArguments("Duplicate").WithLocation(7, 14),
    // (7,14): warning CS8321: The local function 'Duplicate' is declared but never used
    //         void Duplicate() { }
    Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Duplicate").WithArguments("Duplicate").WithLocation(7, 14)
    );
        }
 
        [Fact]
        public void NameConflictParameter()
        {
            var source = @"
class Program
{
    static void Main(string[] args)
    {
        int x = 2;
        void Param(int x) { }
        Param(x);
    }
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3);
            comp.VerifyDiagnostics(
                // (7,24): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void Param(int x) { }
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(7, 24));
 
            comp = CreateCompilation(source, parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void NameConflictTypeParameter()
        {
            var source = @"
class Program
{
    static void Main(string[] args)
    {
        int T;
        void Generic<T>() { }
        Generic<int>();
    }
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3);
            comp.VerifyDiagnostics(
                // (7,22): error CS0136: A local or parameter named 'T' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void Generic<T>() { }
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "T").WithArguments("T").WithLocation(7, 22),
                // (6,13): warning CS0168: The variable 'T' is declared but never used
                //         int T;
                Diagnostic(ErrorCode.WRN_UnreferencedVar, "T").WithArguments("T").WithLocation(6, 13));
 
            comp = CreateCompilation(source, parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (6,13): warning CS0168: The variable 'T' is declared but never used
                //         int T;
                Diagnostic(ErrorCode.WRN_UnreferencedVar, "T").WithArguments("T").WithLocation(6, 13));
        }
 
        [Fact]
        public void NameConflictNestedTypeParameter()
        {
            var source = @"
class Program
{
    static void Main(string[] args)
    {
        T Outer<T>()
        {
            T Inner<T>()
            {
                return default(T);
            }
            return Inner<T>();
        }
        System.Console.Write(Outer<int>());
    }
}
";
            VerifyDiagnostics(source,
    // (8,21): warning CS8387: Type parameter 'T' has the same name as the type parameter from outer method 'Outer<T>()'
    //             T Inner<T>()
    Diagnostic(ErrorCode.WRN_TypeParameterSameAsOuterMethodTypeParameter, "T").WithArguments("T", "Outer<T>()").WithLocation(8, 21)
    );
        }
 
        [Fact]
        public void NameConflictLocalVarFirst()
        {
            var source = @"
class Program
{
    static void Main(string[] args)
    {
        int Conflict;
        void Conflict() { }
    }
}
";
            VerifyDiagnostics(source,
    // (7,14): error CS0128: A local variable named 'Conflict' is already defined in this scope
    //         void Conflict() { }
    Diagnostic(ErrorCode.ERR_LocalDuplicate, "Conflict").WithArguments("Conflict").WithLocation(7, 14),
    // (6,13): warning CS0168: The variable 'Conflict' is declared but never used
    //         int Conflict;
    Diagnostic(ErrorCode.WRN_UnreferencedVar, "Conflict").WithArguments("Conflict").WithLocation(6, 13),
    // (7,14): warning CS8321: The local function 'Conflict' is declared but never used
    //         void Conflict() { }
    Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Conflict").WithArguments("Conflict").WithLocation(7, 14)
    );
        }
 
        [Fact]
        public void NameConflictLocalVarLast()
        {
            var source = @"
class Program
{
    static void Main(string[] args)
    {
        void Conflict() { }
        int Conflict;
    }
}
";
            // TODO: This is strange. Probably has to do with the fact that local variables are preferred over functions.
            VerifyDiagnostics(source,
    // (6,14): error CS0136: A local or parameter named 'Conflict' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
    //         void Conflict() { }
    Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "Conflict").WithArguments("Conflict").WithLocation(6, 14),
    // (7,13): warning CS0168: The variable 'Conflict' is declared but never used
    //         int Conflict;
    Diagnostic(ErrorCode.WRN_UnreferencedVar, "Conflict").WithArguments("Conflict").WithLocation(7, 13),
    // (6,14): warning CS8321: The local function 'Conflict' is declared but never used
    //         void Conflict() { }
    Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Conflict").WithArguments("Conflict").WithLocation(6, 14)
    );
        }
 
        [Fact]
        public void BadUnsafeNoKeyword()
        {
            var source = @"
using System;
 
class Program
{
    static void A()
    {
        void Local()
        {
            int x = 2;
            Console.WriteLine(*&x);
        }
        Local();
    }
    static void Main(string[] args)
    {
        A();
    }
}
";
            VerifyDiagnostics(source,
    // (11,32): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
    //             Console.WriteLine(*&x);
    Diagnostic(ErrorCode.ERR_UnsafeNeeded, "&x").WithLocation(11, 32)
    );
        }
 
        [Fact]
        public void BadUnsafeKeywordDoesntApply()
        {
            var source = @"
using System;
 
class Program
{
    static unsafe void B()
    {
        void Local()
        {
            int x = 2;
            Console.WriteLine(*&x);
        }
        Local();
    }
    static void Main(string[] args)
    {
        B();
    }
}
";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe.WithAllowUnsafe(true));
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void BadEmptyBody()
        {
            var source = @"
class Program
{
    static void Main(string[] args)
    {
        void Local(int x);
        Local(2);
    }
}";
            VerifyDiagnostics(source,
                // (6,14): error CS8112: 'Local(int)' is a local function and must therefore always have a body.
                //         void Local(int x);
                Diagnostic(ErrorCode.ERR_LocalFunctionMissingBody, "Local").WithArguments("Local(int)").WithLocation(6, 14)
            );
        }
 
        [Fact]
        public void BadGotoInto()
        {
            var source = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        goto A;
        void Local()
        {
        A:  Console.Write(2);
        }
        Local();
    }
}";
            VerifyDiagnostics(source,
    // (8,14): error CS0159: No such label 'A' within the scope of the goto statement
    //         goto A;
    Diagnostic(ErrorCode.ERR_LabelNotFound, "A").WithArguments("A").WithLocation(8, 14),
    // (11,9): warning CS0164: This label has not been referenced
    //         A:  Console.Write(2);
    Diagnostic(ErrorCode.WRN_UnreferencedLabel, "A").WithLocation(11, 9)
    );
        }
 
        [Fact]
        public void BadGotoOutOf()
        {
            var source = @"
class Program
{
    static void Main(string[] args)
    {
        void Local()
        {
            goto A;
        }
    A:  Local();
    }
}";
            VerifyDiagnostics(source,
                // (8,13): error CS0159: No such label 'A' within the scope of the goto statement
                //             goto A;
                Diagnostic(ErrorCode.ERR_LabelNotFound, "goto").WithArguments("A").WithLocation(8, 13)
                );
        }
 
        [Fact]
        public void BadDefiniteAssignmentCall()
        {
            var source = @"
using System;
 
class Program
{
    static void A()
    {
        goto Label;
        int x = 2;
        void Local()
        {
            Console.Write(x);
        }
        Label:
        Local();
    }
    static void Main(string[] args)
    {
        A();
    }
}";
            VerifyDiagnostics(source,
                // (9,9): warning CS0162: Unreachable code detected
                //         int x = 2;
                Diagnostic(ErrorCode.WRN_UnreachableCode, "int").WithLocation(9, 9),
                // (15,9): error CS0165: Use of unassigned local variable 'x'
                //         Local();
                Diagnostic(ErrorCode.ERR_UseDefViolation, "Local()").WithArguments("x").WithLocation(15, 9)
    );
        }
 
        [Fact]
        public void BadDefiniteAssignmentDelegateConversion()
        {
            var source = @"
using System;
 
class Program
{
    static void A()
    {
        goto Label;
        int x = 2;
        void Local()
        {
            Console.Write(x);
        }
        Label:
        Action goo = Local;
    }
    static void Main(string[] args)
    {
        A();
    }
}";
            VerifyDiagnostics(source,
                // (9,9): warning CS0162: Unreachable code detected
                //         int x = 2;
                Diagnostic(ErrorCode.WRN_UnreachableCode, "int").WithLocation(9, 9),
                // (15,22): error CS0165: Use of unassigned local variable 'x'
                //         Action goo = Local;
                Diagnostic(ErrorCode.ERR_UseDefViolation, "Local").WithArguments("x").WithLocation(15, 22)
    );
        }
 
        [Fact]
        public void BadDefiniteAssignmentDelegateConstruction()
        {
            var source = @"
using System;
 
class Program
{
    static void A()
    {
        goto Label;
        int x = 2;
        void Local()
        {
            Console.Write(x);
        }
        Label:
        var bar = new Action(Local);
    }
    static void Main(string[] args)
    {
        A();
    }
}";
            VerifyDiagnostics(source,
                // (9,9): warning CS0162: Unreachable code detected
                //         int x = 2;
                Diagnostic(ErrorCode.WRN_UnreachableCode, "int").WithLocation(9, 9),
                // (15,19): error CS0165: Use of unassigned local variable 'x'
                //         var bar = new Action(Local);
                Diagnostic(ErrorCode.ERR_UseDefViolation, "new Action(Local)").WithArguments("x").WithLocation(15, 19)
                );
        }
 
        [Fact]
        public void BadNotUsed()
        {
            var source = @"
class Program
{
    static void A()
    {
        void Local()
        {
        }
    }
    static void Main(string[] args)
    {
        A();
    }
}";
            VerifyDiagnostics(source,
    // (6,14): warning CS8321: The local function 'Local' is declared but never used
    //         void Local()
    Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Local").WithArguments("Local").WithLocation(6, 14)
    );
        }
 
        [Fact]
        public void BadNotUsedSwitch()
        {
            var source = @"
class Program
{
    static void A()
    {
        switch (0)
        {
        case 0:
            void Local()
            {
            }
            break;
        }
    }
    static void Main(string[] args)
    {
        A();
    }
}";
            VerifyDiagnostics(source,
    // (9,18): warning CS8321: The local function 'Local' is declared but never used
    //             void Local()
    Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Local").WithArguments("Local").WithLocation(9, 18)
    );
        }
 
        [Fact]
        public void BadByRefClosure()
        {
            var source = @"
using System;
 
class Program
{
    static void A(ref int x)
    {
        void Local()
        {
            Console.WriteLine(x);
        }
        Local();
    }
    static void Main()
    {
    }
}";
            VerifyDiagnostics(source,
    // (10,31): error CS1628: Cannot use ref or out parameter 'x' inside an anonymous method, lambda expression, query expression, or local function
    //             Console.WriteLine(x);
    Diagnostic(ErrorCode.ERR_AnonDelegateCantUse, "x").WithArguments("x").WithLocation(10, 31)
    );
        }
 
        [Fact]
        public void BadInClosure()
        {
            var source = @"
using System;
 
class Program
{
    static void A(in int x)
    {
        void Local()
        {
            Console.WriteLine(x);
        }
        Local();
    }
    static void Main()
    {
    }
}";
            VerifyDiagnostics(source,
                // (10,31): error CS1628: Cannot use ref, out, or in parameter 'x' inside an anonymous method, lambda expression, query expression, or local function
                //             Console.WriteLine(x);
                Diagnostic(ErrorCode.ERR_AnonDelegateCantUse, "x").WithArguments("x").WithLocation(10, 31)
                );
        }
 
        [Fact]
        public void BadArglistUse()
        {
            var source = @"
using System;
 
class Program
{
    static void A()
    {
        void Local()
        {
            Console.WriteLine(__arglist);
        }
        Local();
    }
    static void B(__arglist)
    {
        void Local()
        {
            Console.WriteLine(__arglist);
        }
        Local();
    }
    static void C() // C and D produce different errors
    {
        void Local(__arglist)
        {
            Console.WriteLine(__arglist);
        }
        Local(__arglist());
    }
    static void D(__arglist)
    {
        void Local(__arglist)
        {
            Console.WriteLine(__arglist);
        }
        Local(__arglist());
    }
    static void Main()
    {
    }
}
";
            VerifyDiagnostics(source,
                // (10,31): error CS0190: The __arglist construct is valid only within a variable argument method
                //             Console.WriteLine(__arglist);
                Diagnostic(ErrorCode.ERR_ArgsInvalid, "__arglist").WithLocation(10, 31),
                // (18,31): error CS4013: Instance of type 'RuntimeArgumentHandle' cannot be used inside a nested function, query expression, iterator block or async method
                //             Console.WriteLine(__arglist);
                Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "__arglist").WithArguments("System.RuntimeArgumentHandle").WithLocation(18, 31),
                // (24,20): error CS1669: __arglist is not valid in this context
                //         void Local(__arglist)
                Diagnostic(ErrorCode.ERR_IllegalVarArgs, "__arglist").WithLocation(24, 20),
                // (26,31): error CS0190: The __arglist construct is valid only within a variable argument method
                //             Console.WriteLine(__arglist);
                Diagnostic(ErrorCode.ERR_ArgsInvalid, "__arglist").WithLocation(26, 31),
                // (32,20): error CS1669: __arglist is not valid in this context
                //         void Local(__arglist)
                Diagnostic(ErrorCode.ERR_IllegalVarArgs, "__arglist").WithLocation(32, 20),
                // (34,31): error CS4013: Instance of type 'RuntimeArgumentHandle' cannot be used inside a nested function, query expression, iterator block or async method
                //             Console.WriteLine(__arglist);
                Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "__arglist").WithArguments("System.RuntimeArgumentHandle").WithLocation(34, 31)
    );
        }
 
        [Fact]
        public void BadClosureStaticRefInstance()
        {
            var source = @"
using System;
 
class Program
{
    int _a = 0;
    static void A()
    {
        void Local()
        {
            Console.WriteLine(_a);
        }
        Local();
    }
    static void Main()
    {
    }
}
";
            VerifyDiagnostics(source,
    // (11,31): error CS0120: An object reference is required for the non-static field, method, or property 'Program._a'
    //             Console.WriteLine(_a);
    Diagnostic(ErrorCode.ERR_ObjectRequired, "_a").WithArguments("Program._a").WithLocation(11, 31)
    );
        }
 
        [Fact]
        public void BadRefIterator()
        {
            var source = @"
using System.Collections.Generic;
 
class Program
{
    static void Main(string[] args)
    {
        IEnumerable<int> RefEnumerable(ref int x)
        {
            yield return x;
        }
        int y = 0;
        RefEnumerable(ref y);
    }
}
";
            VerifyDiagnostics(source,
    // (8,48): error CS1623: Iterators cannot have ref, in or out parameters
    //         IEnumerable<int> RefEnumerable(ref int x)
    Diagnostic(ErrorCode.ERR_BadIteratorArgType, "x").WithLocation(8, 48)
    );
        }
 
        [Fact]
        public void BadRefAsync()
        {
            var source = @"
using System;
using System.Threading.Tasks;
 
class Program
{
    static void Main(string[] args)
    {
        async Task<int> RefAsync(ref int x)
        {
            return await Task.FromResult(x);
        }
        int y = 2;
        Console.Write(RefAsync(ref y).Result);
    }
}
";
            VerifyDiagnostics(source,
    // (9,42): error CS1988: Async methods cannot have ref, in or out parameters
    //         async Task<int> RefAsync(ref int x)
    Diagnostic(ErrorCode.ERR_BadAsyncArgType, "x").WithLocation(9, 42)
    );
        }
 
        [Fact]
        public void Extension_01()
        {
            var source = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        int Local(this int x)
        {
            return x;
        }
        Console.WriteLine(Local(2));
    }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (8,13): error CS1106: Extension method must be defined in a non-generic static class
                //         int Local(this int x)
                Diagnostic(ErrorCode.ERR_BadExtensionAgg, "Local").WithLocation(8, 13)
                );
        }
 
        [Fact]
        public void Extension_02()
        {
            var source =
@"#pragma warning disable 8321
static class E
{
    static void M()
    {
        void F1(this string s) { }
        static void F2(this string s) { }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (6,14): error CS1106: Extension method must be defined in a non-generic static class
                //         void F1(this string s) { }
                Diagnostic(ErrorCode.ERR_BadExtensionAgg, "F1").WithLocation(6, 14),
                // (7,21): error CS1106: Extension method must be defined in a non-generic static class
                //         static void F2(this string s) { }
                Diagnostic(ErrorCode.ERR_BadExtensionAgg, "F2").WithLocation(7, 21));
        }
 
        [Fact]
        public void BadModifiers()
        {
            var source = @"
class Program
{
    static void Main(string[] args)
    {
        const void LocalConst()
        {
        }
        static void LocalStatic()
        {
        }
        readonly void LocalReadonly()
        {
        }
        volatile void LocalVolatile()
        {
        }
        LocalConst();
        LocalStatic();
        LocalReadonly();
        LocalVolatile();
    }
}
";
 
            var baseExpected = new[]
            {
                // (6,9): error CS0106: The modifier 'const' is not valid for this item
                //         const void LocalConst()
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "const").WithArguments("const").WithLocation(6, 9),
                // (12,9): error CS0106: The modifier 'readonly' is not valid for this item
                //         readonly void LocalReadonly()
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "readonly").WithArguments("readonly").WithLocation(12, 9),
                // (15,9): error CS0106: The modifier 'volatile' is not valid for this item
                //         volatile void LocalVolatile()
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "volatile").WithArguments("volatile").WithLocation(15, 9)
            };
 
            var extra = new[]
            {
                // (9,9): error CS8652: The feature 'static local functions' is not available in C# 7.3. Please use language version 8.0 or greater.
                //         static void LocalStatic()
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "static").WithArguments("static local functions", "8.0").WithLocation(9, 9),
            };
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3);
            comp.VerifyDiagnostics(
                baseExpected.Concat(extra).ToArray());
 
            comp = CreateCompilation(source, parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(baseExpected);
 
            comp = CreateCompilation(source, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(baseExpected);
        }
 
        [Fact]
        public void ArglistIterator()
        {
            var source = @"
using System;
using System.Collections.Generic;
 
class Program
{
    static void Main(string[] args)
    {
        IEnumerable<int> Local(__arglist)
        {
            yield return 2;
        }
        Console.WriteLine(string.Join("","", Local(__arglist())));
    }
}
";
            VerifyDiagnostics(source,
                // (9,26): error CS1636: __arglist is not allowed in the parameter list of iterators
                //         IEnumerable<int> Local(__arglist)
                Diagnostic(ErrorCode.ERR_VarargsIterator, "Local").WithLocation(9, 26),
                // (9,32): error CS1669: __arglist is not valid in this context
                //         IEnumerable<int> Local(__arglist)
                Diagnostic(ErrorCode.ERR_IllegalVarArgs, "__arglist").WithLocation(9, 32));
        }
 
        [Fact]
        public void ForwardReference()
        {
            var source = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Local());
        int Local() => 2;
    }
}
";
            CompileAndVerify(source, expectedOutput: "2");
        }
 
        [Fact]
        public void ForwardReferenceCapture()
        {
            var source = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        int x = 2;
        Console.WriteLine(Local());
        int Local() => x;
    }
}
";
            CompileAndVerify(source, expectedOutput: "2");
        }
 
        [Fact]
        public void ForwardRefInLocalFunc()
        {
            var source = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        int x = 2;
        Console.WriteLine(Local());
        int Local()
        {
            x = 3;
            return Local2();
        }
        int Local2() => x;
    }
}
";
            CompileAndVerify(source, expectedOutput: "3");
        }
 
        [Fact]
        public void LocalFuncMutualRecursion()
        {
            var source = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        int x = 5;
        int y = 0;
        Console.WriteLine(Local1());
        int Local1()
        {
            x -= 1;
            return Local2(y++);
        }
        int Local2(int z)
        {
            if (x == 0)
            {
                return z;
            }
            else
            {
                return Local1();
            }
        }
    }
}
";
            CompileAndVerify(source, expectedOutput: "4");
        }
 
        [Fact]
        public void OtherSwitchBlock()
        {
            var source = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        var x = int.Parse(Console.ReadLine());
        switch (x)
        {
        case 0:
            void Local()
            {
            }
            break;
        default:
            Local();
            break;
        }
    }
}
";
            VerifyDiagnostics(source);
        }
 
        [Fact]
        public void NoOperator()
        {
            var source = @"
class Program
{
    static void Main(string[] args)
    {
        Program operator +(Program left, Program right)
        {
            return left;
        }
    }
}
";
            VerifyDiagnostics(source,
                // (6,17): error CS1002: ; expected
                //         Program operator +(Program left, Program right)
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "operator").WithLocation(6, 17),
                // (6,17): error CS1513: } expected
                //         Program operator +(Program left, Program right)
                Diagnostic(ErrorCode.ERR_RbraceExpected, "operator").WithLocation(6, 17),
                // (6,56): error CS1002: ; expected
                //         Program operator +(Program left, Program right)
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(6, 56),
                // (6,9): error CS0119: 'Program' is a type, which is not valid in the given context
                //         Program operator +(Program left, Program right)
                Diagnostic(ErrorCode.ERR_BadSKunknown, "Program").WithArguments("Program", "type").WithLocation(6, 9),
                // (6,28): error CS8185: A declaration is not allowed in this context.
                //         Program operator +(Program left, Program right)
                Diagnostic(ErrorCode.ERR_DeclarationExpressionNotPermitted, "Program left").WithLocation(6, 28),
                // (6,42): error CS8185: A declaration is not allowed in this context.
                //         Program operator +(Program left, Program right)
                Diagnostic(ErrorCode.ERR_DeclarationExpressionNotPermitted, "Program right").WithLocation(6, 42),
                // (6,27): error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported
                //         Program operator +(Program left, Program right)
                Diagnostic(ErrorCode.ERR_PredefinedValueTupleTypeNotFound, "(Program left, Program right)").WithArguments("System.ValueTuple`2").WithLocation(6, 27),
                // (8,13): error CS0127: Since 'Program.Main(string[])' returns void, a return keyword must not be followed by an object expression
                //             return left;
                Diagnostic(ErrorCode.ERR_RetNoObjectRequired, "return").WithArguments("Program.Main(string[])").WithLocation(8, 13),
                // (6,28): error CS0165: Use of unassigned local variable 'left'
                //         Program operator +(Program left, Program right)
                Diagnostic(ErrorCode.ERR_UseDefViolation, "Program left").WithArguments("left").WithLocation(6, 28),
                // (6,42): error CS0165: Use of unassigned local variable 'right'
                //         Program operator +(Program left, Program right)
                Diagnostic(ErrorCode.ERR_UseDefViolation, "Program right").WithArguments("right").WithLocation(6, 42)
                );
        }
 
        [Fact]
        public void NoProperty()
        {
            var source = @"
class Program
{
    static void Main(string[] args)
    {
        int Goo
        {
            get
            {
                return 2;
            }
        }
        int Bar => 2;
    }
}
";
            VerifyDiagnostics(source,
                // (6,16): error CS1002: ; expected
                //         int Goo
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(6, 16),
                // (8,16): error CS1002: ; expected
                //             get
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(8, 16),
                // (13,17): error CS1003: Syntax error, ',' expected
                //         int Bar => 2;
                Diagnostic(ErrorCode.ERR_SyntaxError, "=>").WithArguments(",").WithLocation(13, 17),
                // (13,20): error CS1002: ; expected
                //         int Bar => 2;
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "2").WithLocation(13, 20),
                // (8,13): error CS0103: The name 'get' does not exist in the current context
                //             get
                Diagnostic(ErrorCode.ERR_NameNotInContext, "get").WithArguments("get").WithLocation(8, 13),
                // (10,17): error CS0127: Since 'Program.Main(string[])' returns void, a return keyword must not be followed by an object expression
                //                 return 2;
                Diagnostic(ErrorCode.ERR_RetNoObjectRequired, "return").WithArguments("Program.Main(string[])").WithLocation(10, 17),
                // (13,20): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement
                //         int Bar => 2;
                Diagnostic(ErrorCode.ERR_IllegalStatement, "2").WithLocation(13, 20),
                // (13,9): warning CS0162: Unreachable code detected
                //         int Bar => 2;
                Diagnostic(ErrorCode.WRN_UnreachableCode, "int").WithLocation(13, 9),
                // (6,13): warning CS0168: The variable 'Goo' is declared but never used
                //         int Goo
                Diagnostic(ErrorCode.WRN_UnreferencedVar, "Goo").WithArguments("Goo").WithLocation(6, 13),
                // (13,13): warning CS0168: The variable 'Bar' is declared but never used
                //         int Bar => 2;
                Diagnostic(ErrorCode.WRN_UnreferencedVar, "Bar").WithArguments("Bar").WithLocation(13, 13)
                );
        }
 
        [Fact]
        public void NoFeatureSwitch()
        {
            var source = @"
class Program
{
    static void Main(string[] args)
    {
        void Local() { }
        Local();
    }
}
";
            var option = TestOptions.ReleaseExe;
            CreateCompilation(source, options: option, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp6)).VerifyDiagnostics(
                // (6,14): error CS8059: Feature 'local functions' is not available in C# 6. Please use language version 7.0 or greater.
                //         void Local() { }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion6, "Local").WithArguments("local functions", "7.0").WithLocation(6, 14)
                );
        }
 
        [Fact, WorkItem(10521, "https://github.com/dotnet/roslyn/issues/10521")]
        public void LocalFunctionInIf()
        {
            var source = @"
class Program
{
    static void Main(string[] args)
    {
        if () // typing at this point
        int Add(int x, int y) => x + y;
    }
}
";
            VerifyDiagnostics(source,
                // (6,13): error CS1525: Invalid expression term ')'
                //         if () // typing at this point
                Diagnostic(ErrorCode.ERR_InvalidExprTerm, ")").WithArguments(")").WithLocation(6, 13),
                // (7,9): error CS1023: Embedded statement cannot be a declaration or labeled statement
                //         int Add(int x, int y) => x + y;
                Diagnostic(ErrorCode.ERR_BadEmbeddedStmt, "int Add(int x, int y) => x + y;").WithLocation(7, 9),
                // (7,13): warning CS8321: The local function 'Add' is declared but never used
                //         int Add(int x, int y) => x + y;
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Add").WithArguments("Add").WithLocation(7, 13)
                );
        }
 
        [Fact, WorkItem(10521, "https://github.com/dotnet/roslyn/issues/10521")]
        public void LabeledLocalFunctionInIf()
        {
            var source = @"
class Program
{
    static void Main(string[] args)
    {
        if () // typing at this point
a:      int Add(int x, int y) => x + y;
    }
}
";
            VerifyDiagnostics(source,
                // (6,13): error CS1525: Invalid expression term ')'
                //         if () // typing at this point
                Diagnostic(ErrorCode.ERR_InvalidExprTerm, ")").WithArguments(")").WithLocation(6, 13),
                // (7,1): error CS1023: Embedded statement cannot be a declaration or labeled statement
                // a:      int Add(int x, int y) => x + y;
                Diagnostic(ErrorCode.ERR_BadEmbeddedStmt, "a:      int Add(int x, int y) => x + y;").WithLocation(7, 1),
                // (7,1): warning CS0164: This label has not been referenced
                // a:      int Add(int x, int y) => x + y;
                Diagnostic(ErrorCode.WRN_UnreferencedLabel, "a").WithLocation(7, 1),
                // (7,13): warning CS8321: The local function 'Add' is declared but never used
                // a:      int Add(int x, int y) => x + y;
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Add").WithArguments("Add").WithLocation(7, 13)
                );
        }
 
        [CompilerTrait(CompilerFeature.LocalFunctions, CompilerFeature.Var)]
        public sealed class VarTests : LocalFunctionsTestBase
        {
            [Fact]
            public void IllegalAsReturn()
            {
                var source = @"
using System;
class Program
{
    static void Main()
    {
        var f() => 42;
        Console.WriteLine(f());
    }
}";
                var comp = CreateCompilationWithMscorlib461(source, parseOptions: DefaultParseOptions);
                comp.VerifyDiagnostics(
                    // (7,9): error CS0825: The contextual keyword 'var' may only appear within a local variable declaration or in script code
                    //         var f() => 42;
                    Diagnostic(ErrorCode.ERR_TypeVarNotFound, "var").WithLocation(7, 9));
            }
 
            [Fact]
            public void RealTypeAsReturn()
            {
                var source = @"
using System;
class var 
{
    public override string ToString() => ""dog"";
}
 
class Program
{
    static void Main()
    {
        var f() => new var();
        Console.WriteLine(f());
    }
}";
 
                CompileAndVerify(
                    source,
                    parseOptions: DefaultParseOptions,
                    expectedOutput: "dog");
            }
 
            [Fact]
            public void RealTypeParameterAsReturn()
            {
                var source = @"
using System;
class test 
{
    public override string ToString() => ""dog"";
}
 
class Program
{
    static void Test<var>(var x)
    {
        var f() => x;
        Console.WriteLine(f());
    }
 
    static void Main()
    {
        Test(new test());
    }
}";
 
                CompileAndVerify(
                    source,
                    parseOptions: DefaultParseOptions,
                    expectedOutput: "dog");
            }
 
            [Fact]
            public void IdentifierAndTypeNamedVar()
            {
                var source = @"
using System;
class var 
{
    public override string ToString() => ""dog"";
}
 
class Program
{
    static void Main()
    {
        int var = 42;
        var f() => new var();
        Console.WriteLine($""{f()}-{var}"");
    }
}";
 
                CompileAndVerify(
                    source,
                    parseOptions: DefaultParseOptions,
                    expectedOutput: "dog-42");
            }
        }
 
        [CompilerTrait(CompilerFeature.LocalFunctions, CompilerFeature.Async)]
        public sealed class AsyncTests : LocalFunctionsTestBase
        {
            [Fact]
            public void RealTypeAsReturn()
            {
                var source = @"
using System;
class async 
{
    public override string ToString() => ""dog"";
}
 
class Program
{
    static void Main()
    {
        async f() => new async();
        Console.WriteLine(f());
    }
}";
 
                CompileAndVerify(
                    source,
                    parseOptions: DefaultParseOptions,
                    expectedOutput: "dog");
            }
 
            [Fact]
            public void RealTypeParameterAsReturn()
            {
                var source = @"
using System;
class test 
{
    public override string ToString() => ""dog"";
}
 
class Program
{
    static void Test<async>(async x)
    {
        async f() => x;
        Console.WriteLine(f());
    }
 
    static void Main()
    {
        Test(new test());
    }
}";
 
                CompileAndVerify(
                    source,
                    parseOptions: DefaultParseOptions,
                    expectedOutput: "dog");
            }
 
            [Fact]
            public void ManyMeaningsType()
            {
                var source = @"
using System;
using System.Threading;
using System.Threading.Tasks;
 
class async 
{
    public override string ToString() => ""async"";
}
 
class Program
{
    static void Main()
    {
        async Task<async> Test(Task<async> t)
        {
            async local = await t;
            Console.WriteLine(local);
            return local;
        }
 
        Test(Task.FromResult<async>(new async())).Wait();
    }
}";
 
                var comp = CreateCompilationWithMscorlib46(source, parseOptions: DefaultParseOptions, options: TestOptions.DebugExe);
                CompileAndVerify(
                    comp,
                    expectedOutput: "async");
            }
        }
 
        [Fact]
        [WorkItem(12467, "https://github.com/dotnet/roslyn/issues/12467")]
        public void ParamUnassigned_01()
        {
            var src = @"
class C
{
    public void M1()
    {
        void TakeOutParam1(out int x)
        {
        }
 
        int y;
        TakeOutParam1(out y);
    }
 
        void TakeOutParam2(out int x)
        {
        }
}";
            VerifyDiagnostics(src,
                // (6,14): error CS0177: The out parameter 'x' must be assigned to before control leaves the current method
                //         void TakeOutParam1(out int x)
                Diagnostic(ErrorCode.ERR_ParamUnassigned, "TakeOutParam1").WithArguments("x").WithLocation(6, 14),
                // (14,14): error CS0177: The out parameter 'x' must be assigned to before control leaves the current method
                //         void TakeOutParam2(out int x)
                Diagnostic(ErrorCode.ERR_ParamUnassigned, "TakeOutParam2").WithArguments("x").WithLocation(14, 14)
                );
        }
 
        [Fact]
        [WorkItem(12467, "https://github.com/dotnet/roslyn/issues/12467")]
        public void ParamUnassigned_02()
        {
            var src = @"
class C
{
    public void M1()
    {
        void TakeOutParam1(out int x)
        {
            return; // 1 
        }
 
        int y;
        TakeOutParam1(out y);
    }
 
        void TakeOutParam2(out int x)
        {
            return; // 2 
        }
}";
            VerifyDiagnostics(src,
                // (8,13): error CS0177: The out parameter 'x' must be assigned to before control leaves the current method
                //             return; // 1 
                Diagnostic(ErrorCode.ERR_ParamUnassigned, "return;").WithArguments("x").WithLocation(8, 13),
                // (17,13): error CS0177: The out parameter 'x' must be assigned to before control leaves the current method
                //             return; // 2 
                Diagnostic(ErrorCode.ERR_ParamUnassigned, "return;").WithArguments("x").WithLocation(17, 13)
                );
        }
 
        [Fact]
        [WorkItem(12467, "https://github.com/dotnet/roslyn/issues/12467")]
        public void ParamUnassigned_03()
        {
            var src = @"
class C
{
    public void M1()
    {
        int TakeOutParam1(out int x)
        {
        }
 
        int y;
        TakeOutParam1(out y);
    }
 
        int TakeOutParam2(out int x)
        {
        }
}";
            VerifyDiagnostics(src,
                // (6,13): error CS0161: 'TakeOutParam1(out int)': not all code paths return a value
                //         int TakeOutParam1(out int x)
                Diagnostic(ErrorCode.ERR_ReturnExpected, "TakeOutParam1").WithArguments("TakeOutParam1(out int)").WithLocation(6, 13),
                // (6,13): error CS0177: The out parameter 'x' must be assigned to before control leaves the current method
                //         int TakeOutParam1(out int x)
                Diagnostic(ErrorCode.ERR_ParamUnassigned, "TakeOutParam1").WithArguments("x").WithLocation(6, 13),
                // (14,13): error CS0177: The out parameter 'x' must be assigned to before control leaves the current method
                //         int TakeOutParam2(out int x)
                Diagnostic(ErrorCode.ERR_ParamUnassigned, "TakeOutParam2").WithArguments("x").WithLocation(14, 13),
                // (14,13): error CS0161: 'C.TakeOutParam2(out int)': not all code paths return a value
                //         int TakeOutParam2(out int x)
                Diagnostic(ErrorCode.ERR_ReturnExpected, "TakeOutParam2").WithArguments("C.TakeOutParam2(out int)").WithLocation(14, 13)
                );
        }
 
        [Fact]
        [WorkItem(12467, "https://github.com/dotnet/roslyn/issues/12467")]
        public void ParamUnassigned_04()
        {
            var src = @"
class C
{
    public void M1()
    {
        int TakeOutParam1(out int x)
        {
            return 1;
        }
 
        int y;
        TakeOutParam1(out y);
    }
 
        int TakeOutParam2(out int x)
        {
            return 2;
        }
}";
            VerifyDiagnostics(src,
                // (8,13): error CS0177: The out parameter 'x' must be assigned to before control leaves the current method
                //             return 1;
                Diagnostic(ErrorCode.ERR_ParamUnassigned, "return 1;").WithArguments("x").WithLocation(8, 13),
                // (17,13): error CS0177: The out parameter 'x' must be assigned to before control leaves the current method
                //             return 2;
                Diagnostic(ErrorCode.ERR_ParamUnassigned, "return 2;").WithArguments("x").WithLocation(17, 13)
                );
        }
 
        [Fact]
        [WorkItem(49500, "https://github.com/dotnet/roslyn/issues/49500")]
        public void OutParam_Extern_01()
        {
            var src = @"
using System.Runtime.InteropServices;
 
class C
{
    void M()
    {
        int x;
        local(out x);
        x.ToString();
 
        [DllImport(""a"")]
        static extern void local(out int x);
    }
 
    [DllImport(""a"")]
    static extern void Method(out int x);
}";
            VerifyDiagnostics(src);
        }
 
        [Fact]
        [WorkItem(49500, "https://github.com/dotnet/roslyn/issues/49500")]
        public void OutParam_Extern_02()
        {
            var src = @"
using System.Runtime.InteropServices;
 
class C
{
    void M()
    {
        local1(out _);
        local2(out _);
        local3(out _);
 
        [DllImport(""a"")]
        static extern void local1(out int x) { } // 1
 
        static void local2(out int x) { } // 2
 
        static void local3(out int x); // 3, 4
    }
 
    [DllImport(""a"")]
    static extern void Method(out int x);
}";
            VerifyDiagnostics(src,
                // (13,28): error CS0179: 'local1(out int)' cannot be extern and declare a body
                //         static extern void local1(out int x) { } // 1
                Diagnostic(ErrorCode.ERR_ExternHasBody, "local1").WithArguments("local1(out int)").WithLocation(13, 28),
                // (15,21): error CS0177: The out parameter 'x' must be assigned to before control leaves the current method
                //         static void local2(out int x) { } // 2
                Diagnostic(ErrorCode.ERR_ParamUnassigned, "local2").WithArguments("x").WithLocation(15, 21),
                // (17,21): error CS8112: Local function 'local3(out int)' must declare a body because it is not marked 'static extern'.
                //         static void local3(out int x); // 3, 4
                Diagnostic(ErrorCode.ERR_LocalFunctionMissingBody, "local3").WithArguments("local3(out int)").WithLocation(17, 21),
                // (17,21): error CS0177: The out parameter 'x' must be assigned to before control leaves the current method
                //         static void local3(out int x); // 3, 4
                Diagnostic(ErrorCode.ERR_ParamUnassigned, "local3").WithArguments("x").WithLocation(17, 21));
        }
 
        [Fact]
        [WorkItem(13172, "https://github.com/dotnet/roslyn/issues/13172")]
        public void InheritUnsafeContext()
        {
            var comp = CreateCompilationWithMscorlib46(@"
using System;
using System.Threading.Tasks;
class C
{
    public void M1()
    {
        async Task<IntPtr> Local()
        {
            await Task.Delay(0);
            return (IntPtr)(void*)null;
        }
        var _ = Local();
    }
 
    public void M2()
    {
        unsafe
        {
            async Task<IntPtr> Local()
            {
                await Task.Delay(1);
                return (IntPtr)(void*)null;
            }
            var _ = Local();
        }
    }
 
    public unsafe void M3()
    {
        async Task<IntPtr> Local()
        {
            await Task.Delay(2);
            return (IntPtr)(void*)null;
        }
        var _ = Local();
    }
}
 
unsafe class D
{
    int* p = null;
    public void M()
    {
        async Task<IntPtr> Local()
        {
            await Task.Delay(3);
            return (IntPtr)p;
        }
        var _ = Local();
    }
 
    public unsafe void M2()
    {
        unsafe
        {
            async Task<IntPtr> Local()
            {
                await Task.Delay(4);
                return (IntPtr)(void*)null;
            }
            var _ = Local();
        }
    }
}", options: TestOptions.UnsafeDebugDll);
            comp.VerifyDiagnostics(
                // (11,29): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //             return (IntPtr)(void*)null;
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "void*").WithLocation(11, 29),
                // (11,28): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //             return (IntPtr)(void*)null;
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "(void*)null").WithLocation(11, 28),
                // (47,13): error CS4004: Cannot await in an unsafe context
                //             await Task.Delay(3);
                Diagnostic(ErrorCode.ERR_AwaitInUnsafeContext, "await Task.Delay(3)").WithLocation(47, 13),
                // (22,17): error CS4004: Cannot await in an unsafe context
                //                 await Task.Delay(1);
                Diagnostic(ErrorCode.ERR_AwaitInUnsafeContext, "await Task.Delay(1)").WithLocation(22, 17),
                // (59,17): error CS4004: Cannot await in an unsafe context
                //                 await Task.Delay(4);
                Diagnostic(ErrorCode.ERR_AwaitInUnsafeContext, "await Task.Delay(4)").WithLocation(59, 17),
                // (33,13): error CS4004: Cannot await in an unsafe context
                //             await Task.Delay(2);
                Diagnostic(ErrorCode.ERR_AwaitInUnsafeContext, "await Task.Delay(2)").WithLocation(33, 13));
        }
 
        [Fact, WorkItem(16167, "https://github.com/dotnet/roslyn/issues/16167")]
        public void DeclarationInLocalFunctionParameterDefault()
        {
            var text = @"
class C
{
    public static void Main(int arg)
    {
        void Local1(bool b = M(arg is int z1, z1), int s1 = z1) {}
        void Local2(bool b = M(M(out int z2), z2), int s2 = z2) {}
        void Local3(bool b = M(M((int z3, int a2) = (1, 2)), z3), int a3 = z3) {}
 
        void Local4(bool b = M(arg is var z4, z4), int s1 = z4) {}
        void Local5(bool b = M(M(out var z5), z5), int s2 = z5) {}
        void Local6(bool b = M(M((var z6, int a2) = (1, 2)), z6), int a3 = z6) {}
 
        int t = z1 + z2 + z3 + z4 + z5 + z6;
    }
    static bool M(out int z) // needed to infer type of z5
    {
        z = 1;
        return true;
    }
    static bool M(params object[] args) => true;
}
namespace System
{
    public struct ValueTuple<T1, T2>
    {
        public T1 Item1;
        public T2 Item2;
        public ValueTuple(T1 item1, T2 item2)
        {
            Item1 = item1;
            Item2 = item2;
        }
    }
}
";
            // the scope of an expression variable introduced in the default expression
            // of a local function parameter is that default expression.
            var compilation = CreateCompilationWithMscorlib461(text);
            compilation.VerifyDiagnostics(
                // (6,30): error CS1736: Default parameter value for 'b' must be a compile-time constant
                //         void Local1(bool b = M(arg is int z1, z1), int s1 = z1) {}
                Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "M(arg is int z1, z1)").WithArguments("b").WithLocation(6, 30),
                // (6,61): error CS0103: The name 'z1' does not exist in the current context
                //         void Local1(bool b = M(arg is int z1, z1), int s1 = z1) {}
                Diagnostic(ErrorCode.ERR_NameNotInContext, "z1").WithArguments("z1").WithLocation(6, 61),
                // (7,30): error CS1736: Default parameter value for 'b' must be a compile-time constant
                //         void Local2(bool b = M(M(out int z2), z2), int s2 = z2) {}
                Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "M(M(out int z2), z2)").WithArguments("b").WithLocation(7, 30),
                // (7,61): error CS0103: The name 'z2' does not exist in the current context
                //         void Local2(bool b = M(M(out int z2), z2), int s2 = z2) {}
                Diagnostic(ErrorCode.ERR_NameNotInContext, "z2").WithArguments("z2").WithLocation(7, 61),
                // (8,35): error CS8185: A declaration is not allowed in this context.
                //         void Local3(bool b = M(M((int z3, int a2) = (1, 2)), z3), int a3 = z3) {}
                Diagnostic(ErrorCode.ERR_DeclarationExpressionNotPermitted, "int z3").WithLocation(8, 35),
                // (8,30): error CS1736: Default parameter value for 'b' must be a compile-time constant
                //         void Local3(bool b = M(M((int z3, int a2) = (1, 2)), z3), int a3 = z3) {}
                Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "M(M((int z3, int a2) = (1, 2)), z3)").WithArguments("b").WithLocation(8, 30),
                // (8,76): error CS0103: The name 'z3' does not exist in the current context
                //         void Local3(bool b = M(M((int z3, int a2) = (1, 2)), z3), int a3 = z3) {}
                Diagnostic(ErrorCode.ERR_NameNotInContext, "z3").WithArguments("z3").WithLocation(8, 76),
                // (10,30): error CS1736: Default parameter value for 'b' must be a compile-time constant
                //         void Local4(bool b = M(arg is var z4, z4), int s1 = z4) {}
                Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "M(arg is var z4, z4)").WithArguments("b").WithLocation(10, 30),
                // (10,61): error CS0103: The name 'z4' does not exist in the current context
                //         void Local4(bool b = M(arg is var z4, z4), int s1 = z4) {}
                Diagnostic(ErrorCode.ERR_NameNotInContext, "z4").WithArguments("z4").WithLocation(10, 61),
                // (11,30): error CS1736: Default parameter value for 'b' must be a compile-time constant
                //         void Local5(bool b = M(M(out var z5), z5), int s2 = z5) {}
                Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "M(M(out var z5), z5)").WithArguments("b").WithLocation(11, 30),
                // (11,61): error CS0103: The name 'z5' does not exist in the current context
                //         void Local5(bool b = M(M(out var z5), z5), int s2 = z5) {}
                Diagnostic(ErrorCode.ERR_NameNotInContext, "z5").WithArguments("z5").WithLocation(11, 61),
                // (12,35): error CS8185: A declaration is not allowed in this context.
                //         void Local6(bool b = M(M((var z6, int a2) = (1, 2)), z6), int a3 = z6) {}
                Diagnostic(ErrorCode.ERR_DeclarationExpressionNotPermitted, "var z6").WithLocation(12, 35),
                // (12,30): error CS1736: Default parameter value for 'b' must be a compile-time constant
                //         void Local6(bool b = M(M((var z6, int a2) = (1, 2)), z6), int a3 = z6) {}
                Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "M(M((var z6, int a2) = (1, 2)), z6)").WithArguments("b").WithLocation(12, 30),
                // (12,76): error CS0103: The name 'z6' does not exist in the current context
                //         void Local6(bool b = M(M((var z6, int a2) = (1, 2)), z6), int a3 = z6) {}
                Diagnostic(ErrorCode.ERR_NameNotInContext, "z6").WithArguments("z6").WithLocation(12, 76),
                // (14,17): error CS0103: The name 'z1' does not exist in the current context
                //         int t = z1 + z2 + z3 + z4 + z5 + z6;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "z1").WithArguments("z1").WithLocation(14, 17),
                // (14,22): error CS0103: The name 'z2' does not exist in the current context
                //         int t = z1 + z2 + z3 + z4 + z5 + z6;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "z2").WithArguments("z2").WithLocation(14, 22),
                // (14,27): error CS0103: The name 'z3' does not exist in the current context
                //         int t = z1 + z2 + z3 + z4 + z5 + z6;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "z3").WithArguments("z3").WithLocation(14, 27),
                // (14,32): error CS0103: The name 'z4' does not exist in the current context
                //         int t = z1 + z2 + z3 + z4 + z5 + z6;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "z4").WithArguments("z4").WithLocation(14, 32),
                // (14,37): error CS0103: The name 'z5' does not exist in the current context
                //         int t = z1 + z2 + z3 + z4 + z5 + z6;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "z5").WithArguments("z5").WithLocation(14, 37),
                // (14,42): error CS0103: The name 'z6' does not exist in the current context
                //         int t = z1 + z2 + z3 + z4 + z5 + z6;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "z6").WithArguments("z6").WithLocation(14, 42),
                // (6,14): warning CS8321: The local function 'Local1' is declared but never used
                //         void Local1(bool b = M(arg is int z1, z1), int s1 = z1) {}
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Local1").WithArguments("Local1").WithLocation(6, 14),
                // (7,14): warning CS8321: The local function 'Local2' is declared but never used
                //         void Local2(bool b = M(M(out int z2), z2), int s2 = z2) {}
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Local2").WithArguments("Local2").WithLocation(7, 14),
                // (8,14): warning CS8321: The local function 'Local3' is declared but never used
                //         void Local3(bool b = M(M((int z3, int a2) = (1, 2)), z3), int a3 = z3) {}
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Local3").WithArguments("Local3").WithLocation(8, 14),
                // (10,14): warning CS8321: The local function 'Local4' is declared but never used
                //         void Local4(bool b = M(arg is var z4, z4), int s1 = z4) {}
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Local4").WithArguments("Local4").WithLocation(10, 14),
                // (11,14): warning CS8321: The local function 'Local5' is declared but never used
                //         void Local5(bool b = M(M(out var z5), z5), int s2 = z5) {}
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Local5").WithArguments("Local5").WithLocation(11, 14),
                // (12,14): warning CS8321: The local function 'Local6' is declared but never used
                //         void Local6(bool b = M(M((var z6, int a2) = (1, 2)), z6), int a3 = z6) {}
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Local6").WithArguments("Local6").WithLocation(12, 14)
                );
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
            var descendents = tree.GetRoot().DescendantNodes();
            for (int i = 1; i <= 6; i++)
            {
                var name = $"z{i}";
                var designation = descendents.OfType<SingleVariableDesignationSyntax>().Where(d => d.Identifier.ValueText == name).Single();
                var symbol = (ILocalSymbol)model.GetDeclaredSymbol(designation);
                Assert.NotNull(symbol);
                Assert.Equal("System.Int32", symbol.Type.ToTestDisplayString());
                var refs = descendents.OfType<IdentifierNameSyntax>().Where(n => n.Identifier.ValueText == name).ToArray();
                Assert.Equal(3, refs.Length);
                Assert.Equal(symbol, model.GetSymbolInfo(refs[0]).Symbol);
                Assert.Null(model.GetSymbolInfo(refs[1]).Symbol);
                Assert.Null(model.GetSymbolInfo(refs[2]).Symbol);
            }
        }
 
        [Fact]
        [WorkItem(16757, "https://github.com/dotnet/roslyn/issues/16757")]
        public void LocalFunctionParameterDefaultUsingConst()
        {
            var source = @"
class C
{
    public static void Main()
    {
        const int N = 2;
        void Local1(int n = N) { System.Console.Write(n); }
        Local1();
        Local1(3);
    }
}
";
            CompileAndVerify(source, expectedOutput: "23", sourceSymbolValidator: m =>
            {
                var compilation = m.DeclaringCompilation;
                compilation.VerifyDiagnostics();
                var tree = compilation.SyntaxTrees[0];
                var model = compilation.GetSemanticModel(tree);
                var descendents = tree.GetRoot().DescendantNodes();
 
                var parameter = descendents.OfType<ParameterSyntax>().Single();
                Assert.Equal("int n = N", parameter.ToString());
                Assert.Equal("[System.Int32 n = 2]", model.GetDeclaredSymbol(parameter).ToTestDisplayString());
 
                var name = "N";
                var declarator = descendents.OfType<VariableDeclaratorSyntax>().Where(d => d.Identifier.ValueText == name).Single();
                var symbol = (ILocalSymbol)model.GetDeclaredSymbol(declarator);
                Assert.NotNull(symbol);
                Assert.Equal("System.Int32 N", symbol.ToTestDisplayString());
                var refs = descendents.OfType<IdentifierNameSyntax>().Where(n => n.Identifier.ValueText == name).ToArray();
                Assert.Equal(1, refs.Length);
                Assert.Same(symbol, model.GetSymbolInfo(refs[0]).Symbol);
            });
        }
 
        [Fact, WorkItem(16821, "https://github.com/dotnet/roslyn/issues/16821")]
        public void LocalFunction_ParameterDefaultValue_NameOfLocalFunction()
        {
            var source = """
                using System;
                void Local() {}
                void Local2(string s = nameof(Local)) => Console.WriteLine(s);
                Local2();
                """;
            CreateCompilation(source).VerifyDiagnostics();
        }
 
        [Fact]
        [WorkItem(15536, "https://github.com/dotnet/roslyn/issues/15536")]
        public void CallFromDifferentSwitchSection_01()
        {
            var source = @"
class Program
{
    static void Main()
    {
        Test(string.Empty);
    }
 
    static void Test(object o)
    {
        switch (o)
        {
            case string x:
                Assign();
                Print();
                break;
            case int x:
                void Assign() { x = 5; }
                void Print() => System.Console.WriteLine(x);
                break;
        }
    }
}";
 
            var comp = CreateCompilationWithMscorlib46(source, parseOptions: DefaultParseOptions, options: TestOptions.DebugExe);
            CompileAndVerify(comp, expectedOutput: "5");
        }
 
        [Fact]
        [WorkItem(15536, "https://github.com/dotnet/roslyn/issues/15536")]
        public void CallFromDifferentSwitchSection_02()
        {
            var source = @"
class Program
{
    static void Main()
    {
        Test(string.Empty);
    }
 
    static void Test(object o)
    {
        switch (o)
        {
            case int x:
                void Assign() { x = 5; }
                void Print() => System.Console.WriteLine(x);
                break;
            case string x:
                Assign();
                Print();
                break;
        }
    }
}";
 
            var comp = CreateCompilationWithMscorlib46(source, parseOptions: DefaultParseOptions, options: TestOptions.DebugExe);
            CompileAndVerify(comp, expectedOutput: "5");
        }
 
        [Fact]
        [WorkItem(15536, "https://github.com/dotnet/roslyn/issues/15536")]
        public void CallFromDifferentSwitchSection_03()
        {
            var source = @"
class Program
{
    static void Main()
    {
        Test(string.Empty);
    }
 
    static void Test(object o)
    {
        switch (o)
        {
            case string x:
                Assign();
                System.Action p = Print;
                p();
                break;
            case int x:
                void Assign() { x = 5; }
                void Print() => System.Console.WriteLine(x);
                break;
        }
    }
}";
 
            var comp = CreateCompilationWithMscorlib46(source, parseOptions: DefaultParseOptions, options: TestOptions.DebugExe);
            CompileAndVerify(comp, expectedOutput: "5");
        }
 
        [Fact]
        [WorkItem(15536, "https://github.com/dotnet/roslyn/issues/15536")]
        public void CallFromDifferentSwitchSection_04()
        {
            var source = @"
class Program
{
    static void Main()
    {
        Test(string.Empty);
    }
 
    static void Test(object o)
    {
        switch (o)
        {
            case int x:
                void Assign() { x = 5; }
                void Print() => System.Console.WriteLine(x);
                break;
            case string x:
                Assign();
                System.Action p = Print;
                p();
                break;
        }
    }
}";
 
            var comp = CreateCompilationWithMscorlib46(source, parseOptions: DefaultParseOptions, options: TestOptions.DebugExe);
            CompileAndVerify(comp, expectedOutput: "5");
        }
 
        [Fact]
        [WorkItem(15536, "https://github.com/dotnet/roslyn/issues/15536")]
        public void CallFromDifferentSwitchSection_05()
        {
            var source = @"
class Program
{
    static void Main()
    {
        Test(string.Empty);
    }
 
    static void Test(object o)
    {
        switch (o)
        {
            case string x:
                Local1();
                break;
             case int x:
                void Local1() => Local2(x = 5);
                break;
             case char x:
                void Local2(int y)
                {
                    System.Console.WriteLine(x = 'a');
                    System.Console.WriteLine(y);
                }
                break;
        }
    }
}";
 
            var comp = CreateCompilationWithMscorlib46(source, parseOptions: DefaultParseOptions, options: TestOptions.DebugExe);
            CompileAndVerify(comp, expectedOutput:
@"a
5");
        }
 
        [Fact]
        [WorkItem(16751, "https://github.com/dotnet/roslyn/issues/16751")]
        public void SemanticModelInAttribute_01()
        {
            var source =
@"
public class X
{
    public static void Main()
    {
        const bool b1 = true;
 
        void Local1(
            [Test(p = b1)]
            [Test(p = b2)]
            int p1)
        {
        }
 
        Local1(1);
    }
}
 
class b1 {}
 
class Test : System.Attribute
{
    public bool p {get; set;}
}
";
            var compilation = CreateCompilationWithMscorlib461(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular9);
            compilation.VerifyDiagnostics(
                // (10,23): error CS0103: The name 'b2' does not exist in the current context
                //             [Test(p = b2)]
                Diagnostic(ErrorCode.ERR_NameNotInContext, "b2").WithArguments("b2").WithLocation(10, 23)
                );
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var b2 = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "b2").Single();
            Assert.Null(model.GetSymbolInfo(b2).Symbol);
 
            var b1 = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "b1").Single();
            var b1Symbol = model.GetSymbolInfo(b1).Symbol;
            Assert.Equal("System.Boolean b1", b1Symbol.ToTestDisplayString());
            Assert.Equal(SymbolKind.Local, b1Symbol.Kind);
        }
 
        [Fact]
        [WorkItem(19778, "https://github.com/dotnet/roslyn/issues/19778")]
        public void BindDynamicInvocation()
        {
            var source =
@"using System;
class C
{
    static void M()
    {
        dynamic L<T>(Func<dynamic, T> t, object p) => p;
        L(m => L(d => d, null), null);
        L(m => L(d => d, m), null);
    }
}";
            var comp = CreateCompilationWithMscorlib461(source, references: new[] { SystemCoreRef, CSharpRef });
            comp.VerifyEmitDiagnostics(
                // (8,18): error CS1977: Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type.
                //         L(m => L(d => d, m), null);
                Diagnostic(ErrorCode.ERR_BadDynamicMethodArgLambda, "d => d").WithLocation(8, 18),
                // (8,16): error CS8322: Cannot pass argument with dynamic type to generic local function 'L' with inferred type arguments.
                //         L(m => L(d => d, m), null);
                Diagnostic(ErrorCode.ERR_DynamicLocalFunctionTypeParameter, "L(d => d, m)").WithArguments("L").WithLocation(8, 16));
        }
 
        [Fact]
        [WorkItem(19778, "https://github.com/dotnet/roslyn/issues/19778")]
        public void BindDynamicInvocation_Async()
        {
            var source =
@"using System;
using System.Threading.Tasks;
class C
{
    static void M()
    {
        async Task<dynamic> L<T>(Func<dynamic, T> t, object p)
            => await L(async m => L(async d => await d, m), p);
    }
}";
            var comp = CreateCompilationWithMscorlib461(source, references: new[] { SystemCoreRef, CSharpRef });
            comp.VerifyEmitDiagnostics(
                // (8,37): error CS1977: Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type.
                //             => await L(async m => L(async d => await d, m), p);
                Diagnostic(ErrorCode.ERR_BadDynamicMethodArgLambda, "async d => await d").WithLocation(8, 37),
                // (8,35): error CS8322: Cannot pass argument with dynamic type to generic local function 'L' with inferred type arguments.
                //             => await L(async m => L(async d => await d, m), p);
                Diagnostic(ErrorCode.ERR_DynamicLocalFunctionTypeParameter, "L(async d => await d, m)").WithArguments("L").WithLocation(8, 35),
                // (8,32): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
                //             => await L(async m => L(async d => await d, m), p);
                Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "=>").WithLocation(8, 32));
        }
 
        [Fact]
        [WorkItem(21317, "https://github.com/dotnet/roslyn/issues/21317")]
        [CompilerTrait(CompilerFeature.Dynamic)]
        public void DynamicGenericArg()
        {
            var src = @"
using System.Collections.Generic;
class C
{
    static void M()
    {
        dynamic val = 2;
        dynamic dynamicList = new List<int>();
 
        void L1<T>(T x) { }
        L1(val);
 
        void L2<T>(int x, T y) { }
        L2(1, val);
        L2(val, 3.0f);
 
        void L3<T>(List<T> x) { }
        L3(dynamicList);
 
        void L4<T>(int x, params T[] y) { }
        L4(1, 2, val);
        L4(val, 3, 4);
 
        void L5<T>(T x, params int[] y) { }
        L5(val, 1, 2);
        L5(1, 3, val);
    }
}
";
            VerifyDiagnostics(src,
                // (11,9): error CS8322: Cannot pass argument with dynamic type to generic local function 'L1'. Try specifying the type arguments explicitly.
                //         L1(val);
                Diagnostic(ErrorCode.ERR_DynamicLocalFunctionTypeParameter, "L1(val)").WithArguments("L1").WithLocation(11, 9),
                // (14,9): error CS8322: Cannot pass argument with dynamic type to generic local function 'L2'. Try specifying the type arguments explicitly.
                //         L2(1, val);
                Diagnostic(ErrorCode.ERR_DynamicLocalFunctionTypeParameter, "L2(1, val)").WithArguments("L2").WithLocation(14, 9),
                // (15,9): error CS8322: Cannot pass argument with dynamic type to generic local function 'L2'. Try specifying the type arguments explicitly.
                //         L2(val, 3.0f);
                Diagnostic(ErrorCode.ERR_DynamicLocalFunctionTypeParameter, "L2(val, 3.0f)").WithArguments("L2").WithLocation(15, 9),
                // (18,9): error CS8322: Cannot pass argument with dynamic type to generic local function 'L3'. Try specifying the type arguments explicitly.
                //         L3(dynamicList);
                Diagnostic(ErrorCode.ERR_DynamicLocalFunctionTypeParameter, "L3(dynamicList)").WithArguments("L3").WithLocation(18, 9),
                // (21,9): error CS8322: Cannot pass argument with dynamic type to generic local function 'L4'. Try specifying the type arguments explicitly.
                //         L4(1, 2, val);
                Diagnostic(ErrorCode.ERR_DynamicLocalFunctionTypeParameter, "L4(1, 2, val)").WithArguments("L4").WithLocation(21, 9),
                // (22,9): error CS8322: Cannot pass argument with dynamic type to generic local function 'L4'. Try specifying the type arguments explicitly.
                //         L4(val, 3, 4);
                Diagnostic(ErrorCode.ERR_DynamicLocalFunctionTypeParameter, "L4(val, 3, 4)").WithArguments("L4").WithLocation(22, 9),
                // (25,9): error CS8322: Cannot pass argument with dynamic type to generic local function 'L5'. Try specifying the type arguments explicitly.
                //         L5(val, 1, 2);
                Diagnostic(ErrorCode.ERR_DynamicLocalFunctionTypeParameter, "L5(val, 1, 2)").WithArguments("L5").WithLocation(25, 9),
                // (26,9): error CS8322: Cannot pass argument with dynamic type to generic local function 'L5'. Try specifying the type arguments explicitly.
                //         L5(1, 3, val);
                Diagnostic(ErrorCode.ERR_DynamicLocalFunctionTypeParameter, "L5(1, 3, val)").WithArguments("L5").WithLocation(26, 9)
                );
        }
 
        [Fact]
        [WorkItem(23699, "https://github.com/dotnet/roslyn/issues/23699")]
        public void GetDeclaredSymbolOnTypeParameter()
        {
            var src = @"
class C<T>
{
    void M<U>()
    {
        void LocalFunction<T, U, V>(T p1, U p2, V p3)
        {
        }
    }
}
";
            var comp = CreateCompilation(src);
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);
 
            var localDecl = (LocalFunctionStatementSyntax)tree.FindNodeOrTokenByKind(SyntaxKind.LocalFunctionStatement).AsNode();
 
            var typeParameters = localDecl.TypeParameterList.Parameters;
            var parameters = localDecl.ParameterList.Parameters;
            verifyTypeParameterAndParameter(typeParameters[0], parameters[0], "T");
            verifyTypeParameterAndParameter(typeParameters[1], parameters[1], "U");
            verifyTypeParameterAndParameter(typeParameters[2], parameters[2], "V");
 
            void verifyTypeParameterAndParameter(TypeParameterSyntax typeParameter, ParameterSyntax parameter, string expected)
            {
                var symbol = model.GetDeclaredSymbol(typeParameter);
                Assert.Equal(expected, symbol.ToTestDisplayString());
 
                var parameterSymbol = model.GetDeclaredSymbol(parameter);
                Assert.Equal(expected, parameterSymbol.Type.ToTestDisplayString());
                Assert.Same(symbol, parameterSymbol.Type);
            }
        }
 
        public sealed class ScriptGlobals
        {
            public int SomeGlobal => 42;
        }
 
        [ConditionalFact(typeof(DesktopOnly), Reason = "https://github.com/dotnet/roslyn/issues/28001")]
        public void CanAccessScriptGlobalsFromInsideMethod()
        {
            var source = @"
void Method()
{
    LocalFunction();
    void LocalFunction()
    {
        _ = SomeGlobal;
    }
}";
            CreateSubmission(source, new[] { ScriptTestFixtures.HostRef }, hostObjectType: typeof(ScriptGlobals))
                .VerifyEmitDiagnostics();
        }
 
        [ConditionalFact(typeof(DesktopOnly), Reason = "https://github.com/dotnet/roslyn/issues/28001")]
        public void CanAccessScriptGlobalsFromInsideLambda()
        {
            var source = @"
var lambda = new System.Action(() =>
{
    LocalFunction();
    void LocalFunction()
    {
        _ = SomeGlobal;
    }
});";
            CreateSubmission(source, new[] { ScriptTestFixtures.HostRef }, hostObjectType: typeof(ScriptGlobals))
                .VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void CanAccessPreviousSubmissionVariablesFromInsideMethod()
        {
            var previous = CreateSubmission("int previousSubmissionVariable = 42;")
                .VerifyEmitDiagnostics();
 
            var source = @"
void Method()
{
    LocalFunction();
    void LocalFunction()
    {
        _ = previousSubmissionVariable;
    }
}";
            CreateSubmission(source, previous: previous)
                .VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void CanAccessPreviousSubmissionVariablesFromInsideLambda()
        {
            var previous = CreateSubmission("int previousSubmissionVariable = 42;")
                .VerifyEmitDiagnostics();
 
            var source = @"
var lambda = new System.Action(() =>
{
    LocalFunction();
    void LocalFunction()
    {
        _ = previousSubmissionVariable;
    }
});";
            CreateSubmission(source, previous: previous)
                .VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void CanAccessPreviousSubmissionMethodsFromInsideMethod()
        {
            var previous = CreateSubmission("void PreviousSubmissionMethod() { }")
                .VerifyEmitDiagnostics();
 
            var source = @"
void Method()
{
    LocalFunction();
    void LocalFunction()
    {
        PreviousSubmissionMethod();
    }
}";
            CreateSubmission(source, previous: previous)
                .VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void CanAccessPreviousSubmissionMethodsFromInsideLambda()
        {
            var previous = CreateSubmission("void PreviousSubmissionMethod() { }")
                .VerifyEmitDiagnostics();
 
            var source = @"
var lambda = new System.Action(() =>
{
    LocalFunction();
    void LocalFunction()
    {
        PreviousSubmissionMethod();
    }
});";
            CreateSubmission(source, previous: previous)
                .VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void ShadowNames_01()
        {
            var source =
@"#pragma warning disable 0219
#pragma warning disable 8321
class Program
{
    static void M()
    {
        void F1(object x) { string x = null; } // local
        void F2(object x, string y, int x) { } // parameter
        void F3(object x) { void x() { } } // method
        void F4<@x, @y>(object x) { void y() { } } // type parameter
        void F5(object M, string Program) { }
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3);
            verifyDiagnostics();
 
            comp = CreateCompilation(source, parseOptions: TestOptions.Regular8);
            verifyDiagnostics();
 
            comp = CreateCompilation(source);
            verifyDiagnostics();
 
            void verifyDiagnostics()
            {
                comp.VerifyDiagnostics(
                    // (7,36): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                    //         void F1(object x) { string x = null; } // local
                    Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(7, 36),
                    // (8,41): error CS0100: The parameter name 'x' is a duplicate
                    //         void F2(object x, string y, int x) { } // parameter
                    Diagnostic(ErrorCode.ERR_DuplicateParamName, "x").WithArguments("x").WithLocation(8, 41),
                    // (9,34): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                    //         void F3(object x) { void x() { } } // method
                    Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(9, 34),
                    // (10,32): error CS0412: 'x': a parameter, local variable, or local function cannot have the same name as a method type parameter
                    //         void F4<@x, @y>(object x) { void y() { } } // type parameter
                    Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "x").WithArguments("x").WithLocation(10, 32),
                    // (10,42): error CS0412: 'y': a parameter, local variable, or local function cannot have the same name as a method type parameter
                    //         void F4<@x, @y>(object x) { void y() { } } // type parameter
                    Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "y").WithArguments("y").WithLocation(10, 42));
            }
        }
 
        [Fact]
        public void ShadowNames_Local_01()
        {
            var source =
@"#pragma warning disable 0219
#pragma warning disable 8321
using System.Linq;
class Program
{
    static void M()
    {
        object x = null;
        void F1() { object x = 0; } // local
        void F2(string x) { } // parameter
        void F3() { void x() { } } // method
        void F4<@x>() { } // type parameter
        void F5() { _ = from x in new[] { 1, 2, 3 } select x; } // range variable
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3);
            comp.VerifyDiagnostics(
                // (9,28): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void F1() { object x = 0; } // local
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(9, 28),
                // (10,24): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void F2(string x) { } // parameter
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(10, 24),
                // (11,26): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void F3() { void x() { } } // method
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(11, 26),
                // (12,17): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void F4<@x>() { } // type parameter
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "@x").WithArguments("x").WithLocation(12, 17),
                // (13,30): error CS1931: The range variable 'x' conflicts with a previous declaration of 'x'
                //         void F5() { _ = from x in new[] { 1, 2, 3 } select x; } // range variable
                Diagnostic(ErrorCode.ERR_QueryRangeVariableOverrides, "x").WithArguments("x").WithLocation(13, 30));
 
            comp = CreateCompilation(source, parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics();
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void ShadowNames_Local_02()
        {
            var source =
@"#pragma warning disable 0219
#pragma warning disable 8321
using System.Linq;
class Program
{
    static void M()
    {
        void F1() { object x = 0; } // local
        void F2(string x) { } // parameter
        void F3() { void x() { } } // method
        void F4<@x>() { } // type parameter
        void F5() { _ = from x in new[] { 1, 2, 3 } select x; } // range variable
        object x = null;
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3);
            comp.VerifyDiagnostics(
                // (8,28): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void F1() { object x = 0; } // local
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(8, 28),
                // (9,24): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void F2(string x) { } // parameter
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(9, 24),
                // (10,26): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void F3() { void x() { } } // method
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(10, 26),
                // (11,17): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void F4<@x>() { } // type parameter
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "@x").WithArguments("x").WithLocation(11, 17),
                // (12,30): error CS1931: The range variable 'x' conflicts with a previous declaration of 'x'
                //         void F5() { _ = from x in new[] { 1, 2, 3 } select x; } // range variable
                Diagnostic(ErrorCode.ERR_QueryRangeVariableOverrides, "x").WithArguments("x").WithLocation(12, 30));
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void ShadowNames_Local_03()
        {
            var source =
@"#pragma warning disable 0219
#pragma warning disable 8321
using System.Linq;
class Program
{
    static void M()
    {
        static void F1() { object x = 0; } // local
        static void F2(string x) { } // parameter
        static void F3() { void x() { } } // method
        static void F4<@x>() { } // type parameter
        static void F5() { _ = from x in new[] { 1, 2, 3 } select x; } // range variable
        object x = null;
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void ShadowNames_Parameter()
        {
            var source =
@"#pragma warning disable 0219
#pragma warning disable 8321
using System.Linq;
class Program
{
    static void M(object x)
    {
        void F1() { object x = 0; } // local
        void F2(string x) { } // parameter
        void F3() { void x() { } } // method
        void F4<@x>() { } // type parameter
        void F5() { _ = from x in new[] { 1, 2, 3 } select x; } // range variable
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3);
            // The conflict between the type parameter in F4<x>() and the parameter
            // in M(object x) is not reported, for backwards compatibility.
            comp.VerifyDiagnostics(
                // (8,28): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void F1() { object x = 0; } // local
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(8, 28),
                // (9,24): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void F2(string x) { } // parameter
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(9, 24),
                // (10,26): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void F3() { void x() { } } // method
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(10, 26),
                // (12,30): error CS1931: The range variable 'x' conflicts with a previous declaration of 'x'
                //         void F5() { _ = from x in new[] { 1, 2, 3 } select x; } // range variable
                Diagnostic(ErrorCode.ERR_QueryRangeVariableOverrides, "x").WithArguments("x").WithLocation(12, 30));
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void ShadowNames_TypeParameter()
        {
            var source =
@"#pragma warning disable 0219
#pragma warning disable 8321
using System.Linq;
class Program
{
    static void M<@x>()
    {
        void F1() { object x = 0; } // local
        void F2(string x) { } // parameter
        void F3() { void x() { } } // method
        void F4<@x>() { } // type parameter
        void F5() { _ = from x in new[] { 1, 2, 3 } select x; } // range variable
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3);
            comp.VerifyDiagnostics(
                // (8,28): error CS0412: 'x': a parameter, local variable, or local function cannot have the same name as a method type parameter
                //         void F1() { object x = 0; } // local
                Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "x").WithArguments("x").WithLocation(8, 28),
                // (9,24): error CS0412: 'x': a parameter, local variable, or local function cannot have the same name as a method type parameter
                //         void F2(string x) { } // parameter
                Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "x").WithArguments("x").WithLocation(9, 24),
                // (10,26): error CS0412: 'x': a parameter, local variable, or local function cannot have the same name as a method type parameter
                //         void F3() { void x() { } } // method
                Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "x").WithArguments("x").WithLocation(10, 26),
                // (11,17): warning CS8387: Type parameter 'x' has the same name as the type parameter from outer method 'Program.M<x>()'
                //         void F4<@x>() { } // type parameter
                Diagnostic(ErrorCode.WRN_TypeParameterSameAsOuterMethodTypeParameter, "@x").WithArguments("x", "Program.M<x>()").WithLocation(11, 17),
                // (12,30): error CS1948: The range variable 'x' cannot have the same name as a method type parameter
                //         void F5() { _ = from x in new[] { 1, 2, 3 } select x; } // range variable
                Diagnostic(ErrorCode.ERR_QueryRangeVariableSameAsTypeParam, "x").WithArguments("x").WithLocation(12, 30));
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (11,17): warning CS8387: Type parameter 'x' has the same name as the type parameter from outer method 'Program.M<x>()'
                //         void F4<@x>() { } // type parameter
                Diagnostic(ErrorCode.WRN_TypeParameterSameAsOuterMethodTypeParameter, "@x").WithArguments("x", "Program.M<x>()").WithLocation(11, 17));
        }
 
        [Fact]
        public void ShadowNames_LocalFunction_01()
        {
            var source =
@"#pragma warning disable 0219
#pragma warning disable 8321
using System.Linq;
class Program
{
    static void M()
    {
        void x() { }
        void F1() { object x = 0; } // local
        void F2(string x) { } // parameter
        void F3() { void x() { } } // method
        void F4<@x>() { } // type parameter
        void F5() { _ = from x in new[] { 1, 2, 3 } select x; } // range variable
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3);
            comp.VerifyDiagnostics(
                // (9,28): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void F1() { object x = 0; } // local
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(9, 28),
                // (10,24): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void F2(string x) { } // parameter
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(10, 24),
                // (11,26): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void F3() { void x() { } } // method
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(11, 26),
                // (12,17): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void F4<@x>() { } // type parameter
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "@x").WithArguments("x").WithLocation(12, 17),
                // (13,30): error CS1931: The range variable 'x' conflicts with a previous declaration of 'x'
                //         void F5() { _ = from x in new[] { 1, 2, 3 } select x; } // range variable
                Diagnostic(ErrorCode.ERR_QueryRangeVariableOverrides, "x").WithArguments("x").WithLocation(13, 30));
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void ShadowNames_LocalFunction_02()
        {
            var source =
@"#pragma warning disable 0219
#pragma warning disable 8321
class Program
{
    static void M1()
    {
        void M1() { }
    }
    static void M2(object x)
    {
        void x() { }
    }
    static void M3()
    {
        object x = null;
        void x() { }
    }
    static void M4<T>()
    {
        void T() { }
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3);
            verifyDiagnostics();
 
            comp = CreateCompilation(source);
            verifyDiagnostics();
 
            void verifyDiagnostics()
            {
                comp.VerifyDiagnostics(
                    // (11,14): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                    //         void x() { }
                    Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(11, 14),
                    // (16,14): error CS0128: A local variable or function named 'x' is already defined in this scope
                    //         void x() { }
                    Diagnostic(ErrorCode.ERR_LocalDuplicate, "x").WithArguments("x").WithLocation(16, 14),
                    // (20,14): error CS0412: 'T': a parameter, local variable, or local function cannot have the same name as a method type parameter
                    //         void T() { }
                    Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "T").WithArguments("T").WithLocation(20, 14));
            }
        }
 
        [Fact]
        public void ShadowNames_ThisLocalFunction()
        {
            var source =
@"#pragma warning disable 0219
#pragma warning disable 8321
using System.Linq;
class Program
{
    static void M()
    {
        void F1() { object F1 = 0; } // local
        void F2(string F2) { } // parameter
        void F3() { void F3() { } } // method
        void F4<F4>() { } // type parameter
        void F5() { _ = from F5 in new[] { 1, 2, 3 } select F5; } // range variable
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3);
            comp.VerifyDiagnostics(
                // (8,28): error CS0136: A local or parameter named 'F1' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void F1() { object F1 = 0; } // local
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "F1").WithArguments("F1").WithLocation(8, 28),
                // (9,24): error CS0136: A local or parameter named 'F2' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void F2(string F2) { } // parameter
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "F2").WithArguments("F2").WithLocation(9, 24),
                // (10,26): error CS0136: A local or parameter named 'F3' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void F3() { void F3() { } } // method
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "F3").WithArguments("F3").WithLocation(10, 26),
                // (11,17): error CS0136: A local or parameter named 'F4' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //         void F4<F4>() { } // type parameter
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "F4").WithArguments("F4").WithLocation(11, 17),
                // (12,30): error CS1931: The range variable 'F5' conflicts with a previous declaration of 'F5'
                //         void F5() { _ = from F5 in new[] { 1, 2, 3 } select F5; } // range variable
                Diagnostic(ErrorCode.ERR_QueryRangeVariableOverrides, "F5").WithArguments("F5").WithLocation(12, 30));
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void ShadowNames_LocalFunctionInsideLocalFunction_01()
        {
            var source =
@"#pragma warning disable 0219
#pragma warning disable 8321
class Program
{
    static void M<T>(object x)
    {
        void F()
        {
            void G1(int x) { }
            void G2() { int T = 0; }
            void G3<T>() { }
        }
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3);
            comp.VerifyDiagnostics(
                // (9,25): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //             void G1(int x) { }
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(9, 25),
                // (10,29): error CS0412: 'T': a parameter, local variable, or local function cannot have the same name as a method type parameter
                //             void G2() { int T = 0; }
                Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "T").WithArguments("T").WithLocation(10, 29),
                // (11,21): warning CS8387: Type parameter 'T' has the same name as the type parameter from outer method 'Program.M<T>(object)'
                //             void G3<T>() { }
                Diagnostic(ErrorCode.WRN_TypeParameterSameAsOuterMethodTypeParameter, "T").WithArguments("T", "Program.M<T>(object)").WithLocation(11, 21));
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (11,21): warning CS8387: Type parameter 'T' has the same name as the type parameter from outer method 'Program.M<T>(object)'
                //             void G3<T>() { }
                Diagnostic(ErrorCode.WRN_TypeParameterSameAsOuterMethodTypeParameter, "T").WithArguments("T", "Program.M<T>(object)").WithLocation(11, 21));
        }
 
        [Fact]
        public void ShadowNames_LocalFunctionInsideLocalFunction_02()
        {
            var source =
@"#pragma warning disable 0219
#pragma warning disable 8321
class Program
{
    static void M<T>(object x)
    {
        static void F1()
        {
            void G1(int x) { }
        }
        void F2()
        {
            static void G2() { int T = 0; }
        }
        static void F3()
        {
            static void G3<T>() { }
        }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (17,28): warning CS8387: Type parameter 'T' has the same name as the type parameter from outer method 'Program.M<T>(object)'
                //             static void G3<T>() { }
                Diagnostic(ErrorCode.WRN_TypeParameterSameAsOuterMethodTypeParameter, "T").WithArguments("T", "Program.M<T>(object)").WithLocation(17, 28));
        }
 
        [Fact]
        public void ShadowNames_LocalFunctionInsideLambda_01()
        {
            var source =
@"#pragma warning disable 0219
#pragma warning disable 8321
using System;
class Program
{
    static void M()
    {
        Action a1 = () =>
        {
            int x = 0;
            void F1() { object x = null; }
        };
        Action a2 = () =>
        {
            int T = 0;
            void F2<T>() { }
        };
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3);
            comp.VerifyDiagnostics(
                // (11,32): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //             void F1() { object x = null; }
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(11, 32),
                // (16,21): error CS0136: A local or parameter named 'T' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //             void F2<T>() { }
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "T").WithArguments("T").WithLocation(16, 21));
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void ShadowNames_LocalFunctionInsideLambda_02()
        {
            var source =
@"#pragma warning disable 0219
#pragma warning disable 8321
using System;
class Program
{
    static void M()
    {
        Action<int> a1 = x =>
        {
            void F1(object x) { }
        };
        Action<int> a2 = (int T) =>
        {
            void F2<T>() { }
        };
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3);
            // The conflict between the type parameter in F2<T>() and the parameter
            // in a2 is not reported, for backwards compatibility.
            comp.VerifyDiagnostics(
                // (10,28): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //             void F1(object x) { }
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(10, 28));
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void ShadowNames_LocalFunctionInsideLambda_03()
        {
            var source =
@"using System;
class Program
{
    static void M()
    {
        Action<int> a = x =>
        {
            void x() { }
            x();
        };
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3);
            // The conflict between the local function and the parameter is not reported,
            // for backwards compatibility.
            comp.VerifyDiagnostics();
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void StaticWithThisReference()
        {
            var source =
@"#pragma warning disable 8321
class C
{
    void M()
    {
        static object F1() => this.GetHashCode();
        static object F2() => base.GetHashCode();
        static void F3()
        {
            object G3() => ToString();
        }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (6,31): error CS8422: A static local function cannot contain a reference to 'this' or 'base'.
                //         static object F1() => this.GetHashCode();
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureThis, "this").WithLocation(6, 31),
                // (7,31): error CS8422: A static local function cannot contain a reference to 'this' or 'base'.
                //         static object F2() => base.GetHashCode();
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureThis, "base").WithLocation(7, 31),
                // (10,28): error CS8422: A static local function cannot contain a reference to 'this' or 'base'.
                //             object G3() => ToString();
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureThis, "ToString").WithLocation(10, 28));
        }
 
        [Fact]
        public void StaticWithVariableReference()
        {
            var source =
@"#pragma warning disable 8321
class C
{
    static void M(object x)
    {
        object y = null;
        static object F1() => x;
        static object F2() => y;
        static void F3()
        {
            object G3() => x;
        }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,31): error CS8421: A static local function cannot contain a reference to 'x'.
                //         static object F1() => x;
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureVariable, "x").WithArguments("x").WithLocation(7, 31),
                // (8,31): error CS8421: A static local function cannot contain a reference to 'y'.
                //         static object F2() => y;
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureVariable, "y").WithArguments("y").WithLocation(8, 31),
                // (11,28): error CS8421: A static local function cannot contain a reference to 'x'.
                //             object G3() => x;
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureVariable, "x").WithArguments("x").WithLocation(11, 28));
        }
 
        [Fact]
        public void StaticWithLocalFunctionVariableReference_01()
        {
            var source =
@"#pragma warning disable 8321
class C
{
    static void M()
    {
        static void F(object x)
        {
            object y = null;
            object G1() => x ?? y;
            static object G2() => x ?? y;
        }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (10,35): error CS8421: A static local function cannot contain a reference to 'x'.
                //             static object G2() => x ?? y;
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureVariable, "x").WithArguments("x").WithLocation(10, 35),
                // (10,40): error CS8421: A static local function cannot contain a reference to 'y'.
                //             static object G2() => x ?? y;
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureVariable, "y").WithArguments("y").WithLocation(10, 40));
        }
 
        [Fact]
        public void StaticWithLocalFunctionVariableReference_02()
        {
            var source =
@"#pragma warning disable 8321
class C
{
    static void M(int x)
    {
        static void F1(int y)
        {
            int F2() => x + y;
        }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (8,25): error CS8421: A static local function cannot contain a reference to 'x'.
                //             int F2() => x + y;
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureVariable, "x").WithArguments("x").WithLocation(8, 25));
        }
 
        /// <summary>
        /// Can reference type parameters from enclosing scope.
        /// </summary>
        [Fact]
        public void StaticWithTypeParameterReferences()
        {
            var source =
@"using static System.Console;
class A<T>
{
    internal string F1()
    {
        static string L1() => typeof(T).FullName;
        return L1();
    }
}
class B
{
    internal string F2<T>()
    {
        static string L2() => typeof(T).FullName;
        return L2();
    }
    internal static string F3()
    {
        static string L3<T>()
        {
            static string L4() => typeof(T).FullName;
            return L4();
        }
        return L3<byte>();
    }
}
class Program
{
    static void Main()
    {
        WriteLine(new A<int>().F1());
        WriteLine(new B().F2<string>());
        WriteLine(B.F3());
    }
}";
            CompileAndVerify(source, expectedOutput:
@"System.Int32
System.String
System.Byte");
        }
 
        [Fact]
        public void Conditional_ThisReferenceInStatic()
        {
            var source =
@"#pragma warning disable 0649
#pragma warning disable 8321
using System.Diagnostics;
class A
{
    internal object _f;
}
class B : A
{
    [Conditional(""MyDefine"")]
    static void F(object o)
    {
    }
    void M()
    {
        static void F1() { F(this); }
        static void F2() { F(base._f); }
        static void F3() { F(_f); }
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithPreprocessorSymbols("MyDefine"));
            verifyDiagnostics();
 
            comp = CreateCompilation(source, parseOptions: TestOptions.Regular);
            verifyDiagnostics();
 
            void verifyDiagnostics()
            {
                comp.VerifyDiagnostics(
                    // (16,30): error CS8422: A static local function cannot contain a reference to 'this' or 'base'.
                    //         static void F1() { F(this); }
                    Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureThis, "this").WithLocation(16, 30),
                    // (17,30): error CS8422: A static local function cannot contain a reference to 'this' or 'base'.
                    //         static void F2() { F(base._f); }
                    Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureThis, "base").WithLocation(17, 30),
                    // (18,30): error CS8422: A static local function cannot contain a reference to 'this' or 'base'.
                    //         static void F3() { F(_f); }
                    Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureThis, "_f").WithLocation(18, 30));
            }
        }
 
        [Fact]
        public void LocalFunctionConditional_Errors()
        {
            var source = @"
using System.Diagnostics;
 
class C
{
    void M()
    {
#pragma warning disable 8321 // Unreferenced local function
 
        [Conditional(""DEBUG"")] // 1
        int local1() => 42;
 
        [Conditional(""DEBUG"")] // 2
        void local2(out int i) { i = 42; }
    }
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (10,10): error CS0578: The Conditional attribute is not valid on 'local1()' because its return type is not void
                //         [Conditional("DEBUG")] // 1
                Diagnostic(ErrorCode.ERR_ConditionalMustReturnVoid, @"Conditional(""DEBUG"")").WithArguments("local1()").WithLocation(10, 10),
                // (13,10): error CS0685: Conditional member 'local2(out int)' cannot have an out parameter
                //         [Conditional("DEBUG")] // 2
                Diagnostic(ErrorCode.ERR_ConditionalWithOutParam, @"Conditional(""DEBUG"")").WithArguments("local2(out int)").WithLocation(13, 10));
        }
 
        [Fact]
        public void LocalFunctionObsolete()
        {
            var source = @"
using System;
 
class C
{
    void M1()
    {
        local1(); // 1
        local2(); // 2
 
        [Obsolete]
        void local1() { }
 
        [Obsolete(""hello"", true)]
        void local2() { }
 
#pragma warning disable 8321 // Unreferenced local function
        [Obsolete]
        void local3()
        {
            // no diagnostics expected when calling an Obsolete method within an Obsolete method
            local1();
            local2();
        }
    }
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (8,9): warning CS0612: 'local1()' is obsolete
                //         local1(); // 1
                Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "local1()").WithArguments("local1()").WithLocation(8, 9),
                // (9,9): error CS0619: 'local2()' is obsolete: 'hello'
                //         local2(); // 2
                Diagnostic(ErrorCode.ERR_DeprecatedSymbolStr, "local2()").WithArguments("local2()", "hello").WithLocation(9, 9));
        }
 
        [Fact]
        public void LocalFunction_AttributeMarkedObsolete()
        {
            var source = @"
using System;
 
[Obsolete]
class Attr : Attribute { }
 
class C
{
    void M1()
    {
#pragma warning disable 8321
        [Attr] void local1() { } // 1
        [return: Attr] void local2() { } // 2
        void local3([Attr] int i) { } // 3
        void local4<[Attr] T>(T t) { } // 4
    }
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (12,10): warning CS0612: 'Attr' is obsolete
                //         [Attr] void local1() { } // 1
                Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "Attr").WithArguments("Attr").WithLocation(12, 10),
                // (13,18): warning CS0612: 'Attr' is obsolete
                //         [return: Attr] void local2() { } // 2
                Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "Attr").WithArguments("Attr").WithLocation(13, 18),
                // (14,22): warning CS0612: 'Attr' is obsolete
                //         void local3([Attr] int i) { } // 3
                Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "Attr").WithArguments("Attr").WithLocation(14, 22),
                // (15,22): warning CS0612: 'Attr' is obsolete
                //         void local4<[Attr] T>(T t) { } // 4
                Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "Attr").WithArguments("Attr").WithLocation(15, 22));
        }
 
        [Fact]
        public void LocalFunction_NotNullIfNotNullAttribute()
        {
            var source = @"
using System.Diagnostics.CodeAnalysis;
 
#nullable enable
 
class C
{
    void M()
    {
        _ = local1(null).ToString(); // 1
        _ = local1(""hello"").ToString();
 
        [return: NotNullIfNotNull(""s1"")]
        string? local1(string? s1) => s1;
    }
}
";
            var comp = CreateCompilation(new[] { NotNullIfNotNullAttributeDefinition, source }, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (10,13): warning CS8602: Dereference of a possibly null reference.
                //         _ = local1(null).ToString(); // 1
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "local1(null)").WithLocation(10, 13));
        }
 
        [Fact]
        public void LocalFunction_MaybeNullWhenAttribute()
        {
            var source = @"
#nullable enable
 
using System.Diagnostics.CodeAnalysis;
 
class C
{
    void M()
    {
        _ = tryGetValue(true, out var s)
            ? s.ToString()
            : s.ToString(); // 1
 
        bool tryGetValue(bool b, [MaybeNullWhen(false)] out string s1)
        {
            s1 = b ? ""abc"" : null;
            return b;
        }
    }
}
";
            var comp = CreateCompilation(new[] { MaybeNullWhenAttributeDefinition, source }, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (12,15): warning CS8602: Dereference of a possibly null reference.
                //             : s.ToString(); // 1
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(12, 15));
        }
 
        [Fact]
        public void LocalFunction_MaybeNullWhenAttribute_CheckUsage()
        {
            var source = @"
#nullable enable
 
using System.Diagnostics.CodeAnalysis;
 
class C
{
    void M()
    {
        var s = ""abc"";
        local1();
 
        tryGetValue(""a"", out s);
        local1();
 
        void local1()
        {
            _ = s.ToString(); // 1
        }
 
        bool tryGetValue(string key, [MaybeNullWhen(false)] out string s1)
        {
            s1 = key;
            return true;
        }
    }
}
";
            var comp = CreateCompilation(new[] { MaybeNullWhenAttributeDefinition, source }, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (18,17): warning CS8602: Dereference of a possibly null reference.
                //             _ = s.ToString(); // 1
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(18, 17));
        }
 
        [Fact]
        public void LocalFunction_AllowNullAttribute()
        {
            var source = @"
#nullable enable
 
using System.Diagnostics.CodeAnalysis;
 
class C
{
    void M<T>([AllowNull] T t1, T t2)
    {
        local1(t1);
        local1(t2);
 
        local2(t1); // 1
        local2(t2);
 
        void local1([AllowNull] T t) { }
        void local2(T t) { }
    }
}
";
            var comp = CreateCompilation(new[] { AllowNullAttributeDefinition, source }, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (13,16): warning CS8604: Possible null reference argument for parameter 't' in 'void local2(T t)'.
                //         local2(t1); // 1
                Diagnostic(ErrorCode.WRN_NullReferenceArgument, "t1").WithArguments("t", "void local2(T t)").WithLocation(13, 16));
        }
 
        [Fact]
        public void LocalFunction_MaybeNullAttribute()
        {
            var source = @"
#nullable enable
 
using System.Diagnostics.CodeAnalysis;
 
class C
{
    void M<TOuter>()
    {
        getDefault<string>().ToString(); // 1
        getDefault<string?>().ToString(); // 2
        getDefault<int>().ToString();
        getDefault<int?>().Value.ToString(); // 3
        getDefault<TOuter>().ToString(); // 4
 
        [return: MaybeNull] T getDefault<T>() => default(T);
    }
}
";
            var comp = CreateCompilation(new[] { MaybeNullAttributeDefinition, source }, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (10,9): warning CS8602: Dereference of a possibly null reference.
                //         getDefault<string>().ToString(); // 1
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "getDefault<string>()").WithLocation(10, 9),
                // (11,9): warning CS8602: Dereference of a possibly null reference.
                //         getDefault<string?>().ToString(); // 2
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "getDefault<string?>()").WithLocation(11, 9),
                // (13,9): warning CS8629: Nullable value type may be null.
                //         getDefault<int?>().Value.ToString(); // 3
                Diagnostic(ErrorCode.WRN_NullableValueTypeMayBeNull, "getDefault<int?>()").WithLocation(13, 9),
                // (14,9): warning CS8602: Dereference of a possibly null reference.
                //         getDefault<TOuter>().ToString(); // 4
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "getDefault<TOuter>()").WithLocation(14, 9));
        }
 
        [Fact]
        public void LocalFunction_Nullable_CheckUsage_DoesNotUsePostconditions()
        {
            var source = @"
#nullable enable
 
using System.Diagnostics.CodeAnalysis;
 
class C
{
    void M()
    {
        var s0 = ""hello"";
 
        local1(out s0);
 
        bool local1([MaybeNullWhen(false)] out string s1)
        {
            s0.ToString();
            s1 = ""world"";
            return true;
        }
    }
}
";
            var comp = CreateCompilation(new[] { MaybeNullWhenAttributeDefinition, source }, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void LocalFunction_DoesNotReturn()
        {
            var source = @"
#nullable enable
 
using System.Diagnostics.CodeAnalysis;
 
class C
{
    void M(string? s)
    {
        local1();
        s.ToString();
 
        [DoesNotReturn]
        void local1()
        {
            throw null!;
        }
    }
}
";
            var comp = CreateCompilation(new[] { DoesNotReturnAttributeDefinition, source }, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void LocalFunction_DoesNotReturnIf()
        {
            var source = @"
#nullable enable
 
using System.Diagnostics.CodeAnalysis;
 
class C
{
    void M(string? s1, string? s2)
    {
        local1(s1 != null);
        s1.ToString();
 
        local1(false);
        s2.ToString();
 
        void local1([DoesNotReturnIf(false)] bool b)
        {
            throw null!;
        }
    }
}
";
            var comp = CreateCompilation(new[] { DoesNotReturnIfAttributeDefinition, source }, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void NameOf_ThisReferenceInStatic()
        {
            var source =
@"#pragma warning disable 8321
class C
{
    void M()
    {
        static object F1() => nameof(this.ToString);
        static object F2() => nameof(base.GetHashCode);
        static object F3() => nameof(M);
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void NameOf_InstanceMemberInStatic()
        {
            var source =
@"#pragma warning disable 0649
#pragma warning disable 8321
class C
{
    object _f;
    static void M()
    {
        _ = nameof(_f);
        static object F() => nameof(_f);
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var expr = GetNameOfExpressions(tree)[1];
            var symbol = model.GetSymbolInfo(expr).Symbol;
            Assert.Equal("System.Object C._f", symbol.ToTestDisplayString());
        }
 
        [Fact]
        public void NameOf_CapturedVariableInStatic()
        {
            var source =
@"#pragma warning disable 8321
class C
{
    static void M(object x)
    {
        static object F() => nameof(x);
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var expr = GetNameOfExpressions(tree)[0];
            var symbol = model.GetSymbolInfo(expr).Symbol;
            Assert.Equal("System.Object x", symbol.ToTestDisplayString());
        }
 
        /// <summary>
        /// nameof(x) should bind to shadowing symbol.
        /// </summary>
        [Fact]
        public void NameOf_ShadowedVariable()
        {
            var source =
@"#pragma warning disable 8321
class C
{
    static void M(object x)
    {
        object F()
        {
            int x = 0;
            return nameof(x);
        }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var expr = GetNameOfExpressions(tree)[0];
            var symbol = model.GetSymbolInfo(expr).Symbol;
            Assert.Equal(SymbolKind.Local, symbol.Kind);
            Assert.Equal("System.Int32 x", symbol.ToTestDisplayString());
        }
 
        /// <summary>
        /// nameof(T) should bind to shadowing symbol.
        /// </summary>
        [Fact]
        public void NameOf_ShadowedTypeParameter()
        {
            var source =
@"#pragma warning disable 8321
class C
{
    static void M<T>()
    {
        object F1()
        {
            int T = 0;
            return nameof(T);
        }
        object F2<T>()
        {
            return nameof(T);
        }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (11,19): warning CS8387: Type parameter 'T' has the same name as the type parameter from outer method 'C.M<T>()'
                //         object F2<T>()
                Diagnostic(ErrorCode.WRN_TypeParameterSameAsOuterMethodTypeParameter, "T").WithArguments("T", "C.M<T>()").WithLocation(11, 19));
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var exprs = GetNameOfExpressions(tree);
            var symbol = model.GetSymbolInfo(exprs[0]).Symbol;
            Assert.Equal(SymbolKind.Local, symbol.Kind);
            Assert.Equal("System.Int32 T", symbol.ToTestDisplayString());
            symbol = model.GetSymbolInfo(exprs[1]).Symbol;
            Assert.Equal(SymbolKind.TypeParameter, symbol.Kind);
            Assert.Equal("System.Object F2<T>()", symbol.ContainingSymbol.ToTestDisplayString());
        }
 
        /// <summary>
        /// typeof(T) should bind to nearest type.
        /// </summary>
        [Fact]
        public void TypeOf_ShadowedTypeParameter()
        {
            var source =
@"#pragma warning disable 0219
#pragma warning disable 8321
class C
{
    static void M<T>()
    {
        object F1()
        {
            int T = 0;
            return typeof(T);
        }
        object F2<T>()
        {
            return typeof(T);
        }
        object F3<U>()
        {
            return typeof(U);
        }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (12,19): warning CS8387: Type parameter 'T' has the same name as the type parameter from outer method 'C.M<T>()'
                //         object F2<T>()
                Diagnostic(ErrorCode.WRN_TypeParameterSameAsOuterMethodTypeParameter, "T").WithArguments("T", "C.M<T>()").WithLocation(12, 19));
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var exprs = tree.GetRoot().DescendantNodes().OfType<TypeOfExpressionSyntax>().Select(n => n.Type).ToImmutableArray();
            var symbol = model.GetSymbolInfo(exprs[0]).Symbol;
            Assert.Equal(SymbolKind.TypeParameter, symbol.Kind);
            Assert.Equal("void C.M<T>()", symbol.ContainingSymbol.ToTestDisplayString());
            symbol = model.GetSymbolInfo(exprs[1]).Symbol;
            Assert.Equal(SymbolKind.TypeParameter, symbol.Kind);
            Assert.Equal("System.Object F2<T>()", symbol.ContainingSymbol.ToTestDisplayString());
            symbol = model.GetSymbolInfo(exprs[2]).Symbol;
            Assert.Equal(SymbolKind.TypeParameter, symbol.Kind);
            Assert.Equal("System.Object F3<U>()", symbol.ContainingSymbol.ToTestDisplayString());
        }
 
        /// <summary>
        /// sizeof(T) should bind to nearest type.
        /// </summary>
        [Fact]
        public void SizeOf_ShadowedTypeParameter()
        {
            var source =
@"#pragma warning disable 0219
#pragma warning disable 8321
unsafe class C
{
    static void M<T>() where T : unmanaged
    {
        object F1()
        {
            int T = 0;
            return sizeof(T);
        }
        object F2<T>() where T : unmanaged
        {
            return sizeof(T);
        }
        object F3<U>() where U : unmanaged
        {
            return sizeof(U);
        }
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll);
            comp.VerifyDiagnostics(
                // (12,19): warning CS8387: Type parameter 'T' has the same name as the type parameter from outer method 'C.M<T>()'
                //         object F2<T>()
                Diagnostic(ErrorCode.WRN_TypeParameterSameAsOuterMethodTypeParameter, "T").WithArguments("T", "C.M<T>()").WithLocation(12, 19));
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var exprs = tree.GetRoot().DescendantNodes().OfType<SizeOfExpressionSyntax>().Select(n => n.Type).ToImmutableArray();
            var symbol = model.GetSymbolInfo(exprs[0]).Symbol;
            Assert.Equal(SymbolKind.TypeParameter, symbol.Kind);
            Assert.Equal("void C.M<T>()", symbol.ContainingSymbol.ToTestDisplayString());
            symbol = model.GetSymbolInfo(exprs[1]).Symbol;
            Assert.Equal(SymbolKind.TypeParameter, symbol.Kind);
            Assert.Equal("System.Object F2<T>()", symbol.ContainingSymbol.ToTestDisplayString());
            symbol = model.GetSymbolInfo(exprs[2]).Symbol;
            Assert.Equal(SymbolKind.TypeParameter, symbol.Kind);
            Assert.Equal("System.Object F3<U>()", symbol.ContainingSymbol.ToTestDisplayString());
        }
 
        private static ImmutableArray<ExpressionSyntax> GetNameOfExpressions(SyntaxTree tree)
        {
            return tree.GetRoot().DescendantNodes().
                OfType<InvocationExpressionSyntax>().
                Where(n => n.Expression.ToString() == "nameof").
                Select(n => n.ArgumentList.Arguments[0].Expression).
                ToImmutableArray();
        }
 
        [Fact]
        public void ShadowWithSelfReferencingLocal()
        {
            var source =
@"using System;
class Program
{
    static void Main()
    {
        int x = 13;
        void Local()
        {
            int x = (x = 0) + 42;
            Console.WriteLine(x);
        }
        Local();
        Console.WriteLine(x);
    }
}";
            CompileAndVerify(source, expectedOutput:
@"42
13");
        }
 
        [Fact, WorkItem(38129, "https://github.com/dotnet/roslyn/issues/38129")]
        public void StaticLocalFunctionLocalFunctionReference_01()
        {
            var source =
@"#pragma warning disable 8321
class C
{
    static void M()
    {
        void F1() {}
        static void F2() {}
 
        static void F3()
        {
            F1();
            F2();
        }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (11,13): error CS8421: A static local function cannot contain a reference to 'F1'.
                //             F1();
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureVariable, "F1()").WithArguments("F1").WithLocation(11, 13));
        }
 
        [Fact, WorkItem(39706, "https://github.com/dotnet/roslyn/issues/39706")]
        public void StaticLocalFunctionLocalFunctionReference_02()
        {
            var source =
@"#pragma warning disable 8321
class Program
{
    static void Method()
    {
        void Local<T>() {}
        static void StaticLocal()
        {
            Local<int>();
        }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (9,13): error CS8421: A static local function cannot contain a reference to 'Local'.
                //             Local<int>();
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureVariable, "Local<int>()").WithArguments("Local").WithLocation(9, 13));
        }
 
        [Fact, WorkItem(39706, "https://github.com/dotnet/roslyn/issues/39706")]
        public void StaticLocalFunctionLocalFunctionReference_03()
        {
            var source =
@"using System;
class Program
{
    static void Method()
    {
        int i = 0;
        void Local<T>()
        {
            i = 0;
        }
        Action a = () => i++;
        static void StaticLocal()
        {
            Local<int>();
        }
        StaticLocal();
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (14,13): error CS8421: A static local function cannot contain a reference to 'Local'.
                //             Local<int>();
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureVariable, "Local<int>()").WithArguments("Local").WithLocation(14, 13));
        }
 
        [Fact, WorkItem(38240, "https://github.com/dotnet/roslyn/issues/38240")]
        public void StaticLocalFunctionLocalFunctionDelegateReference_01()
        {
            var source =
@"#pragma warning disable 8321
using System;
class C
{
    static void M()
    {
        void F1() {}
 
        static void F2()
        {
            Action a = F1;
            _ = new Action(F1);
        }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (11,24): error CS8421: A static local function cannot contain a reference to 'F1'.
                //             Action a = F1;
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureVariable, "F1").WithArguments("F1").WithLocation(11, 24),
                // (12,28): error CS8421: A static local function cannot contain a reference to 'F1'.
                //             _ = new Action(F1);
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureVariable, "F1").WithArguments("F1").WithLocation(12, 28));
        }
 
        [Fact, WorkItem(39706, "https://github.com/dotnet/roslyn/issues/39706")]
        public void StaticLocalFunctionLocalFunctionDelegateReference_02()
        {
            var source =
@"#pragma warning disable 8321
using System;
class Program
{
    static void Method()
    {
        void Local<T>() {}
        static void StaticLocal()
        {
            Action a;
            a = Local<int>;
            a = new Action(Local<string>);
        }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (11,17): error CS8421: A static local function cannot contain a reference to 'Local'.
                //             a = Local<int>;
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureVariable, "Local<int>").WithArguments("Local").WithLocation(11, 17),
                // (12,28): error CS8421: A static local function cannot contain a reference to 'Local'.
                //             a = new Action(Local<string>);
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureVariable, "Local<string>").WithArguments("Local").WithLocation(12, 28));
        }
 
        [Fact, WorkItem(39706, "https://github.com/dotnet/roslyn/issues/39706")]
        public void StaticLocalFunctionLocalFunctionDelegateReference_03()
        {
            var source =
@"using System;
class Program
{
    static void Method()
    {
        int i = 0;
        void Local<T>()
        {
            i = 0;
        }
        Action a = () => i++;
        a = StaticLocal();
        static Action StaticLocal()
        {
            return Local<int>;
        }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (15,20): error CS8421: A static local function cannot contain a reference to 'Local'.
                //             return Local<int>;
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureVariable, "Local<int>").WithArguments("Local").WithLocation(15, 20));
        }
 
        [Fact]
        public void StaticLocalFunctionGenericStaticLocalFunction()
        {
            var source =
@"using System;
class Program
{
    static void Main()
    {
        static void F1<T>()
        {
            Console.WriteLine(typeof(T));
        }
        static void F2()
        {
            F1<int>();
            Action a = F1<string>;
            a();
        }
        F2();
    }
}";
            CompileAndVerify(source, expectedOutput:
@"System.Int32
System.String");
        }
 
        [Fact, WorkItem(38240, "https://github.com/dotnet/roslyn/issues/38240")]
        public void StaticLocalFunctionStaticFunctionsDelegateReference()
        {
            var source =
@"#pragma warning disable 8321
using System;
class C
{
    static void M()
    {
        static void F1() {}
        
        static void F2()
        {
            Action m = M;
            Action f1 = F1;
            _ = new Action(M);
            _ = new Action(F1);
        }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact, WorkItem(38240, "https://github.com/dotnet/roslyn/issues/38240")]
        public void StaticLocalFunctionThisAndBaseDelegateReference()
        {
            var source =
@"#pragma warning disable 8321
using System;
class B
{
    public virtual void M() {}
}
 
class C : B
{
    public override void M()
    {
        static void F()
        {
            Action a1 = base.M;
            Action a2 = this.M;
            Action a3 = M;
            _ = new Action(base.M);
            _ = new Action(this.M);
            _ = new Action(M);
        }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (14,25): error CS8422: A static local function cannot contain a reference to 'this' or 'base'.
                //             Action a1 = base.M;
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureThis, "base").WithLocation(14, 25),
                // (15,25): error CS8422: A static local function cannot contain a reference to 'this' or 'base'.
                //             Action a2 = this.M;
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureThis, "this").WithLocation(15, 25),
                // (16,25): error CS8422: A static local function cannot contain a reference to 'this' or 'base'.
                //             Action a3 = M;
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureThis, "M").WithLocation(16, 25),
                // (17,28): error CS8422: A static local function cannot contain a reference to 'this' or 'base'.
                //             _ = new Action(base.M);
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureThis, "base").WithLocation(17, 28),
                // (18,28): error CS8422: A static local function cannot contain a reference to 'this' or 'base'.
                //             _ = new Action(this.M);
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureThis, "this").WithLocation(18, 28),
                // (19,28): error CS8422: A static local function cannot contain a reference to 'this' or 'base'.
                //             _ = new Action(M);
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureThis, "M").WithLocation(19, 28));
        }
 
        [Fact, WorkItem(38240, "https://github.com/dotnet/roslyn/issues/38240")]
        public void StaticLocalFunctionDelegateReferenceWithReceiver()
        {
            var source =
@"#pragma warning disable 649
#pragma warning disable 8321
using System;
class C
{
    object f;
    
    void M()
    {
        object l;
        
        static void F1()
        {
            _ = new Func<int>(f.GetHashCode);
            _ = new Func<int>(l.GetHashCode);
        }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (14,31): error CS8422: A static local function cannot contain a reference to 'this' or 'base'.
                //             _ = new Func<int>(f.GetHashCode);
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureThis, "f").WithLocation(14, 31),
                // (15,31): error CS8421: A static local function cannot contain a reference to 'l'.
                //             _ = new Func<int>(l.GetHashCode);
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureVariable, "l").WithArguments("l").WithLocation(15, 31));
        }
 
        [Fact]
        [WorkItem(38143, "https://github.com/dotnet/roslyn/issues/38143")]
        public void EmittedAsStatic_01()
        {
            var source =
@"class Program
{
    static void M()
    {
        static void local() { }
        System.Action action = local;
    }
}";
            CompileAndVerify(source, options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), symbolValidator: m =>
            {
                var method = (MethodSymbol)m.GlobalNamespace.GetMember("Program.<M>g__local|0_0");
                Assert.True(method.IsStatic);
            });
        }
 
        [Fact]
        [WorkItem(38143, "https://github.com/dotnet/roslyn/issues/38143")]
        public void EmittedAsStatic_02()
        {
            var source =
@"class Program
{
    static void M<T>()
    {
        static void local(T t) { System.Console.Write(t.GetType().FullName); }
        System.Action<T> action = local;
        action(default(T));
    }
    static void Main()
    {
         M<int>();
    }
}";
            CompileAndVerify(source, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), expectedOutput: "System.Int32", symbolValidator: m =>
            {
                var method = (MethodSymbol)m.GlobalNamespace.GetMember("Program.<M>g__local|0_0");
                Assert.True(method.IsStatic);
                Assert.True(method.IsGenericMethod);
                Assert.Equal("void Program.<M>g__local|0_0<T>(T t)", method.ToTestDisplayString());
            });
        }
 
        /// <summary>
        /// Local function in generic method is emitted as a generic
        /// method even if no references to type parameters.
        /// </summary>
        [Fact]
        [WorkItem(38143, "https://github.com/dotnet/roslyn/issues/38143")]
        public void EmittedAsStatic_03()
        {
            var source =
@"class Program
{
    static void M<T>() where T : new()
    {
        static void local(object o) { System.Console.Write(o.GetType().FullName); }
        local(new T());
    }
    static void Main()
    {
         M<int>();
    }
}";
            CompileAndVerify(source, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), expectedOutput: "System.Int32", symbolValidator: m =>
            {
                var method = (MethodSymbol)m.GlobalNamespace.GetMember("Program.<M>g__local|0_0");
                Assert.True(method.IsStatic);
                Assert.True(method.IsGenericMethod);
                Assert.Equal("void Program.<M>g__local|0_0<T>(System.Object o)", method.ToTestDisplayString());
            });
        }
 
        /// <summary>
        /// Emit 'call' rather than 'callvirt' for local functions regardless of whether
        /// the local function is static.
        /// </summary>
        [Fact]
        public void EmitCallInstruction()
        {
            var source =
@"using static System.Console;
class Program
{
    static void Main()
    {
        int i;
        void L1() => WriteLine(i++);
        static void L2(int i) => WriteLine(i);
        i = 1;
        L1();
        L2(i);
    }
}";
            var verifier = CompileAndVerify(source, expectedOutput:
@"1
2");
            verifier.VerifyIL("Program.Main",
@"{
  // Code size       27 (0x1b)
  .maxstack  2
  .locals init (Program.<>c__DisplayClass0_0 V_0) //CS$<>8__locals0
  IL_0000:  ldloca.s   V_0
  IL_0002:  ldc.i4.1
  IL_0003:  stfld      ""int Program.<>c__DisplayClass0_0.i""
  IL_0008:  ldloca.s   V_0
  IL_000a:  call       ""void Program.<Main>g__L1|0_0(ref Program.<>c__DisplayClass0_0)""
  IL_000f:  ldloc.0
  IL_0010:  ldfld      ""int Program.<>c__DisplayClass0_0.i""
  IL_0015:  call       ""void Program.<Main>g__L2|0_1(int)""
  IL_001a:  ret
}");
        }
 
        /// <summary>
        /// '_' should bind to '_' symbol in outer scope even in static local function.
        /// </summary>
        [Fact]
        public void UnderscoreInOuterScope()
        {
            var source =
@"#pragma warning disable 8321
class C1
{
    object _;
    void F1()
    {
        void A1(object x) => _ = x;
        static void B1(object y) => _ = y;
    }
}
class C2
{
    static void F2()
    {
        object _;
        void A2(object x) => _ = x;
        static void B2(object y) => _ = y;
    }
    static void F3()
    {
        void A3(object x) => _ = x;
        static void B3(object y) => _ = y;
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (8,37): error CS8422: A static local function cannot contain a reference to 'this' or 'base'.
                //         static void B1(object y) => _ = y;
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureThis, "_").WithLocation(8, 37),
                // (17,37): error CS8421: A static local function cannot contain a reference to '_'.
                //         static void B2(object y) => _ = y;
                Diagnostic(ErrorCode.ERR_StaticLocalFunctionCannotCaptureVariable, "_").WithArguments("_").WithLocation(17, 37));
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var nodes = tree.GetRoot().DescendantNodes().OfType<AssignmentExpressionSyntax>();
            var actualSymbols = nodes.Select(n => model.GetSymbolInfo(n.Left).Symbol).Select(s => $"{s.Kind}: {s.ToTestDisplayString()}").ToArray();
            var expectedSymbols = new[]
            {
                "Field: System.Object C1._",
                "Field: System.Object C1._",
                "Local: System.Object _",
                "Local: System.Object _",
                "Discard: System.Object _",
                "Discard: System.Object _",
            };
            AssertEx.Equal(expectedSymbols, actualSymbols);
        }
 
        /// <summary>
        /// 'var' should bind to 'var' symbol in outer scope even in static local function.
        /// </summary>
        [Fact]
        public void VarInOuterScope()
        {
            var source =
@"#pragma warning disable 8321
class C1
{
    class @var { }
    static void F1()
    {
        void A1(object x) { var y = x; }
        static void B1(object x) { var y = x; }
    }
}
namespace N
{
    using @var = System.String;
    class C2
    {
        static void F2()
        {
            void A2(object x) { var y = x; }
            static void B3(object x) { var y = x; }
        }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,37): error CS0266: Cannot implicitly convert type 'object' to 'C1.var'. An explicit conversion exists (are you missing a cast?)
                //         void A1(object x) { var y = x; }
                Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("object", "C1.var").WithLocation(7, 37),
                // (8,44): error CS0266: Cannot implicitly convert type 'object' to 'C1.var'. An explicit conversion exists (are you missing a cast?)
                //         static void B1(object x) { var y = x; }
                Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("object", "C1.var").WithLocation(8, 44),
                // (18,41): error CS0266: Cannot implicitly convert type 'object' to 'string'. An explicit conversion exists (are you missing a cast?)
                //             void A2(object x) { var y = x; }
                Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("object", "string").WithLocation(18, 41),
                // (19,48): error CS0266: Cannot implicitly convert type 'object' to 'string'. An explicit conversion exists (are you missing a cast?)
                //             static void B3(object x) { var y = x; }
                Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("object", "string").WithLocation(19, 48));
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var nodes = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>();
            var actualSymbols = nodes.Select(n => model.GetDeclaredSymbol(n)).ToTestDisplayStrings();
            var expectedSymbols = new[]
            {
                "C1.var y",
                "C1.var y",
                "System.String y",
                "System.String y",
            };
            AssertEx.Equal(expectedSymbols, actualSymbols);
        }
 
        [Fact]
        public void AwaitWithinAsyncOuterScope_01()
        {
            var source =
@"#pragma warning disable 1998
#pragma warning disable 8321
using System.Threading.Tasks;
class Program
{
    void F1()
    {
        void A1() { await Task.Yield(); }
        static void B1() { await Task.Yield(); }
    }
    void F2()
    {
        async void A2() { await Task.Yield(); }
        async static void B2() { await Task.Yield(); }
    }
    async void F3()
    {
        void A3() { await Task.Yield(); }
        static void B3() { await Task.Yield(); }
    }
    async void F4()
    {
        async void A4() { await Task.Yield(); }
        async static void B4() { await Task.Yield(); }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (8,21): error CS4033: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.
                //         void A1() { await Task.Yield(); }
                Diagnostic(ErrorCode.ERR_BadAwaitWithoutVoidAsyncMethod, "await Task.Yield()").WithLocation(8, 21),
                // (9,28): error CS4033: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.
                //         static void B1() { await Task.Yield(); }
                Diagnostic(ErrorCode.ERR_BadAwaitWithoutVoidAsyncMethod, "await Task.Yield()").WithLocation(9, 28),
                // (18,21): error CS4033: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.
                //         void A3() { await Task.Yield(); }
                Diagnostic(ErrorCode.ERR_BadAwaitWithoutVoidAsyncMethod, "await Task.Yield()").WithLocation(18, 21),
                // (19,28): error CS4033: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.
                //         static void B3() { await Task.Yield(); }
                Diagnostic(ErrorCode.ERR_BadAwaitWithoutVoidAsyncMethod, "await Task.Yield()").WithLocation(19, 28));
        }
 
        /// <summary>
        /// 'await' should be a contextual keyword in the same way,
        /// regardless of whether local function is static.
        /// </summary>
        [Fact]
        public void AwaitWithinAsyncOuterScope_02()
        {
            var source =
@"#pragma warning disable 1998
#pragma warning disable 8321
class Program
{
    void F1()
    {
        void A1<await>() { }
        static void B1<await>() { }
    }
    void F2()
    {
        async void A2<await>() { }
        async static void B2<await>() { }
    }
    async void F3()
    {
        void A3<await>() { }
        static void B3<await>() { }
    }
    async void F4()
    {
        async void A4<await>() { }
        async static void B4<await>() { }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,17): warning CS8981: The type name 'await' only contains lower-cased ascii characters. Such names may become reserved for the language.
                //         void A1<await>() { }
                Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "await").WithArguments("await").WithLocation(7, 17),
                // (8,24): warning CS8981: The type name 'await' only contains lower-cased ascii characters. Such names may become reserved for the language.
                //         static void B1<await>() { }
                Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "await").WithArguments("await").WithLocation(8, 24),
                // (12,23): error CS4003: 'await' cannot be used as an identifier within an async method or lambda expression
                //         async void A2<await>() { }
                Diagnostic(ErrorCode.ERR_BadAwaitAsIdentifier, "await").WithLocation(12, 23),
                // (12,23): warning CS8981: The type name 'await' only contains lower-cased ascii characters. Such names may become reserved for the language.
                //         async void A2<await>() { }
                Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "await").WithArguments("await").WithLocation(12, 23),
                // (13,30): error CS4003: 'await' cannot be used as an identifier within an async method or lambda expression
                //         async static void B2<await>() { }
                Diagnostic(ErrorCode.ERR_BadAwaitAsIdentifier, "await").WithLocation(13, 30),
                // (13,30): warning CS8981: The type name 'await' only contains lower-cased ascii characters. Such names may become reserved for the language.
                //         async static void B2<await>() { }
                Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "await").WithArguments("await").WithLocation(13, 30),
                // (17,17): warning CS8981: The type name 'await' only contains lower-cased ascii characters. Such names may become reserved for the language.
                //         void A3<await>() { }
                Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "await").WithArguments("await").WithLocation(17, 17),
                // (18,24): warning CS8981: The type name 'await' only contains lower-cased ascii characters. Such names may become reserved for the language.
                //         static void B3<await>() { }
                Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "await").WithArguments("await").WithLocation(18, 24),
                // (22,23): error CS4003: 'await' cannot be used as an identifier within an async method or lambda expression
                //         async void A4<await>() { }
                Diagnostic(ErrorCode.ERR_BadAwaitAsIdentifier, "await").WithLocation(22, 23),
                // (22,23): warning CS8981: The type name 'await' only contains lower-cased ascii characters. Such names may become reserved for the language.
                //         async void A4<await>() { }
                Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "await").WithArguments("await").WithLocation(22, 23),
                // (23,30): error CS4003: 'await' cannot be used as an identifier within an async method or lambda expression
                //         async static void B4<await>() { }
                Diagnostic(ErrorCode.ERR_BadAwaitAsIdentifier, "await").WithLocation(23, 30),
                // (23,30): warning CS8981: The type name 'await' only contains lower-cased ascii characters. Such names may become reserved for the language.
                //         async static void B4<await>() { }
                Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "await").WithArguments("await").WithLocation(23, 30));
        }
 
        [Theory, CombinatorialData, WorkItem(59775, "https://github.com/dotnet/roslyn/issues/59775")]
        public void TypeParameterScope_InMethodAttributeNameOf(bool useCSharp10)
        {
            var source = @"
class C
{
    void M()
    {
        local<object>();
 
        [My(nameof(TParameter))] // 1
        void local<TParameter>() { }
    }
 
    [My(nameof(TParameter))] // 2
    void M2<TParameter>() { }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyTParameter(comp, 0, "void local<TParameter>()");
            VerifyTParameter(comp, 1, "void C.M2<TParameter>()");
        }
 
        [Theory, CombinatorialData, WorkItem(59775, "https://github.com/dotnet/roslyn/issues/59775")]
        public void TypeParameterScope_InMethodAttributeNameOfNameOf(bool useCSharp10)
        {
            var source = @"
class C
{
    void M()
    {
        local<object>();
 
        [My(nameof(nameof(TParameter)))] // 1
        void local<TParameter>() { }
    }
 
    [My(nameof(nameof(TParameter)))] // 2
    void M2<TParameter>() { }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics(
                // (8,20): error CS8081: Expression does not have a name.
                //         [My(nameof(nameof(TParameter)))] // 1
                Diagnostic(ErrorCode.ERR_ExpressionHasNoName, "nameof(TParameter)").WithLocation(8, 20),
                // (12,16): error CS8081: Expression does not have a name.
                //     [My(nameof(nameof(TParameter)))] // 2
                Diagnostic(ErrorCode.ERR_ExpressionHasNoName, "nameof(TParameter)").WithLocation(12, 16)
                );
 
            VerifyTParameter(comp, 0, "void local<TParameter>()");
            VerifyTParameter(comp, 1, "void C.M2<TParameter>()");
        }
 
        [Theory, CombinatorialData, WorkItem(59775, "https://github.com/dotnet/roslyn/issues/59775")]
        public void TypeParameterScope_InMethodAttributeNameOf_TopLevel(bool useCSharp10)
        {
            var source = @"
local<object>();
 
[My(nameof(TParameter))] // 1
void local<TParameter>() { }
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyTParameter(comp, 0, "void local<TParameter>()");
        }
 
        [Theory, CombinatorialData]
        public void TypeParameterScope_InMethodAttributeNameOf_SpeculatingWithNewAttribute(bool useCSharp10)
        {
            var source = @"
class C
{
    void M()
    {
        local<object>();
 
        //[My(nameof(TParameter))]
        void local<TParameter>() { }
    }
 
    //[My(nameof(TParameter))]
    void M2<TParameter>() { }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var parseOptions = useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11;
            var comp = CreateCompilation(source, parseOptions: parseOptions);
            comp.VerifyDiagnostics();
            var tree = comp.SyntaxTrees.Single();
            // Note: offset by one to the left to get away from return type
            var localFuncPosition = tree.GetText().ToString().IndexOf("void local<TParameter>()", StringComparison.Ordinal) - 1;
            var methodPosition = tree.GetText().ToString().IndexOf("void M2<TParameter>()", StringComparison.Ordinal) - 1;
            var parentModel = comp.GetSemanticModel(tree);
 
            var attr = parseAttributeSyntax("[My(nameof(TParameter))]", parseOptions);
            VerifyTParameterSpeculation(parentModel, localFuncPosition, attr, found: false);
            VerifyTParameterSpeculation(parentModel, methodPosition, attr, found: false);
 
            attr = parseAttributeSyntax("[My(TParameter)]", parseOptions);
            VerifyTParameterSpeculation(parentModel, localFuncPosition, attr, found: false);
            VerifyTParameterSpeculation(parentModel, methodPosition, attr, found: false);
 
            return;
 
            // Note: this results in an attribute on a method, but that doesn't bring any extra type parameters
            static AttributeSyntax parseAttributeSyntax(string source, CSharpParseOptions parseOptions)
                => SyntaxFactory.ParseCompilationUnit($@"class X {{ {source} void M() {{ }} }}", options: parseOptions).DescendantNodes().OfType<AttributeSyntax>().Single();
        }
 
        static void VerifyTParameterSpeculation(SemanticModel parentModel, int localFuncPosition, AttributeSyntax attr1, bool found = true)
        {
            SemanticModel speculativeModel;
            var success = parentModel.TryGetSpeculativeSemanticModel(localFuncPosition, attr1, out speculativeModel);
            Assert.True(success);
            Assert.NotNull(speculativeModel);
 
            var symbolInfo = speculativeModel.GetSymbolInfo(getTParameter(attr1));
            if (found)
            {
                Assert.Equal(SymbolKind.TypeParameter, symbolInfo.Symbol.Kind);
            }
            else
            {
                Assert.Null(symbolInfo.Symbol);
            }
            return;
 
            static IdentifierNameSyntax getTParameter(CSharpSyntaxNode node)
            {
                return node.DescendantNodes().OfType<IdentifierNameSyntax>().Where(i => i.Identifier.ValueText == "TParameter").Single();
            }
        }
 
        [Theory, CombinatorialData]
        public void TypeParameterScope_InMethodAttributeNameOf_SpeculatingWithinAttribute(bool useCSharp10)
        {
            var source = @"
class C
{
    void M()
    {
        local<object>();
 
        [My(a)]
        [My(nameof(b))]
        void local<TParameter>() { }
    }
 
    [My(c)]
    [My(nameof(d))]
    void M2<TParameter>() { }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
 
            var parseOptions = useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11;
            var comp = CreateCompilation(source, parseOptions: parseOptions);
            comp.VerifyDiagnostics(
                // (8,13): error CS0103: The name 'a' does not exist in the current context
                //         [My(a)]
                Diagnostic(ErrorCode.ERR_NameNotInContext, "a").WithArguments("a").WithLocation(8, 13),
                // (9,20): error CS0103: The name 'b' does not exist in the current context
                //         [My(nameof(b))]
                Diagnostic(ErrorCode.ERR_NameNotInContext, "b").WithArguments("b").WithLocation(9, 20),
                // (13,9): error CS0103: The name 'c' does not exist in the current context
                //     [My(c)]
                Diagnostic(ErrorCode.ERR_NameNotInContext, "c").WithArguments("c").WithLocation(13, 9),
                // (14,16): error CS0103: The name 'd' does not exist in the current context
                //     [My(nameof(d))]
                Diagnostic(ErrorCode.ERR_NameNotInContext, "d").WithArguments("d").WithLocation(14, 16)
                );
 
            var tree = comp.SyntaxTrees.Single();
            var parentModel = comp.GetSemanticModel(tree);
 
            var aPosition = getIdentifierPosition("a");
            var newNameOf = parseNameof("nameof(TParameter)", parseOptions: parseOptions);
            Assert.Equal("System.String", parentModel.GetSpeculativeTypeInfo(aPosition, newNameOf, SpeculativeBindingOption.BindAsExpression).Type.ToTestDisplayString());
 
            var bPosition = getIdentifierPosition("b");
            var newNameOfArgument = parseIdentifier("TParameter", parseOptions: parseOptions);
            Assert.Equal("TParameter", parentModel.GetSpeculativeTypeInfo(bPosition, newNameOfArgument, SpeculativeBindingOption.BindAsExpression).Type.ToTestDisplayString());
 
            var cPosition = getIdentifierPosition("c");
            Assert.Equal("System.String", parentModel.GetSpeculativeTypeInfo(cPosition, newNameOf, SpeculativeBindingOption.BindAsExpression).Type.ToTestDisplayString());
 
            var dPosition = getIdentifierPosition("d");
            Assert.Equal("TParameter", parentModel.GetSpeculativeTypeInfo(dPosition, newNameOfArgument, SpeculativeBindingOption.BindAsExpression).Type.ToTestDisplayString());
 
            return;
 
            int getIdentifierPosition(string identifier)
            {
                return tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(i => i.Identifier.ValueText == identifier).Single().SpanStart;
            }
 
            static ExpressionSyntax parseNameof(string source, CSharpParseOptions parseOptions)
                => SyntaxFactory.ParseCompilationUnit($@"{source};", options: parseOptions).DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
 
            static ExpressionSyntax parseIdentifier(string source, CSharpParseOptions parseOptions)
                => SyntaxFactory.ParseCompilationUnit($@"{source};", options: parseOptions).DescendantNodes().OfType<IdentifierNameSyntax>().Single();
        }
 
        [Fact]
        public void TypeParameterScope_InMethodAttributeNameOf_SpeculatingWithReplacementAttribute()
        {
            var source = @"
class C
{
    void M()
    {
        local<object>();
 
        [My(a)]
        void local<TParameter>() { }
    }
 
    [My(b)]
    void M2<TParameter>() { }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            // C# 10
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(
                // (8,13): error CS0103: The name 'a' does not exist in the current context
                //         [My(a)]
                Diagnostic(ErrorCode.ERR_NameNotInContext, "a").WithArguments("a").WithLocation(8, 13),
                // (12,9): error CS0103: The name 'b' does not exist in the current context
                //     [My(b)]
                Diagnostic(ErrorCode.ERR_NameNotInContext, "b").WithArguments("b").WithLocation(12, 9)
                );
 
            var tree = comp.SyntaxTrees.Single();
            var parentModel = comp.GetSemanticModel(tree);
            var localFuncPosition = tree.GetText().ToString().IndexOf("[My(a)]", StringComparison.Ordinal);
            var methodPosition = tree.GetText().ToString().IndexOf("[My(b)]", StringComparison.Ordinal);
 
            var attr = parseAttributeSyntax("[My(nameof(TParameter))]", TestOptions.Regular10);
            VerifyTParameterSpeculation(parentModel, localFuncPosition, attr, found: false);
            VerifyTParameterSpeculation(parentModel, methodPosition, attr, found: false);
 
            attr = parseAttributeSyntax("[My(TParameter)]", TestOptions.Regular10);
            VerifyTParameterSpeculation(parentModel, localFuncPosition, attr, found: false);
            VerifyTParameterSpeculation(parentModel, methodPosition, attr, found: false);
 
            // C# 11
            comp = CreateCompilation(source, parseOptions: TestOptions.Regular11);
            comp.VerifyDiagnostics(
                // (8,13): error CS0103: The name 'a' does not exist in the current context
                //         [My(a)]
                Diagnostic(ErrorCode.ERR_NameNotInContext, "a").WithArguments("a").WithLocation(8, 13),
                // (12,9): error CS0103: The name 'b' does not exist in the current context
                //     [My(b)]
                Diagnostic(ErrorCode.ERR_NameNotInContext, "b").WithArguments("b").WithLocation(12, 9)
                );
 
            tree = comp.SyntaxTrees.Single();
            parentModel = comp.GetSemanticModel(tree);
 
            VerifyTParameterSpeculation(parentModel, localFuncPosition, attr, found: false);
            VerifyTParameterSpeculation(parentModel, methodPosition, attr, found: false);
 
            attr = parseAttributeSyntax("[My(TParameter)]", TestOptions.Regular10);
            VerifyTParameterSpeculation(parentModel, localFuncPosition, attr, found: false);
            VerifyTParameterSpeculation(parentModel, methodPosition, attr, found: false);
 
            return;
 
            static AttributeSyntax parseAttributeSyntax(string source, CSharpParseOptions parseOptions)
                => SyntaxFactory.ParseCompilationUnit($@"class X {{ {source} void M() {{ }} }}", options: parseOptions).DescendantNodes().OfType<AttributeSyntax>().Single();
        }
 
        [Theory, CombinatorialData]
        public void TypeParameterScope_InMethodAttributeNameOf_SpeculatingWithReplacementAttributeInsideExisting(bool useCSharp10)
        {
            var source = @"
class C
{
    void M()
    {
        local<object>();
 
        [My(positionA)]
        void local<TParameter>() { }
    }
 
    [My(positionB)]
    void M2<TParameter>() { }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var parseOptions = useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11;
            var comp = CreateCompilation(source, parseOptions: parseOptions);
            comp.VerifyDiagnostics(
                // (8,13): error CS0103: The name 'positionA' does not exist in the current context
                //         [My(positionA)]
                Diagnostic(ErrorCode.ERR_NameNotInContext, "positionA").WithArguments("positionA").WithLocation(8, 13),
                // (12,9): error CS0103: The name 'positionB' does not exist in the current context
                //     [My(positionB)]
                Diagnostic(ErrorCode.ERR_NameNotInContext, "positionB").WithArguments("positionB").WithLocation(12, 9)
                );
 
            var tree = comp.SyntaxTrees.Single();
            var parentModel = comp.GetSemanticModel(tree);
            var localFuncPosition = tree.GetText().ToString().IndexOf("positionA", StringComparison.Ordinal);
            var methodPosition = tree.GetText().ToString().IndexOf("positionB", StringComparison.Ordinal);
 
            var attr = parseAttributeSyntax("[My(nameof(TParameter))]", parseOptions);
            VerifyTParameterSpeculation(parentModel, localFuncPosition, attr);
            VerifyTParameterSpeculation(parentModel, methodPosition, attr);
 
            attr = parseAttributeSyntax("[My(TParameter)]", parseOptions);
            VerifyTParameterSpeculation(parentModel, localFuncPosition, attr, found: false);
            VerifyTParameterSpeculation(parentModel, methodPosition, attr, found: false);
 
            return;
 
            static AttributeSyntax parseAttributeSyntax(string source, CSharpParseOptions parseOptions)
                => SyntaxFactory.ParseCompilationUnit($@"class X {{ {source} void M() {{ }} }}", options: parseOptions).DescendantNodes().OfType<AttributeSyntax>().Single();
        }
 
        [Theory, CombinatorialData, WorkItem(59775, "https://github.com/dotnet/roslyn/issues/59775")]
        [WorkItem(60194, "https://github.com/dotnet/roslyn/issues/60194")]
        public void TypeParameterScope_InMethodAttributeNameOf_CompatBreak(bool useCSharp10)
        {
            var source = @"
class C
{
    class TParameter
    {
        public const string Constant = """";
    }
 
    void M()
    {
        local<object>();
 
        [My(nameof(TParameter.Constant))] // 1
        void local<TParameter>() { }
    }
 
    [My(nameof(TParameter.Constant))] // 2
    void M2<TParameter>() { }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
 
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics(
                // (13,20): error CS0704: Cannot do non-virtual member lookup in 'TParameter' because it is a type parameter
                //         [My(nameof(TParameter.Constant))] // 1
                Diagnostic(ErrorCode.ERR_LookupInTypeVariable, "TParameter").WithArguments("TParameter").WithLocation(13, 20),
                // (17,16): error CS0704: Cannot do non-virtual member lookup in 'TParameter' because it is a type parameter
                //     [My(nameof(TParameter.Constant))] // 2
                Diagnostic(ErrorCode.ERR_LookupInTypeVariable, "TParameter").WithArguments("TParameter").WithLocation(17, 16)
                );
 
            VerifyTParameter(comp, 0, "void local<TParameter>()");
            VerifyTParameter(comp, 1, "void C.M2<TParameter>()");
        }
 
        /// <summary>
        /// Look for usages of "TParameter" and verify the index-th one.
        /// </summary>
        private void VerifyTParameter(CSharpCompilation comp, int index, string expectedContainer, bool findAnyways = false, string lookupFinds = "TParameter", SymbolKind symbolKind = SymbolKind.TypeParameter)
        {
            var tree = comp.SyntaxTrees.First();
            var model = comp.GetSemanticModel(tree);
            var tParameterUsages = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>()
                .Where(i => i.Identifier.ValueText == "TParameter")
                .Where(i => i.Ancestors().Any(a => a.Kind() is SyntaxKind.Attribute or SyntaxKind.TypeConstraint or SyntaxKind.DefaultExpression or SyntaxKind.InvocationExpression or SyntaxKind.EqualsValueClause))
                .ToArray();
 
            var tParameterUsage = tParameterUsages[index];
 
            var symbol = model.GetSymbolInfo(tParameterUsage).Symbol;
            if (expectedContainer is null)
            {
                Assert.Null(symbol);
 
                var typeInfo = model.GetTypeInfo(tParameterUsage);
                if (findAnyways)
                {
                    // In certain cases, like `[TParameter]`, we're able to bind the attribute, find the type but reject it.
                    // So GetTypeInfo does return a type.
                    Assert.Equal(SymbolKind.TypeParameter, typeInfo.Type.Kind);
                }
                else
                {
                    Assert.True(typeInfo.Type.IsErrorType());
                }
 
                Assert.Equal(findAnyways, model.LookupSymbols(tParameterUsage.Position).ToTestDisplayStrings().Contains("TParameter"));
            }
            else
            {
                Assert.Equal(expectedContainer, symbol.ContainingSymbol.ToTestDisplayString());
                Assert.Equal(symbolKind, model.GetTypeInfo(tParameterUsage).Type.Kind);
 
                var lookupResults = model.LookupSymbols(tParameterUsage.Position).ToTestDisplayStrings();
                Assert.Contains(lookupFinds, lookupResults);
                if (lookupFinds != "TParameter")
                {
                    Assert.DoesNotContain("TParameter", lookupResults);
                }
            }
        }
 
        [Fact]
        public void TypeParameterScope_NotInMethodAttribute()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>();
 
        [My(TParameter)] // 1
        void local<TParameter>() { }
    }
 
    [My(TParameter)] // 2
    void M2<TParameter>() { }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(object o) { }
}
");
            comp.VerifyDiagnostics(
                // (8,13): error CS0103: The name 'TParameter' does not exist in the current context
                //         [My(TParameter)] // 1
                Diagnostic(ErrorCode.ERR_NameNotInContext, "TParameter").WithArguments("TParameter").WithLocation(8, 13),
                // (12,9): error CS0103: The name 'TParameter' does not exist in the current context
                //     [My(TParameter)] // 2
                Diagnostic(ErrorCode.ERR_NameNotInContext, "TParameter").WithArguments("TParameter").WithLocation(12, 9)
                );
 
            VerifyTParameter(comp, 0, null);
            VerifyTParameter(comp, 1, null);
        }
 
        [Fact]
        public void TypeParameterScope_NotInMethodAttributeTypeArgument()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>();
 
        [My<TParameter>] // 1
        void local<TParameter>() { }
    }
 
    [My<TParameter>] // 2
    void M2<TParameter>() { }
}
 
public class MyAttribute<T> : System.Attribute
{
}
");
            comp.VerifyDiagnostics(
                // (8,13): error CS0246: The type or namespace name 'TParameter' could not be found (are you missing a using directive or an assembly reference?)
                //         [My<TParameter>] // 1
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "TParameter").WithArguments("TParameter").WithLocation(8, 13),
                // (12,9): error CS0246: The type or namespace name 'TParameter' could not be found (are you missing a using directive or an assembly reference?)
                //     [My<TParameter>] // 2
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "TParameter").WithArguments("TParameter").WithLocation(12, 9)
                );
 
            VerifyTParameter(comp, 0, null);
            VerifyTParameter(comp, 1, null);
        }
 
        [Fact]
        public void TypeParameterScope_NotAsMethodAttributeType()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<System.Attribute>();
 
        [TParameter] // 1
        void local<TParameter>() where TParameter : System.Attribute { }
    }
 
    [TParameter] // 2
    void M2<TParameter>() where TParameter : System.Attribute { }
}
");
            comp.VerifyDiagnostics(
                // (8,10): error CS0246: The type or namespace name 'TParameterAttribute' could not be found (are you missing a using directive or an assembly reference?)
                //         [TParameter] // 1
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "TParameter").WithArguments("TParameterAttribute").WithLocation(8, 10),
                // (8,10): error CS0246: The type or namespace name 'TParameter' could not be found (are you missing a using directive or an assembly reference?)
                //         [TParameter] // 1
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "TParameter").WithArguments("TParameter").WithLocation(8, 10),
                // (12,6): error CS0246: The type or namespace name 'TParameterAttribute' could not be found (are you missing a using directive or an assembly reference?)
                //     [TParameter] // 2
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "TParameter").WithArguments("TParameterAttribute").WithLocation(12, 6),
                // (12,6): error CS0246: The type or namespace name 'TParameter' could not be found (are you missing a using directive or an assembly reference?)
                //     [TParameter] // 2
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "TParameter").WithArguments("TParameter").WithLocation(12, 6)
                );
 
            VerifyTParameter(comp, 0, null);
            VerifyTParameter(comp, 1, null);
        }
 
        [Fact]
        public void TypeParameterScope_NotInMethodAttributeDefault()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>();
 
        [My(default(TParameter))]
        void local<TParameter>() where TParameter : class => throw null;
    }
 
    [My(default(TParameter))]
    void M2<TParameter>() where TParameter : class => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(object o) { }
}
");
            comp.VerifyDiagnostics(
                // (8,21): error CS0246: The type or namespace name 'TParameter' could not be found (are you missing a using directive or an assembly reference?)
                //         [My(default(TParameter))]
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "TParameter").WithArguments("TParameter").WithLocation(8, 21),
                // (12,17): error CS0246: The type or namespace name 'TParameter' could not be found (are you missing a using directive or an assembly reference?)
                //     [My(default(TParameter))]
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "TParameter").WithArguments("TParameter").WithLocation(12, 17)
                );
 
            VerifyTParameter(comp, 0, null);
            VerifyTParameter(comp, 1, null);
        }
 
        [Fact, WorkItem(60110, "https://github.com/dotnet/roslyn/issues/60110")]
        public void TypeParameterScope_NotInParameterAttribute()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>(0);
 
        void local<TParameter>([My(TParameter)] int i) => throw null;
    }
 
    void M2<TParameter>([My(TParameter)] int i) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            // TParameter unexpectedly was found in local function case because of IsInMethodBody logic
            // Tracked by https://github.com/dotnet/roslyn/issues/60110
            comp.VerifyDiagnostics(
                // (8,36): error CS0119: 'TParameter' is a type, which is not valid in the given context
                //         void local<TParameter>([My(TParameter)] int i) => throw null;
                Diagnostic(ErrorCode.ERR_BadSKunknown, "TParameter").WithArguments("TParameter", "type").WithLocation(8, 36),
                // (11,29): error CS0103: The name 'TParameter' does not exist in the current context
                //     void M2<TParameter>([My(TParameter)] int i) => throw null;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "TParameter").WithArguments("TParameter").WithLocation(11, 29)
                );
 
            //VerifyTParameter(comp, 0, null);
            VerifyTParameter(comp, 1, null);
        }
 
        [Fact, WorkItem(60110, "https://github.com/dotnet/roslyn/issues/60110")]
        public void TypeParameterScope_NotInParameterAttribute_NotShadowingConst()
        {
            var comp = CreateCompilation(@"
class C
{
    const string TParameter = """";
 
    void M()
    {
        local<object>(0);
 
        void local<TParameter>([My(TParameter)] int i) => throw null;
    }
 
    void M2<TParameter>([My(TParameter)] int i) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            // TParameter unexpectedly was found in local function case because of IsInMethodBody logic
            // Tracked by https://github.com/dotnet/roslyn/issues/60110
            comp.VerifyDiagnostics(
                // (10,36): error CS0119: 'TParameter' is a type, which is not valid in the given context
                //         void local<TParameter>([My(TParameter)] int i) => throw null;
                Diagnostic(ErrorCode.ERR_BadSKunknown, "TParameter").WithArguments("TParameter", "type").WithLocation(10, 36)
                );
 
            //VerifyTParameter(comp, 0, "C", symbolKind: SymbolKind.NamedType, lookupFinds: "System.String C.TParameter");
            VerifyTParameter(comp, 1, "C", symbolKind: SymbolKind.NamedType, lookupFinds: "System.String C.TParameter");
        }
 
        [Fact, WorkItem(60194, "https://github.com/dotnet/roslyn/issues/60194")]
        public void TypeParameterScope_InParameterAttributeNameOf()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>(0);
 
        void local<TParameter>([My(nameof(TParameter))] int i) => throw null;
    }
 
    void M2<TParameter>([My(nameof(TParameter))] int i) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            comp.VerifyDiagnostics();
 
            VerifyTParameter(comp, 0, "void local<TParameter>(System.Int32 i)");
            VerifyTParameter(comp, 1, "void C.M2<TParameter>(System.Int32 i)");
        }
 
        [Fact]
        public void TypeParameterScope_InParameterAttributeTypeOf()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>(0);
 
        void local<TParameter>([My(typeof(TParameter))] int i) => throw null;
    }
 
    void M2<TParameter>([My(typeof(TParameter))] int i) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(System.Type type) { }
}
");
            comp.VerifyDiagnostics(
                    // (8,36): error CS0416: 'TParameter': an attribute argument cannot use type parameters
                    //         void local<TParameter>([My(typeof(TParameter))] int i) => throw null;
                    Diagnostic(ErrorCode.ERR_AttrArgWithTypeVars, "typeof(TParameter)").WithArguments("TParameter").WithLocation(8, 36),
                    // (11,29): error CS0416: 'TParameter': an attribute argument cannot use type parameters
                    //     void M2<TParameter>([My(typeof(TParameter))] int i) => throw null;
                    Diagnostic(ErrorCode.ERR_AttrArgWithTypeVars, "typeof(TParameter)").WithArguments("TParameter").WithLocation(11, 29)
                );
 
            VerifyTParameter(comp, 0, "void local<TParameter>(System.Int32 i)");
            VerifyTParameter(comp, 1, "void C.M2<TParameter>(System.Int32 i)");
        }
 
        [Fact]
        public void TypeParameterScope_InParameterAttributeSizeOf()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<int>(0);
 
        void local<TParameter>([My(sizeof(TParameter))] int i) where TParameter : unmanaged => throw null;
    }
 
    void M2<TParameter>([My(sizeof(TParameter))] int i) where TParameter : unmanaged => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(int i) { }
}
");
            comp.VerifyDiagnostics(
                // (8,36): error CS0233: 'TParameter' does not have a predefined size, therefore sizeof can only be used in an unsafe context
                //         void local<TParameter>([My(sizeof(TParameter))] int i) where TParameter : unmanaged => throw null;
                Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(TParameter)").WithArguments("TParameter").WithLocation(8, 36),
                // (11,29): error CS0233: 'TParameter' does not have a predefined size, therefore sizeof can only be used in an unsafe context
                //     void M2<TParameter>([My(sizeof(TParameter))] int i) where TParameter : unmanaged => throw null;
                Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(TParameter)").WithArguments("TParameter").WithLocation(11, 29)
                );
 
            VerifyTParameter(comp, 0, "void local<TParameter>(System.Int32 i)");
            VerifyTParameter(comp, 1, "void C.M2<TParameter>(System.Int32 i)");
        }
 
        [Fact]
        public void TypeParameterScope_InParameterAttributeDefault()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>(0);
 
        void local<TParameter>([My(default(TParameter))] int i) where TParameter : class => throw null;
    }
 
    void M2<TParameter>([My(default(TParameter))] int i) where TParameter : class => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(object o) { }
}
");
            comp.VerifyDiagnostics();
 
            VerifyTParameter(comp, 0, "void local<TParameter>(System.Int32 i)");
            VerifyTParameter(comp, 1, "void C.M2<TParameter>(System.Int32 i)");
        }
 
        [Fact]
        public void TypeParameterScope_AsParameterAttributeType()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<System.Attribute>(0);
 
        void local<TParameter>([TParameter] int i) where TParameter : System.Attribute => throw null;
    }
 
    void M2<TParameter>([TParameter] int i) where TParameter : System.Attribute => throw null;
}
");
            comp.VerifyDiagnostics(
                // (8,33): error CS0616: 'TParameter' is not an attribute class
                //         void local<TParameter>([TParameter] int i) where TParameter : System.Attribute => throw null;
                Diagnostic(ErrorCode.ERR_NotAnAttributeClass, "TParameter").WithArguments("TParameter").WithLocation(8, 33),
                // (11,26): error CS0616: 'TParameter' is not an attribute class
                //     void M2<TParameter>([TParameter] int i) where TParameter : System.Attribute => throw null;
                Diagnostic(ErrorCode.ERR_NotAnAttributeClass, "TParameter").WithArguments("TParameter").WithLocation(11, 26)
                );
 
            VerifyTParameter(comp, 0, null, findAnyways: true);
            VerifyTParameter(comp, 1, null, findAnyways: true);
        }
 
        [Fact]
        public void TypeParameterScope_InReturnType()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>();
 
        TParameter local<TParameter>() => throw null;
    }
 
    TParameter M2<TParameter>() => throw null;
}
");
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void TypeParameterScope_InParameterType()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>(null);
 
        void local<TParameter>(TParameter p) => throw null;
    }
 
    void M2<TParameter>(TParameter p) => throw null;
}
");
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void TypeParameterScope_InTypeConstraint()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object, object>();
 
        void local<TParameter2, TParameter>() where TParameter2 : TParameter => throw null;
    }
 
    void M2<TParameter2, TParameter>() where TParameter2 : TParameter => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            comp.VerifyDiagnostics();
 
            VerifyTParameter(comp, 0, "void local<TParameter2, TParameter>()");
            VerifyTParameter(comp, 1, "void C.M2<TParameter2, TParameter>()");
        }
 
        [Fact]
        public void TypeParameterScope_NotInMethodAttributeTypeOf()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>();
 
        [My(typeof(TParameter))]
        void local<TParameter>() => throw null;
    }
 
    [My(typeof(TParameter))]
    void M2<TParameter>() => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            comp.VerifyDiagnostics(
                // (8,20): error CS0246: The type or namespace name 'TParameter' could not be found (are you missing a using directive or an assembly reference?)
                //         [My(typeof(TParameter))]
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "TParameter").WithArguments("TParameter").WithLocation(8, 20),
                // (12,16): error CS0246: The type or namespace name 'TParameter' could not be found (are you missing a using directive or an assembly reference?)
                //     [My(typeof(TParameter))]
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "TParameter").WithArguments("TParameter").WithLocation(12, 16)
                );
 
            VerifyTParameter(comp, 0, null);
            VerifyTParameter(comp, 1, null);
        }
 
        [Fact, WorkItem(60110, "https://github.com/dotnet/roslyn/issues/60110")]
        public void TypeParameterScope_NotInTypeParameterAttribute()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>();
 
        void local<[My(TParameter)] TParameter>() => throw null;
    }
 
    void M2<[My(TParameter)] TParameter>() => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            // TParameter unexpectedly was found in local function case because of IsInMethodBody logic
            // Tracked by https://github.com/dotnet/roslyn/issues/60110
            comp.VerifyDiagnostics(
                // (8,24): error CS0119: 'TParameter' is a type, which is not valid in the given context
                //         void local<[My(TParameter)] TParameter>() => throw null;
                Diagnostic(ErrorCode.ERR_BadSKunknown, "TParameter").WithArguments("TParameter", "type").WithLocation(8, 24),
                // (11,17): error CS0103: The name 'TParameter' does not exist in the current context
                //     void M2<[My(TParameter)] TParameter>() => throw null;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "TParameter").WithArguments("TParameter").WithLocation(11, 17)
                );
 
            //VerifyTParameter(comp, 0, null);
            VerifyTParameter(comp, 1, null);
        }
 
        [Fact, WorkItem(60194, "https://github.com/dotnet/roslyn/issues/60194")]
        public void TypeParameterScope_InTypeParameterAttributeNameOf()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>();
 
        void local<[My(nameof(TParameter))] TParameter>() => throw null;
    }
 
    void M2<[My(nameof(TParameter))] TParameter>() => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            comp.VerifyDiagnostics();
 
            VerifyTParameter(comp, 0, "void local<TParameter>()");
            VerifyTParameter(comp, 1, "void C.M2<TParameter>()");
        }
 
        [Fact]
        public void TypeParameterScope_InTypeParameterAttributeDefault()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>();
 
        void local<[My(default(TParameter))] TParameter>() where TParameter : class => throw null;
    }
 
    void M2<[My(default(TParameter))] TParameter>() where TParameter : class => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(object o) { }
}
");
            comp.VerifyDiagnostics();
 
            VerifyTParameter(comp, 0, "void local<TParameter>()");
            VerifyTParameter(comp, 1, "void C.M2<TParameter>()");
        }
 
        [Fact]
        public void TypeParameterScope_AsTypeParameterAttributeType()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<System.Attribute>();
 
        void local<[TParameter] TParameter>() where TParameter : System.Attribute => throw null;
    }
 
    void M2<[TParameter] TParameter>() where TParameter : System.Attribute => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            comp.VerifyDiagnostics(
                // (8,21): error CS0616: 'TParameter' is not an attribute class
                //         void local<[TParameter] TParameter>() where TParameter : System.Attribute => throw null;
                Diagnostic(ErrorCode.ERR_NotAnAttributeClass, "TParameter").WithArguments("TParameter").WithLocation(8, 21),
                // (11,14): error CS0616: 'TParameter' is not an attribute class
                //     void M2<[TParameter] TParameter>() where TParameter : System.Attribute => throw null;
                Diagnostic(ErrorCode.ERR_NotAnAttributeClass, "TParameter").WithArguments("TParameter").WithLocation(11, 14)
                );
 
            VerifyTParameter(comp, 0, null, findAnyways: true);
            VerifyTParameter(comp, 1, null, findAnyways: true);
        }
 
        [Fact]
        public void TypeParameterScope_InParameterDefaultDefaultValue()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<System.Attribute>();
 
        void local<TParameter>(TParameter s = default(TParameter)) => throw null;
    }
 
    void M2<TParameter>(TParameter s = default(TParameter)) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            comp.VerifyDiagnostics();
 
            VerifyTParameter(comp, 0, "void local<TParameter>([TParameter s = default(TParameter)])");
            VerifyTParameter(comp, 1, "void C.M2<TParameter>([TParameter s = default(TParameter)])");
        }
 
        [Fact]
        public void TypeParameterScope_InParameterDefaultValue()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<System.Attribute>();
 
        void local<TParameter>(TParameter s = TParameter) => throw null;
    }
 
    void M2<TParameter>(TParameter s = TParameter) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            // TParameter unexpectedly was found in local function case because of IsInMethodBody logic
            // Tracked by https://github.com/dotnet/roslyn/issues/60110
            comp.VerifyDiagnostics(
                // (8,47): error CS0119: 'TParameter' is a type, which is not valid in the given context
                //         void local<TParameter>(TParameter s = TParameter) => throw null;
                Diagnostic(ErrorCode.ERR_BadSKunknown, "TParameter").WithArguments("TParameter", "type").WithLocation(8, 47),
                // (11,40): error CS0103: The name 'TParameter' does not exist in the current context
                //     void M2<TParameter>(TParameter s = TParameter) => throw null;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "TParameter").WithArguments("TParameter").WithLocation(11, 40)
                );
 
            //VerifyTParameter(comp, 0, "void local<TParameter>([TParameter s = default(TParameter)])");
            VerifyTParameter(comp, 1, null);
        }
 
        [Fact, WorkItem(60110, "https://github.com/dotnet/roslyn/issues/60110")]
        public void TypeParameterScope_InParameterDefaultValue_NotShadowingConstant()
        {
            var comp = CreateCompilation(@"
class C
{
    const string TParameter = """";
 
    void M()
    {
        local<System.Attribute>();
 
        void local<TParameter>(string s = TParameter) => throw null;
    }
 
    void M2<TParameter>(string s = TParameter) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            // TParameter unexpectedly was found in local function case because of IsInMethodBody logic
            // Tracked by https://github.com/dotnet/roslyn/issues/60110
            comp.VerifyDiagnostics(
                // (10,43): error CS0119: 'TParameter' is a type, which is not valid in the given context
                //         void local<TParameter>(string s = TParameter) => throw null;
                Diagnostic(ErrorCode.ERR_BadSKunknown, "TParameter").WithArguments("TParameter", "type").WithLocation(10, 43)
                );
 
            //VerifyTParameter(comp, 0, "C", symbolKind: SymbolKind.NamedType, lookupFinds: "System.String C.TParameter");
            VerifyTParameter(comp, 1, "C", symbolKind: SymbolKind.NamedType, lookupFinds: "System.String C.TParameter");
        }
 
        [Fact, WorkItem(60194, "https://github.com/dotnet/roslyn/issues/60194")]
        public void TypeParameterScope_InParameterNameOfDefaultValue()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<System.Attribute>();
 
        void local<TParameter>(string s = nameof(TParameter)) => throw null;
    }
 
    void M2<TParameter>(string s = nameof(TParameter)) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            comp.VerifyDiagnostics();
 
            VerifyTParameter(comp, 0, @"void local<TParameter>([System.String s = ""TParameter""])");
            VerifyTParameter(comp, 1, @"void C.M2<TParameter>([System.String s = ""TParameter""])");
        }
 
        [Fact]
        public void TypeParameterScope_InParameterNameOfDefaultValue_NestedLocalFunction()
        {
            var comp = CreateCompilation(@"
class C
{
    const string TParameter = """";
 
    void M()
    {
        local<object>();
 
        void local<TParameter>(string s = TParameter) => throw null;
    }
 
    void M2<TParameter>(string s = TParameter) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            // TParameter unexpectedly was found in local function case because of IsInMethodBody logic
            // Tracked by https://github.com/dotnet/roslyn/issues/60110
            comp.VerifyDiagnostics(
                // (10,43): error CS0119: 'TParameter' is a type, which is not valid in the given context
                //         void local<TParameter>(string s = TParameter) => throw null;
                Diagnostic(ErrorCode.ERR_BadSKunknown, "TParameter").WithArguments("TParameter", "type").WithLocation(10, 43)
                );
 
            //VerifyTParameter(comp, 0, "C", lookupFinds: "System.String C.TParameter", symbolKind: SymbolKind.NamedType);
            VerifyTParameter(comp, 1, "C", lookupFinds: "System.String C.TParameter", symbolKind: SymbolKind.NamedType);
        }
 
        [Fact]
        public void TypeParameterScope_InTypeAttributeNameOf()
        {
            var comp = CreateCompilation(@"
[My(nameof(TParameter))]
class C<TParameter>
{
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name) { }
}
");
            comp.VerifyDiagnostics();
 
            VerifyTParameter(comp, 0, "C<TParameter>");
        }
 
        [Fact]
        public void TypeParameterScope_InTypeAttributeConstant()
        {
            var comp = CreateCompilation(@"
[My(TParameter.Constant)]
class C<TParameter> where TParameter : I
{
}
 
interface I
{
    const string Constant = ""hello"";
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name) { }
}
", targetFramework: TargetFramework.NetCoreApp);
 
            comp.VerifyDiagnostics(
                // (2,5): error CS0704: Cannot do non-virtual member lookup in 'TParameter' because it is a type parameter
                // [My(TParameter.Constant)]
                Diagnostic(ErrorCode.ERR_LookupInTypeVariable, "TParameter").WithArguments("TParameter").WithLocation(2, 5)
                );
 
            VerifyTParameter(comp, 0, "C<TParameter>");
        }
 
        [Fact]
        public void TypeParameterScope_InTypeAttributeType()
        {
            var comp = CreateCompilation(@"
[TParameter]
class C<TParameter> where TParameter : MyAttribute
{
}
 
public class MyAttribute : System.Attribute
{
}
");
            comp.VerifyDiagnostics(
                // (2,2): error CS0616: 'TParameter' is not an attribute class
                // [TParameter]
                Diagnostic(ErrorCode.ERR_NotAnAttributeClass, "TParameter").WithArguments("TParameter").WithLocation(2, 2)
                );
 
            VerifyTParameter(comp, 0, null, findAnyways: true);
        }
 
        [Fact]
        public void TypeParameterScope_InRecordAttributeNameOf()
        {
            var source = @"
[My(nameof(TParameter))]
record R<TParameter>();
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics();
            VerifyTParameter(comp, 0, "R<TParameter>");
 
            comp = CreateCompilation(source, parseOptions: TestOptions.Regular11);
            comp.VerifyDiagnostics();
            VerifyTParameter(comp, 0, "R<TParameter>");
        }
 
        [Fact]
        public void TypeParameterScope_InRecordParameterAttributeNameOf()
        {
            var source = @"
record R<TParameter>([My(nameof(TParameter))] int I);
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics();
            VerifyTParameter(comp, 0, "R<TParameter>");
 
            comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.Regular11);
            comp.VerifyDiagnostics();
            VerifyTParameter(comp, 0, "R<TParameter>");
        }
 
        [Fact]
        public void TypeParameterScope_InRecordAttributeNameOfConstant()
        {
            var source = @"
[My(nameof(TParameter.Constant))]
record R<TParameter>() where TParameter : I;
 
interface I
{
    const string Constant = ""hello"";
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.NetCoreApp);
            comp.VerifyDiagnostics(
                // (2,12): error CS0704: Cannot do non-virtual member lookup in 'TParameter' because it is a type parameter
                // [My(nameof(TParameter.Constant))]
                Diagnostic(ErrorCode.ERR_LookupInTypeVariable, "TParameter").WithArguments("TParameter").WithLocation(2, 12)
                );
            VerifyTParameter(comp, 0, "R<TParameter>");
        }
 
        [Fact]
        public void TypeParameterScope_InRecordAttributeNameOf_RecordStruct()
        {
            var source = @"
[My(nameof(TParameter))]
record struct R<TParameter>();
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
            VerifyTParameter(comp, 0, "R<TParameter>");
        }
 
        [Fact]
        public void TypeParameterScope_AsRecordAttributeType()
        {
            var source = @"
[TParameter]
record R<TParameter>() where TParameter : System.Attribute;
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (2,2): error CS0616: 'TParameter' is not an attribute class
                // [TParameter]
                Diagnostic(ErrorCode.ERR_NotAnAttributeClass, "TParameter").WithArguments("TParameter").WithLocation(2, 2)
                );
            VerifyTParameter(comp, 0, null, findAnyways: true);
        }
 
        [Fact]
        public void TypeParameterScope_InRecordAttributeTypeArgument()
        {
            var source = @"
[My<TParameter>]
record R<TParameter>() where TParameter : System.Attribute;
 
public class MyAttribute<T> : System.Attribute
{
    public MyAttribute() { }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (2,2): error CS8968: 'TParameter': an attribute type argument cannot use type parameters
                // [My<TParameter>]
                Diagnostic(ErrorCode.ERR_AttrTypeArgCannotBeTypeVar, "My<TParameter>").WithArguments("TParameter").WithLocation(2, 2)
                );
            VerifyTParameter(comp, 0, "R<TParameter>");
        }
 
        [Fact]
        public void TypeParameterScope_InRecordAttributeConstant()
        {
            var source = @"
[My(TParameter.Constant)]
record R<TParameter>() where TParameter : I;
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name) { }
}
 
public interface I
{
    const string Constant = ""hello"";
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.NetCoreApp);
            comp.VerifyDiagnostics(
                // (2,5): error CS0704: Cannot do non-virtual member lookup in 'TParameter' because it is a type parameter
                // [My(TParameter.Constant)]
                Diagnostic(ErrorCode.ERR_LookupInTypeVariable, "TParameter").WithArguments("TParameter").WithLocation(2, 5)
                );
            VerifyTParameter(comp, 0, "R<TParameter>");
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InMethodAttributeNameOf(bool useCSharp10)
        {
            var source = @"
class C
{
    void M()
    {
        local(0);
 
        [My(nameof(parameter))] // 1
        void local(int parameter) { }
    }
 
    [My(nameof(parameter))] // 2
    void M2(int parameter) { }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "void local(System.Int32 parameter)");
            VerifyParameter(comp, 1, "void C.M2(System.Int32 parameter)");
        }
 
        /// <summary>
        /// Look for usages of "parameter" and verify the index-th one.
        /// </summary>
        private void VerifyParameter(CSharpCompilation comp, int index, string expectedMethod, string parameterName = "parameter")
        {
            var tree = comp.SyntaxTrees.First();
            var model = comp.GetSemanticModel(tree);
            var parameterUsages = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>()
                .Where(i => i.Identifier.ValueText == parameterName)
                .Where(i => i.Ancestors().Any(a => a.IsKind(SyntaxKind.Attribute) || a.IsKind(SyntaxKind.TypeConstraint) || a.IsKind(SyntaxKind.DefaultExpression) || a.IsKind(SyntaxKind.InvocationExpression)))
                .ToArray();
 
            var parameterUsage = parameterUsages[index];
 
            var symbol = model.GetSymbolInfo(parameterUsage).Symbol;
            if (expectedMethod is null)
            {
                Assert.Null(symbol);
                Assert.True(model.GetTypeInfo(parameterUsage).Type.IsErrorType());
                Assert.DoesNotContain("parameter", model.LookupSymbols(parameterUsage.Position).ToTestDisplayStrings());
            }
            else
            {
                Assert.Equal(expectedMethod, symbol.ContainingSymbol.ToTestDisplayString());
                Assert.Equal("System.Int32", model.GetTypeInfo(parameterUsage).Type.ToTestDisplayString());
 
                var lookupResults = model.LookupSymbols(parameterUsage.Position).ToTestDisplayStrings();
                Assert.Contains($"System.Int32 {parameterName}", lookupResults);
            }
        }
 
        [Fact]
        [WorkItem(60801, "https://github.com/dotnet/roslyn/issues/60801")]
        public void ParameterScope_InMethodAttributeNameOf_GetSymbolInfoOnSpeculativeMethodBodySemanticModel()
        {
            var source = @"
class C
{
    void M()
    {
        [My(nameof(parameter))]
        void local(int parameter) { }
    }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular11);
            comp.VerifyDiagnostics(
                // (7,14): warning CS8321: The local function 'local' is declared but never used
                //         void local(int parameter) { }
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "local").WithArguments("local").WithLocation(7, 14)
                );
 
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);
 
            var tree2 = CSharpSyntaxTree.ParseText(source);
            var method = tree2.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().First();
            Assert.True(model.TryGetSpeculativeSemanticModelForMethodBody(method.Body.SpanStart, method, out var speculativeModel));
 
            var invocation = tree2.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
            Assert.Equal("nameof(parameter)", invocation.ToString());
            var symbolInfo = speculativeModel.GetSymbolInfo(invocation);
            Assert.Null(symbolInfo.Symbol);
        }
 
        [Fact]
        public void ParameterScope_InMethodAttributeNameOf_LookupInEmptyNameof()
        {
            var source = @"
class C
{
    void M()
    {
        [My(nameof())]
        void local(int parameter) { }
    }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular11);
            comp.VerifyDiagnostics(
                // (6,13): error CS0103: The name 'nameof' does not exist in the current context
                //         [My(nameof())]
                Diagnostic(ErrorCode.ERR_NameNotInContext, "nameof").WithArguments("nameof").WithLocation(6, 13),
                // (7,14): warning CS8321: The local function 'local' is declared but never used
                //         void local(int parameter) { }
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "local").WithArguments("local").WithLocation(7, 14)
                );
 
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);
            var nameofExpression = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
 
            // An invocation may not be considered a 'nameof' operator unless it has one argument
            Assert.False(model.LookupSymbols(nameofExpression.ArgumentList.CloseParenToken.SpanStart).ToTestDisplayStrings().Contains("parameter"));
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InMethodAttributeNameOf_ConflictingNames(bool useCSharp10)
        {
            var source = @"
class C
{
    void M()
    {
        local<object>(0);
 
        [My(nameof(parameter))]
        void local<@parameter>(int parameter) => throw null;
    }
 
    [My(nameof(parameter))]
    void M2<@parameter>(int parameter) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics(
                // (9,36): error CS0412: 'parameter': a parameter, local variable, or local function cannot have the same name as a method type parameter
                //         void local<@parameter>(int parameter) => throw null;
                Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "parameter").WithArguments("parameter").WithLocation(9, 36),
                // (13,29): error CS0412: 'parameter': a parameter, local variable, or local function cannot have the same name as a method type parameter
                //     void M2<@parameter>(int parameter) => throw null;
                Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "parameter").WithArguments("parameter").WithLocation(13, 29)
                );
 
            VerifyParameter(comp, 0, "void local<parameter>(System.Int32 parameter)");
            VerifyParameter(comp, 1, "void C.M2<parameter>(System.Int32 parameter)");
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InMethodAttributeNameOf_CompatBreak(bool useCSharp10)
        {
            var source = @"
class C
{
    class @parameter
    {
        internal const int Constant = 0;
    }
 
    void M()
    {
        local(0);
 
        [My(nameof(parameter.Constant))] // 1
        void local(int parameter) { }
    }
 
    [My(nameof(parameter.Constant))] // 2
    void M2(int parameter) { }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics(
                // (13,30): error CS1061: 'int' does not contain a definition for 'Constant' and no accessible extension method 'Constant' accepting a first argument of type 'int' could be found (are you missing a using directive or an assembly reference?)
                //         [My(nameof(parameter.Constant))] // 1
                Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "Constant").WithArguments("int", "Constant").WithLocation(13, 30),
                // (17,26): error CS1061: 'int' does not contain a definition for 'Constant' and no accessible extension method 'Constant' accepting a first argument of type 'int' could be found (are you missing a using directive or an assembly reference?)
                //     [My(nameof(parameter.Constant))] // 2
                Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "Constant").WithArguments("int", "Constant").WithLocation(17, 26)
                );
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InMethodAttributeNameOf_WithReturnTarget(bool useCSharp10)
        {
            var source = @"
class C
{
    void M()
    {
        local(0);
 
        [return: My(nameof(parameter))] // 1
        void local(int parameter) { }
    }
 
    [return: My(nameof(parameter))] // 2
    void M2(int parameter) { }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "void local(System.Int32 parameter)");
            VerifyParameter(comp, 1, "void C.M2(System.Int32 parameter)");
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InMethodAttributeNameOf_SpeculatingWithReplacementAttributeInsideExisting(bool useCSharp10)
        {
            var source = @"
class C
{
    void M()
    {
        local(0);
 
        [My(positionA)]
        void local(int parameter) { }
    }
 
    [My(positionB)]
    void M2(int parameter) { }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var parseOptions = useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11;
            var comp = CreateCompilation(source, parseOptions: parseOptions);
            comp.VerifyDiagnostics(
                // (8,13): error CS0103: The name 'positionA' does not exist in the current context
                //         [My(positionA)]
                Diagnostic(ErrorCode.ERR_NameNotInContext, "positionA").WithArguments("positionA").WithLocation(8, 13),
                // (12,9): error CS0103: The name 'positionB' does not exist in the current context
                //     [My(positionB)]
                Diagnostic(ErrorCode.ERR_NameNotInContext, "positionB").WithArguments("positionB").WithLocation(12, 9)
                );
 
            var tree = comp.SyntaxTrees.Single();
            var parentModel = comp.GetSemanticModel(tree);
            var localFuncPosition = tree.GetText().ToString().IndexOf("positionA", StringComparison.Ordinal);
            var methodPosition = tree.GetText().ToString().IndexOf("positionB", StringComparison.Ordinal);
 
            var attr = parseAttributeSyntax("[My(nameof(parameter))]", parseOptions);
            VerifyParameterSpeculation(parentModel, localFuncPosition, attr);
            VerifyParameterSpeculation(parentModel, methodPosition, attr);
 
            attr = parseAttributeSyntax("[My(parameter)]", parseOptions);
            VerifyParameterSpeculation(parentModel, localFuncPosition, attr, found: false);
            VerifyParameterSpeculation(parentModel, methodPosition, attr, found: false);
 
            return;
 
            static AttributeSyntax parseAttributeSyntax(string source, CSharpParseOptions parseOptions)
                => SyntaxFactory.ParseCompilationUnit($@"class X {{ {source} void M() {{ }} }}", options: parseOptions).DescendantNodes().OfType<AttributeSyntax>().Single();
        }
 
        static void VerifyParameterSpeculation(SemanticModel parentModel, int localFuncPosition, AttributeSyntax attr1, bool found = true)
        {
            SemanticModel speculativeModel;
            var success = parentModel.TryGetSpeculativeSemanticModel(localFuncPosition, attr1, out speculativeModel);
            Assert.True(success);
            Assert.NotNull(speculativeModel);
 
            var symbolInfo = speculativeModel.GetSymbolInfo(getParameter(attr1));
            if (found)
            {
                Assert.Equal(SymbolKind.Parameter, symbolInfo.Symbol.Kind);
            }
            else
            {
                Assert.Null(symbolInfo.Symbol);
            }
            return;
 
            static IdentifierNameSyntax getParameter(CSharpSyntaxNode node)
            {
                return node.DescendantNodes().OfType<IdentifierNameSyntax>().Where(i => i.Identifier.ValueText == "parameter").Single();
            }
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InIndexerAttributeNameOf(bool useCSharp10)
        {
            var source = @"
class C
{
    [My(nameof(parameter))]
    int this[int parameter] => 0;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "System.Int32 C.this[System.Int32 parameter] { get; }");
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InIndexerAttributeNameOf_SetterOnly(bool useCSharp10)
        {
            var source = @"
class C
{
    [My(nameof(parameter))]
    int this[int parameter] { set => throw null; } 
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "System.Int32 C.this[System.Int32 parameter] { set; }");
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InIndexerGetterAttributeNameOf(bool useCSharp10)
        {
            var source = @"
class C
{
    int this[int parameter]
    {
        [My(nameof(parameter))]
        get => throw null;
    }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "System.Int32 C.this[System.Int32 parameter].get");
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InIndexerSetterAttributeNameOf(bool useCSharp10)
        {
            var source = @"
class C
{
    int this[int parameter]
    {
        [My(nameof(parameter))]
        set => throw null;
    }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "void C.this[System.Int32 parameter].set");
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InIndexerInitSetterAttributeNameOf(bool useCSharp10)
        {
            var source = @"
class C
{
    int this[int parameter]
    {
        [My(nameof(parameter))]
        init => throw null;
    }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "void modreq(System.Runtime.CompilerServices.IsExternalInit) C.this[System.Int32 parameter].init");
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InMethodAttributeNameOf_Lambda(bool useCSharp10)
        {
            var source = @"
class C
{
    void M()
    {
        var x = [My(nameof(parameter))] int (int parameter) => 0;
    }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "lambda expression");
        }
 
        [Fact]
        public void ParameterScope_InMethodAttributeNameOf_AnonymousFunctionWithImplicitParameters()
        {
            var source = @"
class C
{
    void M()
    {
        System.Func<int, int> x = [My(nameof(parameter))] delegate { return 1; }
    }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (6,36): error CS0103: The name 'My' does not exist in the current context
                //         System.Func<int, int> x = [My(nameof(parameter))] delegate { return 1; }
                Diagnostic(ErrorCode.ERR_NameNotInContext, "My").WithArguments("My").WithLocation(6, 36),
                // (6,46): error CS0103: The name 'parameter' does not exist in the current context
                //         System.Func<int, int> x = [My(nameof(parameter))] delegate { return 1; }
                Diagnostic(ErrorCode.ERR_NameNotInContext, "parameter").WithArguments("parameter").WithLocation(6, 46),
                // (6,59): error CS1002: ; expected
                //         System.Func<int, int> x = [My(nameof(parameter))] delegate { return 1; }
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "delegate").WithLocation(6, 59),
                // (6,81): error CS1002: ; expected
                //         System.Func<int, int> x = [My(nameof(parameter))] delegate { return 1; }
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(6, 81));
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InMethodAttributeNameOf_Delegate(bool useCSharp10)
        {
            var source = @"
[My(nameof(parameter))] delegate int MyDelegate(int parameter);
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "System.Int32 MyDelegate.Invoke(System.Int32 parameter)");
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InMethodAttributeNameOf_Delegate_ConflictingName(bool useCSharp10)
        {
            var source = @"
[My(nameof(TParameter))] delegate int MyDelegate<TParameter>(int TParameter);
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "System.Int32 MyDelegate<TParameter>.Invoke(System.Int32 TParameter)", parameterName: "TParameter");
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InMethodAttributeNameOf_Constructor(bool useCSharp10)
        {
            var source = @"
class C
{
    [My(nameof(parameter))] C(int parameter) { }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "C..ctor(System.Int32 parameter)");
        }
 
        [Fact]
        public void ParameterScope_NotInMethodAttribute()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local(0);
 
        [My(parameter)] // 1
        void local(int parameter) { }
    }
 
    [My(parameter)] // 2
    void M2(int parameter) { }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(object o) { }
}
");
            comp.VerifyDiagnostics(
                // (8,13): error CS0103: The name 'parameter' does not exist in the current context
                //         [My(parameter)] // 1
                Diagnostic(ErrorCode.ERR_NameNotInContext, "parameter").WithArguments("parameter").WithLocation(8, 13),
                // (12,9): error CS0103: The name 'parameter' does not exist in the current context
                //     [My(parameter)] // 2
                Diagnostic(ErrorCode.ERR_NameNotInContext, "parameter").WithArguments("parameter").WithLocation(12, 9)
                );
 
            VerifyParameter(comp, 0, null);
            VerifyParameter(comp, 1, null);
        }
 
        [Fact]
        public void ParameterScope_NotInMethodAttributeTypeArgument()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local(0);
 
        [My<parameter>] // 1
        void local(int parameter) { }
    }
 
    [My<parameter>] // 2
    void M2(int parameter) { }
}
 
public class MyAttribute<T> : System.Attribute
{
}
");
            comp.VerifyDiagnostics(
                // (8,13): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
                //         [My<parameter>] // 1
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(8, 13),
                // (12,9): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
                //     [My<parameter>] // 2
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(12, 9)
                );
 
            VerifyParameter(comp, 0, null);
            VerifyParameter(comp, 1, null);
        }
 
        [Fact]
        public void ParameterScope_NotAsMethodAttributeType()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local(null);
 
        [parameter] // 1
        void local(System.Attribute parameter) { }
    }
 
    [parameter] // 2
    void M2(System.Attribute parameter) { }
}
");
            comp.VerifyDiagnostics(
                // (8,10): error CS0246: The type or namespace name 'parameterAttribute' could not be found (are you missing a using directive or an assembly reference?)
                //         [parameter] // 1
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameterAttribute").WithLocation(8, 10),
                // (8,10): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
                //         [parameter] // 1
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(8, 10),
                // (12,6): error CS0246: The type or namespace name 'parameterAttribute' could not be found (are you missing a using directive or an assembly reference?)
                //     [parameter] // 2
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameterAttribute").WithLocation(12, 6),
                // (12,6): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
                //     [parameter] // 2
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(12, 6)
                );
 
            VerifyParameter(comp, 0, null);
            VerifyParameter(comp, 1, null);
        }
 
        [Fact]
        public void ParameterScope_NotInParameterAttribute()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local(0);
 
        void local([My(parameter)] int parameter) => throw null;
    }
 
    void M2([My(parameter)] int parameter) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            comp.VerifyDiagnostics(
                // (8,24): error CS0103: The name 'parameter' does not exist in the current context
                //         void local([My(parameter)] int parameter) => throw null;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "parameter").WithArguments("parameter").WithLocation(8, 24),
                // (11,17): error CS0103: The name 'parameter' does not exist in the current context
                //     void M2([My(parameter)] int parameter) => throw null;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "parameter").WithArguments("parameter").WithLocation(11, 17)
                );
 
            VerifyParameter(comp, 0, null);
            VerifyParameter(comp, 1, null);
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InParameterAttributeNameOf(bool useCSharp10)
        {
            var source = @"
class C
{
    void M()
    {
        local(0);
 
        void local([My(nameof(parameter))] int parameter) => throw null;
    }
 
    void M2([My(nameof(parameter))] int parameter) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "void local(System.Int32 parameter)");
            VerifyParameter(comp, 1, "void C.M2(System.Int32 parameter)");
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InParameterAttributeNameOf_ConflictingNames(bool useCSharp10)
        {
            var source = @"
class C
{
    void M()
    {
        local<object>(0);
 
        void local<TParameter>([My(nameof(TParameter))] int TParameter) => throw null;
    }
 
    void M2<TParameter>([My(nameof(TParameter))] int TParameter) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics(
                // (8,61): error CS0412: 'TParameter': a parameter, local variable, or local function cannot have the same name as a method type parameter
                //         void local<TParameter>([My(nameof(TParameter))] int TParameter) => throw null;
                Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "TParameter").WithArguments("TParameter").WithLocation(8, 61),
                // (11,54): error CS0412: 'TParameter': a parameter, local variable, or local function cannot have the same name as a method type parameter
                //     void M2<TParameter>([My(nameof(TParameter))] int TParameter) => throw null;
                Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "TParameter").WithArguments("TParameter").WithLocation(11, 54)
                );
 
            VerifyParameter(comp, 0, "void local<TParameter>(System.Int32 TParameter)", parameterName: "TParameter");
            VerifyParameter(comp, 1, "void C.M2<TParameter>(System.Int32 TParameter)", parameterName: "TParameter");
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InParameterAttributeNameOf_SpeculatingWithReplacementAttributeInsideExisting(bool useCSharp10)
        {
            var source = @"
class C
{
    void M()
    {
        local(0);
 
        void local([My(positionA)] int parameter) { }
    }
 
    void M2([My(positionB)] int parameter) { }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var parseOptions = useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11;
            var comp = CreateCompilation(source, parseOptions: parseOptions);
            comp.VerifyDiagnostics(
                // (8,24): error CS0103: The name 'positionA' does not exist in the current context
                //         void local([My(positionA)] int parameter) { }
                Diagnostic(ErrorCode.ERR_NameNotInContext, "positionA").WithArguments("positionA").WithLocation(8, 24),
                // (11,17): error CS0103: The name 'positionB' does not exist in the current context
                //     void M2([My(positionB)] int parameter) { }
                Diagnostic(ErrorCode.ERR_NameNotInContext, "positionB").WithArguments("positionB").WithLocation(11, 17)
                );
 
            var tree = comp.SyntaxTrees.Single();
            var parentModel = comp.GetSemanticModel(tree);
            var localFuncPosition = tree.GetText().ToString().IndexOf("positionA", StringComparison.Ordinal);
            var methodPosition = tree.GetText().ToString().IndexOf("positionB", StringComparison.Ordinal);
 
            var attr = parseAttributeSyntax("[My(nameof(parameter))]", TestOptions.Regular10);
            VerifyParameterSpeculation(parentModel, localFuncPosition, attr);
            VerifyParameterSpeculation(parentModel, methodPosition, attr);
 
            attr = parseAttributeSyntax("[My(parameter)]", TestOptions.Regular10);
            VerifyParameterSpeculation(parentModel, localFuncPosition, attr, found: false);
            VerifyParameterSpeculation(parentModel, methodPosition, attr, found: false);
 
            return;
 
            static AttributeSyntax parseAttributeSyntax(string source, CSharpParseOptions parseOptions)
                => SyntaxFactory.ParseCompilationUnit($@"class X {{ {source} void M() {{ }} }}", options: parseOptions).DescendantNodes().OfType<AttributeSyntax>().Single();
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InParameterAttributeNameOf_Indexer(bool useCSharp10)
        {
            var source = @"
class C
{
    int this[[My(nameof(parameter))] int parameter] => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "System.Int32 C.this[System.Int32 parameter] { get; }");
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InParameterAttributeNameOf_Indexer_SetterOnly(bool useCSharp10)
        {
            var source = @"
class C
{
    int this[[My(nameof(parameter))] int parameter] { set => throw null; }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "System.Int32 C.this[System.Int32 parameter] { set; }");
        }
 
        [Fact]
        public void ParameterScope_ValueLocalNotInPropertyOrAccessorAttributeNameOf()
        {
            var source = @"
class C
{
    [My(nameof(value))]
    int Property { set => throw null; }
 
    int Property2 { [My(nameof(value))] get => throw null; }
 
    int Property3 { [My(nameof(value))] set => throw null; }
 
    int Property4 { [My(nameof(value))] init => throw null; }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition });
            comp.VerifyDiagnostics(
                // (4,16): error CS0103: The name 'value' does not exist in the current context
                //     [My(nameof(value))]
                Diagnostic(ErrorCode.ERR_NameNotInContext, "value").WithArguments("value").WithLocation(4, 16),
                // (7,32): error CS0103: The name 'value' does not exist in the current context
                //     int Property2 { [My(nameof(value))] get => throw null; }
                Diagnostic(ErrorCode.ERR_NameNotInContext, "value").WithArguments("value").WithLocation(7, 32),
                // (9,32): error CS0103: The name 'value' does not exist in the current context
                //     int Property3 { [My(nameof(value))] set => throw null; }
                Diagnostic(ErrorCode.ERR_NameNotInContext, "value").WithArguments("value").WithLocation(9, 32),
                // (11,32): error CS0103: The name 'value' does not exist in the current context
                //     int Property4 { [My(nameof(value))] init => throw null; }
                Diagnostic(ErrorCode.ERR_NameNotInContext, "value").WithArguments("value").WithLocation(11, 32)
                );
        }
 
        [Fact, WorkItem(1556927, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1556927")]
        public void ParameterScope_ValueLocalNotInPropertyOrAccessorAttributeNameOf_UnknownAccessor()
        {
            var source = @"
class C
{
    int Property4 { [My(nameof(value))] unknown => throw null; }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name) { }
}
";
            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition });
            comp.VerifyDiagnostics(
                // (4,9): error CS0548: 'C.Property4': property or indexer must have at least one accessor
                //     int Property4 { [My(nameof(value))] unknown => throw null; }
                Diagnostic(ErrorCode.ERR_PropertyWithNoAccessors, "Property4").WithArguments("C.Property4").WithLocation(4, 9),
                // (4,41): error CS1014: A get or set accessor expected
                //     int Property4 { [My(nameof(value))] unknown => throw null; }
                Diagnostic(ErrorCode.ERR_GetOrSetExpected, "unknown").WithLocation(4, 41)
                );
 
            var tree = comp.SyntaxTrees.First();
            var model = comp.GetSemanticModel(tree);
            var node = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>()
                .Where(i => i.Identifier.ValueText == "value")
                .Where(i => i.Ancestors().Any(a => a.IsKind(SyntaxKind.Attribute)))
                .Single();
 
            Assert.Null(model.GetSymbolInfo(node).Symbol);
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InParameterAttributeNameOf_Constructor(bool useCSharp10)
        {
            var source = @"
class C
{
    C([My(nameof(parameter))] int parameter) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "C..ctor(System.Int32 parameter)");
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InParameterAttributeNameOf_Delegate(bool useCSharp10)
        {
            var source = @"
delegate void MyDelegate([My(nameof(parameter))] int parameter);
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "void MyDelegate.Invoke(System.Int32 parameter)");
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InParameterAttributeNameOf_ConversionOperator(bool useCSharp10)
        {
            var source = @"
class C
{
    public static implicit operator C([My(nameof(parameter))] int parameter) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "C C.op_Implicit(System.Int32 parameter)");
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InParameterAttributeNameOf_Operator(bool useCSharp10)
        {
            var source = @"
class C
{
    public static C operator +([My(nameof(parameter))] int parameter, C other) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "C C.op_Addition(System.Int32 parameter, C other)");
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InParameterAttributeNameOf_Lambda(bool useCSharp10)
        {
            var source = @"
class C
{
    void M()
    {
        var x = ([My(nameof(parameter))] int parameter) => 0;
    }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "lambda expression");
        }
 
        [Fact]
        public void ParameterScope_InParameterAttributeNameOf_AnonymousDelegate()
        {
            var source = @"
class C
{
    void M()
    {
        var x = delegate ([My(nameof(parameter))] int parameter) { return 0; };
    }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (6,27): error CS7014: Attributes are not valid in this context.
                //         var x = delegate ([My(nameof(parameter))] int parameter) { return 0; };
                Diagnostic(ErrorCode.ERR_AttributesNotAllowed, "[My(nameof(parameter))]").WithLocation(6, 27)
                );
 
            VerifyParameter(comp, 0, "lambda expression");
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InTypeParameterAttributeNameOf(bool useCSharp10)
        {
            var source = @"
class C
{
    void M()
    {
        local<object>(0);
 
        void local<[My(nameof(parameter))] T>(int parameter) { }
    }
 
    void M2<[My(nameof(parameter))] T>(int parameter) { }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "void local<T>(System.Int32 parameter)");
            VerifyParameter(comp, 1, "void C.M2<T>(System.Int32 parameter)");
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InTypeParameterAttributeNameOf_SpeculatingWithReplacementAttributeInsideExisting(bool useCSharp10)
        {
            var source = @"
class C
{
    void M()
    {
        local<object>(0);
 
        void local<[My(positionA)] T>(int parameter) { }
    }
 
    void M2<[My(positionB)] T>(int parameter) { }
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var parseOptions = useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11;
            var comp = CreateCompilation(source, parseOptions: parseOptions);
            comp.VerifyDiagnostics(
                // (8,24): error CS0103: The name 'positionA' does not exist in the current context
                //         void local([My(positionA)] int parameter) { }
                Diagnostic(ErrorCode.ERR_NameNotInContext, "positionA").WithArguments("positionA").WithLocation(8, 24),
                // (11,17): error CS0103: The name 'positionB' does not exist in the current context
                //     void M2([My(positionB)] int parameter) { }
                Diagnostic(ErrorCode.ERR_NameNotInContext, "positionB").WithArguments("positionB").WithLocation(11, 17)
                );
 
            var tree = comp.SyntaxTrees.Single();
            var parentModel = comp.GetSemanticModel(tree);
            var localFuncPosition = tree.GetText().ToString().IndexOf("positionA", StringComparison.Ordinal);
            var methodPosition = tree.GetText().ToString().IndexOf("positionB", StringComparison.Ordinal);
 
            var attr = parseAttributeSyntax("[My(nameof(parameter))]", TestOptions.Regular10);
            VerifyParameterSpeculation(parentModel, localFuncPosition, attr);
            VerifyParameterSpeculation(parentModel, methodPosition, attr);
 
            attr = parseAttributeSyntax("[My(parameter)]", TestOptions.Regular10);
            VerifyParameterSpeculation(parentModel, localFuncPosition, attr, found: false);
            VerifyParameterSpeculation(parentModel, methodPosition, attr, found: false);
 
            return;
 
            static AttributeSyntax parseAttributeSyntax(string source, CSharpParseOptions parseOptions)
                => SyntaxFactory.ParseCompilationUnit($@"class X {{ {source} void M() {{ }} }}", options: parseOptions).DescendantNodes().OfType<AttributeSyntax>().Single();
        }
 
        [Theory, CombinatorialData]
        public void ParameterScope_InTypeParameterAttributeNameOf_Delegate(bool useCSharp10)
        {
            var source = @"
delegate int MyDelegate<[My(nameof(parameter))] T>(int parameter);
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
";
            var comp = CreateCompilation(source, parseOptions: useCSharp10 ? TestOptions.Regular10 : TestOptions.Regular11);
            comp.VerifyDiagnostics();
 
            VerifyParameter(comp, 0, "System.Int32 MyDelegate<T>.Invoke(System.Int32 parameter)");
        }
 
        [Fact]
        public void ParameterScope_NotAsParameterAttributeType()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local(null);
 
        void local([parameter] System.Attribute parameter) => throw null;
    }
 
    void M2([parameter] System.Attribute parameter) => throw null;
}
");
            comp.VerifyDiagnostics(
                // (8,21): error CS0246: The type or namespace name 'parameterAttribute' could not be found (are you missing a using directive or an assembly reference?)
                //         void local([parameter] System.Attribute parameter) => throw null;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameterAttribute").WithLocation(8, 21),
                // (8,21): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
                //         void local([parameter] System.Attribute parameter) => throw null;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(8, 21),
                // (11,14): error CS0246: The type or namespace name 'parameterAttribute' could not be found (are you missing a using directive or an assembly reference?)
                //     void M2([parameter] System.Attribute parameter) => throw null;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameterAttribute").WithLocation(11, 14),
                // (11,14): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
                //     void M2([parameter] System.Attribute parameter) => throw null;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(11, 14)
                );
 
            VerifyParameter(comp, 0, null);
        }
 
        [Fact]
        public void ParameterScope_NotInReturnType()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local(0);
 
        parameter local(int parameter) => throw null;
    }
 
    parameter M2(int parameter) => throw null;
}
");
            comp.VerifyDiagnostics(
                // (8,9): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
                //         parameter local(int parameter) => throw null;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(8, 9),
                // (11,5): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
                //     parameter M2(int parameter) => throw null;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(11, 5)
                );
        }
 
        [Fact]
        public void ParameterScope_NotInParameterType()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local(null);
 
        void local(parameter parameter) => throw null;
    }
 
    void M2<TParameter>(parameter parameter) => throw null;
}
");
            comp.VerifyDiagnostics(
                // (8,20): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
                //         void local(parameter parameter) => throw null;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(8, 20),
                // (11,25): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
                //     void M2<TParameter>(parameter parameter) => throw null;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(11, 25)
                );
        }
 
        [Fact]
        public void ParameterScope_NotInTypeConstraint()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>(0);
        M2<object>(0);
 
        void local<TParameter>(int parameter) where TParameter : parameter => throw null;
    }
 
    void M2<TParameter>(int parameter) where TParameter : parameter => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            comp.VerifyDiagnostics(
                // (6,9): error CS0311: The type 'object' cannot be used as type parameter 'TParameter' in the generic type or method 'local<TParameter>(int)'. There is no implicit reference conversion from 'object' to 'parameter'.
                //         local<object>(0);
                Diagnostic(ErrorCode.ERR_GenericConstraintNotSatisfiedRefType, "local<object>").WithArguments("local<TParameter>(int)", "parameter", "TParameter", "object").WithLocation(6, 9),
                // (7,9): error CS0311: The type 'object' cannot be used as type parameter 'TParameter' in the generic type or method 'C.M2<TParameter>(int)'. There is no implicit reference conversion from 'object' to 'parameter'.
                //         M2<object>(0);
                Diagnostic(ErrorCode.ERR_GenericConstraintNotSatisfiedRefType, "M2<object>").WithArguments("C.M2<TParameter>(int)", "parameter", "TParameter", "object").WithLocation(7, 9),
                // (9,66): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
                //         void local<TParameter>(int parameter) where TParameter : parameter => throw null;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(9, 66),
                // (12,59): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
                //     void M2<TParameter>(int parameter) where TParameter : parameter => throw null;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(12, 59)
                );
 
            VerifyParameter(comp, 0, null);
            VerifyParameter(comp, 1, null);
        }
 
        [Fact]
        public void ParameterScope_NotInParameterDefaultDefaultValue()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local();
 
        void local(string parameter = default(parameter)) => throw null;
    }
 
    void M2(string parameter = default(parameter)) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            comp.VerifyDiagnostics(
                // (8,27): error CS1750: A value of type 'parameter' cannot be used as a default parameter because there are no standard conversions to type 'string'
                //         void local(string parameter = default(parameter)) => throw null;
                Diagnostic(ErrorCode.ERR_NoConversionForDefaultParam, "parameter").WithArguments("parameter", "string").WithLocation(8, 27),
                // (8,47): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
                //         void local(string parameter = default(parameter)) => throw null;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(8, 47),
                // (11,20): error CS1750: A value of type 'parameter' cannot be used as a default parameter because there are no standard conversions to type 'string'
                //     void M2(string parameter = default(parameter)) => throw null;
                Diagnostic(ErrorCode.ERR_NoConversionForDefaultParam, "parameter").WithArguments("parameter", "string").WithLocation(11, 20),
                // (11,40): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
                //     void M2(string parameter = default(parameter)) => throw null;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(11, 40)
                );
 
            VerifyParameter(comp, 0, null);
            VerifyParameter(comp, 1, null);
        }
 
        [Fact]
        public void ParameterScope_NotInParameterNameOfDefaultValue()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local();
 
        void local(string parameter = nameof(parameter)) => throw null;
    }
 
    void M2(string parameter = nameof(parameter)) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            comp.VerifyDiagnostics(
                // (8,46): error CS0103: The name 'parameter' does not exist in the current context
                //         void local(string parameter = nameof(parameter)) => throw null;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "parameter").WithArguments("parameter").WithLocation(8, 46),
                // (11,39): error CS0103: The name 'parameter' does not exist in the current context
                //     void M2(string parameter = nameof(parameter)) => throw null;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "parameter").WithArguments("parameter").WithLocation(11, 39)
                );
 
            VerifyParameter(comp, 0, null);
            VerifyParameter(comp, 1, null);
        }
 
        [Fact]
        public void MethodScope_InParameterAttribute()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>(0);
 
        void local<TParameter>([My(local)] int i) => throw null;
    }
 
    void M2<TParameter>([My(M2)] int i) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            comp.VerifyDiagnostics(
                // (8,36): error CS1503: Argument 1: cannot convert from 'method group' to 'string'
                //         void local<TParameter>([My(local)] int i) => throw null;
                Diagnostic(ErrorCode.ERR_BadArgType, "local").WithArguments("1", "method group", "string").WithLocation(8, 36),
                // (11,29): error CS1503: Argument 1: cannot convert from 'method group' to 'string'
                //     void M2<TParameter>([My(M2)] int i) => throw null;
                Diagnostic(ErrorCode.ERR_BadArgType, "M2").WithArguments("1", "method group", "string").WithLocation(11, 29)
                );
        }
 
        [Fact]
        public void MethodScope_InParameterAttributeNameOf()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>(0);
 
        void local<TParameter>([My(nameof(local))] int i) => throw null;
    }
 
    void M2<TParameter>([My(nameof(M2))] int i) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void MethodScope_InTypeParameterAttribute()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>(0);
 
        void local<[My(local)] TParameter>(int i) => throw null;
    }
 
    void M2<[My(M2)] TParameter>(int i) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            comp.VerifyDiagnostics(
                // (8,24): error CS1503: Argument 1: cannot convert from 'method group' to 'string'
                //         void local<[My(local)] TParameter>(int i) => throw null;
                Diagnostic(ErrorCode.ERR_BadArgType, "local").WithArguments("1", "method group", "string").WithLocation(8, 24),
                // (11,17): error CS1503: Argument 1: cannot convert from 'method group' to 'string'
                //     void M2<[My(M2)] TParameter>(int i) => throw null;
                Diagnostic(ErrorCode.ERR_BadArgType, "M2").WithArguments("1", "method group", "string").WithLocation(11, 17)
                );
        }
 
        [Fact]
        public void MethodScope_InTypeParameterAttributeNameOf()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>(0);
 
        void local<[My(nameof(local))] TParameter>(int i) => throw null;
    }
 
    void M2<[My(nameof(M2))] TParameter>(int i) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void MethodScope_InMethodAttribute()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>(0);
 
        [My(local)]
        void local<TParameter>(int i) => throw null;
    }
 
    [My(M2)]
    void M2<TParameter>(int i) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            comp.VerifyDiagnostics(
                // (8,13): error CS1503: Argument 1: cannot convert from 'method group' to 'string'
                //         [My(local)]
                Diagnostic(ErrorCode.ERR_BadArgType, "local").WithArguments("1", "method group", "string").WithLocation(8, 13),
                // (12,9): error CS1503: Argument 1: cannot convert from 'method group' to 'string'
                //     [My(M2)]
                Diagnostic(ErrorCode.ERR_BadArgType, "M2").WithArguments("1", "method group", "string").WithLocation(12, 9)
                );
        }
 
        [Fact]
        public void MethodScope_InMethodAttributeNameOf()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>(0);
 
        [My(nameof(local))]
        void local<TParameter>(int i) => throw null;
    }
 
    [My(nameof(M2))]
    void M2<TParameter>(int i) => throw null;
}
 
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            comp.VerifyDiagnostics();
        }
 
        [Fact, WorkItem(1556927, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1556927")]
        public void LambdaOutsideMemberModel()
        {
            var text = @"
public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
 
int P
{
    badAccessorName
    {
        M([My(nameof(P))] env => env);
";
            var comp = CreateCompilation(text);
 
            var tree = comp.SyntaxTrees.First();
            var model = comp.GetSemanticModel(tree);
            var node = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>()
                .Where(i => i.Identifier.ValueText == "P")
                .Where(i => i.Ancestors().Any(a => a.IsKind(SyntaxKind.Attribute)))
                .Single();
 
            // int P ... should be pulled into MyAttribute as it's more likely that there's an errant close curly in the
            // type, versus a property in a compilation unit.
            var symbol = model.GetSymbolInfo(node).Symbol;
            Assert.NotNull(symbol);
            var property = (IPropertySymbol)symbol;
            Assert.Equal("P", property.Name);
            Assert.Equal("MyAttribute", property.ContainingType.Name);
        }
 
        [Fact, WorkItem(43697, "https://github.com/dotnet/roslyn/issues/43697")]
        public void DefiniteAssignment_01()
        {
            var text = @"
using System;
using System.Threading.Tasks;
 
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
#pragma warning disable CS1998 // This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
 
public class C
{
    public void M()
    {
        bool a;
        M1();
        Console.WriteLine(a);
        async Task M1()
        {
            if ("""" == String.Empty)
            {
                throw new Exception();
            }
            else
            {
                a = true;
            }
        }
    }
}
";
            CreateCompilation(text).VerifyDiagnostics(
                // (14,27): error CS0165: Use of unassigned local variable 'a'
                //         Console.WriteLine(a);
                Diagnostic(ErrorCode.ERR_UseDefViolation, "a").WithArguments("a").WithLocation(14, 27)
                );
        }
 
        [Fact, WorkItem(43697, "https://github.com/dotnet/roslyn/issues/43697")]
        public void DefiniteAssignment_02()
        {
            var text = @"
using System;
using System.Threading.Tasks;
 
public class C
{
    public void M()
    {
        bool a;
        M1();
        Console.WriteLine(a);
        Task M1()
        {
            if ("""" == String.Empty)
            {
                throw new Exception();
            }
            else
            {
                a = true;
            }
 
            return null;
        }
    }
}
";
            CreateCompilation(text).VerifyDiagnostics();
        }
 
        [Fact, WorkItem(43697, "https://github.com/dotnet/roslyn/issues/43697")]
        public void DefiniteAssignment_03()
        {
            var text = @"
using System;
using System.Threading.Tasks;
 
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
 
public class C
{
    public void M()
    {
        bool a;
        M1();
        Console.WriteLine(a);
        async Task M1()
        {
            await Task.Yield();
 
            if ("""" == String.Empty)
            {
                throw new Exception();
            }
            else
            {
                a = true;
            }
        }
    }
}
";
            CreateCompilation(text).VerifyDiagnostics(
                // (13,27): error CS0165: Use of unassigned local variable 'a'
                //         Console.WriteLine(a);
                Diagnostic(ErrorCode.ERR_UseDefViolation, "a").WithArguments("a").WithLocation(13, 27)
                );
        }
 
        [Fact, WorkItem(43697, "https://github.com/dotnet/roslyn/issues/43697")]
        public void DefiniteAssignment_04()
        {
            var text = @"
using System;
using System.Threading.Tasks;
 
#pragma warning disable CS1998 // This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
 
public class C
{
    public async Task M()
    {
        bool a;
        await M1();
        Console.WriteLine(a);
        async Task M1()
        {
            if ("""" == String.Empty)
            {
                throw new Exception();
            }
            else
            {
                a = true;
            }
        }
    }
}
";
            CreateCompilation(text).VerifyDiagnostics(
                // (13,27): error CS0165: Use of unassigned local variable 'a'
                //         Console.WriteLine(a);
                Diagnostic(ErrorCode.ERR_UseDefViolation, "a").WithArguments("a").WithLocation(13, 27)
                );
        }
 
        [Fact, WorkItem(43697, "https://github.com/dotnet/roslyn/issues/43697")]
        public void DefiniteAssignment_05()
        {
            var text = @"
using System;
using System.Threading.Tasks;
 
public class C
{
    public async Task M()
    {
        bool a;
        await M1();
        Console.WriteLine(a);
        async Task M1()
        {
            await Task.Yield();
 
            if ("""" == String.Empty)
            {
                throw new Exception();
            }
            else
            {
                a = true;
            }
        }
    }
}
";
            CreateCompilation(text).VerifyDiagnostics(
                // (11,27): error CS0165: Use of unassigned local variable 'a'
                //         Console.WriteLine(a);
                Diagnostic(ErrorCode.ERR_UseDefViolation, "a").WithArguments("a").WithLocation(11, 27)
                );
        }
 
        [Fact]
        public void TestLocalFunctionDeclaration()
        {
            var compilation = CreateCompilation("""
                                                class Test
                                                {
                                                  void M()
                                                  {
                                                      int LocalFunc(string s) {}
                                                  }
                                                }
                                                """);
            var tree = compilation.SyntaxTrees[0];
            var semanticModel = compilation.GetSemanticModel(tree);
            var root = tree.GetCompilationUnitRoot();
            var localFunction = root.DescendantNodes().OfType<LocalFunctionStatementSyntax>().Single();
            IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(localFunction);
 
            Assert.Equal("System.Int32 LocalFunc(System.String s)", methodSymbol.ToTestDisplayString());
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/73905")]
        public void IdentifierInNameofInAttributeOnLocalFunctionInAccessor()
        {
            var src = """
using System;
 
[AttributeUsage(AttributeTargets.All)]
class A : Attribute
{
    public A(string s) { }
}
 
class C
{
    event EventHandler E
    {
        add
        {
            [param: A(nameof(p))] void F(int p) { }
        }
        remove
        {
        }
    }
}
""";
            var comp = CreateCompilation(src);
            comp.VerifyEmitDiagnostics(
                // (15,14): warning CS0657: 'param' is not a valid attribute location for this declaration. Valid attribute locations for this declaration are 'method, return'. All attributes in this block will be ignored.
                //             [param: A(nameof(p))] void F(int p) { }
                Diagnostic(ErrorCode.WRN_AttributeLocationOnBadDeclaration, "param").WithArguments("param", "method, return").WithLocation(15, 14),
                // (15,40): warning CS8321: The local function 'F' is declared but never used
                //             [param: A(nameof(p))] void F(int p) { }
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "F").WithArguments("F").WithLocation(15, 40));
 
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);
            var nameof = GetSyntax<InvocationExpressionSyntax>(tree, "nameof(p)");
            var p = nameof.ArgumentList.Arguments[0].Expression;
            Assert.Equal("System.Int32", model.GetTypeInfo(p).Type.ToTestDisplayString());
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/73905")]
        public void IdentifierInNameofInAttributeOnLocalFunctionInMethod()
        {
            var src = """
using System;
 
[AttributeUsage(AttributeTargets.All)]
class A : Attribute
{
    public A(string s) { }
}
 
class C
{
    void M()
    {
        [param: A(nameof(p))] void F(int p) { }
    }
}
""";
            var comp = CreateCompilation(src);
            comp.VerifyEmitDiagnostics(
                // (13,10): warning CS0657: 'param' is not a valid attribute location for this declaration. Valid attribute locations for this declaration are 'method, return'. All attributes in this block will be ignored.
                //         [param: A(nameof(p))] void F(int p) { }
                Diagnostic(ErrorCode.WRN_AttributeLocationOnBadDeclaration, "param").WithArguments("param", "method, return").WithLocation(13, 10),
                // (13,36): warning CS8321: The local function 'F' is declared but never used
                //         [param: A(nameof(p))] void F(int p) { }
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "F").WithArguments("F").WithLocation(13, 36));
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/73905")]
        public void IdentifierInNameofInAttributeOnLocalFunctionInMethodWithParameter()
        {
            var src = """
using System;
 
[AttributeUsage(AttributeTargets.All)]
class A : Attribute
{
    public A(string s) { }
}
 
class C
{
    void M(int p)
    {
        [param: A(nameof(p))] void F(int p2) { }
    }
}
""";
            var comp = CreateCompilation(src);
            comp.VerifyEmitDiagnostics(
                // (13,10): warning CS0657: 'param' is not a valid attribute location for this declaration. Valid attribute locations for this declaration are 'method, return'. All attributes in this block will be ignored.
                //         [param: A(nameof(p))] void F(int p2) { }
                Diagnostic(ErrorCode.WRN_AttributeLocationOnBadDeclaration, "param").WithArguments("param", "method, return").WithLocation(13, 10),
                // (13,36): warning CS8321: The local function 'F' is declared but never used
                //         [param: A(nameof(p))] void F(int p2) { }
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "F").WithArguments("F").WithLocation(13, 36));
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/73905")]
        public void IdentifierInNameofInParamAttributeOnLocalFunctionInPrimaryConstructorType()
        {
            var src = """
using System;
 
[AttributeUsage(AttributeTargets.All)]
class A : Attribute
{
    public A(string s) { }
}
 
class C(int p)
{
    void M()
    {
        [param: A(nameof(p))] void F(int p2) { }
    }
}
""";
            var comp = CreateCompilation(src);
            comp.VerifyEmitDiagnostics(
                // (9,13): warning CS9113: Parameter 'p' is unread.
                // class C(int p)
                Diagnostic(ErrorCode.WRN_UnreadPrimaryConstructorParameter, "p").WithArguments("p").WithLocation(9, 13),
                // (13,10): warning CS0657: 'param' is not a valid attribute location for this declaration. Valid attribute locations for this declaration are 'method, return'. All attributes in this block will be ignored.
                //         [param: A(nameof(p))] void F(int p2) { }
                Diagnostic(ErrorCode.WRN_AttributeLocationOnBadDeclaration, "param").WithArguments("param", "method, return").WithLocation(13, 10),
                // (13,36): warning CS8321: The local function 'F' is declared but never used
                //         [param: A(nameof(p))] void F(int p2) { }
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "F").WithArguments("F").WithLocation(13, 36));
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/73905")]
        public void IdentifierInNameofInAttributeOnLocalFunctionInPrimaryConstructorType()
        {
            var src = """
using System;
 
[AttributeUsage(AttributeTargets.All)]
class A : Attribute
{
    public A(string s) { }
}
 
class C(int p)
{
    void M()
    {
        [A(nameof(p))] void F() { }
    }
}
""";
            var comp = CreateCompilation(src);
            comp.VerifyEmitDiagnostics(
                // (9,13): warning CS9113: Parameter 'p' is unread.
                // class C(int p)
                Diagnostic(ErrorCode.WRN_UnreadPrimaryConstructorParameter, "p").WithArguments("p").WithLocation(9, 13),
                // (13,29): warning CS8321: The local function 'F' is declared but never used
                //         [A(nameof(p))] void F() { }
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "F").WithArguments("F").WithLocation(13, 29));
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/73905")]
        public void IdentifierInAttributeOnLocalFunctionInPrimaryConstructorType()
        {
            var src = """
using System;
 
[AttributeUsage(AttributeTargets.All)]
class A : Attribute
{
    public A(string s) { }
}
 
class C(string p)
{
    void M()
    {
        [A(p)] void F() { }
    }
}
""";
            var comp = CreateCompilation(src);
            comp.VerifyEmitDiagnostics(
                // (9,16): warning CS9113: Parameter 'p' is unread.
                // class C(string p)
                Diagnostic(ErrorCode.WRN_UnreadPrimaryConstructorParameter, "p").WithArguments("p").WithLocation(9, 16),
                // (13,12): error CS9105: Cannot use primary constructor parameter 'string p' in this context.
                //         [A(p)] void F() { }
                Diagnostic(ErrorCode.ERR_InvalidPrimaryConstructorParameterReference, "p").WithArguments("string p").WithLocation(13, 12),
                // (13,12): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
                //         [A(p)] void F() { }
                Diagnostic(ErrorCode.ERR_BadAttributeArgument, "p").WithLocation(13, 12),
                // (13,21): warning CS8321: The local function 'F' is declared but never used
                //         [A(p)] void F() { }
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "F").WithArguments("F").WithLocation(13, 21));
        }
    }
}