File: Symbols\ExtendedPartialMethodsTests.cs
Web Access
Project: src\src\Compilers\CSharp\Test\Symbol\Microsoft.CodeAnalysis.CSharp.Symbol.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Symbol.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 System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
    public class ExtendedPartialMethodsTests : CSharpTestBase
    {
        [Fact]
        public void NonVoidReturnType_LangVersion()
        {
            const string text = @"
partial class C
{
    internal partial int M1();
    internal partial int M1() => 1;
}";
            var comp = CreateCompilation(text, parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (4,26): error CS8400: Feature 'extended partial methods' is not available in C# 8.0. Please use language version 9.0 or greater.
                //     internal partial int M1();
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "M1").WithArguments("extended partial methods", "9.0").WithLocation(4, 26),
                // (5,26): error CS8400: Feature 'extended partial methods' is not available in C# 8.0. Please use language version 9.0 or greater.
                //     internal partial int M1() => 1;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "M1").WithArguments("extended partial methods", "9.0").WithLocation(5, 26)
            );
 
            comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void NonVoidReturnType_NoAccessibility()
        {
            const string text = @"
partial class C
{
    partial int M1();
    partial int M1() => 1;
}";
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (4,17): error CS8794: Partial method 'C.M1()' must have accessibility modifiers because it has a non-void return type.
                //     partial int M1();
                Diagnostic(ErrorCode.ERR_PartialMethodWithNonVoidReturnMustHaveAccessMods, "M1").WithArguments("C.M1()").WithLocation(4, 17),
                // (5,17): error CS8794: Partial method 'C.M1()' must have accessibility modifiers because it has a non-void return type.
                //     partial int M1() => 1;
                Diagnostic(ErrorCode.ERR_PartialMethodWithNonVoidReturnMustHaveAccessMods, "M1").WithArguments("C.M1()").WithLocation(5, 17)
            );
        }
 
        [Fact]
        public void NonVoidReturnType_NoImpl()
        {
            const string text = @"
partial class C
{
    private partial int M1();
}";
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (4,25): error CS8793: Partial method 'C.M1()' must have an implementation part because it has accessibility modifiers.
                //     private partial int M1();
                Diagnostic(ErrorCode.ERR_PartialMethodWithAccessibilityModsMustHaveImplementation, "M1").WithArguments("C.M1()").WithLocation(4, 25)
            );
        }
 
        [Fact]
        public void NonVoidReturnType_NoImpl_NoAccessibility()
        {
            const string text = @"
partial class C
{
    partial int M1();
}";
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (4,17): error CS8794: Partial method 'C.M1()' must have accessibility modifiers because it has a non-void return type.
                //     partial int M1();
                Diagnostic(ErrorCode.ERR_PartialMethodWithNonVoidReturnMustHaveAccessMods, "M1").WithArguments("C.M1()").WithLocation(4, 17)
            );
        }
 
        [Fact]
        public void NonVoidReturnType_Semantics()
        {
            const string text1 = @"
partial class C
{
    private partial int M1();
 
    public static void Main()
    {
        System.Console.WriteLine(new C().M1());
    }
}";
 
            const string text2 = @"
partial class C
{
    private partial int M1() { return 42; }
}
";
            var verifier = CompileAndVerify(new[] { text1, text2 }, parseOptions: TestOptions.RegularWithExtendedPartialMethods, expectedOutput: "42");
            verifier.VerifyDiagnostics();
        }
 
        [Fact]
        public void OutParam_LangVersion()
        {
            const string text = @"
partial class C
{
    private partial void M1(out int i);
    private partial void M1(out int i) { i = 0; }
}";
            var comp = CreateCompilation(text, parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (4,26): error CS8400: Feature 'extended partial methods' is not available in C# 8.0. Please use language version 9.0 or greater.
                //     private partial void M1(out int i);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "M1").WithArguments("extended partial methods", "9.0").WithLocation(4, 26),
                // (5,26): error CS8400: Feature 'extended partial methods' is not available in C# 8.0. Please use language version 9.0 or greater.
                //     private partial void M1(out int i) { i = 0; }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "M1").WithArguments("extended partial methods", "9.0").WithLocation(5, 26)
            );
 
            comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void OutParam_NoAccessibility()
        {
            const string text = @"
partial class C
{
    partial void M1(out int i);
    partial void M1(out int i) { i = 0; }
}";
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (4,18): error CS8795: Partial method 'C.M1(out int)' must have accessibility modifiers because it has 'out' parameters.
                //     partial void M1(out int i);
                Diagnostic(ErrorCode.ERR_PartialMethodWithOutParamMustHaveAccessMods, "M1").WithArguments("C.M1(out int)").WithLocation(4, 18),
                // (5,18): error CS8795: Partial method 'C.M1(out int)' must have accessibility modifiers because it has 'out' parameters.
                //     partial void M1(out int i) { i = 0; }
                Diagnostic(ErrorCode.ERR_PartialMethodWithOutParamMustHaveAccessMods, "M1").WithArguments("C.M1(out int)").WithLocation(5, 18)
            );
        }
 
        [Fact]
        public void OutParam_NoImpl()
        {
            const string text = @"
partial class C
{
    private partial void M1(out int i);
}";
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (4,26): error CS8793: Partial method 'C.M1(out int)' must have an implementation part because it has accessibility modifiers.
                //     private partial void M1(out int i);
                Diagnostic(ErrorCode.ERR_PartialMethodWithAccessibilityModsMustHaveImplementation, "M1").WithArguments("C.M1(out int)").WithLocation(4, 26)
            );
        }
 
        [Fact]
        public void OutParam_NoImpl_NoAccessibility()
        {
            const string text = @"
partial class C
{
    partial void M1(out int i);
}";
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (4,18): error CS8795: Partial method 'C.M1(out int)' must have accessibility modifiers because it has 'out' parameters.
                //     partial void M1(out int i);
                Diagnostic(ErrorCode.ERR_PartialMethodWithOutParamMustHaveAccessMods, "M1").WithArguments("C.M1(out int)").WithLocation(4, 18)
            );
        }
 
        [Fact]
        public void OutParam_Semantics()
        {
            const string text1 = @"
partial class C
{
    private partial void M1(out int value);
 
    public static void Main()
    {
        new C().M1(out var value);
        System.Console.WriteLine(value);
    }
}";
 
            const string text2 = @"
partial class C
{
    private partial void M1(out int value) { value = 42; }
}
";
            var verifier = CompileAndVerify(new[] { text1, text2 }, parseOptions: TestOptions.RegularWithExtendedPartialMethods, expectedOutput: "42");
            verifier.VerifyDiagnostics();
        }
 
        [Fact]
        public void OutParam_DefiniteAssignment()
        {
            const string text1 = @"
partial class C
{
    private partial void M1(out int value);
 
    public static void Main()
    {
        int i;
        new C().M1(out i);
        System.Console.Write(i);
    }
}";
 
            const string text2 = @"
partial class C
{
    private partial void M1(out int value) { value = 42; }
}
";
            var verifier = CompileAndVerify(new[] { text1, text2 }, parseOptions: TestOptions.RegularWithExtendedPartialMethods, expectedOutput: "42");
            verifier.VerifyDiagnostics();
        }
 
        public static readonly object[][] s_accessMods = new[]
        {
            new[] { "public" },
            new[] { "internal" },
            new[] { "protected" },
            new[] { "private" },
            new[] { "protected internal" },
            new[] { "private protected" }
        };
 
        [Theory]
        [MemberData(nameof(s_accessMods))]
        public void AccessMod_LangVersion(string mod)
        {
            var text = $@"
partial class C
{{
    {mod} partial void M1();
    {mod} partial void M1() {{ }}
}}";
            var comp = CreateCompilation(text, parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (4,27): error CS8400: Feature 'extended partial methods' is not available in C# 8.0. Please use language version 9.0 or greater.
                //     internal partial void M1();
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "M1").WithArguments("extended partial methods", "9.0"),
                // (5,27): error CS8400: Feature 'extended partial methods' is not available in C# 8.0. Please use language version 9.0 or greater.
                //     internal partial void M1() { }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "M1").WithArguments("extended partial methods", "9.0")
            );
 
            comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void AccessMod_Mismatch_01()
        {
            var text = @"
partial class C
{
     public partial void M1();
     internal partial void M1() { }
}";
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (5,28): error CS8797: Both partial method declarations must have equivalent accessibility modifiers.
                //      internal partial void M1() { }
                Diagnostic(ErrorCode.ERR_PartialMemberAccessibilityDifference, "M1").WithLocation(5, 28)
            );
        }
 
        [Fact]
        public void AccessMod_Mismatch_02()
        {
            var text = @"
partial class C
{
     private partial void M1();
     partial void M1() { }
}";
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (5,19): error CS8797: Both partial member declarations must have identical accessibility modifiers.
                //      partial void M1() { }
                Diagnostic(ErrorCode.ERR_PartialMemberAccessibilityDifference, "M1").WithLocation(5, 19)
            );
        }
 
        [Fact]
        public void AccessMod_Mismatch_03()
        {
            var text = @"
partial class C
{
     partial void M1();
     private partial void M1() { }
}";
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (5,27): error CS8797: Both partial member declarations must have identical accessibility modifiers.
                //      private partial void M1() { }
                Diagnostic(ErrorCode.ERR_PartialMemberAccessibilityDifference, "M1").WithLocation(5, 27)
            );
        }
 
        [Theory]
        [MemberData(nameof(s_accessMods))]
        public void AccessMod_NoImpl(string mod)
        {
            var text = $@"
partial class C
{{
    {mod} partial void M1();
}}";
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (4,27): error CS8795: Partial method C.M1() must have an implementation part because it has accessibility modifiers.
                //     {mod} partial void M1();
                Diagnostic(ErrorCode.ERR_PartialMethodWithAccessibilityModsMustHaveImplementation, "M1").WithArguments("C.M1()")
            );
        }
 
        [Fact]
        public void Static_NoImpl()
        {
            const string text1 = @"
partial class C
{
    static partial void M1();
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void Simple_NoImpl()
        {
            const string text1 = @"
partial class C
{
    partial void M1();
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void Virtual_LangVersion()
        {
            const string text1 = @"
partial class C
{
    internal virtual partial int M1();
    internal virtual partial int M1() => 1;
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (4,34): error CS8400: Feature 'extended partial methods' is not available in C# 8.0. Please use language version 9.0 or greater.
                //     internal virtual partial int M1();
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "M1").WithArguments("extended partial methods", "9.0").WithLocation(4, 34),
                // (5,34): error CS8400: Feature 'extended partial methods' is not available in C# 8.0. Please use language version 9.0 or greater.
                //     internal virtual partial int M1() => 1;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "M1").WithArguments("extended partial methods", "9.0").WithLocation(5, 34)
            );
 
            comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void Virtual_NoAccessibility()
        {
            const string text1 = @"
partial class C
{
    virtual partial void M1();
    virtual partial void M1() { }
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (4,26): error CS8796: Partial method 'C.M1()' must have accessibility modifiers because it has a 'virtual', 'override', 'sealed', 'new', or 'extern' modifier.
                //     virtual partial void M1();
                Diagnostic(ErrorCode.ERR_PartialMethodWithExtendedModMustHaveAccessMods, "M1").WithArguments("C.M1()").WithLocation(4, 26),
                // (5,26): error CS8796: Partial method 'C.M1()' must have accessibility modifiers because it has a 'virtual', 'override', 'sealed', 'new', or 'extern' modifier.
                //     virtual partial void M1() { }
                Diagnostic(ErrorCode.ERR_PartialMethodWithExtendedModMustHaveAccessMods, "M1").WithArguments("C.M1()").WithLocation(5, 26)
            );
        }
 
        [Fact]
        public void Virtual_NoImpl()
        {
            const string text1 = @"
partial class C
{
    internal virtual partial void M1();
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (4,35): error CS8793: Partial method 'C.M1()' must have an implementation part because it has accessibility modifiers.
                //     internal virtual partial void M1();
                Diagnostic(ErrorCode.ERR_PartialMethodWithAccessibilityModsMustHaveImplementation, "M1").WithArguments("C.M1()").WithLocation(4, 35)
            );
        }
 
        [Fact]
        public void Virtual_Mismatch_01()
        {
            const string text1 = @"
partial class C
{
    internal virtual partial void M1();
    internal partial void M1() { }
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (5,27): error CS8798: Both partial method declarations must have equal combinations of 'virtual', 'override', 'sealed', or 'new' modifiers.
                //     internal partial void M1() { }
                Diagnostic(ErrorCode.ERR_PartialMemberExtendedModDifference, "M1").WithLocation(5, 27)
            );
        }
 
        [Fact]
        public void Virtual_Mismatch_02()
        {
            const string text1 = @"
partial class C
{
    internal partial void M1();
    internal virtual partial void M1() { }
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (5,35): error CS8798: Both partial method declarations must have equal combinations of 'virtual', 'override', 'sealed', or 'new' modifiers.
                //     internal virtual partial void M1() { }
                Diagnostic(ErrorCode.ERR_PartialMemberExtendedModDifference, "M1").WithLocation(5, 35)
            );
        }
 
        [Fact]
        public void Virtual_Semantics()
        {
            const string text1 = @"
using System;
 
public partial class C
{
    internal virtual partial int M1();
    internal virtual partial int M1() => 1;
}
 
public class D : C
{
    internal override int M1() => 2;
 
    static void UseC(C c)
    {
        Console.Write(c.M1());
    }
 
    public static void Main()
    {
        UseC(new C());
        UseC(new D());
    }
}";
            CompileAndVerify(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods, expectedOutput: "12").VerifyDiagnostics();
        }
 
        [Fact]
        public void Virtual_AllowNull_01()
        {
            const string text1 = @"
#nullable enable
using System.Diagnostics.CodeAnalysis;
 
partial class C
{
    internal virtual partial void M1([AllowNull] string s1);
    internal virtual partial void M1(string s1) { }
}
class D : C
{
    internal override void M1(string s1) // 1
    {
    }
}";
            var comp = CreateCompilation(new[] { text1, AllowNullAttributeDefinition }, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (12,28): warning CS8765: Nullability of type of parameter 's1' doesn't match overridden member (possibly because of nullability attributes).
                //     internal override void M1(string s1) // 1
                Diagnostic(ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnOverride, "M1").WithArguments("s1").WithLocation(12, 28)
            );
        }
 
        [Fact]
        public void Virtual_AllowNull_02()
        {
            const string text1 = @"
#nullable enable
using System.Diagnostics.CodeAnalysis;
 
partial class C
{
    internal virtual partial void M1(string s1);
    internal virtual partial void M1([AllowNull] string s1) { }
}
class D : C
{
    internal override void M1(string s1) // 1
    {
    }
}";
            var comp = CreateCompilation(new[] { text1, AllowNullAttributeDefinition }, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (12,28): warning CS8765: Nullability of type of parameter 's1' doesn't match overridden member (possibly because of nullability attributes).
                //     internal override void M1(string s1) // 1
                Diagnostic(ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnOverride, "M1").WithArguments("s1").WithLocation(12, 28)
            );
        }
 
        [Fact]
        public void Virtual_AllowNull_03()
        {
            const string text1 = @"
#nullable enable
using System.Diagnostics.CodeAnalysis;
 
partial class C
{
    internal virtual partial void M1(string s1);
    internal virtual partial void M1([AllowNull] string s1) { }
}
class D : C
{
    internal override void M1([AllowNull] string s1)
    {
    }
}";
            var comp = CreateCompilation(new[] { text1, AllowNullAttributeDefinition }, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void Virtual_AllowNull_04()
        {
            const string text1 = @"
#nullable enable
using System.Diagnostics.CodeAnalysis;
 
partial class C
{
    internal virtual partial void M1([AllowNull] string s1);
    internal virtual partial void M1(string s1) { }
}
class D : C
{
    internal override void M1([AllowNull] string s1)
    {
    }
}";
            var comp = CreateCompilation(new[] { text1, AllowNullAttributeDefinition }, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void Virtual_AllowNull_05()
        {
            const string text1 = @"
#nullable enable
using System.Diagnostics.CodeAnalysis;
 
partial class C
{
    internal virtual partial void M1([AllowNull] string s1, string s2);
    internal virtual partial void M1(string s1, [AllowNull] string s2) { }
}
class D : C
{
    internal override void M1([AllowNull] string s1, [AllowNull] string s2)
    {
    }
}";
            var comp = CreateCompilation(new[] { text1, AllowNullAttributeDefinition }, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void Virtual_AllowNull_06()
        {
            const string text1 = @"
#nullable enable
using System.Diagnostics.CodeAnalysis;
 
partial class C
{
    internal virtual partial void M1([AllowNull] string s1, string s2);
    internal virtual partial void M1(string s1, [AllowNull] string s2) { }
}
partial class D : C
{
    internal override partial void M1(string s1, [AllowNull] string s2);
    internal override partial void M1([AllowNull] string s1, string s2) { }
}";
            var comp = CreateCompilation(new[] { text1, AllowNullAttributeDefinition }, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void Override_LangVersion()
        {
            const string text1 = @"
partial class D
{
    public override partial string ToString();
    public override partial string ToString() => ""hello"";
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (4,36): error CS8400: Feature 'extended partial methods' is not available in C# 8.0. Please use language version 9.0 or greater.
                //     public override partial string ToString();
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "ToString").WithArguments("extended partial methods", "9.0").WithLocation(4, 36),
                // (5,36): error CS8400: Feature 'extended partial methods' is not available in C# 8.0. Please use language version 9.0 or greater.
                //     public override partial string ToString() => "hello";
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "ToString").WithArguments("extended partial methods", "9.0").WithLocation(5, 36)
            );
            var method = comp.GetMember<MethodSymbol>("D.ToString");
            Assert.Equal("System.String System.Object.ToString()", method.OverriddenMethod.ToTestDisplayString());
 
            comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
            method = comp.GetMember<MethodSymbol>("D.ToString");
            Assert.Equal("System.String System.Object.ToString()", method.OverriddenMethod.ToTestDisplayString());
        }
 
        [Fact]
        public void Override_WrongAccessibility()
        {
            const string text1 = @"
partial class D
{
    internal override partial string ToString();
    internal override partial string ToString() => ""hello"";
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (4,38): error CS0507: 'D.ToString()': cannot change access modifiers when overriding 'public' inherited member 'object.ToString()'
                //     internal override partial string ToString();
                Diagnostic(ErrorCode.ERR_CantChangeAccessOnOverride, "ToString").WithArguments("D.ToString()", "public", "object.ToString()").WithLocation(4, 38));
            var method = comp.GetMember<MethodSymbol>("D.ToString");
            Assert.Equal("System.String System.Object.ToString()", method.OverriddenMethod.ToTestDisplayString());
        }
 
        [Fact]
        public void Override_AbstractBase()
        {
            const string text1 = @"
abstract class C
{
    internal abstract void M1();
}
 
partial class D : C
{
    internal override partial void M1();
    internal override partial void M1() { }
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
 
            var method = comp.GetMember<MethodSymbol>("D.M1");
            Assert.Equal(comp.GetMember<MethodSymbol>("C.M1"), method.OverriddenMethod);
        }
 
        [Fact]
        public void Override_NoAccessibility()
        {
            const string text1 = @"
class C
{
    internal virtual void M1() { }
}
 
partial class D : C
{
    override partial void M1();
    override partial void M1() { }
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (9,27): error CS8796: Partial method 'D.M1()' must have accessibility modifiers because it has a 'virtual', 'override', 'sealed', 'new', or 'extern' modifier.
                //     override partial void M1();
                Diagnostic(ErrorCode.ERR_PartialMethodWithExtendedModMustHaveAccessMods, "M1").WithArguments("D.M1()").WithLocation(9, 27),
                // (9,27): error CS0507: 'D.M1()': cannot change access modifiers when overriding 'internal' inherited member 'C.M1()'
                //     override partial void M1();
                Diagnostic(ErrorCode.ERR_CantChangeAccessOnOverride, "M1").WithArguments("D.M1()", "internal", "C.M1()").WithLocation(9, 27),
                // (10,27): error CS8796: Partial method 'D.M1()' must have accessibility modifiers because it has a 'virtual', 'override', 'sealed', 'new', or 'extern' modifier.
                //     override partial void M1() { }
                Diagnostic(ErrorCode.ERR_PartialMethodWithExtendedModMustHaveAccessMods, "M1").WithArguments("D.M1()").WithLocation(10, 27)
            );
            var method = comp.GetMember<MethodSymbol>("D.M1");
            Assert.Equal(comp.GetMember<MethodSymbol>("C.M1"), method.OverriddenMethod);
        }
 
        [Fact]
        public void Override_NoImpl()
        {
            const string text1 = @"
class C
{
    internal virtual void M1() { }
}
 
partial class D : C
{
    internal override partial void M1();
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (9,36): error CS8793: Partial method 'D.M1()' must have an implementation part because it has accessibility modifiers.
                //     internal override partial void M1();
                Diagnostic(ErrorCode.ERR_PartialMethodWithAccessibilityModsMustHaveImplementation, "M1").WithArguments("D.M1()").WithLocation(9, 36)
            );
            var method = comp.GetMember<MethodSymbol>("D.M1");
            Assert.Equal(comp.GetMember<MethodSymbol>("C.M1"), method.OverriddenMethod);
        }
 
        [Fact]
        public void Override_NoImpl_NoAccessibility()
        {
            const string text1 = @"
class C
{
    internal virtual void M1() { }
}
 
partial class D : C
{
    override partial void M1();
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (9,27): error CS8796: Partial method 'D.M1()' must have accessibility modifiers because it has a 'virtual', 'override', 'sealed', 'new', or 'extern' modifier.
                //     override partial void M1();
                Diagnostic(ErrorCode.ERR_PartialMethodWithExtendedModMustHaveAccessMods, "M1").WithArguments("D.M1()").WithLocation(9, 27),
                // (9,27): error CS0507: 'D.M1()': cannot change access modifiers when overriding 'internal' inherited member 'C.M1()'
                //     override partial void M1();
                Diagnostic(ErrorCode.ERR_CantChangeAccessOnOverride, "M1").WithArguments("D.M1()", "internal", "C.M1()").WithLocation(9, 27)
            );
            var method = comp.GetMember<MethodSymbol>("D.M1");
            Assert.Equal(comp.GetMember<MethodSymbol>("C.M1"), method.OverriddenMethod);
        }
 
        [Fact]
        public void Override_Mismatch_01()
        {
            const string text1 = @"
class C
{
    internal virtual void M1() { }
}
partial class D : C
{
    internal override partial void M1();
    internal partial void M1() { }
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (9,27): error CS8798: Both partial method declarations must have equal combinations of 'virtual', 'override', 'sealed', or 'new' modifiers.
                //     internal partial void M1() { }
                Diagnostic(ErrorCode.ERR_PartialMemberExtendedModDifference, "M1").WithLocation(9, 27)
            );
        }
 
        [Fact]
        public void Override_Mismatch_02()
        {
            const string text1 = @"
class C
{
    internal virtual void M1() { }
}
partial class D : C
{
    internal partial void M1();
    internal override partial void M1() { }
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (8,27): warning CS0114: 'D.M1()' hides inherited member 'C.M1()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
                //     internal partial void M1();
                Diagnostic(ErrorCode.WRN_NewOrOverrideExpected, "M1").WithArguments("D.M1()", "C.M1()").WithLocation(8, 27),
                // (9,36): error CS8798: Both partial method declarations must have equal combinations of 'virtual', 'override', 'sealed', or 'new' modifiers.
                //     internal override partial void M1() { }
                Diagnostic(ErrorCode.ERR_PartialMemberExtendedModDifference, "M1").WithLocation(9, 36)
            );
        }
 
        [Fact]
        public void Override_AllowNull_01()
        {
            const string text1 = @"
#nullable enable
using System.Diagnostics.CodeAnalysis;
 
class C
{
    internal virtual void M1([AllowNull] string s) { }
}
partial class D : C
{
    internal override partial void M1(string s1); // 1
    internal override partial void M1(string s1) { }
}";
            var comp = CreateCompilation(new[] { text1, AllowNullAttributeDefinition }, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (11,36): warning CS8765: Nullability of type of parameter 's1' doesn't match overridden member (possibly because of nullability attributes).
                //     internal override partial void M1(string s1); // 1
                Diagnostic(ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnOverride, "M1").WithArguments("s1").WithLocation(11, 36)
            );
        }
 
        [Fact]
        public void Override_AllowNull_02()
        {
            const string text1 = @"
#nullable enable
using System.Diagnostics.CodeAnalysis;
 
class C
{
    internal virtual void M1([AllowNull] string s1, [AllowNull] string s2) { }
}
partial class D : C
{
    internal override partial void M1([AllowNull] string s1, string s2);
    internal override partial void M1(string s1, [AllowNull] string s2)
    {
        s1.ToString(); // 1
        s2.ToString(); // 2
    }
}";
            var comp = CreateCompilation(new[] { text1, AllowNullAttributeDefinition }, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (14,9): warning CS8602: Dereference of a possibly null reference.
                //         s1.ToString(); // 1
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s1").WithLocation(14, 9),
                // (15,9): warning CS8602: Dereference of a possibly null reference.
                //         s2.ToString(); // 2
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s2").WithLocation(15, 9));
        }
 
        [Fact]
        public void Override_GenericBase()
        {
            const string text1 = @"
#nullable enable
 
class C<T>
{
    internal virtual void M1(T t1) { }
}
partial class D : C<string>
{
    internal override partial void M1(string t1);
    internal override partial void M1(string t1)
    {
    }
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void Sealed_LangVersion()
        {
            const string text1 = @"
class C
{
    internal virtual void M1() { }
}
partial class D : C
{
    internal sealed override partial void M1();
    internal sealed override partial void M1() { }
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (8,43): error CS8400: Feature 'extended partial methods' is not available in C# 8.0. Please use language version 9.0 or greater.
                //     internal sealed override partial void M1();
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "M1").WithArguments("extended partial methods", "9.0").WithLocation(8, 43),
                // (9,43): error CS8400: Feature 'extended partial methods' is not available in C# 8.0. Please use language version 9.0 or greater.
                //     internal sealed override partial void M1() { }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "M1").WithArguments("extended partial methods", "9.0").WithLocation(9, 43)
            );
            comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void Sealed_NoAccessibility()
        {
            const string text1 = @"
class C
{
    internal virtual void M1() { }
}
partial class D : C
{
    sealed override partial void M1();
    sealed override partial void M1() { }
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (8,34): error CS8796: Partial method 'D.M1()' must have accessibility modifiers because it has a 'virtual', 'override', 'sealed', 'new', or 'extern' modifier.
                //     sealed override partial void M1();
                Diagnostic(ErrorCode.ERR_PartialMethodWithExtendedModMustHaveAccessMods, "M1").WithArguments("D.M1()").WithLocation(8, 34),
                // (8,34): error CS0507: 'D.M1()': cannot change access modifiers when overriding 'internal' inherited member 'C.M1()'
                //     sealed override partial void M1();
                Diagnostic(ErrorCode.ERR_CantChangeAccessOnOverride, "M1").WithArguments("D.M1()", "internal", "C.M1()").WithLocation(8, 34),
                // (9,34): error CS8796: Partial method 'D.M1()' must have accessibility modifiers because it has a 'virtual', 'override', 'sealed', 'new', or 'extern' modifier.
                //     sealed override partial void M1() { }
                Diagnostic(ErrorCode.ERR_PartialMethodWithExtendedModMustHaveAccessMods, "M1").WithArguments("D.M1()").WithLocation(9, 34)
            );
        }
 
        [Fact]
        public void Sealed_Mismatch_01()
        {
            const string text1 = @"
class C
{
    internal virtual void M1() { }
}
partial class D : C
{
    internal sealed override partial void M1();
    internal override partial void M1() { }
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (9,36): error CS8798: Both partial method declarations must have equal combinations of 'virtual', 'override', 'sealed', or 'new' modifiers.
                //     internal override partial void M1() { }
                Diagnostic(ErrorCode.ERR_PartialMemberExtendedModDifference, "M1").WithLocation(9, 36)
            );
        }
 
        [Fact]
        public void Sealed_Mismatch_02()
        {
            const string text1 = @"
class C
{
    internal virtual void M1() { }
}
partial class D : C
{
    internal override partial void M1();
    internal sealed override partial void M1() { }
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (9,43): error CS8798: Both partial method declarations must have equal combinations of 'virtual', 'override', 'sealed', or 'new' modifiers.
                //     internal sealed override partial void M1() { }
                Diagnostic(ErrorCode.ERR_PartialMemberExtendedModDifference, "M1").WithLocation(9, 43)
            );
        }
 
        [Fact]
        public void SealedOverride_Reordered()
        {
            const string text1 = @"
class C
{
    internal virtual void M1() { }
}
partial class D : C
{
    internal override sealed partial void M1();
    internal sealed override partial void M1() { }
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void NewVirtual_Reordered()
        {
            const string text1 = @"
class C
{
    internal virtual void M1() { }
}
partial class D : C
{
    internal new virtual partial void M1();
    internal virtual new partial void M1() { }
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void Extern_LangVersion()
        {
            const string text1 = @"
using System.Runtime.InteropServices;
 
partial class C
{
    internal static partial void M1();
 
    [DllImport(""something.dll"")]
    internal static extern partial void M1();
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (6,34): error CS8400: Feature 'extended partial methods' is not available in C# 8.0. Please use language version 9.0 or greater.
                //     internal static partial void M1();
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "M1").WithArguments("extended partial methods", "9.0").WithLocation(6, 34),
                // (9,41): error CS8400: Feature 'extended partial methods' is not available in C# 8.0. Please use language version 9.0 or greater.
                //     internal static extern partial void M1();
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "M1").WithArguments("extended partial methods", "9.0").WithLocation(9, 41));
 
            comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void Extern_DuplicateMod()
        {
            const string text1 = @"
using System.Runtime.InteropServices;
 
partial class C
{
    internal static extern partial void M1();
 
    [DllImport(""something.dll"")]
    internal static extern partial void M1();
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (6,41): error CS0759: No defining declaration found for implementing declaration of partial method 'C.M1()'
                //     internal static extern partial void M1();
                Diagnostic(ErrorCode.ERR_PartialMethodMustHaveLatent, "M1").WithArguments("C.M1()").WithLocation(6, 41),
                // (9,41): error CS0757: A partial method may not have multiple implementing declarations
                //     internal static extern partial void M1();
                Diagnostic(ErrorCode.ERR_PartialMethodOnlyOneActual, "M1").WithLocation(9, 41),
                // (9,41): error CS0111: Type 'C' already defines a member called 'M1' with the same parameter types
                //     internal static extern partial void M1();
                Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "M1").WithArguments("M1", "C").WithLocation(9, 41));
        }
 
        [Fact]
        public void Extern_NoAccessibility()
        {
            const string text1 = @"
using System.Runtime.InteropServices;
 
partial class C
{
    static partial void M1();
 
    [DllImport(""something.dll"")]
    static extern partial void M1();
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (9,32): error CS8796: Partial method 'C.M1()' must have accessibility modifiers because it has a 'virtual', 'override', 'sealed', 'new', or 'extern' modifier.
                //     static extern partial void M1();
                Diagnostic(ErrorCode.ERR_PartialMethodWithExtendedModMustHaveAccessMods, "M1").WithArguments("C.M1()").WithLocation(9, 32)
            );
        }
 
        [Fact]
        public void Extern_Symbols()
        {
            const string text1 = @"
using System.Runtime.InteropServices;
 
public partial class C
{
    public static partial void M1();
 
    [DllImport(""something.dll"")]
    public static extern partial void M1();
 
    public static void M2() { M1(); }
}";
 
            const string text2 = @"
using System.Runtime.InteropServices;
 
public partial class C
{
    [DllImport(""something.dll"")]
    public static partial void M1();
 
    public static extern partial void M1();
 
    public static void M2() { M1(); }
}";
            const string expectedIL = @"
{
  // Code size        6 (0x6)
  .maxstack  0
  IL_0000:  call       ""void C.M1()""
  IL_0005:  ret
}";
 
            var verifier = CompileAndVerify(
                text1,
                parseOptions: TestOptions.RegularWithExtendedPartialMethods,
                sourceSymbolValidator: validator,
                symbolValidator: validator);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.M2", expectedIL);
 
            verifier = CompileAndVerify(
                text2,
                parseOptions: TestOptions.RegularWithExtendedPartialMethods,
                sourceSymbolValidator: validator,
                symbolValidator: validator);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.M2", expectedIL);
 
            static void validator(ModuleSymbol module)
            {
                var type = module.ContainingAssembly.GetTypeByMetadataName("C");
                var method = type.GetMember<MethodSymbol>("M1");
 
                // note: we're opting to give the same answer for 'IsExtern' on both partial method declarations 
                // because 'IsExtern' is true when the method is round tripped from metadata.
                Assert.True(method.IsExtern);
                if (method.PartialImplementationPart is MethodSymbol implementation)
                {
                    Assert.True(method.IsPartialDefinition());
                    Assert.True(implementation.IsExtern);
                }
 
                var importData = method.GetDllImportData();
                Assert.NotNull(importData);
                Assert.Equal("something.dll", importData.ModuleName);
                Assert.Equal("M1", importData.EntryPointName);
                Assert.Equal(CharSet.None, importData.CharacterSet);
                Assert.False(importData.SetLastError);
                Assert.False(importData.ExactSpelling);
                Assert.Equal(MethodImplAttributes.PreserveSig, method.ImplementationAttributes);
                Assert.Equal(CallingConvention.Winapi, importData.CallingConvention);
                Assert.Null(importData.BestFitMapping);
                Assert.Null(importData.ThrowOnUnmappableCharacter);
            }
        }
 
        [Fact]
        public void Extern_Symbols_NoDllImport()
        {
            const string text1 = @"
public partial class C
{
    public static partial void M1();
 
    public static extern partial void M1();
 
    public static void M2() { M1(); }
}";
 
            const string text2 = @"
public partial class C
{
    public static partial void M1();
 
    public static extern partial void M1();
 
    public static void M2() { M1(); }
}";
            const string expectedIL = @"
{
  // Code size        6 (0x6)
  .maxstack  0
  IL_0000:  call       ""void C.M1()""
  IL_0005:  ret
}";
 
            var verifier = CompileAndVerify(
                text1,
                parseOptions: TestOptions.RegularWithExtendedPartialMethods,
                sourceSymbolValidator: module => validator(module, isSource: true),
                symbolValidator: module => validator(module, isSource: false),
                // PEVerify fails when extern methods lack an implementation
                verify: Verification.Skipped);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.M2", expectedIL);
 
            verifier = CompileAndVerify(
                text2,
                parseOptions: TestOptions.RegularWithExtendedPartialMethods,
                sourceSymbolValidator: module => validator(module, isSource: true),
                symbolValidator: module => validator(module, isSource: false),
                // PEVerify fails when extern methods lack an implementation
                verify: Verification.Skipped);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.M2", expectedIL);
 
            static void validator(ModuleSymbol module, bool isSource)
            {
                var type = module.ContainingAssembly.GetTypeByMetadataName("C");
                var method = type.GetMember<MethodSymbol>("M1");
 
                // 'IsExtern' is not round tripped when DllImport is missing
                Assert.Equal(isSource, method.IsExtern);
                if (method.PartialImplementationPart is MethodSymbol implementation)
                {
                    Assert.True(method.IsPartialDefinition());
                    Assert.Equal(isSource, implementation.IsExtern);
                }
 
                var importData = method.GetDllImportData();
                Assert.Null(importData);
            }
        }
 
        [Fact]
        public void Async_01()
        {
            const string text = @"
partial class C
{
    partial void M1();
    async partial void M1() { }
}
";
            var comp = CreateCompilation(text);
            comp.VerifyDiagnostics(
                // (5,24): 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 partial void M1() { }
                Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "M1").WithLocation(5, 24));
 
            var method = (MethodSymbol)comp.GetMembers("C.M1")[0];
            Assert.True(method.IsPartialDefinition());
            Assert.False(method.IsAsync);
            Assert.True(method.PartialImplementationPart.IsAsync);
        }
 
        [Fact]
        public void Async_02()
        {
            const string text = @"
using System.Threading.Tasks;
 
partial class C
{
    private partial Task M1();
    private async partial Task M1() { }
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (7,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.
                //     private async partial Task M1() { }
                Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "M1").WithLocation(7, 32));
 
            var method = (MethodSymbol)comp.GetMembers("C.M1")[0];
            Assert.True(method.IsPartialDefinition());
            Assert.False(method.IsAsync);
            Assert.True(method.PartialImplementationPart.IsAsync);
        }
 
        [Fact]
        public void Async_03()
        {
            const string text = @"
using System.Threading.Tasks;
using System;
 
partial class C
{
    private static async Task CompletedTask() { }
 
    private static partial Task<int> M1();
    private static async partial Task<int> M1() { await CompletedTask(); return 1; }
 
    public static async Task Main()
    {
        Console.Write(await M1());
    }
}
";
            var verifier = CompileAndVerify(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods, expectedOutput: "1");
            verifier.VerifyDiagnostics(
                // (7,31): 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.
                //     private static async Task CompletedTask() { }
                Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "CompletedTask").WithLocation(7, 31));
 
            var method = (MethodSymbol)verifier.Compilation.GetMembers("C.M1")[0];
            Assert.True(method.IsPartialDefinition());
            Assert.False(method.IsAsync);
            Assert.True(method.PartialImplementationPart.IsAsync);
        }
 
        [Fact]
        public void Async_04()
        {
            const string text = @"
using System.Threading.Tasks;
 
partial class C
{
    internal async partial Task M();
}
";
 
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (6,33): error CS8793: Partial method 'C.M()' must have an implementation part because it has accessibility modifiers.
                //     internal async partial Task M();
                Diagnostic(ErrorCode.ERR_PartialMethodWithAccessibilityModsMustHaveImplementation, "M").WithArguments("C.M()").WithLocation(6, 33),
                // (6,33): error CS1994: The 'async' modifier can only be used in methods that have a body.
                //     internal async partial Task M();
                Diagnostic(ErrorCode.ERR_BadAsyncLacksBody, "M").WithLocation(6, 33));
        }
 
        [Fact]
        public void Async_05()
        {
            const string text = @"
using System.Threading.Tasks;
 
partial class C
{
    internal async partial Task M();
    internal async partial Task M()
    {
        await Task.Yield();
    }
}
";
 
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (6,33): error CS1994: The 'async' modifier can only be used in methods that have a body.
                //     internal async partial Task M();
                Diagnostic(ErrorCode.ERR_BadAsyncLacksBody, "M").WithLocation(6, 33));
        }
 
        [Fact]
        public void Async_06()
        {
            const string text = @"
using System.Threading.Tasks;
 
partial class C
{
    internal async partial Task M();
    internal partial Task M()
    {
        await Task.Yield();
    }
}
";
 
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (6,33): error CS1994: The 'async' modifier can only be used in methods that have a body.
                //     internal async partial Task M();
                Diagnostic(ErrorCode.ERR_BadAsyncLacksBody, "M").WithLocation(6, 33),
                // (7,27): error CS0161: 'C.M()': not all code paths return a value
                //     internal partial Task M()
                Diagnostic(ErrorCode.ERR_ReturnExpected, "M").WithArguments("C.M()").WithLocation(7, 27),
                // (9,9): error CS4032: 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<Task>'.
                //         await Task.Yield();
                Diagnostic(ErrorCode.ERR_BadAwaitWithoutAsyncMethod, "await Task.Yield()").WithArguments("System.Threading.Tasks.Task").WithLocation(9, 9));
        }
 
        [Fact]
        public void Async_07()
        {
            const string text = @"
using System.Threading.Tasks;
 
partial class C
{
    partial Task M();
    async partial Task M()
    {
        await Task.Yield();
    }
}
";
 
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (6,18): error CS8794: Partial method 'C.M()' must have accessibility modifiers because it has a non-void return type.
                //     partial Task M();
                Diagnostic(ErrorCode.ERR_PartialMethodWithNonVoidReturnMustHaveAccessMods, "M").WithArguments("C.M()").WithLocation(6, 18),
                // (7,24): error CS8794: Partial method 'C.M()' must have accessibility modifiers because it has a non-void return type.
                //     async partial Task M()
                Diagnostic(ErrorCode.ERR_PartialMethodWithNonVoidReturnMustHaveAccessMods, "M").WithArguments("C.M()").WithLocation(7, 24));
        }
 
        [Fact]
        public void New_LangVersion()
        {
            const string text1 = @"
class C
{
    internal void M1() { }
}
 
partial class D : C
{
    internal new partial void M1();
    internal new partial void M1() { }
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (9,31): error CS8400: Feature 'extended partial methods' is not available in C# 8.0. Please use language version 9.0 or greater.
                //     internal new partial void M1();
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "M1").WithArguments("extended partial methods", "9.0").WithLocation(9, 31),
                // (10,31): error CS8400: Feature 'extended partial methods' is not available in C# 8.0. Please use language version 9.0 or greater.
                //     internal new partial void M1() { }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "M1").WithArguments("extended partial methods", "9.0").WithLocation(10, 31));
 
            comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void New_NoImpl()
        {
            const string text1 = @"
class C
{
    internal void M1() { }
}
 
partial class D : C
{
    internal new partial void M1();
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (9,31): error CS8793: Partial method 'D.M1()' must have an implementation part because it has accessibility modifiers.
                //     internal new partial void M1();
                Diagnostic(ErrorCode.ERR_PartialMethodWithAccessibilityModsMustHaveImplementation, "M1").WithArguments("D.M1()").WithLocation(9, 31)
            );
        }
 
        [Fact]
        public void New_NoAccessibility()
        {
            const string text1 = @"
class C
{
    internal void M1() { }
}
 
partial class D : C
{
    new partial void M1();
    new partial void M1() { }
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (9,22): error CS8796: Partial method 'D.M1()' must have accessibility modifiers because it has a 'virtual', 'override', 'sealed', 'new', or 'extern' modifier.
                //     new partial void M1();
                Diagnostic(ErrorCode.ERR_PartialMethodWithExtendedModMustHaveAccessMods, "M1").WithArguments("D.M1()").WithLocation(9, 22),
                // (10,22): error CS8796: Partial method 'D.M1()' must have accessibility modifiers because it has a 'virtual', 'override', 'sealed', 'new', or 'extern' modifier.
                //     new partial void M1() { }
                Diagnostic(ErrorCode.ERR_PartialMethodWithExtendedModMustHaveAccessMods, "M1").WithArguments("D.M1()").WithLocation(10, 22)
            );
        }
 
        [Fact]
        public void New_Mismatch_01()
        {
            const string text1 = @"
class C
{
    internal void M1() { }
}
 
partial class D : C
{
    internal new partial void M1();
    internal partial void M1() { }
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (10,27): error CS8798: Both partial method declarations must have equal combinations of 'virtual', 'override', 'sealed', or 'new' modifiers.
                //     internal partial void M1() { }
                Diagnostic(ErrorCode.ERR_PartialMemberExtendedModDifference, "M1").WithLocation(10, 27)
            );
        }
 
        [Fact]
        public void New_Mismatch_02()
        {
            const string text1 = @"
class C
{
    internal void M1() { }
}
 
partial class D : C
{
    internal partial void M1();
    internal new partial void M1() { }
}";
            var comp = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (9,27): warning CS0108: 'D.M1()' hides inherited member 'C.M1()'. Use the new keyword if hiding was intended.
                //     internal partial void M1();
                Diagnostic(ErrorCode.WRN_NewRequired, "M1").WithArguments("D.M1()", "C.M1()").WithLocation(9, 27),
                // (10,31): error CS8798: Both partial method declarations must have equal combinations of 'virtual', 'override', 'sealed', or 'new' modifiers.
                //     internal new partial void M1() { }
                Diagnostic(ErrorCode.ERR_PartialMemberExtendedModDifference, "M1").WithLocation(10, 31)
            );
        }
 
        [Fact]
        public void InterfaceImpl_01()
        {
            const string text = @"
interface I
{
    void M();
}
 
partial class C
{
    public partial void M();
}
 
partial class C : I
{
    public partial void M()
    {
        System.Console.Write(1);
    }
 
    static void Main()
    {
        I i = new C();
        i.M();
    }
}
";
            var verifier = CompileAndVerify(
                text,
                parseOptions: TestOptions.RegularWithExtendedPartialMethods,
                options: TestOptions.DebugExe,
                expectedOutput: "1");
            verifier.VerifyDiagnostics();
        }
 
        [Fact]
        public void InterfaceImpl_02()
        {
            const string text = @"
interface I
{
    void M();
}
 
partial class C : I
{
    public partial void M();
}
 
partial class C
{
    public partial void M()
    {
        System.Console.Write(1);
    }
 
    static void Main()
    {
        I i = new C();
        i.M();
    }
}
";
            var verifier = CompileAndVerify(
                text,
                parseOptions: TestOptions.RegularWithExtendedPartialMethods,
                options: TestOptions.DebugExe,
                expectedOutput: "1");
            verifier.VerifyDiagnostics();
        }
 
        [Fact]
        public void InterfaceImpl_03()
        {
            const string text = @"
#nullable enable
 
using System.Diagnostics.CodeAnalysis;
 
interface I
{
    void M([AllowNull] string s1);
}
 
partial class C : I
{
    public partial void M(string s1); // 1
}
 
partial class C
{
    public partial void M(string s1)
    {
        s1.ToString();
    }
}
";
            var comp = CreateCompilation(new[] { text, AllowNullAttributeDefinition }, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (13,25): warning CS8767: Nullability of reference types in type of parameter 's1' of 'void C.M(string s1)' doesn't match implicitly implemented member 'void I.M(string s1)' (possibly because of nullability attributes).
                //     public partial void M(string s1);
                Diagnostic(ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnImplicitImplementation, "M").WithArguments("s1", "void C.M(string s1)", "void I.M(string s1)").WithLocation(13, 25));
        }
 
        [Fact]
        public void InterfaceImpl_04()
        {
            const string text = @"
#nullable enable
 
using System.Diagnostics.CodeAnalysis;
 
interface I
{
    void M([AllowNull] string s1, [AllowNull] string s2);
}
 
partial class C : I
{
    public partial void M([AllowNull] string s1, string s2);
}
 
partial class C
{
    public partial void M(string s1, [AllowNull] string s2)
    {
        s1.ToString(); // 1
        s2.ToString(); // 2
    }
}
";
            var comp = CreateCompilation(new[] { text, AllowNullAttributeDefinition }, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (20,9): warning CS8602: Dereference of a possibly null reference.
                //         s1.ToString(); // 1
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s1").WithLocation(20, 9),
                // (21,9): warning CS8602: Dereference of a possibly null reference.
                //         s2.ToString(); // 2
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s2").WithLocation(21, 9));
        }
 
        [Fact]
        public void InterfaceImpl_05()
        {
            const string text = @"
#nullable enable
 
using System.Diagnostics.CodeAnalysis;
 
interface I
{
    void M([AllowNull] string s1);
}
 
partial class C : I
{
    public partial void M([AllowNull] string s1);
}
 
partial class C
{
    public partial void M([AllowNull] string s1) // 1
    {
        s1.ToString(); // 2
    }
}
";
            var comp = CreateCompilation(new[] { text, AllowNullAttributeDefinition }, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (13,28): error CS0579: Duplicate 'AllowNull' attribute
                //     public partial void M([AllowNull] string s1);
                Diagnostic(ErrorCode.ERR_DuplicateAttribute, "AllowNull").WithArguments("AllowNull").WithLocation(13, 28),
                // (20,9): warning CS8602: Dereference of a possibly null reference.
                //         s1.ToString(); // 2
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s1").WithLocation(20, 9));
        }
 
        [Fact]
        public void DefaultInterfaceImpl_NoImpl()
        {
            const string text = @"
#nullable enable
 
partial interface I
{
    internal partial void M(string s1);
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods, targetFramework: TargetFramework.NetCoreApp);
            comp.VerifyDiagnostics(
                // (6,27): error CS8793: Partial method 'I.M(string)' must have an implementation part because it has accessibility modifiers.
                //     internal partial void M(string s1);
                Diagnostic(ErrorCode.ERR_PartialMethodWithAccessibilityModsMustHaveImplementation, "M").WithArguments("I.M(string)").WithLocation(6, 27)
            );
        }
 
        [Fact]
        public void DefaultInterfaceImpl_01()
        {
            const string text = @"
#nullable enable
 
partial interface I
{
    internal partial void M(string s1);
    internal partial void M(string s1) { }
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods, targetFramework: TargetFramework.NetCoreApp);
            comp.VerifyDiagnostics(
            );
        }
 
        [Fact]
        public void DefaultInterfaceImpl_AllowNull_01()
        {
            const string text = @"
#nullable enable
using System.Diagnostics.CodeAnalysis;
 
partial interface I
{
    public partial void M([AllowNull] string s1);
    public partial void M(string s1)
    {
        _ = s1.ToString(); // 1
    }
}
 
class C : I
{
    public void M(string s1) { }
}
";
            // note that I.M is not virtual so C.M does not implement it
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods, targetFramework: TargetFramework.NetCoreApp);
            comp.VerifyDiagnostics(
                // (10,13): warning CS8602: Dereference of a possibly null reference.
                //         _ = s1.ToString();
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s1").WithLocation(10, 13)
            );
        }
 
        [Fact]
        public void DefaultInterfaceImpl_AllowNull_02()
        {
            const string text = @"
#nullable enable
using System.Diagnostics.CodeAnalysis;
 
partial interface I
{
    public virtual partial void M([AllowNull] string s1, string s2);
    public virtual partial void M(string s1, [AllowNull] string s2)
    {
        _ = s1.ToString(); // 1
        _ = s2.ToString(); // 2
    }
}
 
class C : I
{
    void I.M(string s1, string s2) { } // 3, 4
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods, targetFramework: TargetFramework.NetCoreApp);
            comp.VerifyDiagnostics(
                // (10,13): warning CS8602: Dereference of a possibly null reference.
                //         _ = s1.ToString(); // 1
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s1").WithLocation(10, 13),
                // (11,13): warning CS8602: Dereference of a possibly null reference.
                //         _ = s2.ToString(); // 2
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s2").WithLocation(11, 13),
                // (17,12): warning CS8769: Nullability of reference types in type of parameter 's1' doesn't match implemented member 'void I.M(string s1, string s2)' (possibly because of nullability attributes).
                //     void I.M(string s1, string s2) { } // 3, 4
                Diagnostic(ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnExplicitImplementation, "M").WithArguments("s1", "void I.M(string s1, string s2)").WithLocation(17, 12),
                // (17,12): warning CS8769: Nullability of reference types in type of parameter 's2' doesn't match implemented member 'void I.M(string s1, string s2)' (possibly because of nullability attributes).
                //     void I.M(string s1, string s2) { } // 3, 4
                Diagnostic(ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnExplicitImplementation, "M").WithArguments("s2", "void I.M(string s1, string s2)").WithLocation(17, 12)
            );
        }
 
        [Fact]
        public void DefaultInterfaceImpl_AllowNull_03()
        {
            const string text = @"
#nullable enable
using System.Diagnostics.CodeAnalysis;
 
partial interface I
{
    public virtual partial void M([AllowNull] string s1, string s2);
    public virtual partial void M(string s1, [AllowNull] string s2)
    {
        _ = s1.ToString(); // 1
        _ = s2.ToString(); // 2
    }
}
 
partial class C : I
{
    public partial void M(string s1, [AllowNull] string s2);
    public partial void M([AllowNull] string s1, string s2)
    {
        _ = s1.ToString(); // 3
        _ = s2.ToString(); // 4
    }
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods, targetFramework: TargetFramework.NetCoreApp);
            comp.VerifyDiagnostics(
                // (10,13): warning CS8602: Dereference of a possibly null reference.
                //         _ = s1.ToString(); // 1
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s1").WithLocation(10, 13),
                // (11,13): warning CS8602: Dereference of a possibly null reference.
                //         _ = s2.ToString(); // 2
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s2").WithLocation(11, 13),
                // (20,13): warning CS8602: Dereference of a possibly null reference.
                //         _ = s1.ToString(); // 3
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s1").WithLocation(20, 13),
                // (21,13): warning CS8602: Dereference of a possibly null reference.
                //         _ = s2.ToString(); // 4
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s2").WithLocation(21, 13)
            );
        }
 
        [Fact]
        public void ExplicitInterfaceImpl_01()
        {
            const string text = @"
interface I
{
    void M();
}
 
partial class C : I
{
    partial void I.M(); // 1
    partial void I.M() { } // 2
}
";
            var comp = CreateCompilation(text);
            comp.VerifyDiagnostics(
                // (9,20): error CS0754: A partial member may not explicitly implement an interface member
                //     partial void I.M(); // 1
                Diagnostic(ErrorCode.ERR_PartialMemberNotExplicit, "M").WithLocation(9, 20),
                // (10,20): error CS0754: A partial member may not explicitly implement an interface member
                //     partial void I.M() { } // 2
                Diagnostic(ErrorCode.ERR_PartialMemberNotExplicit, "M").WithLocation(10, 20));
        }
 
        [Fact]
        public void ExplicitInterfaceImpl_02()
        {
            const string text = @"
interface I
{
    int M();
}
 
partial class C : I
{
    partial int I.M();
    partial int I.M() => 42;
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (9,19): error CS0754: A partial member may not explicitly implement an interface member
                //     partial int I.M();
                Diagnostic(ErrorCode.ERR_PartialMemberNotExplicit, "M").WithLocation(9, 19),
                // (9,19): error CS8794: Partial method 'C.I.M()' must have accessibility modifiers because it has a non-void return type.
                //     partial int I.M();
                Diagnostic(ErrorCode.ERR_PartialMethodWithNonVoidReturnMustHaveAccessMods, "M").WithArguments("C.I.M()").WithLocation(9, 19),
                // (10,19): error CS0754: A partial member may not explicitly implement an interface member
                //     partial int I.M() => 42;
                Diagnostic(ErrorCode.ERR_PartialMemberNotExplicit, "M").WithLocation(10, 19),
                // (10,19): error CS8794: Partial method 'C.I.M()' must have accessibility modifiers because it has a non-void return type.
                //     partial int I.M() => 42;
                Diagnostic(ErrorCode.ERR_PartialMethodWithNonVoidReturnMustHaveAccessMods, "M").WithArguments("C.I.M()").WithLocation(10, 19));
        }
 
        [Fact]
        public void InsideStruct()
        {
            const string text = @"
partial struct S
{
    public partial int M();
    public partial int M() => 42;
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (4,24): error CS8400: Feature 'extended partial methods' is not available in C# 8.0. Please use language version 9.0 or greater.
                //     public partial int M();
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "M").WithArguments("extended partial methods", "9.0").WithLocation(4, 24),
                // (5,24): error CS8400: Feature 'extended partial methods' is not available in C# 8.0. Please use language version 9.0 or greater.
                //     public partial int M() => 42;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "M").WithArguments("extended partial methods", "9.0").WithLocation(5, 24));
 
            comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void ReturnAttribute_01()
        {
            const string text = @"
class Attr1 : System.Attribute { }
class Attr2 : System.Attribute { }
 
public partial class C
{
    [return: Attr1]
    public partial string M();
 
    [return: Attr2]
    public partial string M() => ""hello"";
}
";
            var expectedAttributeNames = new[] { "Attr1", "Attr2" };
 
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
 
            CompileAndVerify(comp, symbolValidator: validator);
 
            var definitionPart = comp.GetMember<MethodSymbol>("C.M");
            Assert.True(definitionPart.IsPartialDefinition());
            Assert.Equal(expectedAttributeNames, GetAttributeNames(definitionPart.GetReturnTypeAttributes()));
 
            var implementationPart = definitionPart.PartialImplementationPart;
            Assert.NotNull(implementationPart);
            Assert.True(implementationPart.IsPartialImplementation());
            Assert.Equal(expectedAttributeNames, GetAttributeNames(implementationPart.GetReturnTypeAttributes()));
 
            void validator(ModuleSymbol module)
            {
                var method = module.ContainingAssembly
                    .GetTypeByMetadataName("C")
                    .GetMember<MethodSymbol>("M");
 
                Assert.Equal(expectedAttributeNames, GetAttributeNames(method.GetReturnTypeAttributes()));
            }
        }
 
        [Fact]
        public void ConflictingOverloads_RefOut_01()
        {
            const string text = @"
partial class Program
{
    internal static partial void M(ref object o);
    internal static partial void M(out object o);
    internal static partial void M(out object o) { o = null; }
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (4,34): error CS8793: Partial method 'Program.M(ref object)' must have an implementation part because it has accessibility modifiers.
                //     internal static partial void M(ref object o);
                Diagnostic(ErrorCode.ERR_PartialMethodWithAccessibilityModsMustHaveImplementation, "M").WithArguments("Program.M(ref object)").WithLocation(4, 34),
                // (5,34): error CS0663: 'Program' cannot define an overloaded method that differs only on parameter modifiers 'out' and 'ref'
                //     internal static partial void M(out object o);
                Diagnostic(ErrorCode.ERR_OverloadRefKind, "M").WithArguments("Program", "method", "out", "ref").WithLocation(5, 34));
        }
 
        [Fact]
        public void ConflictingOverloads_RefOut_02()
        {
            const string text = @"
partial class Program
{
    internal static partial void M(ref object o);
    internal static partial void M(ref object o) { }
    internal static partial void M(out object o);
    internal static partial void M(out object o) { o = null; }
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (6,34): error CS0663: 'Program' cannot define an overloaded method that differs only on parameter modifiers 'out' and 'ref'
                //     internal static partial void M(out object o);
                Diagnostic(ErrorCode.ERR_OverloadRefKind, "M").WithArguments("Program", "method", "out", "ref").WithLocation(6, 34));
        }
 
        [Fact]
        public void RefReturn()
        {
            const string text = @"
using System;
 
partial class Program
{
    static int i = 1;
    private static partial ref int M();
    private static partial ref int M() => ref i;
 
    static void Main()
    {
        ref int local = ref M();
        Console.Write(local);
        i++;
        Console.Write(local);
    }
}
";
            var verifier = CompileAndVerify(
                text,
                parseOptions: TestOptions.RegularWithExtendedPartialMethods,
                expectedOutput: "12");
            verifier.VerifyDiagnostics();
        }
 
        [Fact]
        public void PrivateProtectedAccessibility_01()
        {
            const string text1 = @"
using System;
 
public partial class Base
{
    private protected static partial void M1();
    private protected static partial void M1() { Console.Write(1); }
}";
 
            const string text2 = @"
class Derived : Base
{
    static void Main()
    {
        M1();
    }
}";
            var verifier = CompileAndVerify(
                new[] { text1, text2 },
                parseOptions: TestOptions.RegularWithExtendedPartialMethods,
                expectedOutput: "1");
            verifier.VerifyDiagnostics();
 
            var comp1 = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            verify(comp1.ToMetadataReference());
            verify(comp1.EmitToImageReference());
 
            void verify(MetadataReference reference)
            {
                var comp2 = CreateCompilation(
                    text2,
                    references: new[] { reference },
                    parseOptions: TestOptions.RegularWithExtendedPartialMethods);
                comp2.VerifyDiagnostics(
                    // (6,9): error CS0122: 'Base.M1()' is inaccessible due to its protection level
                    //         M1();
                    Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("Base.M1()").WithLocation(6, 9));
            }
        }
 
        [Fact]
        public void PrivateProtectedAccessibility_02()
        {
            const string text1 = @"
using System;
 
partial class C
{
    private protected static partial void M1();
    private protected static partial void M1() { Console.Write(1); }
}";
 
            const string text2 = @"
class Program
{
    static void Main()
    {
        C.M1(); // 1
    }
}";
            var comp = CreateCompilation(new[] { text1, text2 }, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (6,11): error CS0122: 'C.M1()' is inaccessible due to its protection level
                //         C.M1(); // 1
                Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("C.M1()").WithLocation(6, 11));
        }
 
        [Fact]
        public void ProtectedAccessibility_01()
        {
            const string text1 = @"
using System;
 
partial class Base
{
    protected static partial void M1();
    protected static partial void M1() { Console.Write(1); }
}";
 
            const string text2 = @"
class Derived : Base
{
    static void Main()
    {
        M1();
    }
}";
            var verifier = CompileAndVerify(
                new[] { text1, text2 },
                parseOptions: TestOptions.RegularWithExtendedPartialMethods,
                expectedOutput: "1");
            verifier.VerifyDiagnostics();
        }
 
        [Fact]
        public void ProtectedAccessibility_02()
        {
            const string text1 = @"
using System;
 
partial class C
{
    protected static partial void M1();
    protected static partial void M1() { Console.Write(1); }
}";
 
            const string text2 = @"
class Program
{
    static void Main()
    {
        C.M1(); // 1
    }
}";
            var comp = CreateCompilation(new[] { text1, text2 }, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (6,11): error CS0122: 'C.M1()' is inaccessible due to its protection level
                //         C.M1(); // 1
                Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("C.M1()").WithLocation(6, 11));
        }
 
        [Fact]
        public void InternalAccessibility_01()
        {
            const string text1 = @"
using System;
 
internal partial class C
{
    internal static partial void M1();
    internal static partial void M1() { Console.Write(1); }
}";
 
            const string text2 = @"
class Program
{
    static void Main()
    {
        C.M1();
    }
}";
            var verifier = CompileAndVerify(
                new[] { text1, text2 },
                parseOptions: TestOptions.RegularWithExtendedPartialMethods,
                expectedOutput: "1");
            verifier.VerifyDiagnostics();
        }
 
        [Fact]
        public void InternalAccessibility_02()
        {
            const string text1 = @"
using System;
 
internal partial class C
{
    internal static partial void M1();
    internal static partial void M1() { Console.Write(1); }
}";
 
            const string text2 = @"
class Program
{
    static void Main()
    {
        C.M1(); // 1
    }
}";
            var comp1 = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp1.VerifyDiagnostics();
            verify(comp1.ToMetadataReference());
            verify(comp1.EmitToImageReference());
 
            void verify(MetadataReference reference)
            {
                var comp2 = CreateCompilation(
                    text2,
                    references: new[] { comp1.ToMetadataReference() },
                    parseOptions: TestOptions.RegularWithExtendedPartialMethods);
                comp2.VerifyDiagnostics(
                    // (6,9): error CS0122: 'C' is inaccessible due to its protection level
                    //         C.M1(); // 1
                    Diagnostic(ErrorCode.ERR_BadAccess, "C").WithArguments("C").WithLocation(6, 9));
            }
        }
 
        [Fact]
        public void ProtectedInternalAccessibility_01()
        {
            const string text1 = @"
using System;
 
public partial class C
{
    protected internal static partial void M1();
    protected internal static partial void M1() { Console.Write(1); }
}";
 
            const string text2 = @"
class Program
{
    static void Main()
    {
        C.M1();
    }
}";
            var verifier = CompileAndVerify(
                new[] { text1, text2 },
                parseOptions: TestOptions.RegularWithExtendedPartialMethods,
                expectedOutput: "1");
            verifier.VerifyDiagnostics();
 
            var comp1 = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            verify(comp1.ToMetadataReference());
            verify(comp1.EmitToImageReference());
 
            void verify(MetadataReference reference)
            {
                var comp2 = CreateCompilation(
                    text2,
                    references: new[] { reference },
                    parseOptions: TestOptions.RegularWithExtendedPartialMethods);
                comp2.VerifyDiagnostics(
                    // (6,11): error CS0122: 'C.M1()' is inaccessible due to its protection level
                    //         C.M1();
                    Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("C.M1()").WithLocation(6, 11));
            }
        }
 
        [Fact]
        public void ProtectedInternalAccessibility_02()
        {
            const string text1 = @"
using System;
 
public partial class Base
{
    protected internal static partial void M1();
    protected internal static partial void M1() { Console.Write(1); }
}";
 
            const string text2 = @"
class Derived : Base
{
    static void Main()
    {
        M1();
    }
}";
            var verifier = CompileAndVerify(
                new[] { text1, text2 },
                parseOptions: TestOptions.RegularWithExtendedPartialMethods,
                expectedOutput: "1");
            verifier.VerifyDiagnostics();
 
            var comp1 = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            verify(comp1.ToMetadataReference());
            verify(comp1.EmitToImageReference());
 
            void verify(MetadataReference reference)
            {
                var verifier = CompileAndVerify(
                    text2,
                    references: new[] { reference },
                    parseOptions: TestOptions.RegularWithExtendedPartialMethods,
                    expectedOutput: "1");
                verifier.VerifyDiagnostics();
            }
        }
 
        [Fact]
        public void PublicAccessibility()
        {
            const string text1 = @"
using System;
 
public partial class C
{
    public static partial void M1();
    public static partial void M1() { Console.Write(1); }
}";
 
            const string text2 = @"
class Program
{
    static void Main()
    {
        C.M1();
    }
}";
            var verifier = CompileAndVerify(
                new[] { text1, text2 },
                parseOptions: TestOptions.RegularWithExtendedPartialMethods,
                expectedOutput: "1");
            verifier.VerifyDiagnostics();
 
            var comp1 = CreateCompilation(text1, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            verify(comp1.ToMetadataReference());
            verify(comp1.EmitToImageReference());
 
            void verify(MetadataReference reference)
            {
                var verifier = CompileAndVerify(
                    text2,
                    references: new[] { reference },
                    parseOptions: TestOptions.RegularWithExtendedPartialMethods,
                    expectedOutput: "1");
                verifier.VerifyDiagnostics();
            }
        }
 
        [Fact]
        public void EntryPoint_01()
        {
            const string text1 = @"
using System.Threading.Tasks;
 
public partial class C
{
    public static partial Task Main();
}";
            var comp1 = CreateCompilation(
                text1,
                parseOptions: TestOptions.RegularWithExtendedPartialMethods,
                options: TestOptions.DebugExe);
            comp1.VerifyDiagnostics(
                // error CS5001: Program does not contain a static 'Main' method suitable for an entry point
                Diagnostic(ErrorCode.ERR_NoEntryPoint).WithLocation(1, 1),
                // (6,32): error CS8793: Partial method 'C.Main()' must have an implementation part because it has accessibility modifiers.
                //     public static partial Task Main();
                Diagnostic(ErrorCode.ERR_PartialMethodWithAccessibilityModsMustHaveImplementation, "Main").WithArguments("C.Main()").WithLocation(6, 32));
        }
 
        [Fact]
        public void EntryPoint_02()
        {
            const string text1 = @"
using System.Threading.Tasks;
using System;
 
public partial class C
{
    public static partial Task Main();
    public static partial async Task Main()
    {
        Console.Write(1);
    }
}";
            var verifier = CompileAndVerify(
                text1,
                parseOptions: TestOptions.RegularWithExtendedPartialMethods,
                options: TestOptions.DebugExe,
                expectedOutput: "1");
            verifier.VerifyDiagnostics(
                // (8,38): 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.
                //     public static partial async Task Main()
                Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Main").WithLocation(8, 38));
        }
 
        [Fact]
        public void EntryPoint_03()
        {
            const string text1 = @"
using System.Threading.Tasks;
 
public partial class C
{
    public static partial Task<int> Main();
}";
            var comp1 = CreateCompilation(
                text1,
                parseOptions: TestOptions.RegularWithExtendedPartialMethods,
                options: TestOptions.DebugExe);
            comp1.VerifyDiagnostics(
                // error CS5001: Program does not contain a static 'Main' method suitable for an entry point
                Diagnostic(ErrorCode.ERR_NoEntryPoint).WithLocation(1, 1),
                // (6,37): error CS8793: Partial method 'C.Main()' must have an implementation part because it has accessibility modifiers.
                //     public static partial Task<int> Main();
                Diagnostic(ErrorCode.ERR_PartialMethodWithAccessibilityModsMustHaveImplementation, "Main").WithArguments("C.Main()").WithLocation(6, 37));
        }
 
        [Fact]
        public void EntryPoint_04()
        {
            const string text1 = @"
using System.Threading.Tasks;
using System;
 
public partial class C
{
    public static partial Task<int> Main();
    public static partial async Task<int> Main()
    {
        Console.Write(1);
        return 1;
    }
}";
            var verifier = CompileAndVerify(
                text1,
                parseOptions: TestOptions.RegularWithExtendedPartialMethods,
                options: TestOptions.DebugExe,
                expectedOutput: "1");
            verifier.VerifyDiagnostics(
                // (8,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.
                //     public static partial async Task<int> Main()
                Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Main").WithLocation(8, 43));
        }
 
        [ConditionalFact(typeof(CoreClrOnly))]
        public void Override_CustomModifiers()
        {
            var source1 = @"
public class C
{
    public virtual void M(in object x) { }
}";
            var comp1 = CreateCompilation(source1, assemblyName: "C");
            comp1.VerifyDiagnostics();
            verify(comp1.ToMetadataReference());
            verify(comp1.EmitToImageReference());
 
            void verify(MetadataReference reference)
            {
 
                var source2 = @"
public partial class D : C
{
    public override partial void M(in object x);
    public override partial void M(in object x) { x.ToString(); }
}
";
                var verifier = CompileAndVerify(source2, references: new[] { reference }, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
                verifier.VerifyTypeIL("D", @"
.class public auto ansi beforefieldinit D
	extends [C]C
{
	// Methods
	.method public hidebysig virtual 
		instance void M (
			[in] object& modreq([netstandard]System.Runtime.InteropServices.InAttribute) x
		) cil managed 
	{
		.param [1]
			.custom instance void System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = (
				01 00 00 00
			)
		// Method begins at RVA 0x2067
		// Code size 9 (0x9)
		.maxstack 8
 
		IL_0000: ldarg.1
		IL_0001: ldind.ref
		IL_0002: callvirt instance string [netstandard]System.Object::ToString()
		IL_0007: pop
		IL_0008: ret
	} // end of method D::M
 
	.method public hidebysig specialname rtspecialname 
		instance void .ctor () cil managed 
	{
		// Method begins at RVA 0x2071
		// Code size 7 (0x7)
		.maxstack 8
 
		IL_0000: ldarg.0
		IL_0001: call instance void [C]C::.ctor()
		IL_0006: ret
	} // end of method D::.ctor
 
} // end of class D
");
            }
        }
 
        [Fact]
        public void InterfaceImpl_InThunk()
        {
            var source = @"
public interface I
{
    void M(in object obj);
}
 
public partial class C : I
{
    public partial void M(in object obj);
    public partial void M(in object obj) { }
}
";
            var verifier = CompileAndVerify(
                source,
                options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All),
                parseOptions: TestOptions.RegularWithExtendedPartialMethods,
                symbolValidator: verify);
            verifier.VerifyDiagnostics();
 
            void verify(ModuleSymbol module)
            {
                Assert.Equal(MetadataImportOptions.All, ((PEModuleSymbol)module).ImportOptions);
                var cType = module.ContainingAssembly.GetTypeByMetadataName("C");
                Assert.NotNull(cType.GetMethod("M"));
                Assert.NotNull(cType.GetMethod("I.M"));
            }
        }
 
        [Fact]
        public void ConsumeExtendedPartialFromVB()
        {
            var csharp = @"
public partial class C
{
    public virtual partial int M1();
    public virtual partial int M1() => 42;
}";
            var comp = CreateCompilation(csharp, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
 
            var vb = @"
Public Class D
    Inherits C
 
    Public Overrides Function M1() As Integer
        Return 123
    End Function
End Class
";
 
            var vbComp = CreateVisualBasicCompilation(vb, referencedAssemblies: TargetFrameworkUtil.GetReferences(TargetFramework.Standard).Add(comp.EmitToImageReference()));
            vbComp.VerifyDiagnostics();
        }
 
        [Fact]
        public void Override_SingleDimensionArraySizesInMetadata()
        {
 
            var il = @"
.class public auto ansi abstract beforefieldinit Base
    extends [mscorlib]System.Object
{
    // Methods
    .method public hidebysig newslot abstract virtual
        void M1 (int32[0...] param) cil managed 
    {
    }
    .method public hidebysig newslot abstract virtual
        int32[0...] M2 () cil managed 
    {
    }
    .method family hidebysig specialname rtspecialname 
        instance void .ctor () cil managed 
    {
        ldarg.0
        call instance void [mscorlib]System.Object::.ctor()
        ret
    }
}";
 
            var source = @"
public partial class Derived : Base
{
    public override partial void M1(int[] param);
    public override partial void M1(int[] param) { }
 
    public override partial int[] M2();
    public override partial int[] M2() => new int[0];
}";
 
            var comp = CreateCompilationWithIL(source, il, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (2,22): error CS0534: 'Derived' does not implement inherited abstract member 'Base.M1(int[*])'
                // public partial class Derived : Base
                Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.M1(int[*])").WithLocation(2, 22),
                // (4,34): error CS0115: 'Derived.M1(int[])': no suitable method found to override
                //     public override partial void M1(int[] param);
                Diagnostic(ErrorCode.ERR_OverrideNotExpected, "M1").WithArguments("Derived.M1(int[])").WithLocation(4, 34),
                // (7,35): error CS0508: 'Derived.M2()': return type must be 'int[*]' to match overridden member 'Base.M2()'
                //     public override partial int[] M2();
                Diagnostic(ErrorCode.ERR_CantChangeReturnTypeOnOverride, "M2").WithArguments("Derived.M2()", "Base.M2()", "int[*]").WithLocation(7, 35)
            );
        }
 
        [Fact]
        public void Override_ArraySizesInMetadata()
        {
            var il = @"
.class public auto ansi abstract beforefieldinit Base
    extends [mscorlib]System.Object
{
    // Methods
    .method public hidebysig newslot abstract virtual
        void M1 (int32[5...5,2...4] param) cil managed 
    {
    }
    .method public hidebysig newslot abstract virtual
        int32[5...5,2...4] M2 () cil managed 
    {
    }
    .method family hidebysig specialname rtspecialname 
        instance void .ctor () cil managed 
    {
        ldarg.0
        call instance void [mscorlib]System.Object::.ctor()
        ret
    }
}";
 
            var source = @"
using System;
partial class Derived : Base
{
    public override partial void M1(int[,] param);
    public override partial int[,] M2();
 
    public override partial void M1(int[,] param)
    {
        Console.Write(1);
    }
    public override partial int[,] M2()
    {
        Console.Write(2);
        return null;
    }
 
    public static void Main()
    {
        var d = new Derived();
        d.M1(null);
        _ = d.M2();
    }
}";
 
            var comp = CreateCompilationWithIL(source, il, options: TestOptions.DebugExe, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            CompileAndVerify(comp, expectedOutput: "12");
 
            var m1 = comp.GetMember<MethodSymbol>("Derived.M1");
            verifyArray(m1.Parameters[0].Type);
 
            var m2 = comp.GetMember<MethodSymbol>("Derived.M2");
            verifyArray(m2.ReturnType);
 
            static void verifyArray(TypeSymbol type)
            {
                var array = (ArrayTypeSymbol)type;
                Assert.False(array.IsSZArray);
                Assert.Equal(2, array.Rank);
                Assert.Equal(5, array.LowerBounds[0]);
                Assert.Equal(1, array.Sizes[0]);
                Assert.Equal(2, array.LowerBounds[1]);
                Assert.Equal(3, array.Sizes[1]);
            }
        }
 
        [Fact, WorkItem(44930, "https://github.com/dotnet/roslyn/issues/44930")]
        public void DifferentReturnTypes_01()
        {
            var source = @"
partial class C
{
    public partial int M();
    public partial long M() => 42; // 1
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(5), parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (5,25): error CS8817: Both partial method declarations must have the same return type.
                //     public partial long M() => 42; // 1
                Diagnostic(ErrorCode.ERR_PartialMethodReturnTypeDifference, "M").WithLocation(5, 25));
 
            comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(6), parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (5,25): error CS8817: Both partial method declarations must have the same return type.
                //     public partial long M() => 42; // 1
                Diagnostic(ErrorCode.ERR_PartialMethodReturnTypeDifference, "M").WithLocation(5, 25));
        }
 
        [Fact, WorkItem(44930, "https://github.com/dotnet/roslyn/issues/44930")]
        public void DifferentReturnTypes_02()
        {
            var source = @"
partial class C
{
    public partial long M();
    public partial int M() => 42; // 1
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (5,24): error CS8817: Both partial method declarations must have the same return type.
                //     public partial int M() => 42; // 1
                Diagnostic(ErrorCode.ERR_PartialMethodReturnTypeDifference, "M").WithLocation(5, 24));
        }
 
        [Fact, WorkItem(44930, "https://github.com/dotnet/roslyn/issues/44930")]
        public void DifferentReturnTypes_03()
        {
            var source = @"
using System.Collections.Generic;
#nullable enable
 
partial class C
{
    public partial string? M1();
    public partial string M1() => ""hello"";
 
    public partial IEnumerable<string?> M2();
    public partial IEnumerable<string> M2() => null!;
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(5), parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
 
            comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(6), parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (8,27): warning CS8825: Partial method declarations 'string? C.M1()' and 'string C.M1()' must have identical nullability for parameter types and return types.
                //     public partial string M1() => "hello";
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "M1").WithArguments("string? C.M1()", "string C.M1()").WithLocation(8, 27),
                // (11,40): warning CS8825: Partial method declarations 'IEnumerable<string?> C.M2()' and 'IEnumerable<string> C.M2()' must have identical nullability for parameter types and return types.
                //     public partial IEnumerable<string> M2() => null!;
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "M2").WithArguments("IEnumerable<string?> C.M2()", "IEnumerable<string> C.M2()").WithLocation(11, 40));
        }
 
        [Fact, WorkItem(44930, "https://github.com/dotnet/roslyn/issues/44930")]
        public void DifferentReturnTypes_04()
        {
            var source = @"
using System.Collections.Generic;
#nullable enable
 
partial class C
{
    public partial string M1();
    public partial string? M1() => null; // 1
 
    public partial IEnumerable<string> M2();
    public partial IEnumerable<string?> M2() => null!; // 2
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(5), parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (8,28): warning CS8819: Nullability of reference types in return type doesn't match partial method declaration.
                //     public partial string? M1() => null; // 1
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnPartial, "M1").WithLocation(8, 28),
                // (11,41): warning CS8819: Nullability of reference types in return type doesn't match partial method declaration.
                //     public partial IEnumerable<string?> M2() => null!; // 2
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnPartial, "M2").WithLocation(11, 41));
 
            comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(6), parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (8,28): warning CS8819: Nullability of reference types in return type doesn't match partial method declaration.
                //     public partial string? M1() => null; // 1
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnPartial, "M1").WithLocation(8, 28),
                // (11,41): warning CS8819: Nullability of reference types in return type doesn't match partial method declaration.
                //     public partial IEnumerable<string?> M2() => null!; // 2
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnPartial, "M2").WithLocation(11, 41));
        }
 
        [Fact, WorkItem(44930, "https://github.com/dotnet/roslyn/issues/44930")]
        public void DifferentReturnTypes_05()
        {
            var source = @"
using System.Collections.Generic;
 
class Base { }
class Derived : Base { }
 
partial class C
{
    public partial Base M1();
    public partial Derived M1() => new Derived(); // 1
 
    public partial IEnumerable<Base> M2();
    public partial IEnumerable<Derived> M2() => null!; // 2
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (10,28): error CS8817: Both partial method declarations must have the same return type.
                //     public partial Derived M1() => new Derived(); // 1
                Diagnostic(ErrorCode.ERR_PartialMethodReturnTypeDifference, "M1").WithLocation(10, 28),
                // (13,41): error CS8817: Both partial method declarations must have the same return type.
                //     public partial IEnumerable<Derived> M2() => null!; // 2
                Diagnostic(ErrorCode.ERR_PartialMethodReturnTypeDifference, "M2").WithLocation(13, 41));
        }
 
        [Fact, WorkItem(44930, "https://github.com/dotnet/roslyn/issues/44930")]
        public void DifferentReturnTypes_06()
        {
            var source = @"
using System.Collections.Generic;
 
class Base { }
class Derived : Base { }
 
partial class C
{
    public partial Derived M1();
    public partial Base M1() => new Base(); // 1
 
    public partial IEnumerable<Derived> M2();
    public partial IEnumerable<Base> M2() => null!; // 2
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (10,25): error CS8817: Both partial method declarations must have the same return type.
                //     public partial Base M1() => new Base(); // 1
                Diagnostic(ErrorCode.ERR_PartialMethodReturnTypeDifference, "M1").WithLocation(10, 25),
                // (13,38): error CS8817: Both partial method declarations must have the same return type.
                //     public partial IEnumerable<Base> M2() => null!; // 2
                Diagnostic(ErrorCode.ERR_PartialMethodReturnTypeDifference, "M2").WithLocation(13, 38));
        }
 
        [Fact, WorkItem(44930, "https://github.com/dotnet/roslyn/issues/44930")]
        public void DifferentReturnTypes_07()
        {
            var source = @"
using System.Collections.Generic;
 
partial class C
{
    public partial U M1<U>();
    public partial V M1<V>() => default;
 
    public partial IEnumerable<U> M2<U>();
    public partial IEnumerable<U> M2<U>() => default;
 
    public partial U M3<U>();
    public partial V M3<V>() => default;
 
    public partial IEnumerable<U> M4<U>();
    public partial IEnumerable<V> M4<V>() => default;
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (7,22): warning CS8826: Partial method declarations 'U C.M1<U>()' and 'V C.M1<V>()' have signature differences.
                //     public partial V M1<V>() => default;
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "M1").WithArguments("U C.M1<U>()", "V C.M1<V>()").WithLocation(7, 22),
                // (13,22): warning CS8826: Partial method declarations 'U C.M3<U>()' and 'V C.M3<V>()' have signature differences.
                //     public partial V M3<V>() => default;
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "M3").WithArguments("U C.M3<U>()", "V C.M3<V>()").WithLocation(13, 22),
                // (16,35): warning CS8826: Partial method declarations 'IEnumerable<U> C.M4<U>()' and 'IEnumerable<V> C.M4<V>()' have signature differences.
                //     public partial IEnumerable<V> M4<V>() => default;
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "M4").WithArguments("IEnumerable<U> C.M4<U>()", "IEnumerable<V> C.M4<V>()").WithLocation(16, 35)
            );
        }
 
        [Fact, WorkItem(44930, "https://github.com/dotnet/roslyn/issues/44930")]
        public void DifferentReturnTypes_08()
        {
            var source = @"
using System.Collections.Generic;
 
partial class C
{
    public partial int M1();
    public partial ERROR M1() => throw null!; // 1
 
    public partial IEnumerable<int> M2();
    public partial IEnumerable<ERROR> M2() => throw null!; // 2
 
    public partial int M3();
    public partial IEnumerable<ERROR> M3() => throw null!; // 3
 
    public partial ERROR M4(); // 4
    public partial int M4() => throw null!;
 
    public partial IEnumerable<ERROR> M5(); // 5
    public partial IEnumerable<int> M5() => throw null!;
 
    public partial IEnumerable<ERROR> M6(); // 6
    public partial int M6() => throw null!;
 
    public partial ERROR M7(); // 7
    public partial ERROR M7() => throw null!; // 8
 
    public partial IEnumerable<ERROR> M8(); // 9
    public partial IEnumerable<ERROR> M8() => throw null!; // 10
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (7,20): error CS0246: The type or namespace name 'ERROR' could not be found (are you missing a using directive or an assembly reference?)
                //     public partial ERROR M1() => throw null!; // 1
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "ERROR").WithArguments("ERROR").WithLocation(7, 20),
                // (7,26): error CS8817: Both partial method declarations must have the same return type.
                //     public partial ERROR M1() => throw null!; // 1
                Diagnostic(ErrorCode.ERR_PartialMethodReturnTypeDifference, "M1").WithLocation(7, 26),
                // (10,32): error CS0246: The type or namespace name 'ERROR' could not be found (are you missing a using directive or an assembly reference?)
                //     public partial IEnumerable<ERROR> M2() => throw null!; // 2
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "ERROR").WithArguments("ERROR").WithLocation(10, 32),
                // (10,39): error CS8817: Both partial method declarations must have the same return type.
                //     public partial IEnumerable<ERROR> M2() => throw null!; // 2
                Diagnostic(ErrorCode.ERR_PartialMethodReturnTypeDifference, "M2").WithLocation(10, 39),
                // (13,32): error CS0246: The type or namespace name 'ERROR' could not be found (are you missing a using directive or an assembly reference?)
                //     public partial IEnumerable<ERROR> M3() => throw null!; // 3
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "ERROR").WithArguments("ERROR").WithLocation(13, 32),
                // (13,39): error CS8817: Both partial method declarations must have the same return type.
                //     public partial IEnumerable<ERROR> M3() => throw null!; // 3
                Diagnostic(ErrorCode.ERR_PartialMethodReturnTypeDifference, "M3").WithLocation(13, 39),
                // (15,20): error CS0246: The type or namespace name 'ERROR' could not be found (are you missing a using directive or an assembly reference?)
                //     public partial ERROR M4(); // 4
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "ERROR").WithArguments("ERROR").WithLocation(15, 20),
                // (16,24): error CS8817: Both partial method declarations must have the same return type.
                //     public partial int M4() => throw null!;
                Diagnostic(ErrorCode.ERR_PartialMethodReturnTypeDifference, "M4").WithLocation(16, 24),
                // (18,32): error CS0246: The type or namespace name 'ERROR' could not be found (are you missing a using directive or an assembly reference?)
                //     public partial IEnumerable<ERROR> M5(); // 5
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "ERROR").WithArguments("ERROR").WithLocation(18, 32),
                // (19,37): error CS8817: Both partial method declarations must have the same return type.
                //     public partial IEnumerable<int> M5() => throw null!;
                Diagnostic(ErrorCode.ERR_PartialMethodReturnTypeDifference, "M5").WithLocation(19, 37),
                // (21,32): error CS0246: The type or namespace name 'ERROR' could not be found (are you missing a using directive or an assembly reference?)
                //     public partial IEnumerable<ERROR> M6(); // 6
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "ERROR").WithArguments("ERROR").WithLocation(21, 32),
                // (22,24): error CS8817: Both partial method declarations must have the same return type.
                //     public partial int M6() => throw null!;
                Diagnostic(ErrorCode.ERR_PartialMethodReturnTypeDifference, "M6").WithLocation(22, 24),
                // (24,20): error CS0246: The type or namespace name 'ERROR' could not be found (are you missing a using directive or an assembly reference?)
                //     public partial ERROR M7(); // 7
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "ERROR").WithArguments("ERROR").WithLocation(24, 20),
                // (25,20): error CS0246: The type or namespace name 'ERROR' could not be found (are you missing a using directive or an assembly reference?)
                //     public partial ERROR M7() => throw null!; // 8
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "ERROR").WithArguments("ERROR").WithLocation(25, 20),
                // (27,32): error CS0246: The type or namespace name 'ERROR' could not be found (are you missing a using directive or an assembly reference?)
                //     public partial IEnumerable<ERROR> M8(); // 9
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "ERROR").WithArguments("ERROR").WithLocation(27, 32),
                // (28,32): error CS0246: The type or namespace name 'ERROR' could not be found (are you missing a using directive or an assembly reference?)
                //     public partial IEnumerable<ERROR> M8() => throw null!; // 10
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "ERROR").WithArguments("ERROR").WithLocation(28, 32));
        }
 
        [Fact, WorkItem(44930, "https://github.com/dotnet/roslyn/issues/44930")]
        public void DifferentReturnTypes_09()
        {
            var source = @"
partial class C
{
    public partial ref int M1();
    public partial int M1() => throw null!; // 1
 
    public partial int M2();
    public partial ref int M2() => throw null!; // 2
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (5,24): error CS8818: Partial member declarations must have matching ref return values.
                //     public partial int M1() => throw null!; // 1
                Diagnostic(ErrorCode.ERR_PartialMemberRefReturnDifference, "M1").WithLocation(5, 24),
                // (5,24): warning CS8826: Partial method declarations 'ref int C.M1()' and 'int C.M1()' have signature differences.
                //     public partial int M1() => throw null!; // 1
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "M1").WithArguments("ref int C.M1()", "int C.M1()").WithLocation(5, 24),
                // (8,28): error CS8818: Partial member declarations must have matching ref return values.
                //     public partial ref int M2() => throw null!; // 2
                Diagnostic(ErrorCode.ERR_PartialMemberRefReturnDifference, "M2").WithLocation(8, 28),
                // (8,28): warning CS8826: Partial method declarations 'int C.M2()' and 'ref int C.M2()' have signature differences.
                //     public partial ref int M2() => throw null!; // 2
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "M2").WithArguments("int C.M2()", "ref int C.M2()").WithLocation(8, 28));
        }
 
        [Fact, WorkItem(44930, "https://github.com/dotnet/roslyn/issues/44930")]
        public void DifferentReturnTypes_10()
        {
            var source = @"
partial class C
{
    public partial U M1<U>();
    public partial U M1<U>() where U : struct => throw null!; // 1
 
    public partial U M2<U>() where U : struct;
    public partial U M2<U>() => throw null!; // 2
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (5,22): error CS0761: Partial method declarations of 'C.M1<U>()' have inconsistent constraints for type parameter 'U'
                //     public partial U M1<U>() where U : struct => throw null!; // 1
                Diagnostic(ErrorCode.ERR_PartialMethodInconsistentConstraints, "M1").WithArguments("C.M1<U>()", "U").WithLocation(5, 22),
                // (8,22): error CS0761: Partial method declarations of 'C.M2<U>()' have inconsistent constraints for type parameter 'U'
                //     public partial U M2<U>() => throw null!; // 2
                Diagnostic(ErrorCode.ERR_PartialMethodInconsistentConstraints, "M2").WithArguments("C.M2<U>()", "U").WithLocation(8, 22));
        }
 
        [Fact, WorkItem(44930, "https://github.com/dotnet/roslyn/issues/44930")]
        public void DifferentReturnTypes_11()
        {
            var source = @"
partial class C<T>
{
    public partial T M1();
    public partial T M2();
}
 
partial class C<T>
{
    public partial T M1() => throw null!;
    public partial T M2() => throw null!;
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
        }
 
        [Fact, WorkItem(44930, "https://github.com/dotnet/roslyn/issues/44930")]
        public void DifferentReturnTypes_12()
        {
            var source = @"
partial class C
{
    public partial (int x, int y) M1();
    public partial (int x1, int y1) M1() => default; // 1
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (5,37): error CS8142: Both partial member declarations, 'C.M1()' and 'C.M1()', must use the same tuple element names.
                //     public partial (int x1, int y1) M1() => default; // 1
                Diagnostic(ErrorCode.ERR_PartialMemberInconsistentTupleNames, "M1").WithArguments("C.M1()", "C.M1()").WithLocation(5, 37));
        }
 
        [Fact, WorkItem(44930, "https://github.com/dotnet/roslyn/issues/44930")]
        public void DifferentReturnTypes_13()
        {
            var source = @"
partial class C
{
    public partial (int x, long y) M1();
    public partial (long x, int y) M1() => default; // 1
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (5,36): error CS8817: Both partial method declarations must have the same return type.
                //     public partial (long x, int y) M1() => default; // 1
                Diagnostic(ErrorCode.ERR_PartialMethodReturnTypeDifference, "M1").WithLocation(5, 36));
        }
 
        [Fact, WorkItem(44930, "https://github.com/dotnet/roslyn/issues/44930")]
        public void DifferentReturnTypes_14()
        {
            var source = @"
partial class C
{
    public partial object M1();
    public partial dynamic M1() => null;
    
    public partial dynamic M2();
    public partial object M2() => null;
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(5), parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
 
            comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(6), parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (5,28): warning CS8826: Partial method declarations 'object C.M1()' and 'dynamic C.M1()' have signature differences.
                //     public partial dynamic M1() => null;
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "M1").WithArguments("object C.M1()", "dynamic C.M1()").WithLocation(5, 28),
                // (8,27): warning CS8826: Partial method declarations 'dynamic C.M2()' and 'object C.M2()' have signature differences.
                //     public partial object M2() => null;
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "M2").WithArguments("dynamic C.M2()", "object C.M2()").WithLocation(8, 27));
        }
 
        [Fact, WorkItem(44930, "https://github.com/dotnet/roslyn/issues/44930")]
        public void DifferentReturnTypes_15()
        {
            var source = @"
using System;
 
partial class C
{
    public partial IntPtr M1();
    public partial nint M1() => 0;
    
    public partial nint M2();
    public partial IntPtr M2() => default;
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(5), parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
 
            comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(6), parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (7,25): warning CS8826: Partial method declarations 'IntPtr C.M1()' and 'nint C.M1()' have signature differences.
                //     public partial nint M1() => 0;
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "M1").WithArguments("IntPtr C.M1()", "nint C.M1()").WithLocation(7, 25),
                // (10,27): warning CS8826: Partial method declarations 'nint C.M2()' and 'IntPtr C.M2()' have signature differences.
                //     public partial IntPtr M2() => default;
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "M2").WithArguments("nint C.M2()", "IntPtr C.M2()").WithLocation(10, 27));
        }
 
        [Fact, WorkItem(44930, "https://github.com/dotnet/roslyn/issues/44930")]
        public void DifferentReturnTypes_16()
        {
            var source = @"
partial class C
{
    public partial ref int M1();
    public partial ref readonly int M1() => throw null!; // 1
 
    public partial ref readonly int M2();
    public partial ref int M2() => throw null!; // 2
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (5,37): error CS8818: Partial member declarations must have matching ref return values.
                //     public partial ref readonly int M1() => throw null!; // 1
                Diagnostic(ErrorCode.ERR_PartialMemberRefReturnDifference, "M1").WithLocation(5, 37),
                // (5,37): warning CS8826: Partial method declarations 'ref int C.M1()' and 'ref readonly int C.M1()' have signature differences.
                //     public partial ref readonly int M1() => throw null!; // 1
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "M1").WithArguments("ref int C.M1()", "ref readonly int C.M1()").WithLocation(5, 37),
                // (8,28): error CS8818: Partial member declarations must have matching ref return values.
                //     public partial ref int M2() => throw null!; // 2
                Diagnostic(ErrorCode.ERR_PartialMemberRefReturnDifference, "M2").WithLocation(8, 28),
                // (8,28): warning CS8826: Partial method declarations 'ref readonly int C.M2()' and 'ref int C.M2()' have signature differences.
                //     public partial ref int M2() => throw null!; // 2
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "M2").WithArguments("ref readonly int C.M2()", "ref int C.M2()").WithLocation(8, 28));
        }
 
        [Fact, WorkItem(44930, "https://github.com/dotnet/roslyn/issues/44930")]
        public void DifferentReturnTypes_17()
        {
            var source = @"
partial class C
{
#nullable enable
    public partial string M1();
    public partial string? M1() => null; // 1
    
    public partial string? M2();
    public partial string M2() => ""hello""; // 2
    
#nullable disable
    public partial string M3();
    public partial string? M3() => null; // 3
    
    public partial string? M4(); // 4
    public partial string M4() => ""hello"";
 
#nullable enable
    public partial string M5();
    public partial string M6() => null!;
    public partial string M7();
    public partial string M8() => null!; // 5
    public partial string? M9();
    public partial string? M10() => null;
    public partial string? M11();
    public partial string? M12() => null;
 
#nullable disable
    public partial string M5() => null;
    public partial string M6();
    public partial string? M7() => null; // 6
    public partial string? M8(); // 7
    public partial string M9() => null;
    public partial string M10();
    public partial string? M11() => null; // 8
    public partial string? M12(); // 9
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(5), parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (6,28): warning CS8819: Nullability of reference types in return type doesn't match partial method declaration.
                //     public partial string? M1() => null; // 1
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnPartial, "M1").WithLocation(6, 28),
                // (13,26): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     public partial string? M3() => null; // 3
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(13, 26),
                // (15,26): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     public partial string? M4(); // 4
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(15, 26),
                // (31,26): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     public partial string? M7() => null; // 6
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(31, 26),
                // (32,26): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     public partial string? M8(); // 7
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(32, 26),
                // (35,26): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     public partial string? M11() => null; // 8
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(35, 26),
                // (36,26): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     public partial string? M12(); // 9
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(36, 26));
 
            comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(6), parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (6,28): warning CS8819: Nullability of reference types in return type doesn't match partial method declaration.
                //     public partial string? M1() => null; // 1
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnPartial, "M1").WithLocation(6, 28),
                // (9,27): warning CS8826: Partial method declarations 'string? C.M2()' and 'string C.M2()' have signature differences.
                //     public partial string M2() => "hello"; // 2
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "M2").WithArguments("string? C.M2()", "string C.M2()").WithLocation(9, 27),
                // (13,26): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     public partial string? M3() => null; // 3
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(13, 26),
                // (15,26): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     public partial string? M4(); // 4
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(15, 26),
                // (22,27): warning CS8826: Partial method declarations 'string? C.M8()' and 'string C.M8()' have signature differences.
                //     public partial string M8() => null!; // 5
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "M8").WithArguments("string? C.M8()", "string C.M8()").WithLocation(22, 27),
                // (31,26): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     public partial string? M7() => null; // 6
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(31, 26),
                // (32,26): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     public partial string? M8(); // 7
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(32, 26),
                // (35,26): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     public partial string? M11() => null; // 8
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(35, 26),
                // (36,26): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     public partial string? M12(); // 9
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(36, 26));
        }
 
        [Fact]
        public void DifferentReturnTypes_18()
        {
            var source =
@"partial class C
{
    public partial ref int F1();
    public partial string F1() => null;
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                // (4,27): error CS8817: Both partial method declarations must have the same return type.
                //     public partial string F1() => null;
                Diagnostic(ErrorCode.ERR_PartialMethodReturnTypeDifference, "F1").WithLocation(4, 27),
                // (4,27): error CS8818: Partial member declarations must have matching ref return values.
                //     public partial string F1() => null;
                Diagnostic(ErrorCode.ERR_PartialMemberRefReturnDifference, "F1").WithLocation(4, 27));
        }
 
        [Fact]
        public void DifferentReturnTypes_19()
        {
            var source =
@"partial class C
{
    public partial ref (int x, int y) F1();
    public partial (int, int) F1() => default;
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics(
                    // (4,31): error CS8818: Partial member declarations must have matching ref return values.
                    //     public partial (int, int) F1() => default;
                    Diagnostic(ErrorCode.ERR_PartialMemberRefReturnDifference, "F1").WithLocation(4, 31),
                    // (4,31): warning CS8826: Partial method declarations 'ref (int x, int y) C.F1()' and '(int, int) C.F1()' have signature differences.
                    //     public partial (int, int) F1() => default;
                    Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "F1").WithArguments("ref (int x, int y) C.F1()", "(int, int) C.F1()").WithLocation(4, 31));
        }
 
        [Fact]
        [WorkItem(45519, "https://github.com/dotnet/roslyn/issues/45519")]
        public void DifferentSignatures_Dynamic()
        {
            var source =
@"partial class C
{
    partial void F1(object o);
    partial void F1(dynamic o) { } // 1
    internal partial void F2(object o);
    internal partial void F2(dynamic o) { } // 2
    internal partial dynamic F3();
    internal partial object F3() => null; // 3
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(5));
            comp.VerifyDiagnostics();
 
            comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(6));
            comp.VerifyDiagnostics(
                // (4,18): warning CS8826: Partial method declarations 'void C.F1(object o)' and 'void C.F1(dynamic o)' have signature differences.
                //     partial void F1(dynamic o) { } // 1
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "F1", isSuppressed: false).WithArguments("void C.F1(object o)", "void C.F1(dynamic o)").WithLocation(4, 18),
                // (6,27): warning CS8826: Partial method declarations 'void C.F2(object o)' and 'void C.F2(dynamic o)' have signature differences.
                //     internal partial void F2(dynamic o) { } // 2
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "F2", isSuppressed: false).WithArguments("void C.F2(object o)", "void C.F2(dynamic o)").WithLocation(6, 27),
                // (8,29): warning CS8826: Partial method declarations 'dynamic C.F3()' and 'object C.F3()' have signature differences.
                //     internal partial object F3() => null; // 3
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "F3", isSuppressed: false).WithArguments("dynamic C.F3()", "object C.F3()").WithLocation(8, 29));
        }
 
        [Fact]
        [WorkItem(45519, "https://github.com/dotnet/roslyn/issues/45519")]
        public void DifferentSignatures_Nullable()
        {
            var source =
@"using System.Collections.Generic;
#nullable enable
partial class C
{
    partial void F1(string? s);
    partial void F1(string s) { } // 1
    partial void F2(IEnumerable<string?> s);
    partial void F2(IEnumerable<string> s) { } // 2
    internal partial void F3(string? s);
    internal partial void F3(string s) { } // 3
    internal partial void F4(IEnumerable<string?> s);
    internal partial void F4(IEnumerable<string> s) { } // 4
    internal partial string? F5();
    internal partial string F5() => null!; // 5
    internal partial IEnumerable<string> F6();
    internal partial IEnumerable<string?> F6() => null!; // 6
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(5));
            comp.VerifyDiagnostics(
                // (6,18): warning CS8611: Nullability of reference types in type of parameter 's' doesn't match partial method declaration.
                //     partial void F1(string s) { } // 1
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnPartial, "F1").WithArguments("s").WithLocation(6, 18),
                // (8,18): warning CS8611: Nullability of reference types in type of parameter 's' doesn't match partial method declaration.
                //     partial void F2(IEnumerable<string> s) { } // 2
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnPartial, "F2").WithArguments("s").WithLocation(8, 18),
                // (10,27): warning CS8611: Nullability of reference types in type of parameter 's' doesn't match partial method declaration.
                //     internal partial void F3(string s) { } // 3
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnPartial, "F3").WithArguments("s").WithLocation(10, 27),
                // (12,27): warning CS8611: Nullability of reference types in type of parameter 's' doesn't match partial method declaration.
                //     internal partial void F4(IEnumerable<string> s) { } // 4
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnPartial, "F4").WithArguments("s").WithLocation(12, 27),
                // (16,43): warning CS8819: Nullability of reference types in return type doesn't match partial method declaration.
                //     internal partial IEnumerable<string?> F6() => null!; // 6
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnPartial, "F6").WithLocation(16, 43));
 
            comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(6));
            comp.VerifyDiagnostics(
                // (6,18): warning CS8611: Nullability of reference types in type of parameter 's' doesn't match partial method declaration.
                //     partial void F1(string s) { } // 1
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnPartial, "F1").WithArguments("s").WithLocation(6, 18),
                // (8,18): warning CS8611: Nullability of reference types in type of parameter 's' doesn't match partial method declaration.
                //     partial void F2(IEnumerable<string> s) { } // 2
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnPartial, "F2").WithArguments("s").WithLocation(8, 18),
                // (10,27): warning CS8611: Nullability of reference types in type of parameter 's' doesn't match partial method declaration.
                //     internal partial void F3(string s) { } // 3
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnPartial, "F3").WithArguments("s").WithLocation(10, 27),
                // (12,27): warning CS8611: Nullability of reference types in type of parameter 's' doesn't match partial method declaration.
                //     internal partial void F4(IEnumerable<string> s) { } // 4
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnPartial, "F4").WithArguments("s").WithLocation(12, 27),
                // (14,29): warning CS8826: Partial method declarations 'string? C.F5()' and 'string C.F5()' have signature differences.
                //     internal partial string F5() => null!; // 5
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "F5").WithArguments("string? C.F5()", "string C.F5()").WithLocation(14, 29),
                // (16,43): warning CS8819: Nullability of reference types in return type doesn't match partial method declaration.
                //     internal partial IEnumerable<string?> F6() => null!; // 6
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnPartial, "F6").WithLocation(16, 43));
        }
 
        // Errors reported for all differences.
        [Fact]
        [WorkItem(45519, "https://github.com/dotnet/roslyn/issues/45519")]
        public void DifferentSignatures_Tuples()
        {
            var source =
@"partial class C
{
    partial void F1<T, U>((T x, U y) t) { }
    partial void F1<T, U>((T x, U y) t);
    partial void F2<T, U>((T x, U y) t) { } // 1
    partial void F2<T, U>((T, U) t);
    partial void F3((dynamic, object) t);
    partial void F3((object x, dynamic y) t) { } // 2
    internal partial void F4<T, U>((T x, U y) t);
    internal partial void F4<T, U>((T, U) t) { } // 3
    internal partial (T, U) F5<T, U>() => default;
    internal partial (T, U) F5<T, U>();
    internal partial (T, U) F6<T, U>() => default; // 4
    internal partial (T x, U y) F6<T, U>();
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(5));
            verifyDiagnostics(comp);
 
            comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(6));
            verifyDiagnostics(comp);
 
            static void verifyDiagnostics(CSharpCompilation comp)
            {
                comp.VerifyDiagnostics(
                    // (5,18): error CS8142: Both partial member declarations, 'C.F2<T, U>((T, U))' and 'C.F2<T, U>((T x, U y))', must use the same tuple element names.
                    //     partial void F2<T, U>((T x, U y) t) { } // 1
                    Diagnostic(ErrorCode.ERR_PartialMemberInconsistentTupleNames, "F2").WithArguments("C.F2<T, U>((T, U))", "C.F2<T, U>((T x, U y))").WithLocation(5, 18),
                    // (8,18): error CS8142: Both partial member declarations, 'C.F3((dynamic, object))' and 'C.F3((object x, dynamic y))', must use the same tuple element names.
                    //     partial void F3((object x, dynamic y) t) { } // 2
                    Diagnostic(ErrorCode.ERR_PartialMemberInconsistentTupleNames, "F3").WithArguments("C.F3((dynamic, object))", "C.F3((object x, dynamic y))").WithLocation(8, 18),
                    // (10,27): error CS8142: Both partial member declarations, 'C.F4<T, U>((T x, U y))' and 'C.F4<T, U>((T, U))', must use the same tuple element names.
                    //     internal partial void F4<T, U>((T, U) t) { } // 3
                    Diagnostic(ErrorCode.ERR_PartialMemberInconsistentTupleNames, "F4").WithArguments("C.F4<T, U>((T x, U y))", "C.F4<T, U>((T, U))").WithLocation(10, 27),
                    // (13,29): error CS8142: Both partial member declarations, 'C.F6<T, U>()' and 'C.F6<T, U>()', must use the same tuple element names.
                    //     internal partial (T, U) F6<T, U>() => default; // 4
                    Diagnostic(ErrorCode.ERR_PartialMemberInconsistentTupleNames, "F6").WithArguments("C.F6<T, U>()", "C.F6<T, U>()").WithLocation(13, 29));
            }
        }
 
        [Fact]
        [WorkItem(45519, "https://github.com/dotnet/roslyn/issues/45519")]
        public void DifferentSignatures_NativeIntegers()
        {
            var source =
@"using System.Collections.Generic;
partial class C
{
    partial void F1(nint i);
    partial void F1(System.IntPtr i) { } // 1
    partial void F2(dynamic x, nint y);
    partial void F2(object x, System.IntPtr y) { } // 2
    internal partial void F3(nint i);
    internal partial void F3(System.IntPtr i) { } // 3
    internal partial IEnumerable<System.IntPtr> F4();
    internal partial IEnumerable<nint> F4() => null; // 4
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(5));
            comp.VerifyDiagnostics();
 
            comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(6));
            comp.VerifyDiagnostics(
                // (5,18): warning CS8826: Partial method declarations 'void C.F1(nint i)' and 'void C.F1(IntPtr i)' have signature differences.
                //     partial void F1(System.IntPtr i) { } // 1
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "F1").WithArguments("void C.F1(nint i)", "void C.F1(IntPtr i)").WithLocation(5, 18),
                // (7,18): warning CS8826: Partial method declarations 'void C.F2(dynamic x, nint y)' and 'void C.F2(object x, IntPtr y)' have signature differences.
                //     partial void F2(object x, System.IntPtr y) { } // 2
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "F2").WithArguments("void C.F2(dynamic x, nint y)", "void C.F2(object x, IntPtr y)").WithLocation(7, 18),
                // (9,27): warning CS8826: Partial method declarations 'void C.F3(nint i)' and 'void C.F3(IntPtr i)' have signature differences.
                //     internal partial void F3(System.IntPtr i) { } // 3
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "F3").WithArguments("void C.F3(nint i)", "void C.F3(IntPtr i)").WithLocation(9, 27),
                // (11,40): warning CS8826: Partial method declarations 'IEnumerable<IntPtr> C.F4()' and 'IEnumerable<nint> C.F4()' have signature differences.
                //     internal partial IEnumerable<nint> F4() => null; // 4
                Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "F4").WithArguments("IEnumerable<IntPtr> C.F4()", "IEnumerable<nint> C.F4()").WithLocation(11, 40));
        }
 
        [Fact]
        public void PublicAPI()
        {
            var source = @"
#nullable enable
 
partial class C
{
    public partial string M1();
    public partial string M1() => ""a"";
 
    partial void M2();
    partial void M2() { }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
            comp.VerifyDiagnostics();
 
            verifyPublicAPI(comp.GetMember<MethodSymbol>("C.M1").GetPublicSymbol());
            verifyPublicAPI(comp.GetMember<MethodSymbol>("C.M2").GetPublicSymbol());
 
            void verifyPublicAPI(IMethodSymbol defSymbol)
            {
                var implSymbol = defSymbol.PartialImplementationPart;
                Assert.NotNull(implSymbol);
                Assert.NotEqual(implSymbol, defSymbol);
 
                Assert.Null(defSymbol.PartialDefinitionPart);
                Assert.Null(implSymbol.PartialImplementationPart);
 
                Assert.Equal(implSymbol.PartialDefinitionPart, defSymbol);
                Assert.Equal(implSymbol.ToTestDisplayString(includeNonNullable: false), defSymbol.ToTestDisplayString(includeNonNullable: false));
            }
        }
    }
}