File: RefReadonlyParameterTests.cs
Web Access
Project: src\src\Compilers\CSharp\Test\Emit3\Microsoft.CodeAnalysis.CSharp.Emit3.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Emit3.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.
 
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Symbols.Retargeting;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Semantics;
 
public partial class RefReadonlyParameterTests : CSharpTestBase
{
    private const string RequiresLocationAttributeName = "RequiresLocationAttribute";
    private const string RequiresLocationAttributeNamespace = "System.Runtime.CompilerServices";
    private const string RequiresLocationAttributeQualifiedName = $"{RequiresLocationAttributeNamespace}.{RequiresLocationAttributeName}";
    private const string InAttributeQualifiedName = "System.Runtime.InteropServices.InAttribute";
 
    private const string RequiresLocationAttributeDefinition = $$"""
        namespace {{RequiresLocationAttributeNamespace}}
        {
            class {{RequiresLocationAttributeName}} : System.Attribute
            {
            }
        }
        """;
 
    private static void VerifyRequiresLocationAttributeSynthesized(ModuleSymbol module)
    {
        var attributeType = module.GlobalNamespace.GetMember<NamedTypeSymbol>(RequiresLocationAttributeQualifiedName);
        if (module is SourceModuleSymbol)
        {
            Assert.Null(attributeType);
        }
        else
        {
            Assert.NotNull(attributeType);
        }
    }
 
    private enum VerifyModifiers
    {
        None,
        In,
        RequiresLocation,
        DoNotVerify
    }
 
    private static void VerifyRefReadonlyParameter(ParameterSymbol parameter,
        bool refKind = true,
        bool metadataIn = true,
        bool attributes = true,
        VerifyModifiers customModifiers = VerifyModifiers.None,
        bool useSiteError = false,
        bool isProperty = false)
    {
        Assert.Equal(refKind, RefKind.RefReadOnlyParameter == parameter.RefKind);
 
        Assert.Equal(metadataIn, parameter.IsMetadataIn);
 
        if (attributes)
        {
            Assert.Empty(parameter.GetAttributes());
        }
 
        switch (customModifiers)
        {
            case VerifyModifiers.None:
                Assert.Empty(parameter.RefCustomModifiers);
                break;
            case VerifyModifiers.In:
                verifyModifier(parameter, InAttributeQualifiedName, optional: false);
                break;
            case VerifyModifiers.RequiresLocation:
                verifyModifier(parameter, RequiresLocationAttributeQualifiedName, optional: true);
                break;
            case VerifyModifiers.DoNotVerify:
                break;
            default:
                throw ExceptionUtilities.UnexpectedValue(customModifiers);
        }
 
        var method = parameter.ContainingSymbol;
        Assert.IsAssignableFrom(isProperty ? typeof(PropertySymbol) : typeof(MethodSymbol), method);
 
        if (useSiteError)
        {
            Assert.True(method.HasUnsupportedMetadata);
            Assert.True(method.HasUseSiteError);
            Assert.Equal((int)ErrorCode.ERR_BindToBogus, method.GetUseSiteDiagnostic().Code);
        }
        else
        {
            Assert.False(method.HasUnsupportedMetadata);
            Assert.False(method.HasUseSiteError);
        }
 
        static void verifyModifier(ParameterSymbol parameter, string qualifiedName, bool optional)
        {
            var mod = Assert.Single(parameter.RefCustomModifiers);
            Assert.Equal(optional, mod.IsOptional);
            Assert.Equal(qualifiedName, mod.Modifier.ToTestDisplayString());
        }
    }
 
    [Fact]
    public void Method()
    {
        var source = """
            class C
            {
                public void M(ref readonly int p) { }
            }
            """;
        var verifier = CompileAndVerify(source, sourceSymbolValidator: verify, symbolValidator: verify);
        verifier.VerifyDiagnostics();
 
        static void verify(ModuleSymbol m)
        {
            VerifyRequiresLocationAttributeSynthesized(m);
 
            var p = m.GlobalNamespace.GetMember<MethodSymbol>("C.M").Parameters.Single();
            VerifyRefReadonlyParameter(p);
        }
    }
 
    [Fact]
    public void ManuallyDefinedAttribute()
    {
        var source = $$"""
            class C
            {
                public void M(ref readonly int p) { }
            }
 
            namespace {{RequiresLocationAttributeNamespace}}
            {
                class {{RequiresLocationAttributeName}} : System.Attribute
                {
                }
            }
            """;
        var verifier = CompileAndVerify(source, sourceSymbolValidator: verify, symbolValidator: verify);
        verifier.VerifyDiagnostics();
 
        static void verify(ModuleSymbol m)
        {
            var attribute = m.GlobalNamespace.GetMember<NamedTypeSymbol>(RequiresLocationAttributeQualifiedName);
            Assert.NotNull(attribute);
 
            var p = m.GlobalNamespace.GetMember<MethodSymbol>("C.M").Parameters.Single();
            VerifyRefReadonlyParameter(p);
        }
    }
 
    [Fact]
    public void ManuallyAppliedAttribute()
    {
        var source = """
            using System.Runtime.CompilerServices;
            [RequiresLocation] class C
            {
                void M1([RequiresLocation] ref readonly int p) { }
                void M2([RequiresLocation] in int p) { }
                void M3([RequiresLocation] ref int p) { }
                void M4([RequiresLocation] int p) { }
                [return: RequiresLocation] int M5() => 5;
                [return: RequiresLocation] ref int M6() => throw null;
                [return: RequiresLocation] ref readonly int M7() => throw null;
                [RequiresLocation] void M8() { }
                [RequiresLocation] public int field;
                [RequiresLocation] int Property { get => @field; set => @field = value; }
            }
            """;
 
        CreateCompilation(new[] { source, RequiresLocationAttributeDefinition }, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // 0.cs(2,2): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            // [RequiresLocation] class C
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(2, 2),
            // 0.cs(4,14): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     void M1([RequiresLocation] ref readonly int p) { }
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(4, 14),
            // 0.cs(4,36): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //     void M1([RequiresLocation] ref readonly int p) { }
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "readonly").WithArguments("ref readonly parameters", "12.0").WithLocation(4, 36),
            // 0.cs(5,14): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     void M2([RequiresLocation] in int p) { }
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(5, 14),
            // 0.cs(6,14): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     void M3([RequiresLocation] ref int p) { }
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(6, 14),
            // 0.cs(7,14): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     void M4([RequiresLocation] int p) { }
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(7, 14),
            // 0.cs(8,14): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     [return: RequiresLocation] int M5() => 5;
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(8, 14),
            // 0.cs(9,14): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     [return: RequiresLocation] ref int M6() => throw null;
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(9, 14),
            // 0.cs(10,14): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     [return: RequiresLocation] ref readonly int M7() => throw null;
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(10, 14),
            // 0.cs(11,6): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     [RequiresLocation] void M8() { }
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(11, 6),
            // 0.cs(12,6): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     [RequiresLocation] public int field;
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(12, 6),
            // 0.cs(13,6): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     [RequiresLocation] int Property { get => @field; set => @field = value; }
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(13, 6));
 
        var expectedDiagnostics = new[]
        {
            // 0.cs(2,2): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            // [RequiresLocation] class C
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(2, 2),
            // 0.cs(4,14): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     void M1([RequiresLocation] ref readonly int p) { }
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(4, 14),
            // 0.cs(5,14): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     void M2([RequiresLocation] in int p) { }
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(5, 14),
            // 0.cs(6,14): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     void M3([RequiresLocation] ref int p) { }
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(6, 14),
            // 0.cs(7,14): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     void M4([RequiresLocation] int p) { }
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(7, 14),
            // 0.cs(8,14): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     [return: RequiresLocation] int M5() => 5;
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(8, 14),
            // 0.cs(9,14): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     [return: RequiresLocation] ref int M6() => throw null;
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(9, 14),
            // 0.cs(10,14): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     [return: RequiresLocation] ref readonly int M7() => throw null;
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(10, 14),
            // 0.cs(11,6): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     [RequiresLocation] void M8() { }
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(11, 6),
            // 0.cs(12,6): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     [RequiresLocation] public int field;
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(12, 6),
            // 0.cs(13,6): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     [RequiresLocation] int Property { get => @field; set => @field = value; }
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(13, 6)
        };
 
        CreateCompilation(new[] { source, RequiresLocationAttributeDefinition }, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(new[] { source, RequiresLocationAttributeDefinition }).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void ManuallyAppliedAttribute_NotDefined()
    {
        var source = """
            using System.Runtime.CompilerServices;
            class C
            {
                void M([RequiresLocation] ref int p) { }
            }
            """;
 
        CreateCompilation(source).VerifyDiagnostics(
            // (1,1): hidden CS8019: Unnecessary using directive.
            // using System.Runtime.CompilerServices;
            Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using System.Runtime.CompilerServices;").WithLocation(1, 1),
            // (4,13): error CS0246: The type or namespace name 'RequiresLocationAttribute' could not be found (are you missing a using directive or an assembly reference?)
            //     void M([RequiresLocation] ref int p) { }
            Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "RequiresLocation").WithArguments("RequiresLocationAttribute").WithLocation(4, 13),
            // (4,13): error CS0246: The type or namespace name 'RequiresLocation' could not be found (are you missing a using directive or an assembly reference?)
            //     void M([RequiresLocation] ref int p) { }
            Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "RequiresLocation").WithArguments("RequiresLocation").WithLocation(4, 13));
 
        CreateCompilation(new[] { source, RequiresLocationAttributeDefinition }).VerifyDiagnostics(
            // 0.cs(4,13): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     void M([RequiresLocation] ref int p) { }
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(4, 13));
    }
 
    [Fact]
    public void ManuallyAppliedAttributes_RequiresLocationIn()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System.Runtime.InteropServices;
            class C
            {
                void M1([RequiresLocation, In] ref int p) { }
                void M2([RequiresLocation, In] in int p) { }
                void M3([RequiresLocation, In] int p) { }
            }
            """;
        CreateCompilation(new[] { source, RequiresLocationAttributeDefinition }).VerifyDiagnostics(
            // 0.cs(5,14): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     void M1([RequiresLocation, In] ref int p) { }
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(5, 14),
            // 0.cs(6,14): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     void M2([RequiresLocation, In] in int p) { }
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(6, 14),
            // 0.cs(7,14): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     void M3([RequiresLocation, In] int p) { }
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(7, 14));
    }
 
    [Fact]
    public void ManuallyAppliedAttributes_In()
    {
        var source = """
            using System.Runtime.InteropServices;
            class C
            {
                public void M([In] ref readonly int p) { }
            }
            """;
        var verifier = CompileAndVerify(source, sourceSymbolValidator: verify, symbolValidator: verify);
        verifier.VerifyDiagnostics();
 
        static void verify(ModuleSymbol m)
        {
            VerifyRequiresLocationAttributeSynthesized(m);
 
            var p = m.GlobalNamespace.GetMember<MethodSymbol>("C.M").Parameters.Single();
            VerifyRefReadonlyParameter(p, attributes: m is not SourceModuleSymbol);
            if (m is SourceModuleSymbol)
            {
                var attribute = Assert.Single(p.GetAttributes());
                Assert.Equal("System.Runtime.InteropServices.InAttribute", attribute.AttributeClass.ToTestDisplayString());
                Assert.Empty(attribute.ConstructorArguments);
                Assert.Empty(attribute.NamedArguments);
            }
        }
    }
 
    [Fact]
    public void ManuallyAppliedAttributes_InOut()
    {
        var source = """
            using System.Runtime.InteropServices;
            class C
            {
                void M1([Out] ref readonly int p) { }
                void M2([In, Out] ref readonly int p) { }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (4,36): error CS9199: A ref readonly parameter cannot have the Out attribute.
            //     void M1([Out] ref readonly int p) { }
            Diagnostic(ErrorCode.ERR_OutAttrOnRefReadonlyParam, "p").WithLocation(4, 36),
            // (5,40): error CS9199: A ref readonly parameter cannot have the Out attribute.
            //     void M2([In, Out] ref readonly int p) { }
            Diagnostic(ErrorCode.ERR_OutAttrOnRefReadonlyParam, "p").WithLocation(5, 40));
    }
 
    [Fact]
    public void ManuallyAppliedAttributes_IsReadOnly()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System.Runtime.InteropServices;
            class C
            {
                void M1([IsReadOnly] ref readonly int p) { }
                void M2([In, IsReadOnly] ref readonly int p) { }
                void M3([In, RequiresLocation, IsReadOnly] ref int p) { }
            }
 
            namespace System.Runtime.CompilerServices
            {
                public class IsReadOnlyAttribute : System.Attribute { }
            }
            """;
        CreateCompilation(new[] { source, RequiresLocationAttributeDefinition }).VerifyDiagnostics(
            // 0.cs(5,14): error CS8335: Do not use 'System.Runtime.CompilerServices.IsReadOnlyAttribute'. This is reserved for compiler usage.
            //     void M1([IsReadOnly] ref readonly int p) { }
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsReadOnly").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(5, 14),
            // 0.cs(6,18): error CS8335: Do not use 'System.Runtime.CompilerServices.IsReadOnlyAttribute'. This is reserved for compiler usage.
            //     void M2([In, IsReadOnly] ref readonly int p) { }
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsReadOnly").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(6, 18),
            // 0.cs(7,18): error CS8335: Do not use 'System.Runtime.CompilerServices.RequiresLocationAttribute'. This is reserved for compiler usage.
            //     void M3([In, RequiresLocation, IsReadOnly] ref int p) { }
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "RequiresLocation").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(7, 18),
            // 0.cs(7,36): error CS8335: Do not use 'System.Runtime.CompilerServices.IsReadOnlyAttribute'. This is reserved for compiler usage.
            //     void M3([In, RequiresLocation, IsReadOnly] ref int p) { }
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsReadOnly").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(7, 36));
    }
 
    [Fact]
    public void BothAttributes()
    {
        // public class C
        // {
        //     public void M([IsReadOnly] ref readonly int p) { }
        // }
        var ilSource = """
            .class public auto ansi abstract sealed beforefieldinit C extends System.Object
            {
                .method public hidebysig instance void M([in] int32& p) cil managed
                {
                    .param [1]
                        .custom instance void System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = (
                            01 00 00 00
                        )
                        .custom instance void System.Runtime.CompilerServices.RequiresLocationAttribute::.ctor() = (
                            01 00 00 00
                        )
                    .maxstack 8
                    ret
                }
            }
 
            .class public auto ansi sealed beforefieldinit System.Runtime.CompilerServices.IsReadOnlyAttribute extends System.Object
            {
                .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
                {
                    .maxstack 8
                    ret
                }
            }
 
            .class public auto ansi sealed beforefieldinit System.Runtime.CompilerServices.RequiresLocationAttribute extends System.Object
            {
                .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
                {
                    .maxstack 8
                    ret
                }
            }
            """;
        var comp = CreateCompilationWithIL("", ilSource).VerifyDiagnostics();
 
        var p = comp.GlobalNamespace.GetMember<MethodSymbol>("C.M").Parameters.Single();
        VerifyRefReadonlyParameter(p, attributes: false);
        var attribute = Assert.Single(p.GetAttributes());
        Assert.Equal("System.Runtime.CompilerServices.IsReadOnlyAttribute", attribute.AttributeClass.ToTestDisplayString());
        Assert.Empty(attribute.ConstructorArguments);
        Assert.Empty(attribute.NamedArguments);
    }
 
    [Fact]
    public void ReturnParameter()
    {
        // public class C
        // {
        //     [return: RequiresLocation]
        //     public ref int M() { }
        // }
        var ilSource = """
            .class public auto ansi abstract sealed beforefieldinit C extends System.Object
            {
                .method public hidebysig instance int32& M() cil managed
                {
                    .param [0]
                        .custom instance void System.Runtime.CompilerServices.RequiresLocationAttribute::.ctor() = (
                            01 00 00 00
                        )
                    .maxstack 8
                    ret
                }
            }
 
            .class public auto ansi sealed beforefieldinit System.Runtime.CompilerServices.RequiresLocationAttribute extends System.Object
            {
                .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
                {
                    .maxstack 8
                    ret
                }
            }
            """;
        var comp = CreateCompilationWithIL("", ilSource).VerifyDiagnostics();
 
        var m = comp.GlobalNamespace.GetMember<MethodSymbol>("C.M");
        Assert.Equal(RefKind.Ref, m.RefKind);
    }
 
    [Fact]
    public void Modreq_NonVirtual()
    {
        // public class C
        // {
        //     public void M(modreq(In) ref readonly int p) { }
        // }
        var ilSource = """
            .class public auto ansi abstract sealed beforefieldinit C extends System.Object
            {
                .method public hidebysig instance void M(
                    [in] int32& modreq(System.Runtime.InteropServices.InAttribute) p
                    ) cil managed
                {
                    .param [1]
                        .custom instance void System.Runtime.CompilerServices.RequiresLocationAttribute::.ctor() = (
                            01 00 00 00
                        )
                    .maxstack 8
                    ret
                }
            }
 
            .class public auto ansi sealed beforefieldinit System.Runtime.CompilerServices.RequiresLocationAttribute extends System.Object
            {
                .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
                {
                    .maxstack 8
                    ret
                }
            }
 
            .class public auto ansi sealed beforefieldinit System.Runtime.InteropServices.InAttribute extends System.Object
            {
                .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
                {
                    .maxstack 8
                    ret
                }
            }
            """;
        var comp = CreateCompilationWithIL("", ilSource).VerifyDiagnostics();
 
        var p = comp.GlobalNamespace.GetMember<MethodSymbol>("C.M").Parameters.Single();
        VerifyRefReadonlyParameter(p, customModifiers: VerifyModifiers.In, useSiteError: true);
    }
 
    [Fact]
    public void Method_Virtual()
    {
        var source = """
            class C
            {
                public virtual void M(ref readonly int p) { }
            }
            """;
        var verifier = CompileAndVerify(source, sourceSymbolValidator: verify, symbolValidator: verify);
        verifier.VerifyDiagnostics();
 
        static void verify(ModuleSymbol m)
        {
            VerifyRequiresLocationAttributeSynthesized(m);
 
            var p = m.GlobalNamespace.GetMember<MethodSymbol>("C.M").Parameters.Single();
            VerifyRefReadonlyParameter(p, customModifiers: VerifyModifiers.In);
        }
    }
 
    [Fact]
    public void Method_Abstract()
    {
        var source = """
            abstract class C
            {
                public abstract void M(ref readonly int p);
            }
            """;
        var verifier = CompileAndVerify(source, sourceSymbolValidator: verify, symbolValidator: verify);
        verifier.VerifyDiagnostics();
 
        static void verify(ModuleSymbol m)
        {
            VerifyRequiresLocationAttributeSynthesized(m);
 
            var p = m.GlobalNamespace.GetMember<MethodSymbol>("C.M").Parameters.Single();
            VerifyRefReadonlyParameter(p, customModifiers: VerifyModifiers.In);
        }
    }
 
    [Fact]
    public void Constructor()
    {
        var source = """
            class C
            {
                public C(ref readonly int p) { }
            }
            """;
        var verifier = CompileAndVerify(source, sourceSymbolValidator: verify, symbolValidator: verify);
        verifier.VerifyDiagnostics();
 
        static void verify(ModuleSymbol m)
        {
            VerifyRequiresLocationAttributeSynthesized(m);
 
            var p = m.GlobalNamespace.GetMember<MethodSymbol>("C..ctor").Parameters.Single();
            VerifyRefReadonlyParameter(p);
        }
    }
 
    [Fact]
    public void AttributeConstructor()
    {
        var source = """
            [A(1)]
            class A : System.Attribute
            {
                A(ref readonly int x) { }
            }
            
            [B()]
            class B : System.Attribute
            {
                B(ref readonly int x = 2) { }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (1,2): error CS8358: Cannot use attribute constructor 'A.A(ref readonly int)' because it has 'in' or 'ref readonly' parameters.
            // [A(1)]
            Diagnostic(ErrorCode.ERR_AttributeCtorInParameter, "A(1)").WithArguments("A.A(ref readonly int)").WithLocation(1, 2),
            // (1,4): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter
            // [A(1)]
            Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "1").WithArguments("1").WithLocation(1, 4),
            // (7,2): error CS8358: Cannot use attribute constructor 'B.B(ref readonly int)' because it has 'in' or 'ref readonly' parameters.
            // [B()]
            Diagnostic(ErrorCode.ERR_AttributeCtorInParameter, "B()").WithArguments("B.B(ref readonly int)").WithLocation(7, 2),
            // (10,28): warning CS9521: A default value is specified for 'ref readonly' parameter 'x', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
            //     B(ref readonly int x = 2) { }
            Diagnostic(ErrorCode.WRN_RefReadonlyParameterDefaultValue, "2").WithArguments("x").WithLocation(10, 28));
    }
 
    [Fact]
    public void PrimaryConstructor_Class()
    {
        var source = """
            class C(ref readonly int p);
            """;
        var verifier = CompileAndVerify(source, sourceSymbolValidator: verify, symbolValidator: verify);
        verifier.VerifyDiagnostics(
            // (1,26): warning CS9113: Parameter 'p' is unread.
            // class C(ref readonly int p);
            Diagnostic(ErrorCode.WRN_UnreadPrimaryConstructorParameter, "p").WithArguments("p").WithLocation(1, 26));
 
        static void verify(ModuleSymbol m)
        {
            VerifyRequiresLocationAttributeSynthesized(m);
 
            var p = m.GlobalNamespace.GetMember<MethodSymbol>("C..ctor").Parameters.Single();
            VerifyRefReadonlyParameter(p);
        }
    }
 
    [Fact]
    public void PrimaryConstructor_Struct()
    {
        var source = """
            struct C(ref readonly int p);
            """;
        var verifier = CompileAndVerify(source, sourceSymbolValidator: verify, symbolValidator: verify);
        verifier.VerifyDiagnostics(
            // (1,27): warning CS9113: Parameter 'p' is unread.
            // struct C(ref readonly int p);
            Diagnostic(ErrorCode.WRN_UnreadPrimaryConstructorParameter, "p").WithArguments("p").WithLocation(1, 27));
 
        static void verify(ModuleSymbol m)
        {
            VerifyRequiresLocationAttributeSynthesized(m);
 
            var c = m.GlobalNamespace.GetTypeMember("C");
            var ctor = c.InstanceConstructors.Single(s => s.Parameters is [{ Name: "p" }]);
            var p = ctor.Parameters.Single();
            VerifyRefReadonlyParameter(p);
        }
    }
 
    [Fact]
    public void PrimaryConstructor_Record()
    {
        var source = """
            record C(ref readonly int p);
            """;
        var verifier = CompileAndVerify(new[] { source, IsExternalInitTypeDefinition },
            sourceSymbolValidator: verify, symbolValidator: verify,
            verify: Verification.FailsPEVerify);
        verifier.VerifyDiagnostics();
 
        static void verify(ModuleSymbol m)
        {
            VerifyRequiresLocationAttributeSynthesized(m);
 
            var c = m.GlobalNamespace.GetTypeMember("C");
            var ctor = c.InstanceConstructors.Single(s => s.Parameters is [{ Name: "p" }]);
            var p = ctor.Parameters.Single();
            VerifyRefReadonlyParameter(p);
        }
    }
 
    [Fact]
    public void PrimaryConstructor_RecordStruct()
    {
        var source = """
            record struct C(ref readonly int p);
            """;
        var verifier = CompileAndVerify(new[] { source, IsExternalInitTypeDefinition },
            sourceSymbolValidator: verify, symbolValidator: verify);
        verifier.VerifyDiagnostics();
 
        static void verify(ModuleSymbol m)
        {
            VerifyRequiresLocationAttributeSynthesized(m);
 
            var c = m.GlobalNamespace.GetTypeMember("C");
            var ctor = c.InstanceConstructors.Single(s => s.Parameters is [{ Name: "p" }]);
            var p = ctor.Parameters.Single();
            VerifyRefReadonlyParameter(p);
        }
    }
 
    [Fact]
    public void Operators()
    {
        var source = """
            class C
            {
                public static C operator+(ref readonly C x, C y) => x;
                public static C operator--(ref readonly C x) => x;
                public static implicit operator C(ref readonly int x) => null;
                public static explicit operator C(ref readonly short x) => null;
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (3,29): error CS0631: ref and out are not valid in this context
            //     public static C operator+(ref readonly C x, C y) => x;
            Diagnostic(ErrorCode.ERR_IllegalRefParam, "+").WithLocation(3, 29),
            // (4,29): error CS0631: ref and out are not valid in this context
            //     public static C operator--(ref readonly C x) => x;
            Diagnostic(ErrorCode.ERR_IllegalRefParam, "--").WithLocation(4, 29),
            // (5,37): error CS0631: ref and out are not valid in this context
            //     public static implicit operator C(ref readonly int x) => null;
            Diagnostic(ErrorCode.ERR_IllegalRefParam, "C").WithLocation(5, 37),
            // (6,37): error CS0631: ref and out are not valid in this context
            //     public static explicit operator C(ref readonly short x) => null;
            Diagnostic(ErrorCode.ERR_IllegalRefParam, "C").WithLocation(6, 37));
    }
 
    [Fact]
    public void ExpressionTrees_Invalid()
    {
        var source = """
            using System;
            using System.Linq.Expressions;
 
            Expression<D> e1 = (ref readonly int p) => C.M(in p);
            Expression<D> e2 = (ref readonly int p) => C.M(ref p);
            Expression<D> e3 = (ref readonly int p) => C.M(p);
            Expression<D> e4 = (int p) => C.M(in p);
            Expression<Action<int>> e5 = (int p) => C.M(out p);
 
            delegate void D(ref readonly int p);
 
            static class C
            {
                public static void M(ref readonly int x) { }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (4,38): error CS1951: An expression tree lambda may not contain a ref, in or out parameter
            // Expression<D> e1 = (ref readonly int p) => C.M(in p);
            Diagnostic(ErrorCode.ERR_ByRefParameterInExpressionTree, "p").WithLocation(4, 38),
            // (5,52): error CS8329: Cannot use variable 'p' as a ref or out value because it is a readonly variable
            // Expression<D> e2 = (ref readonly int p) => C.M(ref p);
            Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "p").WithArguments("variable", "p").WithLocation(5, 52),
            // (6,38): error CS1951: An expression tree lambda may not contain a ref, in or out parameter
            // Expression<D> e3 = (ref readonly int p) => C.M(p);
            Diagnostic(ErrorCode.ERR_ByRefParameterInExpressionTree, "p").WithLocation(6, 38),
            // (6,48): warning CS9195: Argument 1 should be passed with the 'in' keyword
            // Expression<D> e3 = (ref readonly int p) => C.M(p);
            Diagnostic(ErrorCode.WRN_ArgExpectedIn, "p").WithArguments("1").WithLocation(6, 48),
            // (7,25): error CS1676: Parameter 1 must be declared with the 'ref readonly' keyword
            // Expression<D> e4 = (int p) => C.M(in p);
            Diagnostic(ErrorCode.ERR_BadParamRef, "p").WithArguments("1", "ref readonly").WithLocation(7, 25),
            // (7,28): error CS1661: Cannot convert lambda expression to type 'Expression<D>' because the parameter types do not match the delegate parameter types
            // Expression<D> e4 = (int p) => C.M(in p);
            Diagnostic(ErrorCode.ERR_CantConvAnonMethParams, "=>").WithArguments("lambda expression", "System.Linq.Expressions.Expression<D>").WithLocation(7, 28),
            // (8,49): error CS1615: Argument 1 may not be passed with the 'out' keyword
            // Expression<Action<int>> e5 = (int p) => C.M(out p);
            Diagnostic(ErrorCode.ERR_BadArgExtraRef, "p").WithArguments("1", "out").WithLocation(8, 49));
    }
 
    [Fact]
    public void ExpressionTrees_Valid()
    {
        var source = """
            using System;
            using System.Linq.Expressions;
 
            C.E((int p) => C.M(in p));
            C.E((int p) => C.M(ref p));
            C.E((int p) => C.M(p));
            C.E((int p) => C.M(5));
 
            static class C
            {
                public static void M(ref readonly int x) => Console.Write(x);
                public static void E(Expression<Action<int>> e) => e.Compile()(4);
            }
            """;
        CompileAndVerify(source, expectedOutput: "4445").VerifyDiagnostics(
            // (6,20): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            // C.E((int p) => C.M(p));
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "p").WithArguments("1").WithLocation(6, 20),
            // (7,20): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter
            // C.E((int p) => C.M(5));
            Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "5").WithArguments("1").WithLocation(7, 20));
    }
 
    [Fact]
    public void Delegate()
    {
        var source = """
            delegate void D(ref readonly int p);
            """;
        var verifier = CompileAndVerify(source, sourceSymbolValidator: verify, symbolValidator: verify);
        verifier.VerifyDiagnostics();
 
        static void verify(ModuleSymbol m)
        {
            VerifyRequiresLocationAttributeSynthesized(m);
 
            var p = m.GlobalNamespace.GetMember<MethodSymbol>("D.Invoke").Parameters.Single();
            VerifyRefReadonlyParameter(p, customModifiers: VerifyModifiers.In);
        }
    }
 
    [Fact]
    public void Lambda()
    {
        var source = """
            var lam = (ref readonly int p) => { };
            System.Console.WriteLine(lam.GetType());
            """;
        var verifier = CompileAndVerify(source, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All),
            sourceSymbolValidator: verify, symbolValidator: verify,
            expectedOutput: "<>A{00000004}`1[System.Int32]");
        verifier.VerifyDiagnostics();
 
        static void verify(ModuleSymbol m)
        {
            VerifyRequiresLocationAttributeSynthesized(m);
 
            if (m is not SourceModuleSymbol)
            {
                var p = m.GlobalNamespace.GetMember<MethodSymbol>("Program.<>c.<<Main>$>b__0_0").Parameters.Single();
                VerifyRefReadonlyParameter(p);
            }
        }
    }
 
    [Fact]
    public void LocalFunction()
    {
        var source = """
            void local(ref readonly int p) { }
            System.Console.WriteLine(((object)local).GetType());
            """;
        var verifier = CompileAndVerify(source, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All),
            sourceSymbolValidator: verify, symbolValidator: verify,
            expectedOutput: "<>A{00000004}`1[System.Int32]");
        verifier.VerifyDiagnostics();
 
        static void verify(ModuleSymbol m)
        {
            VerifyRequiresLocationAttributeSynthesized(m);
 
            if (m is not SourceModuleSymbol)
            {
                var p = m.GlobalNamespace.GetMember<MethodSymbol>("Program.<<Main>$>g__local|0_0").Parameters.Single();
                VerifyRefReadonlyParameter(p);
            }
        }
    }
 
    [Theory]
    [InlineData("var x = (ref readonly int p) => { };")]
    [InlineData("var x = local; void local(ref readonly int p) { }")]
    public void AnonymousDelegate(string def)
    {
        var source = $"""
            {def}
            System.Console.WriteLine(((object)x).GetType());
            """;
        var verifier = CompileAndVerify(source, sourceSymbolValidator: verify, symbolValidator: verify,
            expectedOutput: "<>A{00000004}`1[System.Int32]");
        verifier.VerifyDiagnostics();
 
        static void verify(ModuleSymbol m)
        {
            VerifyRequiresLocationAttributeSynthesized(m);
 
            if (m is not SourceModuleSymbol)
            {
                var p = m.GlobalNamespace.GetMember<MethodSymbol>("<>A{00000004}.Invoke").Parameters.Single();
                VerifyRefReadonlyParameter(p,
                    // Invoke method is virtual but no modreq is emitted. https://github.com/dotnet/roslyn/issues/69079
                    useSiteError: true);
            }
        }
    }
 
    [Fact]
    public void FunctionPointer()
    {
        var source = """
            class C
            {
                public unsafe void M(delegate*<ref readonly int, void> p) { }
            }
            """;
        var verifier = CompileAndVerify(new[] { source, RequiresLocationAttributeDefinition }, options: TestOptions.UnsafeReleaseDll,
            sourceSymbolValidator: verify, symbolValidator: verify);
        verifier.VerifyDiagnostics();
 
        static void verify(ModuleSymbol m)
        {
            Assert.NotNull(m.GlobalNamespace.GetMember<NamedTypeSymbol>(RequiresLocationAttributeQualifiedName));
 
            var p = m.GlobalNamespace.GetMember<MethodSymbol>("C.M").Parameters.Single();
            var ptr = (FunctionPointerTypeSymbol)p.Type;
            var p2 = ptr.Signature.Parameters.Single();
            VerifyRefReadonlyParameter(p2, customModifiers: VerifyModifiers.RequiresLocation);
        }
    }
 
    [Fact]
    public void FunctionPointer_Modopt_CustomAttribute_In()
    {
        // public class C
        // {
        //     public unsafe delegate*<in int modopt(MyAttribute), void> D;
        // }
        var ilSource = """
            .class public auto ansi beforefieldinit C extends System.Object
            {
                .field public method void *(int32& modreq(System.Runtime.InteropServices.InAttribute) modopt(MyAttribute)) D
            }
 
            .class public auto ansi sealed beforefieldinit System.Runtime.InteropServices.InAttribute extends System.Object
            {
            }
 
            .class public auto ansi sealed beforefieldinit MyAttribute extends System.Object
            {
            }
            """;
 
        var source = """
            class D
            {
                unsafe void M(C c)
                {
                    int x = 6;
                    c.D(x);
                    c.D(ref x);
                    c.D(in x);
                }
            }
            """;
 
        CreateCompilationWithIL(source, ilSource, options: TestOptions.UnsafeDebugDll, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (7,17): error CS9194: Argument 1 may not be passed with the 'ref' keyword in language version 11.0. To pass 'ref' arguments to 'in' parameters, upgrade to language version 12.0 or greater.
            //         c.D(ref x);
            Diagnostic(ErrorCode.ERR_BadArgExtraRefLangVersion, "x").WithArguments("1", "11.0", "12.0").WithLocation(7, 17));
 
        var comp = CreateCompilationWithIL(source, ilSource, options: TestOptions.UnsafeDebugDll);
        comp.VerifyDiagnostics(
            // (7,17): warning CS9191: The 'ref' modifier for argument 1 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
            //         c.D(ref x);
            Diagnostic(ErrorCode.WRN_BadArgRef, "x").WithArguments("1").WithLocation(7, 17));
 
        var ptr = (FunctionPointerTypeSymbol)comp.GlobalNamespace.GetMember<FieldSymbol>("C.D").Type;
        var p = ptr.Signature.Parameters.Single();
        VerifyRefReadonlyParameter(p, refKind: false, attributes: false, customModifiers: VerifyModifiers.DoNotVerify);
        Assert.Equal(RefKind.In, p.RefKind);
        Assert.Empty(p.GetAttributes());
        AssertEx.SetEqual(new[]
        {
            (false, InAttributeQualifiedName),
            (true, "MyAttribute")
        }, p.RefCustomModifiers.Select(m => (m.IsOptional, m.Modifier.ToTestDisplayString())));
    }
 
    /// <summary>
    /// Demonstrates that modopt encoding of 'ref readonly' parameters in function pointers
    /// won't break older compilers (they will see the parameter as 'ref').
    /// </summary>
    [Fact]
    public void FunctionPointer_Modopt_CustomAttribute_Ref()
    {
        // public class C
        // {
        //     public unsafe delegate*<ref int modopt(MyAttribute), void> D;
        // }
        var ilSource = """
            .class public auto ansi beforefieldinit C extends System.Object
            {
                .field public method void *(int32& modopt(MyAttribute)) D
            }
 
            .class public auto ansi sealed beforefieldinit MyAttribute extends System.Object
            {
            }
            """;
 
        var source = """
            class D
            {
                unsafe void M(C c)
                {
                    int x = 6;
                    c.D(x);
                    c.D(ref x);
                    c.D(in x);
 
                    delegate*<int, void> v = c.D;
                    delegate*<ref int, void> r = c.D;
                    delegate*<in int, void> i = c.D;
                    delegate*<ref readonly int, void> rr = c.D;
                    delegate*<out int, void> o = c.D;
                }
            }
            """;
 
        CreateCompilationWithIL(new[] { source, RequiresLocationAttributeDefinition }, ilSource, options: TestOptions.UnsafeDebugDll, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // 0.cs(6,13): error CS1620: Argument 1 must be passed with the 'ref' keyword
            //         c.D(x);
            Diagnostic(ErrorCode.ERR_BadArgRef, "x").WithArguments("1", "ref").WithLocation(6, 13),
            // 0.cs(8,16): error CS1620: Argument 1 must be passed with the 'ref' keyword
            //         c.D(in x);
            Diagnostic(ErrorCode.ERR_BadArgRef, "x").WithArguments("1", "ref").WithLocation(8, 16),
            // 0.cs(10,34): error CS0266: Cannot implicitly convert type 'delegate*<ref int, void>' to 'delegate*<int, void>'. An explicit conversion exists (are you missing a cast?)
            //         delegate*<int, void> v = c.D;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "c.D").WithArguments("delegate*<ref int, void>", "delegate*<int, void>").WithLocation(10, 34),
            // 0.cs(12,37): error CS0266: Cannot implicitly convert type 'delegate*<ref int, void>' to 'delegate*<in int, void>'. An explicit conversion exists (are you missing a cast?)
            //         delegate*<in int, void> i = c.D;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "c.D").WithArguments("delegate*<ref int, void>", "delegate*<in int, void>").WithLocation(12, 37),
            // 0.cs(13,23): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //         delegate*<ref readonly int, void> rr = c.D;
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "readonly").WithArguments("ref readonly parameters", "12.0").WithLocation(13, 23),
            // 0.cs(13,48): error CS0266: Cannot implicitly convert type 'delegate*<ref int, void>' to 'delegate*<ref readonly int, void>'. An explicit conversion exists (are you missing a cast?)
            //         delegate*<ref readonly int, void> rr = c.D;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "c.D").WithArguments("delegate*<ref int, void>", "delegate*<ref readonly int, void>").WithLocation(13, 48),
            // 0.cs(14,38): error CS0266: Cannot implicitly convert type 'delegate*<ref int, void>' to 'delegate*<out int, void>'. An explicit conversion exists (are you missing a cast?)
            //         delegate*<out int, void> o = c.D;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "c.D").WithArguments("delegate*<ref int, void>", "delegate*<out int, void>").WithLocation(14, 38));
 
        var comp = CreateCompilationWithIL(new[] { source, RequiresLocationAttributeDefinition }, ilSource, options: TestOptions.UnsafeDebugDll);
        comp.VerifyDiagnostics(
            // 0.cs(6,13): error CS1620: Argument 1 must be passed with the 'ref' keyword
            //         c.D(x);
            Diagnostic(ErrorCode.ERR_BadArgRef, "x").WithArguments("1", "ref").WithLocation(6, 13),
            // 0.cs(8,16): error CS1620: Argument 1 must be passed with the 'ref' keyword
            //         c.D(in x);
            Diagnostic(ErrorCode.ERR_BadArgRef, "x").WithArguments("1", "ref").WithLocation(8, 16),
            // 0.cs(10,34): error CS0266: Cannot implicitly convert type 'delegate*<ref int, void>' to 'delegate*<int, void>'. An explicit conversion exists (are you missing a cast?)
            //         delegate*<int, void> v = c.D;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "c.D").WithArguments("delegate*<ref int, void>", "delegate*<int, void>").WithLocation(10, 34),
            // 0.cs(12,37): error CS0266: Cannot implicitly convert type 'delegate*<ref int, void>' to 'delegate*<in int, void>'. An explicit conversion exists (are you missing a cast?)
            //         delegate*<in int, void> i = c.D;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "c.D").WithArguments("delegate*<ref int, void>", "delegate*<in int, void>").WithLocation(12, 37),
            // 0.cs(13,48): error CS0266: Cannot implicitly convert type 'delegate*<ref int, void>' to 'delegate*<ref readonly int, void>'. An explicit conversion exists (are you missing a cast?)
            //         delegate*<ref readonly int, void> rr = c.D;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "c.D").WithArguments("delegate*<ref int, void>", "delegate*<ref readonly int, void>").WithLocation(13, 48),
            // 0.cs(14,38): error CS0266: Cannot implicitly convert type 'delegate*<ref int, void>' to 'delegate*<out int, void>'. An explicit conversion exists (are you missing a cast?)
            //         delegate*<out int, void> o = c.D;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "c.D").WithArguments("delegate*<ref int, void>", "delegate*<out int, void>").WithLocation(14, 38));
 
        var ptr = (FunctionPointerTypeSymbol)comp.GlobalNamespace.GetMember<FieldSymbol>("C.D").Type;
        var p = ptr.Signature.Parameters.Single();
        VerifyRefReadonlyParameter(p, refKind: false, metadataIn: false, attributes: false, customModifiers: VerifyModifiers.DoNotVerify);
        Assert.Equal(RefKind.Ref, p.RefKind);
        Assert.Empty(p.GetAttributes());
        var m = p.RefCustomModifiers.Single();
        Assert.True(m.IsOptional);
        Assert.Equal("MyAttribute", m.Modifier.ToTestDisplayString());
    }
 
    [Fact]
    public void FunctionPointer_ModreqIn_ModoptRequiresLocation()
    {
        // public class C
        // {
        //     public unsafe delegate*<in int modopt(RequiresLocation), void> D;
        // }
        var ilSource = """
            .class public auto ansi beforefieldinit C extends System.Object
            {
                .field public method void *(int32& modreq(System.Runtime.InteropServices.InAttribute) modopt(System.Runtime.CompilerServices.RequiresLocationAttribute)) D
            }
 
            .class public auto ansi sealed beforefieldinit System.Runtime.InteropServices.InAttribute extends System.Object
            {
            }
 
            .class public auto ansi sealed beforefieldinit System.Runtime.CompilerServices.RequiresLocationAttribute extends System.Object
            {
            }
            """;
 
        var source = """
            class D
            {
                void M(C c)
                {
                    int x = 6;
                    c.D(ref x);
                }
            }
            """;
 
        var comp = CreateCompilationWithIL(source, ilSource, options: TestOptions.UnsafeDebugDll);
        comp.VerifyDiagnostics(
            // (6,9): error CS0570: 'delegate*<in int, void>' is not supported by the language
            //         c.D(ref x);
            Diagnostic(ErrorCode.ERR_BindToBogus, "c.D(ref x)").WithArguments("delegate*<in int, void>").WithLocation(6, 9),
            // (6,11): error CS0570: 'C.D' is not supported by the language
            //         c.D(ref x);
            Diagnostic(ErrorCode.ERR_BindToBogus, "D").WithArguments("C.D").WithLocation(6, 11));
 
        var ptr = (FunctionPointerTypeSymbol)comp.GlobalNamespace.GetMember<FieldSymbol>("C.D").Type;
        var p = ptr.Signature.Parameters.Single();
        VerifyRefReadonlyParameter(p, refKind: false, attributes: false, customModifiers: VerifyModifiers.DoNotVerify, useSiteError: true);
        Assert.Equal(RefKind.In, p.RefKind);
        Assert.Empty(p.GetAttributes());
        AssertEx.SetEqual(new[]
        {
            (false, InAttributeQualifiedName),
            (true, RequiresLocationAttributeQualifiedName)
        }, p.RefCustomModifiers.Select(m => (m.IsOptional, m.Modifier.ToTestDisplayString())));
    }
 
    [Fact]
    public void FunctionPointer_ModoptRequiresLocation_ModreqCustom()
    {
        // public class C
        // {
        //     public unsafe delegate*<ref readonly int modreq(MyAttribute), void> D;
        // }
        var ilSource = """
            .class public auto ansi beforefieldinit C extends System.Object
            {
                .field public method void *(int32& modopt(System.Runtime.CompilerServices.RequiresLocationAttribute) modreq(MyAttribute)) D
            }
 
            .class public auto ansi sealed beforefieldinit System.Runtime.CompilerServices.RequiresLocationAttribute extends System.Object
            {
            }
 
            .class public auto ansi sealed beforefieldinit MyAttribute extends System.Object
            {
            }
            """;
 
        var source = """
            class X
            {
                void M(C c)
                {
                    int x = 111;
                    c.D(ref x);
                }
            }
            """;
 
        var comp = CreateCompilationWithIL(source, ilSource, options: TestOptions.UnsafeDebugDll).VerifyDiagnostics(
            // (6,9): error CS0570: 'delegate*<ref readonly int, void>' is not supported by the language
            //         c.D(ref x);
            Diagnostic(ErrorCode.ERR_BindToBogus, "c.D(ref x)").WithArguments("delegate*<ref readonly int, void>").WithLocation(6, 9),
            // (6,11): error CS0570: 'C.D' is not supported by the language
            //         c.D(ref x);
            Diagnostic(ErrorCode.ERR_BindToBogus, "D").WithArguments("C.D").WithLocation(6, 11));
 
        var ptr = (FunctionPointerTypeSymbol)comp.GlobalNamespace.GetMember<FieldSymbol>("C.D").Type;
        var p = ptr.Signature.Parameters.Single();
        VerifyRefReadonlyParameter(p, attributes: false, customModifiers: VerifyModifiers.DoNotVerify, useSiteError: true);
        Assert.Empty(p.GetAttributes());
        AssertEx.SetEqual(new[]
        {
            (false, "MyAttribute"),
            (true, RequiresLocationAttributeQualifiedName)
        }, p.RefCustomModifiers.Select(m => (m.IsOptional, m.Modifier.ToTestDisplayString())));
    }
 
    [Fact]
    public void FunctionPointer_ModreqRequiresLocation()
    {
        // public class C
        // {
        //     public unsafe delegate*<ref int modreq(RequiresLocation), void> D;
        // }
        var ilSource = """
            .class public auto ansi beforefieldinit C extends System.Object
            {
                .field public method void *(int32& modreq(System.Runtime.CompilerServices.RequiresLocationAttribute)) D
            }
 
            .class public auto ansi sealed beforefieldinit System.Runtime.CompilerServices.RequiresLocationAttribute extends System.Object
            {
            }
            """;
 
        var source = """
            class X
            {
                void M(C c)
                {
                    int x = 111;
                    c.D(ref x);
                }
            }
            """;
 
        var comp = CreateCompilationWithIL(source, ilSource, options: TestOptions.UnsafeDebugDll);
        comp.VerifyDiagnostics(
            // (6,9): error CS0570: 'delegate*<ref int, void>' is not supported by the language
            //         c.D(ref x);
            Diagnostic(ErrorCode.ERR_BindToBogus, "c.D(ref x)").WithArguments("delegate*<ref int, void>").WithLocation(6, 9),
            // (6,11): error CS0570: 'C.D' is not supported by the language
            //         c.D(ref x);
            Diagnostic(ErrorCode.ERR_BindToBogus, "D").WithArguments("C.D").WithLocation(6, 11));
 
        var ptr = (FunctionPointerTypeSymbol)comp.GlobalNamespace.GetMember<FieldSymbol>("C.D").Type;
        var p = ptr.Signature.Parameters.Single();
        VerifyRefReadonlyParameter(p, refKind: false, metadataIn: false, attributes: false, customModifiers: VerifyModifiers.DoNotVerify, useSiteError: true);
        Assert.Equal(RefKind.Ref, p.RefKind);
        Assert.Empty(p.GetAttributes());
        var mod = Assert.Single(p.RefCustomModifiers);
        Assert.False(mod.IsOptional);
        Assert.Equal(RequiresLocationAttributeQualifiedName, mod.Modifier.ToTestDisplayString());
    }
 
    [Fact]
    public void FunctionPointer_MissingInAttribute()
    {
        var source = """
            class C
            {
                public unsafe void M(delegate*<ref readonly int, void> p) { }
            }
            """;
        var comp = CreateCompilation(new[] { source, RequiresLocationAttributeDefinition }, options: TestOptions.UnsafeDebugDll);
        comp.MakeTypeMissing(WellKnownType.System_Runtime_InteropServices_InAttribute);
        CompileAndVerify(comp, sourceSymbolValidator: verify, symbolValidator: verify).VerifyDiagnostics();
 
        static void verify(ModuleSymbol m)
        {
            Assert.NotNull(m.GlobalNamespace.GetMember<NamedTypeSymbol>(RequiresLocationAttributeQualifiedName));
 
            var p = m.GlobalNamespace.GetMember<MethodSymbol>("C.M").Parameters.Single();
            var ptr = (FunctionPointerTypeSymbol)p.Type;
            var p2 = ptr.Signature.Parameters.Single();
            VerifyRefReadonlyParameter(p2, customModifiers: VerifyModifiers.RequiresLocation);
        }
    }
 
    [Fact]
    public void FunctionPointer_MissingRequiresLocationAttribute()
    {
        var source = """
            class C
            {
                public unsafe void M(delegate*<ref readonly int, void> p) { }
            }
            """;
        var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugDll);
        comp.VerifyDiagnostics(
            // (3,36): error CS0518: Predefined type 'System.Runtime.CompilerServices.RequiresLocationAttribute' is not defined or imported
            //     public unsafe void M(delegate*<ref readonly int, void> p) { }
            Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "ref readonly int").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(3, 36));
    }
 
    [Fact]
    public void FunctionPointer_NoAttribute_PlusNormalMethod()
    {
        var source = """
            class C
            {
                public unsafe void M1(delegate*<ref readonly int, void> p) { }
                public void M2(ref readonly int p) { }
            }
            """;
        var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugDll);
        comp.VerifyDiagnostics(
            // (3,37): error CS0518: Predefined type 'System.Runtime.CompilerServices.RequiresLocationAttribute' is not defined or imported
            //     public unsafe void M1(delegate*<ref readonly int, void> p) { }
            Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "ref readonly int").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(3, 37));
    }
 
    [Fact]
    public void FunctionPointer_InternalAttribute()
    {
        // Attribute is synthesized for Assembly1, but it's not visible to Assembly2.
        var source1 = """
            [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Assembly2")]
            internal class C
            {
                public void M(ref readonly int p) { }
            }
            """;
        var comp1 = CreateCompilation(source1, assemblyName: "Assembly1").VerifyDiagnostics();
        var comp1Ref = comp1.EmitToImageReference();
        var source2 = """
            class D
            {
                public unsafe object M(delegate*<ref readonly int, void> p)
                {
                    var c = new C();
                    int x = 5;
                    c.M(in x);
                    var attr = new System.Runtime.CompilerServices.RequiresLocationAttribute();
                    return attr;
                }
            }
            """;
        var comp2 = CreateCompilation(source2, new[] { comp1Ref }, assemblyName: "Assembly2", options: TestOptions.UnsafeDebugDll);
        comp2.VerifyDiagnostics(
            // (3,38): error CS0518: Predefined type 'System.Runtime.CompilerServices.RequiresLocationAttribute' is not defined or imported
            //     public unsafe object M(delegate*<ref readonly int, void> p)
            Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "ref readonly int").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(3, 38),
            // (8,56): error CS0234: The type or namespace name 'RequiresLocationAttribute' does not exist in the namespace 'System.Runtime.CompilerServices' (are you missing an assembly reference?)
            //         var attr = new System.Runtime.CompilerServices.RequiresLocationAttribute();
            Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "RequiresLocationAttribute").WithArguments("RequiresLocationAttribute", "System.Runtime.CompilerServices").WithLocation(8, 56));
 
        // Assembly1 defines the attribute in source and has IVT to Assembly2, so the attribute is visible to Assembly2.
        var comp1b = CreateCompilation(new[] { source1, RequiresLocationAttributeDefinition }, assemblyName: "Assembly1").VerifyDiagnostics();
        var comp1bRef = comp1b.EmitToImageReference();
        var comp2b = CreateCompilation(source2, new[] { comp1bRef }, assemblyName: "Assembly2", options: TestOptions.UnsafeDebugDll);
        comp2b.VerifyDiagnostics();
 
        // Assembly1 defines the attribute in source but doesn't have IVT to Assembly3, so the attribute isn't visible to Assembly3.
        var source3 = """
            class D
            {
                public unsafe object M(delegate*<ref readonly int, void> p)
                {
                    var attr = new System.Runtime.CompilerServices.RequiresLocationAttribute();
                    return attr;
                }
            }
            """;
        var comp3 = CreateCompilation(source3, new[] { comp1bRef }, assemblyName: "Assembly3", options: TestOptions.UnsafeDebugDll);
        comp3.VerifyDiagnostics(
            // (3,38): error CS0518: Predefined type 'System.Runtime.CompilerServices.RequiresLocationAttribute' is not defined or imported
            //     public unsafe object M(delegate*<ref readonly int, void> p)
            Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "ref readonly int").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(3, 38),
            // (5,56): error CS0122: 'RequiresLocationAttribute' is inaccessible due to its protection level
            //         var attr = new System.Runtime.CompilerServices.RequiresLocationAttribute();
            Diagnostic(ErrorCode.ERR_BadAccess, "RequiresLocationAttribute").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(5, 56));
    }
 
    [Fact]
    public void FunctionPointer_DefineManually_LaterDefinedInRuntime()
    {
        // Library defines an API with function pointer, manually declaring the attribute.
        var source1 = """
            public class C
            {
                public unsafe void M(delegate*<ref readonly int, void> f)
                {
                    int x = 123;
                    f(in x);
                }
            }
            """;
        var comp1v1 = CreateCompilation(new[] { source1, RequiresLocationAttributeDefinition }, assemblyName: "Assembly1", options: TestOptions.UnsafeReleaseDll);
        comp1v1.VerifyDiagnostics();
        verifyModoptFromAssembly(comp1v1, "Assembly1");
        var comp1v1Ref = comp1v1.EmitToImageReference();
 
        // Consumer can use the API.
        var source2 = """
            public class D
            {
                public unsafe void M()
                {
                    new C().M(&F);
                }
                static void F(ref readonly int x) => System.Console.Write("F" + x);
            }
            """;
        var comp2 = CreateCompilation(source2, new[] { comp1v1Ref }, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics();
        verifyModoptFromAssembly(comp2, "Assembly1");
        var comp2Ref = comp2.EmitToImageReference();
 
        var source3 = """
            try
            {
                new D().M();
            }
            catch (System.MissingMethodException e)
            {
                System.Console.Write(e.Message.Contains("Void C.M(Void (Int32 ByRef))"));
            }
            """;
        var verifier3v1 = CompileAndVerify(source3, new[] { comp1v1Ref, comp2Ref }, expectedOutput: "F123").VerifyDiagnostics();
        verifyModoptFromAssembly(verifier3v1.Compilation, "Assembly1");
 
        // .NET runtime declares the attribute.
        var source4 = """
            namespace System.Runtime.CompilerServices
            {
                [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
                public sealed class RequiresLocationAttribute : Attribute
                {
                }
            }
            """;
        var comp4 = CreateCompilation(source4, assemblyName: "Assembly4").VerifyDiagnostics();
        var comp4Ref = comp4.EmitToImageReference();
 
        // Library is recompiled against the newest runtime.
        var comp1v2 = CreateCompilation(source1, new[] { comp4Ref }, assemblyName: "Assembly1", options: TestOptions.UnsafeReleaseDll);
        comp1v2.VerifyDiagnostics();
        verifyModoptFromAssembly(comp1v2, "Assembly4");
        var comp1v2Ref = comp1v2.EmitToImageReference();
 
        // That breaks the consumer.
        var verifier3v2 = CompileAndVerify(source3, new[] { comp1v2Ref, comp2Ref, comp4Ref }, expectedOutput: "True").VerifyDiagnostics();
        verifyModoptFromAssembly(verifier3v2.Compilation, "Assembly4");
 
        // Unless the library adds type forwarding.
        var source5 = """
            using System.Runtime.CompilerServices;
            [assembly: TypeForwardedToAttribute(typeof(RequiresLocationAttribute))]
            """;
        var comp1v3 = CreateCompilation(new[] { source1, source5 }, new[] { comp4Ref }, assemblyName: "Assembly1", options: TestOptions.UnsafeReleaseDll);
        comp1v3.VerifyDiagnostics();
        verifyModoptFromAssembly(comp1v3, "Assembly4");
        var comp1v3Ref = comp1v3.EmitToImageReference();
        CompileAndVerify(source3, new[] { comp1v3Ref, comp2Ref, comp4Ref }, expectedOutput: "F123").VerifyDiagnostics();
 
        // Or keeps the manual attribute definition.
        var comp1v4 = CreateCompilation(new[] { source1, RequiresLocationAttributeDefinition }, new[] { comp4Ref }, assemblyName: "Assembly1", options: TestOptions.UnsafeReleaseDll);
        comp1v4.VerifyDiagnostics();
        verifyModoptFromAssembly(comp1v4, "Assembly1");
        var comp1v4Ref = comp1v4.EmitToImageReference();
        CompileAndVerify(source3, new[] { comp1v4Ref, comp2Ref, comp4Ref }, expectedOutput: "F123").VerifyDiagnostics();
 
        static void verifyModoptFromAssembly(Compilation comp, string assemblyName)
        {
            var f = ((CSharpCompilation)comp).GetMember<MethodSymbol>("C.M").Parameters.Single();
            var p = ((FunctionPointerTypeSymbol)f.Type).Signature.Parameters.Single();
            var mod = p.RefCustomModifiers.Single();
            Assert.True(mod.IsOptional);
            Assert.Equal(RequiresLocationAttributeQualifiedName, mod.Modifier.ToTestDisplayString());
            Assert.Equal(assemblyName, mod.Modifier.ContainingAssembly.Name);
        }
    }
 
    [Fact]
    public void FunctionPointer_DefineManually_AndInReference()
    {
        var source1 = """
            namespace System.Runtime.CompilerServices
            {
                [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
                public sealed class RequiresLocationAttribute : Attribute
                {
                }
            }
            """;
        var comp1 = CreateCompilation(source1, assemblyName: "Assembly1").VerifyDiagnostics();
        var comp1Ref = comp1.EmitToImageReference();
 
        // Attribute declared both in the same assembly and in a reference.
        var source2 = """
            public class C
            {
                public unsafe void M(delegate*<ref readonly int, void> f) { }
            }
            """;
        var comp2 = CreateCompilation(new[] { source2, RequiresLocationAttributeDefinition }, new[] { comp1Ref },
            assemblyName: "Assembly2", options: TestOptions.UnsafeReleaseDll);
        CompileAndVerify(comp2, sourceSymbolValidator: verify2, symbolValidator: verify2).VerifyDiagnostics();
 
        static void verify2(ModuleSymbol m)
        {
            Assert.NotNull(m.GlobalNamespace.GetMember<NamedTypeSymbol>(RequiresLocationAttributeQualifiedName));
 
            var modifier = verify(m);
            Assert.Equal("Assembly2", modifier.ContainingAssembly.Name);
        }
 
        // Attribute declared only in a reference.
        var comp3 = CreateCompilation(source2, new[] { comp1Ref }, assemblyName: "Assembly3", options: TestOptions.UnsafeReleaseDll);
        CompileAndVerify(comp3, sourceSymbolValidator: verify3, symbolValidator: verify3).VerifyDiagnostics();
 
        static void verify3(ModuleSymbol m)
        {
            Assert.Null(m.GlobalNamespace.GetMember<NamedTypeSymbol>(RequiresLocationAttributeQualifiedName));
 
            var modifier = verify(m);
            Assert.Equal("Assembly1", modifier.ContainingAssembly.Name);
        }
 
        static INamedTypeSymbol verify(ModuleSymbol m)
        {
            var p = m.GlobalNamespace.GetMember<MethodSymbol>("C.M").Parameters.Single();
            var ptr = (FunctionPointerTypeSymbol)p.Type;
            var p2 = ptr.Signature.Parameters.Single();
            VerifyRefReadonlyParameter(p2, customModifiers: VerifyModifiers.RequiresLocation);
            return p2.RefCustomModifiers.Single().Modifier;
        }
    }
 
    [Fact]
    public void FunctionPointer_Local()
    {
        var source = """
            class C
            {
                unsafe void M()
                {
                    delegate*<ref readonly int, void> p = null;
                }
            }
            """;
        var comp = CreateCompilation(new[] { source, RequiresLocationAttributeDefinition }, options: TestOptions.UnsafeDebugDll).VerifyDiagnostics();
        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
        var local = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Single();
        var symbol = model.GetDeclaredSymbol(local).GetSymbol<LocalSymbol>()!.Type as FunctionPointerTypeSymbol;
        VerifyRefReadonlyParameter(symbol!.Signature.Parameters.Single(), customModifiers: VerifyModifiers.RequiresLocation);
    }
 
    [Fact]
    public void FunctionPointer_Local_MissingRequiresLocationAttribute()
    {
        var source = """
            class C
            {
                unsafe void M()
                {
                    delegate*<ref readonly int, void> p = null;
                }
            }
            """;
        var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugDll);
        comp.VerifyDiagnostics(
            // (5,19): error CS0518: Predefined type 'System.Runtime.CompilerServices.RequiresLocationAttribute' is not defined or imported
            //         delegate*<ref readonly int, void> p = null;
            Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "ref readonly int").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(5, 19));
    }
 
    [Fact]
    public void FunctionPointer_CrossAssembly()
    {
        var source1 = """
            public class C
            {
                public unsafe delegate*<ref readonly int, void> D;
            }
            """;
        var comp1 = CreateCompilation(new[] { source1, RequiresLocationAttributeDefinition }, options: TestOptions.UnsafeDebugDll);
        comp1.VerifyDiagnostics();
        var comp1Ref = comp1.ToMetadataReference();
 
        var source2 = """
            class D
            {
                unsafe void M(C c)
                {
                    int x = 6;
                    c.D(x);
                    c.D(ref x);
                    c.D(in x);
                }
            }
            """;
        CreateCompilation(source2, new[] { comp1Ref }, parseOptions: TestOptions.Regular11, options: TestOptions.UnsafeDebugDll).VerifyDiagnostics(
            // (6,13): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //         c.D(x);
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "x").WithArguments("ref readonly parameters", "12.0").WithLocation(6, 13),
            // (8,16): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //         c.D(in x);
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "x").WithArguments("ref readonly parameters", "12.0").WithLocation(8, 16));
 
        var expectedDiagnostics = new[]
        {
            // (6,13): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         c.D(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(6, 13)
        };
 
        CreateCompilation(source2, new[] { comp1Ref }, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeDebugDll).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source2, new[] { comp1Ref }, options: TestOptions.UnsafeDebugDll).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void AttributeIL()
    {
        var source = """
            class C
            {
                public void M(ref readonly int p) { }
            }
            """;
        var verifier = CompileAndVerify(source, targetFramework: TargetFramework.NetStandard20);
        verifier.VerifyDiagnostics();
        verifier.VerifyTypeIL(RequiresLocationAttributeName, """
            .class private auto ansi sealed beforefieldinit System.Runtime.CompilerServices.RequiresLocationAttribute
                extends [netstandard]System.Attribute
            {
                .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
                	01 00 00 00
                )
                .custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = (
                	01 00 00 00
                )
                // Methods
                .method public hidebysig specialname rtspecialname 
                	instance void .ctor () cil managed 
                {
                	// Method begins at RVA 0x2050
                	// Code size 7 (0x7)
                	.maxstack 8
                	IL_0000: ldarg.0
                	IL_0001: call instance void [netstandard]System.Attribute::.ctor()
                	IL_0006: ret
                } // end of method RequiresLocationAttribute::.ctor
            } // end of class System.Runtime.CompilerServices.RequiresLocationAttribute
            """);
    }
 
    [Fact]
    public void Modifier()
    {
        var source = """
            class C
            {
                void M(ref readonly int p) => throw null;
            }
            """;
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (3,16): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //     void M(ref readonly int p) => throw null;
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "readonly").WithArguments("ref readonly parameters", "12.0").WithLocation(3, 16));
 
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics();
        var comp = CreateCompilation(source).VerifyDiagnostics();
 
        var p = comp.GlobalNamespace.GetMember<MethodSymbol>("C.M").Parameters.Single();
        VerifyRefReadonlyParameter(p);
    }
 
    [Fact]
    public void Modifier_Invalid_01()
    {
        var source = """
            class C
            {
                void M(ref params readonly int[] p) => throw null;
            }
            """;
        var comp = CreateCompilation(source).VerifyDiagnostics(
            // (3,16): error CS8328:  The parameter modifier 'params' cannot be used with 'ref'
            //     void M(ref params readonly int[] p) => throw null;
            Diagnostic(ErrorCode.ERR_BadParameterModifiers, "params").WithArguments("params", "ref").WithLocation(3, 16),
            // (3,23): error CS9190: 'readonly' modifier must be specified after 'ref'.
            //     void M(ref params readonly int[] p) => throw null;
            Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 23));
 
        var p = comp.GlobalNamespace.GetMember<MethodSymbol>("C.M").Parameters.Single();
        VerifyRefReadonlyParameter(p, refKind: false, metadataIn: false);
        Assert.Equal(RefKind.Ref, p.RefKind);
    }
 
    [Fact]
    public void Modifier_Invalid_02()
    {
        var source = """
            class C
            {
                void M(in readonly int p) => throw null;
            }
            """;
        var comp = CreateCompilation(source).VerifyDiagnostics(
            // (3,15): error CS9190: 'readonly' modifier must be specified after 'ref'.
            //     void M(in readonly int p) => throw null;
            Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 15));
 
        var p = comp.GlobalNamespace.GetMember<MethodSymbol>("C.M").Parameters.Single();
        VerifyRefReadonlyParameter(p, refKind: false);
        Assert.Equal(RefKind.In, p.RefKind);
    }
 
    [Fact]
    public void DuplicateModifier_01()
    {
        var source = """
            class C
            {
                void M(ref readonly readonly int p) { }
            }
            """;
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (3,16): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //     void M(ref readonly readonly int p) { }
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "readonly").WithArguments("ref readonly parameters", "12.0").WithLocation(3, 16),
            // (3,25): error CS1107: A parameter can only have one 'readonly' modifier
            //     void M(ref readonly readonly int p) { }
            Diagnostic(ErrorCode.ERR_DupParamMod, "readonly").WithArguments("readonly").WithLocation(3, 25));
 
        var expectedDiagnostics = new[]
        {
            // (3,25): error CS1107: A parameter can only have one 'readonly' modifier
            //     void M(ref readonly readonly int p) { }
            Diagnostic(ErrorCode.ERR_DupParamMod, "readonly").WithArguments("readonly").WithLocation(3, 25)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void DuplicateModifier_02()
    {
        var source = """
            class C
            {
                void M(readonly readonly int p) { }
            }
            """;
        var expectedDiagnostics = new[]
        {
            // (3,12): error CS9190: 'readonly' modifier must be specified after 'ref'.
            //     void M(readonly readonly int p) { }
            Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 12),
            // (3,21): error CS9190: 'readonly' modifier must be specified after 'ref'.
            //     void M(readonly readonly int p) { }
            Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 21)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void DuplicateModifier_03()
    {
        var source = """
            class C
            {
                void M(readonly ref readonly int p) { }
            }
            """;
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (3,12): error CS9190: 'readonly' modifier must be specified after 'ref'.
            //     void M(readonly ref readonly int p) { }
            Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 12),
            // (3,25): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //     void M(readonly ref readonly int p) { }
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "readonly").WithArguments("ref readonly parameters", "12.0").WithLocation(3, 25));
 
        var expectedDiagnostics = new[]
        {
            // (3,12): error CS9190: 'readonly' modifier must be specified after 'ref'.
            //     void M(readonly ref readonly int p) { }
            Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 12)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void DuplicateModifier_04()
    {
        var source = """
            class C
            {
                void M(readonly readonly ref int p) { }
            }
            """;
        var expectedDiagnostics = new[]
        {
            // (3,12): error CS9190: 'readonly' modifier must be specified after 'ref'.
            //     void M(readonly readonly ref int p) { }
            Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 12),
            // (3,21): error CS9190: 'readonly' modifier must be specified after 'ref'.
            //     void M(readonly readonly ref int p) { }
            Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 21)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void DuplicateModifier_05()
    {
        var source = """
            class C
            {
                void M(ref readonly ref readonly int p) { }
            }
            """;
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (3,16): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //     void M(ref readonly ref readonly int p) { }
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "readonly").WithArguments("ref readonly parameters", "12.0").WithLocation(3, 16),
            // (3,25): error CS1107: A parameter can only have one 'ref' modifier
            //     void M(ref readonly ref readonly int p) { }
            Diagnostic(ErrorCode.ERR_DupParamMod, "ref").WithArguments("ref").WithLocation(3, 25),
            // (3,29): error CS1107: A parameter can only have one 'readonly' modifier
            //     void M(ref readonly ref readonly int p) { }
            Diagnostic(ErrorCode.ERR_DupParamMod, "readonly").WithArguments("readonly").WithLocation(3, 29));
 
        var expectedDiagnostics = new[]
        {
            // (3,25): error CS1107: A parameter can only have one 'ref' modifier
            //     void M(ref readonly ref readonly int p) { }
            Diagnostic(ErrorCode.ERR_DupParamMod, "ref").WithArguments("ref").WithLocation(3, 25),
            // (3,29): error CS1107: A parameter can only have one 'readonly' modifier
            //     void M(ref readonly ref readonly int p) { }
            Diagnostic(ErrorCode.ERR_DupParamMod, "readonly").WithArguments("readonly").WithLocation(3, 29)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void ReadonlyWithoutRef()
    {
        var source = """
            class C
            {
                void M(readonly int p) => throw null;
            }
            """;
        var expectedDiagnostics = new[]
        {
            // (3,12): error CS9190: 'readonly' modifier must be specified after 'ref'.
            //     void M(readonly int p) => throw null;
            Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 12)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void ReadonlyWithParams()
    {
        var source = """
            class C
            {
                void M(readonly params int[] p) => throw null;
            }
            """;
        var expectedDiagnostics = new[]
        {
            // (3,12): error CS9190: 'readonly' modifier must be specified after 'ref'.
            //     void M(readonly params int[] p) => throw null;
            Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 12)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void RefReadonlyWithParams_01()
    {
        var source = """
            class C
            {
                void M(params ref readonly int[] p) => throw null;
            }
            """;
        var expectedDiagnostics = new[]
        {
            // (3,19): error CS1611: The params parameter cannot be declared as ref
            //     void M(params ref readonly int[] p) => throw null;
            Diagnostic(ErrorCode.ERR_ParamsCantBeWithModifier, "ref").WithArguments("ref").WithLocation(3, 19)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void RefReadonlyWithParams_02()
    {
        var source = """
            class C
            {
                void M(ref readonly params int[] p) => throw null;
            }
            """;
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (3,16): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //     void M(ref readonly params int[] p) => throw null;
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "readonly").WithArguments("ref readonly parameters", "12.0").WithLocation(3, 16),
            // (3,25): error CS8328:  The parameter modifier 'params' cannot be used with 'ref'
            //     void M(ref readonly params int[] p) => throw null;
            Diagnostic(ErrorCode.ERR_BadParameterModifiers, "params").WithArguments("params", "ref").WithLocation(3, 25));
 
        var expectedDiagnostics = new[]
        {
            // (3,25): error CS8328:  The parameter modifier 'params' cannot be used with 'ref'
            //     void M(ref readonly params int[] p) => throw null;
            Diagnostic(ErrorCode.ERR_BadParameterModifiers, "params").WithArguments("params", "ref").WithLocation(3, 25)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void ReadonlyWithIn()
    {
        var source = """
            class C
            {
                void M(in readonly int[] p) => throw null;
            }
            """;
        var expectedDiagnostics = new[]
        {
            // (3,15): error CS9190: 'readonly' modifier must be specified after 'ref'.
            //     void M(in readonly int[] p) => throw null;
            Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 15)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void RefReadonlyWithIn()
    {
        var source = """
            class C
            {
                void M(ref readonly in int[] p) => throw null;
            }
            """;
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (3,16): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //     void M(ref readonly in int[] p) => throw null;
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "readonly").WithArguments("ref readonly parameters", "12.0").WithLocation(3, 16),
            // (3,25): error CS8328:  The parameter modifier 'in' cannot be used with 'ref'
            //     void M(ref readonly in int[] p) => throw null;
            Diagnostic(ErrorCode.ERR_BadParameterModifiers, "in").WithArguments("in", "ref").WithLocation(3, 25));
 
        var expectedDiagnostics = new[]
        {
            // (3,25): error CS8328:  The parameter modifier 'in' cannot be used with 'ref'
            //     void M(ref readonly in int[] p) => throw null;
            Diagnostic(ErrorCode.ERR_BadParameterModifiers, "in").WithArguments("in", "ref").WithLocation(3, 25)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void ReadonlyWithOut()
    {
        var source = """
            class C
            {
                void M(out readonly int[] p) => throw null;
            }
            """;
        var expectedDiagnostics = new[]
        {
            // (3,16): error CS9190: 'readonly' modifier must be specified after 'ref'.
            //     void M(out readonly int[] p) => throw null;
            Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 16)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void RefReadonlyWithOut()
    {
        var source = """
            class C
            {
                void M(ref readonly out int[] p) => throw null;
            }
            """;
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (3,16): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //     void M(ref readonly out int[] p) => throw null;
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "readonly").WithArguments("ref readonly parameters", "12.0").WithLocation(3, 16),
            // (3,25): error CS8328:  The parameter modifier 'out' cannot be used with 'ref'
            //     void M(ref readonly out int[] p) => throw null;
            Diagnostic(ErrorCode.ERR_BadParameterModifiers, "out").WithArguments("out", "ref").WithLocation(3, 25));
 
        var expectedDiagnostics = new[]
        {
            // (3,25): error CS8328:  The parameter modifier 'out' cannot be used with 'ref'
            //     void M(ref readonly out int[] p) => throw null;
            Diagnostic(ErrorCode.ERR_BadParameterModifiers, "out").WithArguments("out", "ref").WithLocation(3, 25)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void ReadonlyWithThis()
    {
        var source = """
            static class C
            {
                public static void M(this readonly int p) => throw null;
            }
            """;
        var expectedDiagnostics = new[]
        {
            // (3,31): error CS9190: 'readonly' modifier must be specified after 'ref'.
            //     public static void M(this readonly int p) => throw null;
            Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 31)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void RefReadonlyWithThis_01()
    {
        var source = """
            static class C
            {
                public static void M(this ref readonly int p) => throw null;
            }
            """;
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (3,35): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //     public static void M(this ref readonly int p) => throw null;
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "readonly").WithArguments("ref readonly parameters", "12.0").WithLocation(3, 35));
 
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics();
        CreateCompilation(source).VerifyDiagnostics();
    }
 
    [Fact]
    public void RefReadonlyWithThis_02()
    {
        var source = """
            static class C
            {
                public static void M(ref this readonly int p) => throw null;
            }
            """;
        var expectedDiagnostics = new[]
        {
            // (3,35): error CS9190: 'readonly' modifier must be specified after 'ref'.
            //     public static void M(ref this readonly int p) => throw null;
            Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 35)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void RefReadonlyWithThis_03()
    {
        var source = """
            static class C
            {
                public static void M(ref readonly this int p) => throw null;
            }
            """;
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (3,30): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //     public static void M(ref readonly this int p) => throw null;
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "readonly").WithArguments("ref readonly parameters", "12.0").WithLocation(3, 30));
 
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics();
        CreateCompilation(source).VerifyDiagnostics();
    }
 
    [Fact]
    public void RefReadonlyWithScoped_01()
    {
        var source = """
            static class C
            {
                public static void M(scoped ref readonly int p) => throw null;
            }
            """;
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (3,37): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //     public static void M(scoped ref readonly int p) => throw null;
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "readonly").WithArguments("ref readonly parameters", "12.0").WithLocation(3, 37));
 
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics();
        CreateCompilation(source).VerifyDiagnostics();
    }
 
    [Fact]
    public void RefReadonlyWithScoped_02()
    {
        var source = """
            static class C
            {
                public static void M(ref scoped readonly int p) => throw null;
            }
            """;
        var expectedDiagnostics = new[]
        {
            // (3,30): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
            //     public static void M(ref scoped readonly int p) => throw null;
            Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(3, 30),
            // (3,37): error CS1001: Identifier expected
            //     public static void M(ref scoped readonly int p) => throw null;
            Diagnostic(ErrorCode.ERR_IdentifierExpected, "readonly").WithLocation(3, 37),
            // (3,37): error CS1003: Syntax error, ',' expected
            //     public static void M(ref scoped readonly int p) => throw null;
            Diagnostic(ErrorCode.ERR_SyntaxError, "readonly").WithArguments(",").WithLocation(3, 37),
            // (3,37): error CS9190: 'readonly' modifier must be specified after 'ref'.
            //     public static void M(ref scoped readonly int p) => throw null;
            Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 37)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void RefReadonlyWithScoped_03()
    {
        var source = """
            static class C
            {
                public static void M(readonly scoped ref int p) => throw null;
            }
            """;
        var expectedDiagnostics = new[]
        {
            // (3,26): error CS9190: 'readonly' modifier must be specified after 'ref'.
            //     public static void M(readonly scoped ref int p) => throw null;
            Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 26),
            // (3,35): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
            //     public static void M(readonly scoped ref int p) => throw null;
            Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(3, 35),
            // (3,42): error CS1001: Identifier expected
            //     public static void M(readonly scoped ref int p) => throw null;
            Diagnostic(ErrorCode.ERR_IdentifierExpected, "ref").WithLocation(3, 42),
            // (3,42): error CS1003: Syntax error, ',' expected
            //     public static void M(readonly scoped ref int p) => throw null;
            Diagnostic(ErrorCode.ERR_SyntaxError, "ref").WithArguments(",").WithLocation(3, 42)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void ReadonlyWithScoped()
    {
        var source = """
            static class C
            {
                public static void M(scoped readonly int p) => throw null;
            }
            """;
        var expectedDiagnostics = new[]
        {
            // (3,26): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
            //     public static void M(scoped readonly int p) => throw null;
            Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(3, 26),
            // (3,33): error CS1001: Identifier expected
            //     public static void M(scoped readonly int p) => throw null;
            Diagnostic(ErrorCode.ERR_IdentifierExpected, "readonly").WithLocation(3, 33),
            // (3,33): error CS1003: Syntax error, ',' expected
            //     public static void M(scoped readonly int p) => throw null;
            Diagnostic(ErrorCode.ERR_SyntaxError, "readonly").WithArguments(",").WithLocation(3, 33),
            // (3,33): error CS9190: 'readonly' modifier must be specified after 'ref'.
            //     public static void M(scoped readonly int p) => throw null;
            Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 33)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void RefReadonly_ScopedParameterName()
    {
        var source = """
            static class C
            {
                public static void M(ref readonly int scoped) => throw null;
            }
            """;
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (3,30): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //     public static void M(ref readonly int scoped) => throw null;
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "readonly").WithArguments("ref readonly parameters", "12.0").WithLocation(3, 30));
 
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics();
        CreateCompilation(source).VerifyDiagnostics();
    }
 
    [Fact]
    public void RefReadonly_ScopedTypeName()
    {
        var source = """
            struct scoped { }
            static class C
            {
                public static void M(ref readonly scoped p) => throw null;
            }
            """;
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (1,8): error CS9062: Types and aliases cannot be named 'scoped'.
            // struct scoped { }
            Diagnostic(ErrorCode.ERR_ScopedTypeNameDisallowed, "scoped").WithLocation(1, 8),
            // (4,30): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //     public static void M(ref readonly scoped p) => throw null;
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "readonly").WithArguments("ref readonly parameters", "12.0").WithLocation(4, 30));
 
        var expectedDiagnostics = new[]
        {
            // (1,8): error CS9062: Types and aliases cannot be named 'scoped'.
            // struct scoped { }
            Diagnostic(ErrorCode.ERR_ScopedTypeNameDisallowed, "scoped").WithLocation(1, 8),
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, parseOptions: TestOptions.Regular9).VerifyDiagnostics(
            // (1,8): warning CS8981: The type name 'scoped' only contains lower-cased ascii characters. Such names may become reserved for the language.
            // struct scoped { }
            Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "scoped").WithArguments("scoped").WithLocation(1, 8),
            // (4,30): error CS8773: Feature 'ref readonly parameters' is not available in C# 9.0. Please use language version 12.0 or greater.
            //     public static void M(ref readonly scoped p) => throw null;
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion9, "readonly").WithArguments("ref readonly parameters", "12.0").WithLocation(4, 30));
    }
 
    [Fact]
    public void RefReadonly_ScopedBothNames()
    {
        var source = """
            struct scoped { }
            static class C
            {
                public static void M(ref readonly scoped scoped) => throw null;
            }
            """;
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (1,8): error CS9062: Types and aliases cannot be named 'scoped'.
            // struct scoped { }
            Diagnostic(ErrorCode.ERR_ScopedTypeNameDisallowed, "scoped").WithLocation(1, 8),
            // (4,30): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //     public static void M(ref readonly scoped scoped) => throw null;
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "readonly").WithArguments("ref readonly parameters", "12.0").WithLocation(4, 30));
 
        var expectedDiagnostics = new[]
        {
            // (1,8): error CS9062: Types and aliases cannot be named 'scoped'.
            // struct scoped { }
            Diagnostic(ErrorCode.ERR_ScopedTypeNameDisallowed, "scoped").WithLocation(1, 8),
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, parseOptions: TestOptions.Regular9).VerifyDiagnostics(
            // (1,8): warning CS8981: The type name 'scoped' only contains lower-cased ascii characters. Such names may become reserved for the language.
            // struct scoped { }
            Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "scoped").WithArguments("scoped").WithLocation(1, 8),
            // (4,30): error CS8773: Feature 'ref readonly parameters' is not available in C# 9.0. Please use language version 12.0 or greater.
            //     public static void M(ref readonly scoped scoped) => throw null;
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion9, "readonly").WithArguments("ref readonly parameters", "12.0").WithLocation(4, 30));
    }
 
    [Fact]
    public void RefReadonlyParameter_Assignable_PlainArgument()
    {
        var source = """
            class C
            {
                static void M(ref readonly int p) => System.Console.Write(p);
                static void Main()
                {
                    int x = 5;
                    M(x);
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: "5");
        verifier.VerifyDiagnostics(
            // (7,11): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         M(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(7, 11));
        verifier.VerifyIL("C.Main", """
            {
              // Code size       10 (0xa)
              .maxstack  1
              .locals init (int V_0) //x
              IL_0000:  ldc.i4.5
              IL_0001:  stloc.0
              IL_0002:  ldloca.s   V_0
              IL_0004:  call       "void C.M(ref readonly int)"
              IL_0009:  ret
            }
            """);
    }
 
    [Theory, CombinatorialData]
    public void RefReadonlyParameter_Assignable_RefOrInArgument([CombinatorialValues("ref", "in")] string modifier)
    {
        var source = $$"""
            class C
            {
                static void M(ref readonly int p) => System.Console.Write(p);
                static void Main()
                {
                    int x = 5;
                    M({{modifier}} x);
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: "5");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.Main", """
            {
              // Code size       10 (0xa)
              .maxstack  1
              .locals init (int V_0) //x
              IL_0000:  ldc.i4.5
              IL_0001:  stloc.0
              IL_0002:  ldloca.s   V_0
              IL_0004:  call       "void C.M(ref readonly int)"
              IL_0009:  ret
            }
            """);
    }
 
    [Fact]
    public void RefReadonlyParameter_ReadonlyRef_PlainArgument()
    {
        var source = """
            class C
            {
                static void M(ref readonly int p) => System.Console.Write(p);
                static readonly int x = 5;
                static void Main()
                {
                    M(x);
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: "5", verify: Verification.Fails);
        verifier.VerifyDiagnostics(
            // (7,11): warning CS9195: Argument 1 should be passed with the 'in' keyword
            //         M(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedIn, "x").WithArguments("1").WithLocation(7, 11));
        verifier.VerifyIL("C.Main", """
            {
              // Code size       11 (0xb)
              .maxstack  1
              IL_0000:  ldsflda    "int C.x"
              IL_0005:  call       "void C.M(ref readonly int)"
              IL_000a:  ret
            }
            """);
    }
 
    [Fact]
    public void RefReadonlyParameter_ReadonlyRef_RefArgument()
    {
        var source = """
            class C
            {
                static void M(ref readonly int p) => System.Console.Write(p);
                static readonly int x = 5;
                static void Main()
                {
                    M(ref x);
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (7,15): error CS0199: A static readonly field cannot be used as a ref or out value (except in a static constructor)
            //         M(ref x);
            Diagnostic(ErrorCode.ERR_RefReadonlyStatic, "x").WithLocation(7, 15));
    }
 
    [Fact]
    public void RefReadonlyParameter_ReadonlyRef_InArgument()
    {
        var source = """
            class C
            {
                static void M(ref readonly int p) => System.Console.Write(p);
                static readonly int x = 5;
                static void Main()
                {
                    M(in x);
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: "5", verify: Verification.Fails);
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.Main", """
            {
              // Code size       11 (0xb)
              .maxstack  1
              IL_0000:  ldsflda    "int C.x"
              IL_0005:  call       "void C.M(ref readonly int)"
              IL_000a:  ret
            }
            """);
    }
 
    [Fact]
    public void RefReadonlyParameter_RValue_PlainArgument()
    {
        var source = """
            class C
            {
                static void M(ref readonly int p) => System.Console.Write(p);
                static void Main()
                {
                    M(5);
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: "5");
        verifier.VerifyDiagnostics(
            // (6,11): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter
            //         M(5);
            Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "5").WithArguments("1").WithLocation(6, 11));
        verifier.VerifyIL("C.Main", """
            {
              // Code size       10 (0xa)
              .maxstack  1
              .locals init (int V_0)
              IL_0000:  ldc.i4.5
              IL_0001:  stloc.0
              IL_0002:  ldloca.s   V_0
              IL_0004:  call       "void C.M(ref readonly int)"
              IL_0009:  ret
            }
            """);
    }
 
    [Fact]
    public void RefReadonlyParameter_RValue_RefOrInArgument()
    {
        var source = """
            class C
            {
                static void M(ref readonly int p) => System.Console.Write(p);
                static void Main()
                {
                    M(ref 6);
                    M(in 7);
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (6,15): error CS1510: A ref or out value must be an assignable variable
            //         M(ref 6);
            Diagnostic(ErrorCode.ERR_RefLvalueExpected, "6").WithLocation(6, 15),
            // (7,14): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
            //         M(in 7);
            Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "7").WithLocation(7, 14));
    }
 
    [Fact]
    public void RefReadonlyParameter_OutArgument()
    {
        var source = """
            class C
            {
                static void M(ref readonly int p) => System.Console.WriteLine(p);
                static readonly int x = 5;
                static void Main()
                {
                    M(out x);
                    int y;
                    M(out y);
                    M(out 6);
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (7,15): error CS0199: A static readonly field cannot be used as a ref or out value (except in a static constructor)
            //         M(out x);
            Diagnostic(ErrorCode.ERR_RefReadonlyStatic, "x").WithLocation(7, 15),
            // (9,15): error CS1615: Argument 1 may not be passed with the 'out' keyword
            //         M(out y);
            Diagnostic(ErrorCode.ERR_BadArgExtraRef, "y").WithArguments("1", "out").WithLocation(9, 15),
            // (10,15): error CS1510: A ref or out value must be an assignable variable
            //         M(out 6);
            Diagnostic(ErrorCode.ERR_RefLvalueExpected, "6").WithLocation(10, 15));
    }
 
    [Fact]
    public void PassingParameters_In_RefReadonly_PlainArgument()
    {
        var source = """
            class C
            {
                static void M1(in int p)
                {
                    M2(p);
                }
                static void M2(ref readonly int p) => System.Console.Write(p);
                static void Main() => M1(5);
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: "5");
        verifier.VerifyDiagnostics(
            // (5,12): warning CS9195: Argument 1 should be passed with the 'in' keyword
            //         M2(p);
            Diagnostic(ErrorCode.WRN_ArgExpectedIn, "p").WithArguments("1").WithLocation(5, 12));
        verifier.VerifyIL("C.M1", """
            {
              // Code size        7 (0x7)
              .maxstack  1
              IL_0000:  ldarg.0
              IL_0001:  call       "void C.M2(ref readonly int)"
              IL_0006:  ret
            }
            """);
    }
 
    [Fact]
    public void PassingParameters_In_RefReadonly_RefArgument()
    {
        var source = """
            class C
            {
                static void M1(in int p)
                {
                    M2(ref p);
                }
                static void M2(ref readonly int p) => System.Console.Write(p);
                static void Main() => M1(5);
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (5,16): error CS8329: Cannot use variable 'p' as a ref or out value because it is a readonly variable
            //         M2(ref p);
            Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "p").WithArguments("variable", "p").WithLocation(5, 16));
    }
 
    [Fact]
    public void PassingParameters_In_RefReadonly_InArgument()
    {
        var source = """
            class C
            {
                static void M1(in int p)
                {
                    M2(in p);
                }
                static void M2(ref readonly int p) => System.Console.Write(p);
                static void Main() => M1(5);
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: "5");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.M1", """
            {
              // Code size        7 (0x7)
              .maxstack  1
              IL_0000:  ldarg.0
              IL_0001:  call       "void C.M2(ref readonly int)"
              IL_0006:  ret
            }
            """);
    }
 
    [Fact]
    public void PassingParameters_RefReadonly_In_PlainArgument()
    {
        var source = """
            class C
            {
                static void M1(ref readonly int p)
                {
                    M2(p);
                }
                static void M2(in int p) => System.Console.Write(p);
                static void Main()
                {
                    int x = 5;
                    M1(ref x);
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: "5");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.M1", """
            {
              // Code size        7 (0x7)
              .maxstack  1
              IL_0000:  ldarg.0
              IL_0001:  call       "void C.M2(in int)"
              IL_0006:  ret
            }
            """);
    }
 
    [Fact]
    public void PassingParameters_RefReadonly_In_RefArgument()
    {
        var source = """
            class C
            {
                static void M1(ref readonly int p)
                {
                    M2(ref p);
                }
                static void M2(in int p) => System.Console.Write(p);
                static void Main()
                {
                    int x = 5;
                    M1(ref x);
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (5,16): error CS8329: Cannot use variable 'p' as a ref or out value because it is a readonly variable
            //         M2(ref p);
            Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "p").WithArguments("variable", "p").WithLocation(5, 16));
    }
 
    [Fact]
    public void PassingParameters_RefReadonly_In_InArgument()
    {
        var source = """
            class C
            {
                static void M1(ref readonly int p)
                {
                    M2(in p);
                }
                static void M2(in int p) => System.Console.Write(p);
                static void Main()
                {
                    int x = 5;
                    M1(ref x);
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: "5");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.M1", """
            {
              // Code size        7 (0x7)
              .maxstack  1
              IL_0000:  ldarg.0
              IL_0001:  call       "void C.M2(in int)"
              IL_0006:  ret
            }
            """);
    }
 
    [Fact]
    public void PassingParameters_RefReadonly_RefReadonly_PlainArgument()
    {
        var source = """
            class C
            {
                static void M1(ref readonly int p)
                {
                    M2(p);
                }
                static void M2(ref readonly int p) => System.Console.Write(p);
                static void Main()
                {
                    int x = 5;
                    M1(ref x);
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: "5");
        verifier.VerifyDiagnostics(
            // (5,12): warning CS9195: Argument 1 should be passed with the 'in' keyword
            //         M2(p);
            Diagnostic(ErrorCode.WRN_ArgExpectedIn, "p").WithArguments("1").WithLocation(5, 12));
        verifier.VerifyIL("C.M1", """
            {
              // Code size        7 (0x7)
              .maxstack  1
              IL_0000:  ldarg.0
              IL_0001:  call       "void C.M2(ref readonly int)"
              IL_0006:  ret
            }
            """);
    }
 
    [Fact]
    public void PassingParameters_RefReadonly_RefReadonly_RefArgument()
    {
        var source = """
            class C
            {
                static void M1(ref readonly int p)
                {
                    M2(ref p);
                }
                static void M2(ref readonly int p) => System.Console.Write(p);
                static void Main()
                {
                    int x = 5;
                    M1(ref x);
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (5,16): error CS8329: Cannot use variable 'p' as a ref or out value because it is a readonly variable
            //         M2(ref p);
            Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "p").WithArguments("variable", "p").WithLocation(5, 16));
    }
 
    [Fact]
    public void PassingParameters_RefReadonly_RefReadonly_InArgument()
    {
        var source = """
            class C
            {
                static void M1(ref readonly int p)
                {
                    M2(in p);
                }
                static void M2(ref readonly int p) => System.Console.Write(p);
                static void Main()
                {
                    int x = 5;
                    M1(ref x);
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: "5");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.M1", """
            {
              // Code size        7 (0x7)
              .maxstack  1
              IL_0000:  ldarg.0
              IL_0001:  call       "void C.M2(ref readonly int)"
              IL_0006:  ret
            }
            """);
    }
 
    [Fact]
    public void PassingParameters_RefReadonly_RefOrOut()
    {
        var source = """
            class C
            {
                static void M(ref readonly int p)
                {
                    Ref(p);
                    Ref(ref p);
                    Ref(in p);
                    Ref(out p);
 
                    Out(p);
                    Out(ref p);
                    Out(in p);
                    Out(out p);
                }
                static void Ref(ref int p) => throw null;
                static void Out(out int p) => throw null;
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (5,13): error CS1620: Argument 1 must be passed with the 'ref' keyword
            //         Ref(p);
            Diagnostic(ErrorCode.ERR_BadArgRef, "p").WithArguments("1", "ref").WithLocation(5, 13),
            // (6,17): error CS8329: Cannot use variable 'p' as a ref or out value because it is a readonly variable
            //         Ref(ref p);
            Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "p").WithArguments("variable", "p").WithLocation(6, 17),
            // (7,16): error CS1620: Argument 1 must be passed with the 'ref' keyword
            //         Ref(in p);
            Diagnostic(ErrorCode.ERR_BadArgRef, "p").WithArguments("1", "ref").WithLocation(7, 16),
            // (8,17): error CS8329: Cannot use variable 'p' as a ref or out value because it is a readonly variable
            //         Ref(out p);
            Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "p").WithArguments("variable", "p").WithLocation(8, 17),
            // (10,13): error CS1620: Argument 1 must be passed with the 'out' keyword
            //         Out(p);
            Diagnostic(ErrorCode.ERR_BadArgRef, "p").WithArguments("1", "out").WithLocation(10, 13),
            // (11,17): error CS8329: Cannot use variable 'p' as a ref or out value because it is a readonly variable
            //         Out(ref p);
            Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "p").WithArguments("variable", "p").WithLocation(11, 17),
            // (12,16): error CS1620: Argument 1 must be passed with the 'out' keyword
            //         Out(in p);
            Diagnostic(ErrorCode.ERR_BadArgRef, "p").WithArguments("1", "out").WithLocation(12, 16),
            // (13,17): error CS8329: Cannot use variable 'p' as a ref or out value because it is a readonly variable
            //         Out(out p);
            Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "p").WithArguments("variable", "p").WithLocation(13, 17));
    }
 
    [Fact]
    public void RefReturn_ReadonlyToMutable()
    {
        var source = """
            class C
            {
                ref int M(ref readonly int x)
                {
                    return ref x;
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (5,20): error CS8333: Cannot return variable 'x' by writable reference because it is a readonly variable
            //         return ref x;
            Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "x").WithArguments("variable", "x").WithLocation(5, 20));
    }
 
    [Fact]
    public void RefReturn_ReadonlyToReadonly()
    {
        var source = """
            class C
            {
                ref readonly int M(ref readonly int x)
                {
                    return ref x;
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics();
    }
 
    [Fact]
    public void RefReturn_ReadonlyFromMutable()
    {
        var source = """
            class C
            {
                ref int M1() => throw null;
                void M2(ref readonly int x) { }
                void M3()
                {
                    M2(M1());
                    M2(in M1());
                    M2(ref M1());
                    M2(out M1());
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (7,12): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         M2(M1());
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "M1()").WithArguments("1").WithLocation(7, 12),
            // (10,16): error CS1615: Argument 1 may not be passed with the 'out' keyword
            //         M2(out M1());
            Diagnostic(ErrorCode.ERR_BadArgExtraRef, "M1()").WithArguments("1", "out").WithLocation(10, 16));
    }
 
    [Fact]
    public void RefReturn_ReadonlyFromReadonly()
    {
        var source = """
            class C
            {
                ref readonly int M1() => throw null;
                void M2(ref readonly int x) { }
                void M3()
                {
                    M2(M1());
                    M2(in M1());
                    M2(ref M1());
                    M2(out M1());
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (7,12): warning CS9195: Argument 1 should be passed with the 'in' keyword
            //         M2(M1());
            Diagnostic(ErrorCode.WRN_ArgExpectedIn, "M1()").WithArguments("1").WithLocation(7, 12),
            // (9,16): error CS8329: Cannot use method 'M1' as a ref or out value because it is a readonly variable
            //         M2(ref M1());
            Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "M1()").WithArguments("method", "M1").WithLocation(9, 16),
            // (10,16): error CS8329: Cannot use method 'M1' as a ref or out value because it is a readonly variable
            //         M2(out M1());
            Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "M1()").WithArguments("method", "M1").WithLocation(10, 16));
    }
 
    [Fact]
    public void RefAssignment()
    {
        var source = """
            ref struct C
            {
                public C(ref readonly int p)
                {
                    r = ref p; // 1
                    rro = ref p;
                    ror = ref p; // 2
                    rorro = ref p;
                }
 
                ref int r;
                ref readonly int rro;
                readonly ref int ror;
                readonly ref readonly int rorro;
 
                void M(ref readonly int p)
                {
                    ref int a = ref p; // 3
                    ref readonly int b = ref p;
                    r = ref p; // 4
                    rro = ref p; // 5
                    ror = ref p; // 6
                    rorro = ref p; // 7
                }
            }
            """;
        CreateCompilation(source, targetFramework: TargetFramework.Net70).VerifyDiagnostics(
            // (5,17): error CS8331: Cannot assign to variable 'p' or use it as the right hand side of a ref assignment because it is a readonly variable
            //         r = ref p; // 1
            Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "p").WithArguments("variable", "p").WithLocation(5, 17),
            // (7,19): error CS8331: Cannot assign to variable 'p' or use it as the right hand side of a ref assignment because it is a readonly variable
            //         ror = ref p; // 2
            Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "p").WithArguments("variable", "p").WithLocation(7, 19),
            // (18,25): error CS8329: Cannot use variable 'p' as a ref or out value because it is a readonly variable
            //         ref int a = ref p; // 3
            Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "p").WithArguments("variable", "p").WithLocation(18, 25),
            // (20,17): error CS8331: Cannot assign to variable 'p' or use it as the right hand side of a ref assignment because it is a readonly variable
            //         r = ref p; // 4
            Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "p").WithArguments("variable", "p").WithLocation(20, 17),
            // (21,9): error CS9079: Cannot ref-assign 'p' to 'rro' because 'p' can only escape the current method through a return statement.
            //         rro = ref p; // 5
            Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "rro = ref p").WithArguments("rro", "p").WithLocation(21, 9),
            // (22,9): error CS0191: A readonly field cannot be assigned to (except in a constructor or init-only setter of the type in which the field is defined or a variable initializer)
            //         ror = ref p; // 6
            Diagnostic(ErrorCode.ERR_AssgReadonly, "ror").WithLocation(22, 9),
            // (23,9): error CS0191: A readonly field cannot be assigned to (except in a constructor or init-only setter of the type in which the field is defined or a variable initializer)
            //         rorro = ref p; // 7
            Diagnostic(ErrorCode.ERR_AssgReadonly, "rorro").WithLocation(23, 9));
    }
 
    [Theory, CombinatorialData]
    public void RefAssignment_BetweenParameters(
        [CombinatorialValues("in", "ref readonly", "ref")] string modifier1,
        [CombinatorialValues("in", "ref readonly", "ref")] string modifier2)
    {
        var source = $$"""
            class C
            {
                static void M1({{modifier1}} int x, {{modifier2}} int y)
                {
                    x = ref y;
                }
                static void M2({{modifier1}} int x, {{modifier2}} int y)
                {
                    System.Console.WriteLine(x + " " + y);
                    x = ref y;
                    System.Console.WriteLine(x + " " + y);
                }
                static void Main()
                {
                    int x = 5;
                    int y = 6;
                    M2({{getArgumentModifier(modifier1)}} x, {{getArgumentModifier(modifier2)}} y);
                }
            }
            """;
 
        if (modifier1 == "ref" && modifier2 != "ref")
        {
            CreateCompilation(source).VerifyDiagnostics(
                // (5,17): error CS8331: Cannot assign to variable 'y' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         x = ref y;
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "y").WithArguments("variable", "y").WithLocation(5, 17),
                // (10,17): error CS8331: Cannot assign to variable 'y' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         x = ref y;
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "y").WithArguments("variable", "y").WithLocation(10, 17));
        }
        else
        {
            var verifier = CompileAndVerify(source, expectedOutput: """
                5 6
                6 6
                """);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.M1", """
                {
                  // Code size        4 (0x4)
                  .maxstack  1
                  IL_0000:  ldarg.1
                  IL_0001:  starg.s    V_0
                  IL_0003:  ret
                }
                """);
        }
 
        static string getArgumentModifier(string parameterModifier)
        {
            return parameterModifier switch
            {
                "ref" => "ref",
                _ => "in",
            };
        }
    }
 
    [Theory, CombinatorialData]
    public void RefAssignment_BetweenParameters_Struct(
        [CombinatorialValues("in", "ref readonly", "ref")] string modifier1,
        [CombinatorialValues("in", "ref readonly", "ref")] string modifier2)
    {
        var source = $$"""
            struct S(int v)
            {
                public int V = v;
            }
            class C
            {
                static int M1({{modifier1}} S x, {{modifier2}} S y)
                {
                    return (x = ref y).V;
                }
                static void M2({{modifier1}} S x, {{modifier2}} S y)
                {
                    System.Console.WriteLine(x.V + " " + y.V);
                    System.Console.WriteLine((x = ref y).V);
                    System.Console.WriteLine(x.V + " " + y.V);
                }
                static void Main()
                {
                    S x = new S(5);
                    S y = new S(6);
                    M2({{getArgumentModifier(modifier1)}} x, {{getArgumentModifier(modifier2)}} y);
                }
            }
            """;
 
        if (modifier1 == "ref" && modifier2 != "ref")
        {
            CreateCompilation(source).VerifyDiagnostics(
                // (9,25): error CS8331: Cannot assign to variable 'y' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         return (x = ref y).V;
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "y").WithArguments("variable", "y").WithLocation(9, 25),
                // (14,43): error CS8331: Cannot assign to variable 'y' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         System.Console.WriteLine((x = ref y).V);
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "y").WithArguments("variable", "y").WithLocation(14, 43));
        }
        else
        {
            var verifier = CompileAndVerify(source, expectedOutput: """
                5 6
                6
                6 6
                """);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.M1", """
                {
                  // Code size       10 (0xa)
                  .maxstack  2
                  IL_0000:  ldarg.1
                  IL_0001:  dup
                  IL_0002:  starg.s    V_0
                  IL_0004:  ldfld      "int S.V"
                  IL_0009:  ret
                }
                """);
        }
 
        static string getArgumentModifier(string parameterModifier)
        {
            return parameterModifier switch
            {
                "ref" => "ref",
                _ => "in",
            };
        }
    }
 
    [ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.RestrictedTypesNeedDesktop)]
    public void RefReadonlyParameter_Arglist()
    {
        var source = """
            class C
            {
                static void M(ref readonly int p, __arglist) => System.Console.WriteLine(p);
                static void Main()
                {
                    int x = 111;
                    M(x, __arglist(x));
                    M(ref x, __arglist(x));
                    M(in x, __arglist(x));
                }
            }
            """;
        var verifier = CompileAndVerify(source, verify: Verification.FailsILVerify, expectedOutput: """
            111
            111
            111
            """);
        verifier.VerifyDiagnostics(
            // (7,11): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         M(x, __arglist(x));
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(7, 11));
    }
 
    [Fact]
    public void RefReadonlyParameter_Arglist_OutArgument()
    {
        var source = """
            class C
            {
                static void M(ref readonly int p, __arglist) => System.Console.WriteLine(p);
                static void Main()
                {
                    int x = 111;
                    M(out x, __arglist(x));
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (7,15): error CS1615: Argument 1 may not be passed with the 'out' keyword
            //         M(out x, __arglist(x));
            Diagnostic(ErrorCode.ERR_BadArgExtraRef, "x").WithArguments("1", "out").WithLocation(7, 15));
    }
 
    [Fact]
    public void RefReadonlyParameter_CrossAssembly()
    {
        var source1 = """
            public class C
            {
                public void M(ref readonly int p) => System.Console.Write(p);
                void M2()
                {
                    int x = 5;
                    M(x);
                    M(ref x);
                    M(in x);
                }
            }
            """;
        var comp1 = CreateCompilation(source1).VerifyDiagnostics(
            // (7,11): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         M(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(7, 11));
        var comp1Ref = comp1.ToMetadataReference();
 
        var source2 = """
            class D
            {
                void M(C c)
                {
                    int x = 6;
                    c.M(x);
                    c.M(ref x);
                    c.M(in x);
                }
            }
            """;
        CreateCompilation(source2, new[] { comp1Ref }, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (6,13): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //         c.M(x);
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "x").WithArguments("ref readonly parameters", "12.0").WithLocation(6, 13),
            // (8,16): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //         c.M(in x);
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "x").WithArguments("ref readonly parameters", "12.0").WithLocation(8, 16));
 
        var expectedDiagnostics = new[]
        {
            // (6,13): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         c.M(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(6, 13)
        };
 
        CreateCompilation(source2, new[] { comp1Ref }, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source2, new[] { comp1Ref }).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void RefReadonlyParameter_Ctor()
    {
        var source = """
            class C
            {
                private C(ref readonly int p) => System.Console.Write(p);
                static void Main()
                {
                    int x = 5;
                    new C(x);
                    new C(ref x);
                    new C(in x);
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: "555").VerifyDiagnostics(
            // (7,15): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         new C(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(7, 15));
    }
 
    [Fact]
    public void RefReadonlyParameter_Ctor_OutArgument()
    {
        var source = """
            class C
            {
                private C(ref readonly int p) => throw null;
                static void Main()
                {
                    int x = 5;
                    new C(out x);
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (7,19): error CS1615: Argument 1 may not be passed with the 'out' keyword
            //         new C(out x);
            Diagnostic(ErrorCode.ERR_BadArgExtraRef, "x").WithArguments("1", "out").WithLocation(7, 19));
    }
 
    [Fact]
    public void RefReadonlyParameter_Indexer()
    {
        var source = """
            class C
            {
                int this[ref readonly int p]
                {
                    get
                    {
                        System.Console.Write(p);
                        return p;
                    }
                }
 
                static void Main()
                {
                    var c = new C();
                    int x = 5;
                    _ = c[x];
                    _ = c[ref x];
                    _ = c[in x];
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: "555").VerifyDiagnostics(
            // (16,15): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         _ = c[x];
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(16, 15));
    }
 
    [Fact]
    public void RefReadonlyParameter_Indexer_OutArgument()
    {
        var source = """
            class C
            {
                int this[ref readonly int p] => throw null;
                static void Main()
                {
                    var c = new C();
                    int x = 5;
                    _ = c[out x];
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (8,19): error CS1615: Argument 1 may not be passed with the 'out' keyword
            //         _ = c[out x];
            Diagnostic(ErrorCode.ERR_BadArgExtraRef, "x").WithArguments("1", "out").WithLocation(8, 19));
    }
 
    [Fact]
    public void RefReadonlyParameter_FunctionPointer()
    {
        var source = """
            class C
            {
                static void M(ref readonly int p) => System.Console.Write(p);
                static unsafe void Main()
                {
                    delegate*<ref readonly int, void> f = &M;
                    int x = 5;
                    f(x);
                    f(ref x);
                    f(in x);
                }
            }
            """;
        var verifier = CompileAndVerify(new[] { source, RequiresLocationAttributeDefinition },
            expectedOutput: "555", options: TestOptions.UnsafeReleaseExe, verify: Verification.Fails);
        verifier.VerifyDiagnostics(
            // (8,11): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         f(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(8, 11));
    }
 
    [Fact]
    public void RefReadonlyParameter_FunctionPointer_OutArgument()
    {
        var source = """
            class C
            {
                static void M(ref readonly int p) => throw null;
                static unsafe void Main()
                {
                    delegate*<ref readonly int, void> f = &M;
                    int x = 5;
                    f(out x);
                }
            }
            """;
        CreateCompilation(new[] { source, RequiresLocationAttributeDefinition }, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(
            // (8,15): error CS1615: Argument 1 may not be passed with the 'out' keyword
            //         f(out x);
            Diagnostic(ErrorCode.ERR_BadArgExtraRef, "x").WithArguments("1", "out").WithLocation(8, 15));
    }
 
    [Fact]
    public void RefReadonlyParameter_NamedArguments()
    {
        var source = """
            class C
            {
                static void M(in int a, ref readonly int b)
                {
                    System.Console.Write(a);
                    System.Console.Write(b);
                }
                static void Main()
                {
                    int x = 5;
                    int y = 6;
                    M(b: x, a: y); // 1
                    M(b: x, a: in y); // 2
                    M(a: x, y); // 3
                    M(a: x, in y); // 4
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: "65655656").VerifyDiagnostics(
            // (12,14): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         M(b: x, a: y); // 1
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(12, 14),
            // (13,14): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         M(b: x, a: in y); // 2
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(13, 14),
            // (14,17): warning CS9192: Argument 2 should be passed with 'ref' or 'in' keyword
            //         M(a: x, y); // 3
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "y").WithArguments("2").WithLocation(14, 17));
    }
 
    [Fact]
    public void RefReadonlyParameter_RefArgument_OverloadResolution_01()
    {
        var source = """
            class C
            {
                static string M1(string s, ref int i) => "string" + i;
                static string M1(object o, in int i) => "object" + i;
                static string M1(C c, ref readonly int i) => "c" + i;
                static void Main()
                {
                    int i = 5;
                    System.Console.WriteLine(M1(null, ref i));
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (9,34): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(string, ref int)' and 'C.M1(C, ref readonly int)'
            //         System.Console.WriteLine(M1(null, ref i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(string, ref int)", "C.M1(C, ref readonly int)").WithLocation(9, 34));
    }
 
    [Fact]
    public void RefReadonlyParameter_RefArgument_OverloadResolution_01_Ctor()
    {
        var source = """
            class C
            {
                private C(string s, ref int i) => System.Console.WriteLine("string" + i);
                private C(object o, in int i) => System.Console.WriteLine("object" + i);
                private C(C c, ref readonly int i) => System.Console.WriteLine("c" + i);
                static void Main()
                {
                    int i = 5;
                    new C(null, ref i);
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (9,13): error CS0121: The call is ambiguous between the following methods or properties: 'C.C(string, ref int)' and 'C.C(C, ref readonly int)'
            //         new C(null, ref i);
            Diagnostic(ErrorCode.ERR_AmbigCall, "C").WithArguments("C.C(string, ref int)", "C.C(C, ref readonly int)").WithLocation(9, 13));
    }
 
    [Fact]
    public void RefReadonlyParameter_RefArgument_OverloadResolution_02()
    {
        var source = """
            class C
            {
                static string M1(string s, ref int i) => "string" + i;
                static string M1(object o, in int i) => "object" + i;
                static string M1(C c, ref readonly int i) => "c" + i;
                static void Main()
                {
                    int i = 5;
                    System.Console.WriteLine(M1(default(string), ref i));
                    System.Console.WriteLine(M1(default(object), ref i));
                    System.Console.WriteLine(M1(default(C), ref i));
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: """
            string5
            object5
            c5
            """).VerifyDiagnostics(
            // (10,58): warning CS9191: The 'ref' modifier for argument 2 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
            //         System.Console.WriteLine(M1(default(object), ref i));
            Diagnostic(ErrorCode.WRN_BadArgRef, "i").WithArguments("2").WithLocation(10, 58));
    }
 
    [Fact]
    public void RefReadonlyParameter_RefArgument_OverloadResolution_02_Ctor()
    {
        var source = """
            class C
            {
                private C(string s, ref int i) => System.Console.WriteLine("string" + i);
                private C(object o, in int i) => System.Console.WriteLine("object" + i);
                static void Main()
                {
                    int i = 5;
                    new C(default(object), ref i);
                }
            }
            """;
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (8,15): error CS1503: Argument 1: cannot convert from 'object' to 'string'
            //         new C(default(object), ref i);
            Diagnostic(ErrorCode.ERR_BadArgType, "default(object)").WithArguments("1", "object", "string").WithLocation(8, 15));
 
        var expectedDiagnostics = new[]
        {
            // (8,36): warning CS9190: The 'ref' modifier for argument 2 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
            //         new C(default(object), ref i);
            Diagnostic(ErrorCode.WRN_BadArgRef, "i").WithArguments("2").WithLocation(8, 36)
        };
 
        CompileAndVerify(source, expectedOutput: "object5", parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CompileAndVerify(source, expectedOutput: "object5").VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void RefReadonlyParameter_RefArgument_OverloadResolution_03()
    {
        var source = """
            class C
            {
                static string M1(object o, in int i) => "object" + i;
                static string M1(C c, ref readonly int i) => "c" + i;
                static void Main()
                {
                    int i = 5;
                    System.Console.WriteLine(M1(null, ref i));
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: "c5").VerifyDiagnostics();
    }
 
    [Fact]
    public void RefReadonlyParameter_RefArgument_OverloadResolution_03_Ctor()
    {
        var source = """
            class C
            {
                private C(object o, in int i) => System.Console.WriteLine("object" + i);
                private C(C c, ref readonly int i) => System.Console.WriteLine("c" + i);
                static void Main()
                {
                    int i = 5;
                    new C(null, ref i);
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: "c5").VerifyDiagnostics();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_01()
    {
        var source = """
            interface I1 { }
            interface I2 { }
            class C
            {
                static string M1(I1 o, in int i) => " 1" + i;
                static string M1(I2 o, ref readonly int i) => " 2" + i;
                static void Main()
                {
                    int i = 5;
                    System.Console.Write(M1(null, ref i));
                    System.Console.Write(M1(null, in i));
                    System.Console.Write(M1(null, i));
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (10,30): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I1, in int)' and 'C.M1(I2, ref readonly int)'
            //         System.Console.Write(M1(null, ref i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I1, in int)", "C.M1(I2, ref readonly int)").WithLocation(10, 30),
            // (11,30): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I1, in int)' and 'C.M1(I2, ref readonly int)'
            //         System.Console.Write(M1(null, in i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I1, in int)", "C.M1(I2, ref readonly int)").WithLocation(11, 30),
            // (12,30): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I1, in int)' and 'C.M1(I2, ref readonly int)'
            //         System.Console.Write(M1(null, i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I1, in int)", "C.M1(I2, ref readonly int)").WithLocation(12, 30));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_02()
    {
        var source1 = """
            interface I1 { }
            interface I2 { }
            class C
            {
                public static string M1(I1 o, ref int i) => " 1" + i;
                public static string M1(I2 o, ref readonly int i) => " 2" + i;
            }
            """;
 
        var source2 = """
            int i = 5;
            System.Console.Write(C.M1(null, ref i));
            """;
 
        CreateCompilation(new[] { source1, source2 }).VerifyDiagnostics(
            // 1.cs(2,24): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I1, ref int)' and 'C.M1(I2, ref readonly int)'
            // System.Console.Write(C.M1(null, ref i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I1, ref int)", "C.M1(I2, ref readonly int)").WithLocation(2, 24));
 
        var source3 = """
            int i = 5;
            System.Console.Write(C.M1(null, in i));
            System.Console.Write(C.M1(null, i));
            """;
 
        CompileAndVerify(new[] { source1, source3 }, expectedOutput: "25 25").VerifyDiagnostics(
            // 1.cs(3,33): warning CS9192: Argument 2 should be passed with 'ref' or 'in' keyword
            // System.Console.Write(C.M1(null, i));
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "i").WithArguments("2").WithLocation(3, 33));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_03()
    {
        var source = """
            interface I1 { }
            interface I2 { }
            class C
            {
                static string M1(I1 o, int i) => " 1" + i;
                static string M1(I2 o, ref readonly int i) => " 2" + i;
                static void Main()
                {
                    int i = 5;
                    System.Console.Write(M1(null, ref i));
                    System.Console.Write(M1(null, in i));
                    System.Console.Write(M1(null, i));
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: "25 25 15").VerifyDiagnostics();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_04()
    {
        var source = """
            interface I1 { }
            interface I2 { }
            interface I3 { }
            class C
            {
                static string M1(I1 o, in int i) => " 1" + i;
                static string M1(I2 o, ref int i) => " 2" + i;
                static string M1(I3 o, ref readonly int i) => " 3" + i;
                static void Main()
                {
                    int i = 5;
                    System.Console.Write(M1(null, ref i));
                    System.Console.Write(M1(null, in i));
                    System.Console.Write(M1(null, i));
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (12,30): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I1, in int)' and 'C.M1(I2, ref int)'
            //         System.Console.Write(M1(null, ref i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I1, in int)", "C.M1(I2, ref int)").WithLocation(12, 30),
            // (13,30): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I1, in int)' and 'C.M1(I3, ref readonly int)'
            //         System.Console.Write(M1(null, in i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I1, in int)", "C.M1(I3, ref readonly int)").WithLocation(13, 30),
            // (14,30): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I1, in int)' and 'C.M1(I3, ref readonly int)'
            //         System.Console.Write(M1(null, i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I1, in int)", "C.M1(I3, ref readonly int)").WithLocation(14, 30));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_05()
    {
        var source1 = """
            interface I1 { }
            interface I2 { }
            interface I3 { }
            interface I4 { }
            class C
            {
                public static string M1(I1 o, int i) => " 1" + i;
                public static string M1(I2 o, in int i) => " 2" + i;
                public static string M1(I3 o, ref int i) => " 3" + i;
                public static string M1(I4 o, ref readonly int i) => " 4" + i;
            }
            """;
 
        var source2 = """
            int i = 5;
            System.Console.Write(C.M1(null, ref i));
            System.Console.Write(C.M1(null, in i));
            """;
 
        CreateCompilation(new[] { source1, source2 }).VerifyDiagnostics(
            // 1.cs(2,24): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I2, in int)' and 'C.M1(I3, ref int)'
            // System.Console.Write(C.M1(null, ref i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I2, in int)", "C.M1(I3, ref int)").WithLocation(2, 24),
            // 1.cs(3,24): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I2, in int)' and 'C.M1(I4, ref readonly int)'
            // System.Console.Write(C.M1(null, in i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I2, in int)", "C.M1(I4, ref readonly int)").WithLocation(3, 24));
 
        var source3 = """
            int i = 5;
            System.Console.Write(C.M1(null, i));
            """;
 
        CompileAndVerify(new[] { source1, source3 }, expectedOutput: "15").VerifyDiagnostics();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_06()
    {
        var source = """
            interface I1 { }
            interface I2 { }
            class C
            {
                static string M1(I1 o, in int i) => " 1" + i;
                static string M1(I2 o, ref int i) => " 2" + i;
                static void Main()
                {
                    int i = 5;
                    System.Console.Write(M1(null, ref i));
                    System.Console.Write(M1(null, in i));
                    System.Console.Write(M1(null, i));
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: "25 15 15", parseOptions: TestOptions.Regular11).VerifyDiagnostics();
 
        var expectedDiagnostics = new[]
        {
            // (10,30): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I1, in int)' and 'C.M1(I2, ref int)'
            //         System.Console.Write(M1(null, ref i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I1, in int)", "C.M1(I2, ref int)").WithLocation(10, 30)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Theory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_07([CombinatorialValues(LanguageVersion.CSharp11, LanguageVersion.CSharp12, LanguageVersion.Preview)] LanguageVersion languageVersion)
    {
        var source1 = """
            interface I1 { }
            interface I2 { }
            class C
            {
                public static string M1(I1 o, in int i, ref int j) => " 1" + i + j;
                public static string M1(I2 o, ref int i, in int j) => " 2" + i + j;
            }
            """;
 
        var source2 = """
            int i = 5;
            int j = 6;
            System.Console.Write(C.M1(null, ref i, ref j));
            System.Console.Write(C.M1(null, in i, in j));
            System.Console.Write(C.M1(null, in i, j));
            System.Console.Write(C.M1(null, i, in j));
            System.Console.Write(C.M1(null, i, j));
            """;
 
        CreateCompilation(new[] { source1, source2 }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
            languageVersion == LanguageVersion.CSharp11
                // 1.cs(3,37): error CS9194: Argument 2 may not be passed with the 'ref' keyword in language version 11.0. To pass 'ref' arguments to 'in' parameters, upgrade to language version 12.0 or greater.
                // System.Console.Write(C.M1(null, ref i, ref j));
                ? Diagnostic(ErrorCode.ERR_BadArgExtraRefLangVersion, "i").WithArguments("2", "11.0", "12.0").WithLocation(3, 37)
                // 1.cs(3,24): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I1, in int, ref int)' and 'C.M1(I2, ref int, in int)'
                // System.Console.Write(C.M1(null, ref i, ref j));
                : Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I1, in int, ref int)", "C.M1(I2, ref int, in int)").WithLocation(3, 24),
            // 1.cs(4,42): error CS1620: Argument 3 must be passed with the 'ref' keyword
            // System.Console.Write(C.M1(null, in i, in j));
            Diagnostic(ErrorCode.ERR_BadArgRef, "j").WithArguments("3", "ref").WithLocation(4, 42),
            // 1.cs(5,39): error CS1620: Argument 3 must be passed with the 'ref' keyword
            // System.Console.Write(C.M1(null, in i, j));
            Diagnostic(ErrorCode.ERR_BadArgRef, "j").WithArguments("3", "ref").WithLocation(5, 39),
            // 1.cs(6,39): error CS1620: Argument 3 must be passed with the 'ref' keyword
            // System.Console.Write(C.M1(null, i, in j));
            Diagnostic(ErrorCode.ERR_BadArgRef, "j").WithArguments("3", "ref").WithLocation(6, 39),
            // 1.cs(7,36): error CS1620: Argument 3 must be passed with the 'ref' keyword
            // System.Console.Write(C.M1(null, i, j));
            Diagnostic(ErrorCode.ERR_BadArgRef, "j").WithArguments("3", "ref").WithLocation(7, 36));
 
        var source3 = """
            int i = 5;
            int j = 6;
            System.Console.Write(C.M1(null, ref i, in j));
            System.Console.Write(C.M1(null, ref i, j));
            System.Console.Write(C.M1(null, in i, ref j));
            System.Console.Write(C.M1(null, i, ref j));
            """;
 
        CompileAndVerify(new[] { source1, source3 }, expectedOutput: "256 256 156 156", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_08()
    {
        var source = """
            interface I1 { }
            interface I2 { }
            class C
            {
                public static string M1(I1 o, in int i, ref readonly int j) => " 1" + i + j;
                public static string M1(I2 o, ref readonly int i, in int j) => " 2" + i + j;
                static void Main()
                {
                    int i = 5;
                    System.Console.Write(C.M1(null, ref i, ref i));
                    System.Console.Write(C.M1(null, ref i, in i));
                    System.Console.Write(C.M1(null, ref i, i));
                    System.Console.Write(C.M1(null, in i, ref i));
                    System.Console.Write(C.M1(null, in i, in i));
                    System.Console.Write(C.M1(null, in i, i));
                    System.Console.Write(C.M1(null, i, ref i));
                    System.Console.Write(C.M1(null, i, in i));
                    System.Console.Write(C.M1(null, i, i));
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (10,32): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I1, in int, ref readonly int)' and 'C.M1(I2, ref readonly int, in int)'
            //         System.Console.Write(C.M1(null, ref i, ref i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I1, in int, ref readonly int)", "C.M1(I2, ref readonly int, in int)").WithLocation(10, 32),
            // (11,32): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I1, in int, ref readonly int)' and 'C.M1(I2, ref readonly int, in int)'
            //         System.Console.Write(C.M1(null, ref i, in i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I1, in int, ref readonly int)", "C.M1(I2, ref readonly int, in int)").WithLocation(11, 32),
            // (12,32): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I1, in int, ref readonly int)' and 'C.M1(I2, ref readonly int, in int)'
            //         System.Console.Write(C.M1(null, ref i, i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I1, in int, ref readonly int)", "C.M1(I2, ref readonly int, in int)").WithLocation(12, 32),
            // (13,32): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I1, in int, ref readonly int)' and 'C.M1(I2, ref readonly int, in int)'
            //         System.Console.Write(C.M1(null, in i, ref i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I1, in int, ref readonly int)", "C.M1(I2, ref readonly int, in int)").WithLocation(13, 32),
            // (14,32): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I1, in int, ref readonly int)' and 'C.M1(I2, ref readonly int, in int)'
            //         System.Console.Write(C.M1(null, in i, in i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I1, in int, ref readonly int)", "C.M1(I2, ref readonly int, in int)").WithLocation(14, 32),
            // (15,32): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I1, in int, ref readonly int)' and 'C.M1(I2, ref readonly int, in int)'
            //         System.Console.Write(C.M1(null, in i, i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I1, in int, ref readonly int)", "C.M1(I2, ref readonly int, in int)").WithLocation(15, 32),
            // (16,32): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I1, in int, ref readonly int)' and 'C.M1(I2, ref readonly int, in int)'
            //         System.Console.Write(C.M1(null, i, ref i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I1, in int, ref readonly int)", "C.M1(I2, ref readonly int, in int)").WithLocation(16, 32),
            // (17,32): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I1, in int, ref readonly int)' and 'C.M1(I2, ref readonly int, in int)'
            //         System.Console.Write(C.M1(null, i, in i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I1, in int, ref readonly int)", "C.M1(I2, ref readonly int, in int)").WithLocation(17, 32),
            // (18,32): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I1, in int, ref readonly int)' and 'C.M1(I2, ref readonly int, in int)'
            //         System.Console.Write(C.M1(null, i, i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I1, in int, ref readonly int)", "C.M1(I2, ref readonly int, in int)").WithLocation(18, 32));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_09()
    {
        var source = """
            interface I1 { }
            interface I2 { }
            class C
            {
                string M1(I1 o, in int i, in int j, in int k) => "1";
                string M1(I2 o, in int i, in int j, ref int k) => "2";
                static void Main()
                {
                    int i = 5;
                    System.Console.Write(new C().M1(null, in i, ref i, ref i));
                }
            }
            """;
        CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (10,57): error CS9194: Argument 3 may not be passed with the 'ref' keyword in language version 11.0. To pass 'ref' arguments to 'in' parameters, upgrade to language version 12.0 or greater.
            //         System.Console.Write(new C().M1(null, in i, ref i, ref i));
            Diagnostic(ErrorCode.ERR_BadArgExtraRefLangVersion, "i").WithArguments("3", "11.0", "12.0").WithLocation(10, 57),
            // (10,64): error CS9194: Argument 4 may not be passed with the 'ref' keyword in language version 11.0. To pass 'ref' arguments to 'in' parameters, upgrade to language version 12.0 or greater.
            //         System.Console.Write(new C().M1(null, in i, ref i, ref i));
            Diagnostic(ErrorCode.ERR_BadArgExtraRefLangVersion, "i").WithArguments("4", "11.0", "12.0").WithLocation(10, 64));
 
        var expectedDiagnostics = new[]
        {
            // (10,38): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I1, in int, in int, in int)' and 'C.M1(I2, in int, in int, ref int)'
            //         System.Console.Write(new C().M1(null, in i, ref i, ref i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I1, in int, in int, in int)", "C.M1(I2, in int, in int, ref int)").WithLocation(10, 38)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_10()
    {
        var source = """
            interface I1 { }
            interface I2 { }
            class C
            {
                string M1(I1 o, in int i, in int j, in int k) => "1";
                string M1(I2 o, in int i, in int j, in int k) => "2";
                static void Main()
                {
                    int i = 5;
                    System.Console.Write(new C().M1(null, in i, ref i, ref i));
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (10,38): error CS0121: The call is ambiguous between the following methods or properties: 'C.M1(I1, in int, in int, in int)' and 'C.M1(I2, in int, in int, in int)'
            //         System.Console.Write(new C().M1(null, in i, ref i, ref i));
            Diagnostic(ErrorCode.ERR_AmbigCall, "M1").WithArguments("C.M1(I1, in int, in int, in int)", "C.M1(I2, in int, in int, in int)").WithLocation(10, 38));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_11()
    {
        var source1 = """
            using System;
            using System.Runtime.InteropServices;
 
            interface I1 { }
            interface I2 { }
 
            [ComImport, Guid("96A2DE64-6D44-4DA5-BBA4-25F5F07E0E6B")]
            interface I
            {
                void M(I1 o, ref int i);
                void M(I2 o, in int i);
            }
 
            class C : I
            {
                void I.M(I1 o, ref int i) => System.Console.Write("1");
                void I.M(I2 o, in int i) => System.Console.Write("2");
            }
            """;
 
        var source2 = """
            I i = new C();
            int x = 42;
            i.M(null, 43);
            i.M(null, x);
            i.M(null, in x);
            """;
 
        var expectedOutput = "222";
        CompileAndVerify(new[] { source1, source2 }, expectedOutput: expectedOutput, parseOptions: TestOptions.Regular11).VerifyDiagnostics();
        CompileAndVerify(new[] { source1, source2 }, expectedOutput: expectedOutput, parseOptions: TestOptions.Regular12).VerifyDiagnostics();
        CompileAndVerify(new[] { source1, source2 }, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        var source3 = """
            I i = new C();
            int x = 42;
            i.M(null, ref x);
            """;
 
        CompileAndVerify(new[] { source1, source3 }, expectedOutput: "1", parseOptions: TestOptions.Regular11).VerifyDiagnostics();
 
        var expectedDiagnostics = new[]
        {
            // 1.cs(3,3): error CS0121: The call is ambiguous between the following methods or properties: 'I.M(I1, ref int)' and 'I.M(I2, in int)'
            // i.M(null, ref x);
            Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("I.M(I1, ref int)", "I.M(I2, in int)").WithLocation(3, 3)
        };
 
        CreateCompilation(new[] { source1, source3 }, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(new[] { source1, source3 }).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_12()
    {
        var source1 = """
            using System;
            using System.Runtime.InteropServices;
 
            interface I1 { }
            interface I2 { }
 
            [ComImport, Guid("96A2DE64-6D44-4DA5-BBA4-25F5F07E0E6B")]
            interface I
            {
                void M(I1 o, ref int i);
                void M(I2 o, ref readonly int i);
            }
 
            class C : I
            {
                void I.M(I1 o, ref int i) => System.Console.Write("1");
                void I.M(I2 o, ref readonly int i) => System.Console.Write("2");
            }
            """;
 
        var source2 = """
            I i = new C();
            int x = 42;
            i.M(null, 43);
            i.M(null, x);
            i.M(null, in x);
            """;
        CompileAndVerify(new[] { source1, source2 }, expectedOutput: "222").VerifyDiagnostics(
            // 1.cs(3,11): warning CS9193: Argument 2 should be a variable because it is passed to a 'ref readonly' parameter
            // i.M(null, 43);
            Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "43").WithArguments("2").WithLocation(3, 11),
            // 1.cs(4,11): warning CS9192: Argument 2 should be passed with 'ref' or 'in' keyword
            // i.M(null, x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("2").WithLocation(4, 11));
 
        var source3 = """
            I i = new C();
            int x = 42;
            i.M(null, ref x);
            """;
        CreateCompilation(new[] { source1, source3 }).VerifyDiagnostics(
            // 1.cs(3,3): error CS0121: The call is ambiguous between the following methods or properties: 'I.M(I1, ref int)' and 'I.M(I2, ref readonly int)'
            // i.M(null, ref x);
            Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("I.M(I1, ref int)", "I.M(I2, ref readonly int)").WithLocation(3, 3));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_ExtensionMethod_01()
    {
        var source = """
            class C
            {
                string M1(in int i) => "C";
                static void Main()
                {
                    int i = 5;
                    System.Console.Write(new C().M1(ref i));
                    System.Console.Write(new C().M1(in i));
                    System.Console.Write(new C().M1(i));
                }
            }
            static class E
            {
                public static string M1(this C c, ref int i) => "E";
            }
            """;
        CompileAndVerify(source, expectedOutput: "ECC", parseOptions: TestOptions.Regular11).VerifyDiagnostics();
 
        var expectedDiagnostics = new[]
        {
            // (7,45): warning CS9191: The 'ref' modifier for argument 1 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
            //         System.Console.Write(new C().M1(ref i));
            Diagnostic(ErrorCode.WRN_BadArgRef, "i").WithArguments("1").WithLocation(7, 45)
        };
 
        CompileAndVerify(source, expectedOutput: "CCC", parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CompileAndVerify(source, expectedOutput: "CCC").VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_ExtensionMethod_02()
    {
        var source = """
            using N1;
            class C
            {
                string M1(in int i) => "C";
                static void Main()
                {
                    int i = 5;
                    System.Console.Write(new C().M1(ref i));
                    System.Console.Write(new C().M1(in i));
                    System.Console.Write(new C().M1(i));
                }
            }
            static class X
            {
                public static string M1(this C c, in int i) => "X";
            }
            namespace N1
            {
                static class Y
                {
                    public static string M1(this C c, ref int i) => "Y";
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: "YCC", parseOptions: TestOptions.Regular11).VerifyDiagnostics();
 
        var expectedDiagnostics = new[]
        {
            // (1,1): hidden CS8019: Unnecessary using directive.
            // using N1;
            Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using N1;").WithLocation(1, 1),
            // (8,45): warning CS9191: The 'ref' modifier for argument 1 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
            //         System.Console.Write(new C().M1(ref i));
            Diagnostic(ErrorCode.WRN_BadArgRef, "i").WithArguments("1").WithLocation(8, 45)
        };
 
        CompileAndVerify(source, expectedOutput: "CCC", parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CompileAndVerify(source, expectedOutput: "CCC").VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_ExtensionMethod_03()
    {
        var source = """
            using N1;
            class C
            {
                string M1(in int i) => "C";
                static void Main()
                {
                    int i = 5;
                    System.Console.Write(new C().M1(ref i));
                    System.Console.Write(new C().M1(in i));
                    System.Console.Write(new C().M1(i));
                }
            }
            static class X
            {
                public static string M1(this C c, ref readonly int i) => "X";
            }
            namespace N1
            {
                static class Y
                {
                    public static string M1(this C c, ref int i) => "Y";
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: "CCC").VerifyDiagnostics(
            // (1,1): hidden CS8019: Unnecessary using directive.
            // using N1;
            Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using N1;").WithLocation(1, 1),
            // (8,45): warning CS9191: The 'ref' modifier for argument 1 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
            //         System.Console.Write(new C().M1(ref i));
            Diagnostic(ErrorCode.WRN_BadArgRef, "i").WithArguments("1").WithLocation(8, 45));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_ExtensionMethod_04()
    {
        var source1 = """
            class C
            {
                public string M1(in int i, ref int j) => "C";
            }
            static class E
            {
                public static string M1(this C c, ref int i, in int j) => "E";
            }
            """;
 
        var source2 = """
            int i = 5;
            System.Console.Write(new C().M1(in i, in i));
            System.Console.Write(new C().M1(in i, i));
            System.Console.Write(new C().M1(i, in i));
            System.Console.Write(new C().M1(i, i));
            """;
 
        var expectedDiagnostics2 = new[]
        {
            // 1.cs(2,42): error CS1620: Argument 2 must be passed with the 'ref' keyword
            // System.Console.Write(new C().M1(in i, in i));
            Diagnostic(ErrorCode.ERR_BadArgRef, "i").WithArguments("2", "ref").WithLocation(2, 42),
            // 1.cs(3,39): error CS1620: Argument 2 must be passed with the 'ref' keyword
            // System.Console.Write(new C().M1(in i, i));
            Diagnostic(ErrorCode.ERR_BadArgRef, "i").WithArguments("2", "ref").WithLocation(3, 39),
            // 1.cs(4,39): error CS1620: Argument 2 must be passed with the 'ref' keyword
            // System.Console.Write(new C().M1(i, in i));
            Diagnostic(ErrorCode.ERR_BadArgRef, "i").WithArguments("2", "ref").WithLocation(4, 39),
            // 1.cs(5,36): error CS1620: Argument 2 must be passed with the 'ref' keyword
            // System.Console.Write(new C().M1(i, i));
            Diagnostic(ErrorCode.ERR_BadArgRef, "i").WithArguments("2", "ref").WithLocation(5, 36)
        };
 
        CreateCompilation(new[] { source1, source2 }, parseOptions: TestOptions.Regular11).VerifyDiagnostics(expectedDiagnostics2);
        CreateCompilation(new[] { source1, source2 }, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics2);
        CreateCompilation(new[] { source1, source2 }).VerifyDiagnostics(expectedDiagnostics2);
 
        var source3 = """
            int i = 5;
            System.Console.Write(new C().M1(ref i, ref i));
            """;
 
        CreateCompilation(new[] { source1, source3 }, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // 1.cs(2,37): error CS9194: Argument 1 may not be passed with the 'ref' keyword in language version 11.0. To pass 'ref' arguments to 'in' parameters, upgrade to language version 12.0 or greater.
            // System.Console.Write(new C().M1(ref i, ref i));
            Diagnostic(ErrorCode.ERR_BadArgExtraRefLangVersion, "i").WithArguments("1", "11.0", "12.0").WithLocation(2, 37));
 
        var expectedDiagnostics3 = new[]
        {
            // 1.cs(2,37): warning CS9191: The 'ref' modifier for argument 1 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
            // System.Console.Write(new C().M1(ref i, ref i));
            Diagnostic(ErrorCode.WRN_BadArgRef, "i").WithArguments("1").WithLocation(2, 37)
        };
 
        var expectedOutput3 = "C";
        CompileAndVerify(new[] { source1, source3 }, expectedOutput: expectedOutput3, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics3);
        CompileAndVerify(new[] { source1, source3 }, expectedOutput: expectedOutput3).VerifyDiagnostics(expectedDiagnostics3);
 
        var source4 = """
            int i = 5;
            System.Console.Write(new C().M1(ref i, i));
            System.Console.Write(new C().M1(in i, ref i));
            System.Console.Write(new C().M1(i, ref i));
            """;
 
        var expectedOutput4 = "ECC";
        CompileAndVerify(new[] { source1, source4 }, expectedOutput: expectedOutput4, parseOptions: TestOptions.Regular11).VerifyDiagnostics();
        CompileAndVerify(new[] { source1, source4 }, expectedOutput: expectedOutput4, parseOptions: TestOptions.Regular12).VerifyDiagnostics();
        CompileAndVerify(new[] { source1, source4 }, expectedOutput: expectedOutput4).VerifyDiagnostics();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_ExtensionMethod_05()
    {
        var source = """
            class C
            {
                string M1(in int i) => "C";
                static void Main()
                {
                    int i = 5;
                    System.Console.Write(new C().M1(in i));
                    System.Console.Write(new C().M1(i));
                }
            }
            static class E
            {
                public static string M1(this C c, int i) => "E";
            }
            """;
        var expectedOutput = "CC";
        CompileAndVerify(source, expectedOutput: expectedOutput, parseOptions: TestOptions.Regular11).VerifyDiagnostics();
        CompileAndVerify(source, expectedOutput: expectedOutput, parseOptions: TestOptions.Regular12).VerifyDiagnostics();
        CompileAndVerify(source, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_ExtensionMethod_06()
    {
        var source = """
            class C
            {
                string M1(int i) => "C";
                static void Main()
                {
                    int i = 5;
                    System.Console.Write(new C().M1(in i));
                    System.Console.Write(new C().M1(i));
                }
            }
            static class E
            {
                public static string M1(this C c, in int i) => "E";
            }
            """;
        var expectedOutput = "EC";
        CompileAndVerify(source, expectedOutput: expectedOutput, parseOptions: TestOptions.Regular11).VerifyDiagnostics();
        CompileAndVerify(source, expectedOutput: expectedOutput, parseOptions: TestOptions.Regular12).VerifyDiagnostics();
        CompileAndVerify(source, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_ExtensionMethod_07()
    {
        var source = """
            class C
            {
                string M1(ref readonly int i) => "C";
                static void Main()
                {
                    int i = 5;
                    System.Console.Write(new C().M1(i));
                }
            }
            static class E
            {
                public static string M1(this C c, ref readonly int i) => "E";
            }
            """;
        CompileAndVerify(source, expectedOutput: "C").VerifyDiagnostics(
            // (7,41): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         System.Console.Write(new C().M1(i));
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "i").WithArguments("1").WithLocation(7, 41));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_ExtensionMethod_08()
    {
        var source = """
            class C
            {
                string M1(in int i) => "C";
                static void Main()
                {
                    int i = 5;
                    System.Console.Write(new C().M1(in i));
                }
            }
            static class E
            {
                public static string M1(this C c, ref readonly int i) => "E";
            }
            """;
        CompileAndVerify(source, expectedOutput: "C").VerifyDiagnostics();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_ExtensionMethod_09()
    {
        var source = """
            namespace N1
            {
                namespace N2
                {
                    class C
                    {
                        string M1(in int i) => "C";
                        static void Main()
                        {
                            int i = 5;
                            System.Console.Write(new C().M1(ref i));
                            System.Console.Write(new C().M1(in i));
                            System.Console.Write(new C().M1(i));
                        }
                    }
                    static class X
                    {
                        public static string M1(this C c, ref readonly int i) => "X";
                    }
                }
                static class Y
                {
                    public static string M1(this N2.C c, int i) => "Y";
                }
            }
            static class Z
            {
                public static string M1(this N1.N2.C c, ref int i) => "Z";
            }
            """;
        CompileAndVerify(source, expectedOutput: "CCC").VerifyDiagnostics(
            // (11,53): warning CS9191: The 'ref' modifier for argument 1 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
            //                 System.Console.Write(new C().M1(ref i));
            Diagnostic(ErrorCode.WRN_BadArgRef, "i").WithArguments("1").WithLocation(11, 53));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_ExtensionMethod_10()
    {
        var source = """
            class C
            {
                string M1(in int i, in int j, in int k) => "C";
                static void Main()
                {
                    int i = 5;
                    System.Console.Write(new C().M1(in i, ref i, ref i));
                }
            }
            static class E
            {
                public static string M1(this C c, in int i, in int j, ref int k) => "E";
            }
            """;
        CompileAndVerify(source, expectedOutput: "C").VerifyDiagnostics(
            // (7,51): warning CS9191: The 'ref' modifier for argument 2 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
            //         System.Console.Write(new C().M1(in i, ref i, ref i));
            Diagnostic(ErrorCode.WRN_BadArgRef, "i").WithArguments("2").WithLocation(7, 51),
            // (7,58): warning CS9191: The 'ref' modifier for argument 3 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
            //         System.Console.Write(new C().M1(in i, ref i, ref i));
            Diagnostic(ErrorCode.WRN_BadArgRef, "i").WithArguments("3").WithLocation(7, 58));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_ExtensionMethod_11()
    {
        var source = """
            using N1;
            class C
            {
                string M1(in int i, in int j, in int k) => "C";
                static void Main()
                {
                    int i = 5;
                    System.Console.Write(new C().M1(in i, ref i, ref i));
                }
            }
            static class X
            {
                public static string M1(this C c, in int i, in int j, ref int k) => "X";
            }
            namespace N1
            {
                static class Y
                {
                    public static string M1(this C c, in int i, in int j, in int k) => "Y";
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: "C").VerifyDiagnostics(
            // (1,1): hidden CS8019: Unnecessary using directive.
            // using N1;
            Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using N1;").WithLocation(1, 1),
            // (8,51): warning CS9191: The 'ref' modifier for argument 2 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
            //         System.Console.Write(new C().M1(in i, ref i, ref i));
            Diagnostic(ErrorCode.WRN_BadArgRef, "i").WithArguments("2").WithLocation(8, 51),
            // (8,58): warning CS9191: The 'ref' modifier for argument 3 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
            //         System.Console.Write(new C().M1(in i, ref i, ref i));
            Diagnostic(ErrorCode.WRN_BadArgRef, "i").WithArguments("3").WithLocation(8, 58));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_ExtensionMethod_12()
    {
        var source = """
            using N1;
            class C
            {
                string M1(in int i, in int j, in int k) => "C";
                static void Main()
                {
                    int i = 5;
                    System.Console.Write(new C().M1(in i, ref i, ref i));
                }
            }
            static class X
            {
                public static string M1(this C c, in int i, in int j, in int k) => "X";
            }
            namespace N1
            {
                static class Y
                {
                    public static string M1(this C c, in int i, in int j, ref int k) => "Y";
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: "C").VerifyDiagnostics(
            // (1,1): hidden CS8019: Unnecessary using directive.
            // using N1;
            Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using N1;").WithLocation(1, 1),
            // (8,51): warning CS9191: The 'ref' modifier for argument 2 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
            //         System.Console.Write(new C().M1(in i, ref i, ref i));
            Diagnostic(ErrorCode.WRN_BadArgRef, "i").WithArguments("2").WithLocation(8, 51),
            // (8,58): warning CS9191: The 'ref' modifier for argument 3 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
            //         System.Console.Write(new C().M1(in i, ref i, ref i));
            Diagnostic(ErrorCode.WRN_BadArgRef, "i").WithArguments("3").WithLocation(8, 58));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_ExtensionMethod_13()
    {
        var source = """
            class C
            {
                string M1(in int i, in int j, in int k) => "C";
                static void Main()
                {
                    int i = 5;
                    System.Console.Write(new C().M1(in i, in i, ref i));
                }
            }
            static class E
            {
                public static string M1<T>(this T t, in int i, in int j, ref int k) => "E";
            }
            """;
        CompileAndVerify(source, expectedOutput: "E", parseOptions: TestOptions.Regular11).VerifyDiagnostics();
 
        var expectedDiagnostics = new[]
        {
            // (7,57): warning CS9191: The 'ref' modifier for argument 3 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
            //         System.Console.Write(new C().M1(in i, in i, ref i));
            Diagnostic(ErrorCode.WRN_BadArgRef, "i").WithArguments("3").WithLocation(7, 57)
        };
 
        CompileAndVerify(source, expectedOutput: "C", parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CompileAndVerify(source, expectedOutput: "C").VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void OverloadResolution_ExtensionMethod_14()
    {
        var source = """
            class C
            {
                string M1(in int i, in int j, in int k) => "C";
                static void Main()
                {
                    int i = 5;
                    System.Console.Write(new C().M1(in i, ref i, ref i));
                }
            }
            static class E
            {
                public static string M1<T>(this T t, in int i, in int j, in int k) => "E";
            }
            """;
        // Neither method is better than the other, so the first scope wins.
        CompileAndVerify(source, expectedOutput: "C").VerifyDiagnostics(
            // (7,51): warning CS9191: The 'ref' modifier for argument 2 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
            //         System.Console.Write(new C().M1(in i, ref i, ref i));
            Diagnostic(ErrorCode.WRN_BadArgRef, "i").WithArguments("2").WithLocation(7, 51),
            // (7,58): warning CS9191: The 'ref' modifier for argument 3 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
            //         System.Console.Write(new C().M1(in i, ref i, ref i));
            Diagnostic(ErrorCode.WRN_BadArgRef, "i").WithArguments("3").WithLocation(7, 58));
    }
 
    [Fact]
    public void RefReadonlyParameter_PlainArgument_OverloadResolution()
    {
        var source = """
            class C
            {
                static string M1(ref readonly int i) => "ref readonly" + i;
                static string M1(int i) => "plain" + i;
                static void Main()
                {
                    int i = 5;
                    System.Console.Write(M1(i));
                    System.Console.Write(M1(6));
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: "plain5plain6").VerifyDiagnostics();
    }
 
    [Fact]
    public void RefReadonlyParameter_WrongType()
    {
        var source = """
            class C
            {
                static void M(ref readonly int i) => throw null;
                static void Main()
                {
                    string x = null;
                    M(x);
                    M(ref x);
                    M(in x);
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (7,11): error CS1503: Argument 1: cannot convert from 'string' to 'ref readonly int'
            //         M(x);
            Diagnostic(ErrorCode.ERR_BadArgType, "x").WithArguments("1", "string", "ref readonly int").WithLocation(7, 11),
            // (8,15): error CS1503: Argument 1: cannot convert from 'ref string' to 'ref readonly int'
            //         M(ref x);
            Diagnostic(ErrorCode.ERR_BadArgType, "x").WithArguments("1", "ref string", "ref readonly int").WithLocation(8, 15),
            // (9,14): error CS1503: Argument 1: cannot convert from 'in string' to 'ref readonly int'
            //         M(in x);
            Diagnostic(ErrorCode.ERR_BadArgType, "x").WithArguments("1", "in string", "ref readonly int").WithLocation(9, 14));
    }
 
    [Theory, CombinatorialData]
    public void DefaultParameterValue_EqualsValue(bool fromMetadata)
    {
        var source1 = """
            public class C
            {
                public static void M(ref readonly int i = 1) => System.Console.Write(i);
            }
            """;
        var warning1 =
            // (3,47): warning CS9200: A default value is specified for 'ref readonly' parameter 'i', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
            //     public static void M(ref readonly int i = 1) => System.Console.Write(i);
            Diagnostic(ErrorCode.WRN_RefReadonlyParameterDefaultValue, "1").WithArguments("i").WithLocation(3, 47);
        var source2 = """
            class D
            {
                static void Main()
                {
                    int x = 2;
                    C.M();
                    C.M(x);
                    C.M(ref x);
                    C.M(in x);
                }
                static void M2() => C.M();
            }
            """;
        var warning2 =
            // (7,13): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         C.M(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(7, 13);
        var comp = fromMetadata
            ? CreateCompilation(source2, new[] { CreateCompilation(source1).VerifyDiagnostics(warning1).EmitToImageReference() }, options: TestOptions.ReleaseExe)
            : CreateCompilation(new[] { source1, source2 }, options: TestOptions.ReleaseExe);
        var verifier = CompileAndVerify(comp, expectedOutput: "1222");
        verifier.VerifyDiagnostics(fromMetadata ? new[] { warning2 } : new[] { warning1, warning2 });
        verifier.VerifyIL("D.M2", """
            {
              // Code size       10 (0xa)
              .maxstack  1
              .locals init (int V_0)
              IL_0000:  ldc.i4.1
              IL_0001:  stloc.0
              IL_0002:  ldloca.s   V_0
              IL_0004:  call       "void C.M(ref readonly int)"
              IL_0009:  ret
            }
            """);
    }
 
    [Theory, CombinatorialData]
    public void DefaultParameterValue_Attribute(bool fromMetadata)
    {
        var source1 = """
            using System.Runtime.InteropServices;
            public class C
            {
                public static void M([Optional, DefaultParameterValue(1)] ref readonly int i) => System.Console.Write(i);
            }
            """;
        var warning1 =
            // (4,37): warning CS9200: A default value is specified for 'ref readonly' parameter 'i', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
            //     public static void M([Optional, DefaultParameterValue(1)] ref readonly int i) => System.Console.Write(i);
            Diagnostic(ErrorCode.WRN_RefReadonlyParameterDefaultValue, "DefaultParameterValue(1)").WithArguments("i").WithLocation(4, 37);
        var source2 = """
            class D
            {
                static void Main()
                {
                    int x = 2;
                    C.M();
                    C.M(x);
                    C.M(ref x);
                    C.M(in x);
                }
                static void M2() => C.M();
            }
            """;
        var warning2 =
            // (7,13): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         C.M(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(7, 13);
        var comp = fromMetadata
            ? CreateCompilation(source2, new[] { CreateCompilation(source1).VerifyDiagnostics(warning1).EmitToImageReference() }, options: TestOptions.ReleaseExe)
            : CreateCompilation(new[] { source1, source2 }, options: TestOptions.ReleaseExe);
        var verifier = CompileAndVerify(comp, expectedOutput: "1222");
        verifier.VerifyDiagnostics(fromMetadata ? new[] { warning2 } : new[] { warning1, warning2 });
        verifier.VerifyIL("D.M2", """
            {
              // Code size       10 (0xa)
              .maxstack  1
              .locals init (int V_0)
              IL_0000:  ldc.i4.1
              IL_0001:  stloc.0
              IL_0002:  ldloca.s   V_0
              IL_0004:  call       "void C.M(ref readonly int)"
              IL_0009:  ret
            }
            """);
    }
 
    [Fact]
    public void DefaultParameterValue_AttributeAndEqualsValue()
    {
        var source = """
            using System.Runtime.InteropServices;
            class C
            {
                static void M([DefaultParameterValue(1)] ref readonly int i = 1) => throw null;
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (4,20): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
            //     static void M([DefaultParameterValue(1)] ref readonly int i = 1) => throw null;
            Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(4, 20),
            // (4,67): warning CS9200: A default value is specified for 'ref readonly' parameter 'i', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
            //     static void M([DefaultParameterValue(1)] ref readonly int i = 1) => throw null;
            Diagnostic(ErrorCode.WRN_RefReadonlyParameterDefaultValue, "1").WithArguments("i").WithLocation(4, 67),
            // (4,67): error CS8017: The parameter has multiple distinct default values.
            //     static void M([DefaultParameterValue(1)] ref readonly int i = 1) => throw null;
            Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "1").WithLocation(4, 67));
    }
 
    [Fact]
    public void DefaultParameterValue_OptionalAndEqualsValue()
    {
        var source = """
            using System.Runtime.InteropServices;
            class C
            {
                static void M([Optional] ref readonly int i = 1) => throw null;
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (4,20): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
            //     static void M([Optional] ref readonly int i = 1) => throw null;
            Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "Optional").WithLocation(4, 20),
            // (4,51): warning CS9200: A default value is specified for 'ref readonly' parameter 'i', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
            //     static void M([Optional] ref readonly int i = 1) => throw null;
            Diagnostic(ErrorCode.WRN_RefReadonlyParameterDefaultValue, "1").WithArguments("i").WithLocation(4, 51));
    }
 
    [Fact]
    public void DefaultParameterValue_All()
    {
        var source = """
            using System.Runtime.InteropServices;
            class C
            {
                static void M([Optional, DefaultParameterValue(1)] ref readonly int i = 1) => throw null;
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (4,20): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
            //     static void M([Optional, DefaultParameterValue(1)] ref readonly int i = 1) => throw null;
            Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "Optional").WithLocation(4, 20),
            // (4,30): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
            //     static void M([Optional, DefaultParameterValue(1)] ref readonly int i = 1) => throw null;
            Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(4, 30),
            // (4,77): warning CS9200: A default value is specified for 'ref readonly' parameter 'i', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
            //     static void M([Optional, DefaultParameterValue(1)] ref readonly int i = 1) => throw null;
            Diagnostic(ErrorCode.WRN_RefReadonlyParameterDefaultValue, "1").WithArguments("i").WithLocation(4, 77),
            // (4,77): error CS8017: The parameter has multiple distinct default values.
            //     static void M([Optional, DefaultParameterValue(1)] ref readonly int i = 1) => throw null;
            Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "1").WithLocation(4, 77));
    }
 
    [Theory, CombinatorialData]
    public void DefaultParameterValue_DecimalConstant_Valid(bool fromMetadata)
    {
        var source1 = """
            using System;
            using System.Globalization;
            using System.Runtime.CompilerServices;
            using System.Runtime.InteropServices;
            public class C
            {
                public static void M1([Optional, DecimalConstant(1, 0, 0u, 0u, 11u)] ref readonly decimal d) => Console.WriteLine("M1 " + d.ToString(CultureInfo.InvariantCulture));
                public static void M2(ref readonly decimal d = 1.1m) => Console.WriteLine("M2 " + d.ToString(CultureInfo.InvariantCulture));
            }
            """;
        var warnings1 = new[]
        {
            // (7,38): warning CS9200: A default value is specified for 'ref readonly' parameter 'd', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
            //     public static void M1([Optional, DecimalConstant(1, 0, 0u, 0u, 11u)] ref readonly decimal d) => Console.WriteLine("M1 " + d.ToString(CultureInfo.InvariantCulture));
            Diagnostic(ErrorCode.WRN_RefReadonlyParameterDefaultValue, "DecimalConstant(1, 0, 0u, 0u, 11u)").WithArguments("d").WithLocation(7, 38),
            // (8,52): warning CS9200: A default value is specified for 'ref readonly' parameter 'd', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
            //     public static void M2(ref readonly decimal d = 1.1m) => Console.WriteLine("M2 " + d.ToString(CultureInfo.InvariantCulture));
            Diagnostic(ErrorCode.WRN_RefReadonlyParameterDefaultValue, "1.1m").WithArguments("d").WithLocation(8, 52),
        };
        var source2 = """
            class D
            {
                static void Main()
                {
                    decimal x = 2.2m;
                    C.M1();
                    C.M1(x);
                    C.M1(ref x);
                    C.M1(in x);
 
                    decimal y = 3.3m;
                    C.M2();
                    C.M2(y);
                    C.M2(ref y);
                    C.M2(in y);
                }
                static void M3() => C.M1();
                static void M4() => C.M2();
            }
            """;
        var warnings2 = new[]
        {
            // (7,14): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         C.M1(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(7, 14),
            // (13,14): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         C.M2(y);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "y").WithArguments("1").WithLocation(13, 14)
        };
        var comp = fromMetadata
            ? CreateCompilation(source2, new[] { CreateCompilation(source1).VerifyDiagnostics(warnings1).EmitToImageReference() }, options: TestOptions.ReleaseExe)
            : CreateCompilation(new[] { source1, source2 }, options: TestOptions.ReleaseExe);
        var verifier = CompileAndVerify(comp, expectedOutput: """
            M1 1.1
            M1 2.2
            M1 2.2
            M1 2.2
            M2 1.1
            M2 3.3
            M2 3.3
            M2 3.3
            """);
        verifier.VerifyDiagnostics(fromMetadata ? warnings2 : warnings1.Concat(warnings2).ToArray());
        verifier.VerifyIL("D.M3", """
            {
              // Code size       20 (0x14)
              .maxstack  5
              .locals init (decimal V_0)
              IL_0000:  ldc.i4.s   11
              IL_0002:  ldc.i4.0
              IL_0003:  ldc.i4.0
              IL_0004:  ldc.i4.0
              IL_0005:  ldc.i4.1
              IL_0006:  newobj     "decimal..ctor(int, int, int, bool, byte)"
              IL_000b:  stloc.0
              IL_000c:  ldloca.s   V_0
              IL_000e:  call       "void C.M1(ref readonly decimal)"
              IL_0013:  ret
            }
            """);
        verifier.VerifyIL("D.M4", """
            {
              // Code size       20 (0x14)
              .maxstack  5
              .locals init (decimal V_0)
              IL_0000:  ldc.i4.s   11
              IL_0002:  ldc.i4.0
              IL_0003:  ldc.i4.0
              IL_0004:  ldc.i4.0
              IL_0005:  ldc.i4.1
              IL_0006:  newobj     "decimal..ctor(int, int, int, bool, byte)"
              IL_000b:  stloc.0
              IL_000c:  ldloca.s   V_0
              IL_000e:  call       "void C.M2(ref readonly decimal)"
              IL_0013:  ret
            }
            """);
    }
 
    [Fact]
    public void DefaultParameterValue_DecimalConstant_Invalid()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System.Runtime.InteropServices;
            class C
            {
                static void M1([DecimalConstant(1, 0, 0u, 0u, 11u)] ref readonly decimal d) => throw null;
                static void M2([Optional, DecimalConstant(1, 0, 0u, 0u, 11u)] ref readonly decimal d = 1.1m) => throw null;
                static void Main()
                {
                    M1();
                    M2();
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (6,21): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
            //     static void M2([Optional, DecimalConstant(1, 0, 0u, 0u, 11u)] ref readonly decimal d = 1.1m) => throw null;
            Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "Optional").WithLocation(6, 21),
            // (6,92): warning CS9200: A default value is specified for 'ref readonly' parameter 'd', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
            //     static void M2([Optional, DecimalConstant(1, 0, 0u, 0u, 11u)] ref readonly decimal d = 1.1m) => throw null;
            Diagnostic(ErrorCode.WRN_RefReadonlyParameterDefaultValue, "1.1m").WithArguments("d").WithLocation(6, 92),
            // (9,9): error CS7036: There is no argument given that corresponds to the required parameter 'd' of 'C.M1(ref readonly decimal)'
            //         M1();
            Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "M1").WithArguments("d", "C.M1(ref readonly decimal)").WithLocation(9, 9));
    }
 
    [Theory, CombinatorialData]
    public void DefaultParameterValue_DateTimeConstant_Valid(bool fromMetadata)
    {
        var source1 = """
            using System;
            using System.Runtime.CompilerServices;
            using System.Runtime.InteropServices;
            public class C
            {
                public static void M([Optional, DateTimeConstant(100L)] ref readonly DateTime d) => Console.Write(d.Ticks);
            }
            """;
        var warning1 =
            // (6,37): warning CS9200: A default value is specified for 'ref readonly' parameter 'd', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
            //     public static void M([Optional, DateTimeConstant(100L)] ref readonly DateTime d) => Console.Write(d.Ticks);
            Diagnostic(ErrorCode.WRN_RefReadonlyParameterDefaultValue, "DateTimeConstant(100L)").WithArguments("d").WithLocation(6, 37);
        var source2 = """
            class D
            {
                static void Main() => C.M();
            }
            """;
        var comp = fromMetadata
            ? CreateCompilation(source2, new[] { CreateCompilation(source1).VerifyDiagnostics(warning1).EmitToImageReference() }, options: TestOptions.ReleaseExe)
            : CreateCompilation(new[] { source1, source2 }, options: TestOptions.ReleaseExe);
        var verifier = CompileAndVerify(comp, expectedOutput: "100");
        verifier.VerifyDiagnostics(fromMetadata ? Array.Empty<DiagnosticDescription>() : new[] { warning1 });
        verifier.VerifyIL("D.Main", """
            {
              // Code size       17 (0x11)
              .maxstack  1
              .locals init (System.DateTime V_0)
              IL_0000:  ldc.i4.s   100
              IL_0002:  conv.i8
              IL_0003:  newobj     "System.DateTime..ctor(long)"
              IL_0008:  stloc.0
              IL_0009:  ldloca.s   V_0
              IL_000b:  call       "void C.M(ref readonly System.DateTime)"
              IL_0010:  ret
            }
            """);
    }
 
    [Fact]
    public void DefaultParameterValue_DateTimeConstant_Invalid()
    {
        var source = """
            using System;
            using System.Runtime.CompilerServices;
            class C
            {
                static void M([DateTimeConstant(100L)] ref readonly DateTime d) => throw null;
                static void Main()
                {
                    M();
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (8,9): error CS7036: There is no argument given that corresponds to the required parameter 'd' of 'C.M(ref readonly DateTime)'
            //         M();
            Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "M").WithArguments("d", "C.M(ref readonly System.DateTime)").WithLocation(8, 9));
    }
 
    [Theory, CombinatorialData]
    public void OperationTree([CombinatorialValues("ref ", "in ", "")] string modifier)
    {
        var source = $$"""
            class C
            {
                void M(ref readonly int p) { }
                void M2(int x)
                /*<bind>*/{
                    M({{modifier}}x);
                }/*</bind>*/
            }
            """;
        var comp = CreateCompilation(source);
 
        VerifyOperationTreeAndDiagnosticsForTest<BlockSyntax>(comp, $$"""
            IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
              IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'M({{modifier}}x);')
                Expression:
                  IInvocationOperation ( void C.M(ref readonly System.Int32 p)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'M({{modifier}}x)')
                    Instance Receiver:
                      IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: 'M')
                    Arguments(1):
                        IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: p) (OperationKind.Argument, Type: null) (Syntax: '{{modifier}}x')
                          IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.Int32) (Syntax: 'x')
                          InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
                          OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
            """,
            modifier == ""
                ? new[]
                {
                    // (6,11): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
                    //         M(x);
                    Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(6, 11)
                }
                : DiagnosticDescription.None);
 
        VerifyFlowGraphForTest<BlockSyntax>(comp, $$"""
            Block[B0] - Entry
                Statements (0)
                Next (Regular) Block[B1]
            Block[B1] - Block
                Predecessors: [B0]
                Statements (1)
                    IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'M({{modifier}}x);')
                      Expression:
                        IInvocationOperation ( void C.M(ref readonly System.Int32 p)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'M({{modifier}}x)')
                          Instance Receiver:
                            IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: 'M')
                          Arguments(1):
                              IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: p) (OperationKind.Argument, Type: null) (Syntax: '{{modifier}}x')
                                IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.Int32) (Syntax: 'x')
                                InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
                                OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
                Next (Regular) Block[B2]
            Block[B2] - Exit
                Predecessors: [B1]
                Statements (0)
            """);
    }
 
    [Fact]
    public void Invocation_VirtualMethod()
    {
        var source = """
            class C
            {
                protected virtual void M(ref readonly int p) => System.Console.WriteLine(p);
                static void Main()
                {
                    int x = 111;
                    new C().M(ref x);
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: "111");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.Main", """
            {
              // Code size       16 (0x10)
              .maxstack  2
              .locals init (int V_0) //x
              IL_0000:  ldc.i4.s   111
              IL_0002:  stloc.0
              IL_0003:  newobj     "C..ctor()"
              IL_0008:  ldloca.s   V_0
              IL_000a:  callvirt   "void C.M(ref readonly int)"
              IL_000f:  ret
            }
            """);
    }
 
    [Fact]
    public void Invocation_OverriddenMethod()
    {
        var source = """
            class B
            {
                protected virtual void M(ref readonly int p) => System.Console.WriteLine("B" + p);
            }
            class C : B
            {
                protected override void M(ref readonly int p) => System.Console.WriteLine("C" + p);
                static void Main()
                {
                    int x = 111;
                    new C().M(ref x);
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: "C111");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.Main", """
            {
              // Code size       16 (0x10)
              .maxstack  2
              .locals init (int V_0) //x
              IL_0000:  ldc.i4.s   111
              IL_0002:  stloc.0
              IL_0003:  newobj     "C..ctor()"
              IL_0008:  ldloca.s   V_0
              IL_000a:  callvirt   "void B.M(ref readonly int)"
              IL_000f:  ret
            }
            """);
    }
 
    [Fact]
    public void Invocation_Constructor()
    {
        var source = """
            class C
            {
                C(ref readonly int p) => System.Console.WriteLine(p);
                static void Main()
                {
                    int x = 111;
                    new C(ref x);
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: "111");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.Main", """
            {
              // Code size       12 (0xc)
              .maxstack  1
              .locals init (int V_0) //x
              IL_0000:  ldc.i4.s   111
              IL_0002:  stloc.0
              IL_0003:  ldloca.s   V_0
              IL_0005:  newobj     "C..ctor(ref readonly int)"
              IL_000a:  pop
              IL_000b:  ret
            }
            """);
    }
 
    [Fact]
    public void Invocation_Indexer()
    {
        var source = """
            class C
            {
                int this[ref readonly int p]
                {
                    get
                    {
                        System.Console.WriteLine(p);
                        return 0;
                    }
                }
                static void Main()
                {
                    int x = 111;
                    _ = new C()[ref x];
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: "111");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.Main", """
            {
              // Code size       17 (0x11)
              .maxstack  2
              .locals init (int V_0) //x
              IL_0000:  ldc.i4.s   111
              IL_0002:  stloc.0
              IL_0003:  newobj     "C..ctor()"
              IL_0008:  ldloca.s   V_0
              IL_000a:  call       "int C.this[ref readonly int].get"
              IL_000f:  pop
              IL_0010:  ret
            }
            """);
    }
 
    [Fact]
    public void Invocation_FunctionPointer()
    {
        var source = """
            class C
            {
                static void M(ref readonly int p) => System.Console.WriteLine(p);
                static unsafe void Main()
                {
                    delegate*<ref readonly int, void> f = &M;
                    int x = 111;
                    f(ref x);
                }
            }
            """;
        var verifier = CompileAndVerify(new[] { source, RequiresLocationAttributeDefinition },
            expectedOutput: "111", options: TestOptions.UnsafeReleaseExe, verify: Verification.Fails);
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.Main", """
            {
              // Code size       19 (0x13)
              .maxstack  2
              .locals init (int V_0, //x
                            delegate*<ref readonly int, void> V_1)
              IL_0000:  ldftn      "void C.M(ref readonly int)"
              IL_0006:  ldc.i4.s   111
              IL_0008:  stloc.0
              IL_0009:  stloc.1
              IL_000a:  ldloca.s   V_0
              IL_000c:  ldloc.1
              IL_000d:  calli      "delegate*<ref readonly int, void>"
              IL_0012:  ret
            }
            """);
    }
 
    [Fact]
    public void Invocation_Operator_Metadata()
    {
        // public class C
        // {
        //     public static C operator+(ref readonly C x, C y) => x;
        //     public static C operator--(ref readonly C x) => x;
        //     public static implicit operator C(ref readonly int x) => null;
        //     public static explicit operator C(ref readonly short x) => null;
        // }
        var ilSource = """
            .class public auto ansi beforefieldinit C extends System.Object
            {
                .method public hidebysig specialname static 
                    class C op_Addition (
                        [in] class C& x,
                        class C y
                    ) cil managed 
                {
                    .param [1]
                        .custom instance void System.Runtime.CompilerServices.RequiresLocationAttribute::.ctor() = (
                            01 00 00 00
                        )
                    .maxstack 8
                    ret
                }
 
                .method public hidebysig specialname static 
                    class C op_Decrement (
                        [in] class C& x
                    ) cil managed 
                {
                    .param [1]
                        .custom instance void System.Runtime.CompilerServices.RequiresLocationAttribute::.ctor() = (
                            01 00 00 00
                        )
                    .maxstack 8
                    ret
                }
 
                .method public hidebysig specialname static 
                    class C op_Implicit (
                        [in] int32& x
                    ) cil managed 
                {
                    .param [1]
                        .custom instance void System.Runtime.CompilerServices.RequiresLocationAttribute::.ctor() = (
                            01 00 00 00
                        )
                    .maxstack 8
                    ret
                }
 
                .method public hidebysig specialname static 
                    class C op_Explicit (
                        [in] int16& x
                    ) cil managed 
                {
                    .param [1]
                        .custom instance void System.Runtime.CompilerServices.RequiresLocationAttribute::.ctor() = (
                            01 00 00 00
                        )
                    .maxstack 8
                    ret
                }
            }
 
            .class public auto ansi sealed beforefieldinit System.Runtime.CompilerServices.RequiresLocationAttribute extends System.Object
            {
                .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
                {
                    .maxstack 8
                    ret
                }
            }
            """;
        var source = """
            int i = 4;
            short s = 5;
            C c = null;
            _ = c + c;
            c--;
            c = i;
            c = (C)s;
            """;
        CreateCompilationWithIL(source, ilSource).VerifyDiagnostics(
            // (4,5): error CS0019: Operator '+' cannot be applied to operands of type 'C' and 'C'
            // _ = c + c;
            Diagnostic(ErrorCode.ERR_BadBinaryOps, "c + c").WithArguments("+", "C", "C").WithLocation(4, 5),
            // (5,1): error CS0023: Operator '--' cannot be applied to operand of type 'C'
            // c--;
            Diagnostic(ErrorCode.ERR_BadUnaryOp, "c--").WithArguments("--", "C").WithLocation(5, 1),
            // (6,5): error CS0029: Cannot implicitly convert type 'int' to 'C'
            // c = i;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "i").WithArguments("int", "C").WithLocation(6, 5),
            // (7,5): error CS0030: Cannot convert type 'short' to 'C'
            // c = (C)s;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(C)s").WithArguments("short", "C").WithLocation(7, 5));
    }
 
    [Theory, CombinatorialData]
    public void Invocation_ExtensionMethod([CombinatorialValues("ref readonly", "ref", "in")] string modifier)
    {
        var source = $$"""
            static class C
            {
                static void M(this {{modifier}} int x) => System.Console.Write(x);
                static void Main()
                {
                    var x = 1;
                    x.M();
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: "1");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.Main", $$"""
            {
              // Code size       10 (0xa)
              .maxstack  1
              .locals init (int V_0) //x
              IL_0000:  ldc.i4.1
              IL_0001:  stloc.0
              IL_0002:  ldloca.s   V_0
              IL_0004:  call       "void C.M({{modifier}} int)"
              IL_0009:  ret
            }
            """);
    }
 
    [Theory, CombinatorialData]
    public void Invocation_ExtensionMethod_Metadata([CombinatorialValues("ref readonly", "ref", "in")] string modifier)
    {
        var source1 = $$"""
            public static class E
            {
                public static void M(this {{modifier}} int x) => System.Console.Write(x);
            }
            """;
        var comp1 = CreateCompilation(source1).VerifyDiagnostics();
        var comp1Ref = comp1.EmitToImageReference();
 
        var source2 = """
            static class Program
            {
                static void Main()
                {
                    var x = 1;
                    x.M();
                }
            }
            """;
        var verifier = CompileAndVerify(source2, new[] { comp1Ref }, expectedOutput: "1");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("Program.Main", $$"""
            {
              // Code size       10 (0xa)
              .maxstack  1
              .locals init (int V_0) //x
              IL_0000:  ldc.i4.1
              IL_0001:  stloc.0
              IL_0002:  ldloca.s   V_0
              IL_0004:  call       "void E.M({{modifier}} int)"
              IL_0009:  ret
            }
            """);
    }
 
    [Fact]
    public void Invocation_ExtensionMethod_SecondParameter()
    {
        var source = """
            static class C
            {
                static void M1(this int x, ref readonly int y) { }
                static void M2(this ref readonly int x, ref readonly int y) { }
                static void M3()
                {
                    var x = 1;
                    x.M1(in x);
                    x.M1(x);
                    M1(x, in x);
                    M1(x, x);
                    x.M2(in x);
                    x.M2(x);
                    M2(x, in x);
                    M2(x, x);
                    M2(in x, in x);
                    M2(in x, x);
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (9,14): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         x.M1(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(9, 14),
            // (11,15): warning CS9192: Argument 2 should be passed with 'ref' or 'in' keyword
            //         M1(x, x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("2").WithLocation(11, 15),
            // (13,14): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         x.M2(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(13, 14),
            // (14,12): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         M2(x, in x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(14, 12),
            // (15,12): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         M2(x, x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(15, 12),
            // (15,15): warning CS9192: Argument 2 should be passed with 'ref' or 'in' keyword
            //         M2(x, x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("2").WithLocation(15, 15),
            // (17,18): warning CS9192: Argument 2 should be passed with 'ref' or 'in' keyword
            //         M2(in x, x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("2").WithLocation(17, 18));
    }
 
    [Fact]
    public void Invocation_ExtensionMethod_SecondParameter_ReadOnly()
    {
        var source = """
            static class C
            {
                static void M1(this int x, ref readonly int y) { }
                static void M2(this ref readonly int x, ref readonly int y) { }
                static void M3(ref readonly int x)
                {
                    x.M1(in x);
                    x.M1(x);
                    M1(x, in x);
                    M1(x, x);
                    x.M2(in x);
                    x.M2(x);
                    M2(x, in x);
                    M2(x, x);
                    M2(in x, in x);
                    M2(in x, x);
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (8,14): warning CS9195: Argument 1 should be passed with the 'in' keyword
            //         x.M1(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedIn, "x").WithArguments("1").WithLocation(8, 14),
            // (10,15): warning CS9195: Argument 2 should be passed with the 'in' keyword
            //         M1(x, x);
            Diagnostic(ErrorCode.WRN_ArgExpectedIn, "x").WithArguments("2").WithLocation(10, 15),
            // (12,14): warning CS9195: Argument 1 should be passed with the 'in' keyword
            //         x.M2(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedIn, "x").WithArguments("1").WithLocation(12, 14),
            // (13,12): warning CS9195: Argument 1 should be passed with the 'in' keyword
            //         M2(x, in x);
            Diagnostic(ErrorCode.WRN_ArgExpectedIn, "x").WithArguments("1").WithLocation(13, 12),
            // (14,12): warning CS9195: Argument 1 should be passed with the 'in' keyword
            //         M2(x, x);
            Diagnostic(ErrorCode.WRN_ArgExpectedIn, "x").WithArguments("1").WithLocation(14, 12),
            // (14,15): warning CS9195: Argument 2 should be passed with the 'in' keyword
            //         M2(x, x);
            Diagnostic(ErrorCode.WRN_ArgExpectedIn, "x").WithArguments("2").WithLocation(14, 15),
            // (16,18): warning CS9195: Argument 2 should be passed with the 'in' keyword
            //         M2(in x, x);
            Diagnostic(ErrorCode.WRN_ArgExpectedIn, "x").WithArguments("2").WithLocation(16, 18));
    }
 
    [Fact]
    public void Invocation_ExtensionMethod_RValue()
    {
        var source = """
            static class C
            {
                static void M(this ref readonly int x) => System.Console.Write(x);
                static void Main()
                {
                    5.M();
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: "5");
        verifier.VerifyDiagnostics(
            // (6,9): warning CS9193: Argument 0 should be a variable because it is passed to a 'ref readonly' parameter
            //         5.M();
            Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "5").WithArguments("0").WithLocation(6, 9));
        verifier.VerifyIL("C.Main", """
            {
              // Code size       10 (0xa)
              .maxstack  1
              .locals init (int V_0)
              IL_0000:  ldc.i4.5
              IL_0001:  stloc.0
              IL_0002:  ldloca.s   V_0
              IL_0004:  call       "void C.M(ref readonly int)"
              IL_0009:  ret
            }
            """);
    }
 
    [Fact]
    public void Invocation_ExtensionMethod_RValue_SecondParameter()
    {
        var source = """
            static class C
            {
                static void M1(this int x, ref readonly int y) { }
                static void M2(this ref readonly int x, ref readonly int y) => System.Console.Write(x + y);
                static void M3()
                {
                    5.M1(111);
                    M1(5, 111);
                    5.M2(111);
                    M2(5, 111);
                    5.M2(in 111);
                    M2(in 5, 111);
                    M2(in 5, in 111);
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (7,14): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter
            //         5.M1(111);
            Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "111").WithArguments("1").WithLocation(7, 14),
            // (8,15): warning CS9193: Argument 2 should be a variable because it is passed to a 'ref readonly' parameter
            //         M1(5, 111);
            Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "111").WithArguments("2").WithLocation(8, 15),
            // (9,9): warning CS9193: Argument 0 should be a variable because it is passed to a 'ref readonly' parameter
            //         5.M2(111);
            Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "5").WithArguments("0").WithLocation(9, 9),
            // (9,14): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter
            //         5.M2(111);
            Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "111").WithArguments("1").WithLocation(9, 14),
            // (10,12): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter
            //         M2(5, 111);
            Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "5").WithArguments("1").WithLocation(10, 12),
            // (10,15): warning CS9193: Argument 2 should be a variable because it is passed to a 'ref readonly' parameter
            //         M2(5, 111);
            Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "111").WithArguments("2").WithLocation(10, 15),
            // (11,9): warning CS9193: Argument 0 should be a variable because it is passed to a 'ref readonly' parameter
            //         5.M2(in 111);
            Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "5").WithArguments("0").WithLocation(11, 9),
            // (11,17): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
            //         5.M2(in 111);
            Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "111").WithLocation(11, 17),
            // (12,15): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
            //         M2(in 5, 111);
            Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "5").WithLocation(12, 15),
            // (12,18): warning CS9193: Argument 2 should be a variable because it is passed to a 'ref readonly' parameter
            //         M2(in 5, 111);
            Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "111").WithArguments("2").WithLocation(12, 18),
            // (13,15): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
            //         M2(in 5, in 111);
            Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "5").WithLocation(13, 15),
            // (13,21): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
            //         M2(in 5, in 111);
            Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "111").WithLocation(13, 21));
    }
 
    [Theory, CombinatorialData]
    public void Invocation_ExtensionMethod_Pointer([CombinatorialValues("ref readonly", "ref", "in")] string modifier)
    {
        var source = $$"""
            static class C
            {
                static void M(this {{modifier}} int x) => System.Console.Write(x);
                static unsafe void Main()
                {
                    var x = 1;
                    (&x)->M();
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: "1",
            options: TestOptions.UnsafeReleaseExe, verify: Verification.Fails);
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.Main", $$"""
            {
              // Code size       11 (0xb)
              .maxstack  1
              .locals init (int V_0) //x
              IL_0000:  ldc.i4.1
              IL_0001:  stloc.0
              IL_0002:  ldloca.s   V_0
              IL_0004:  conv.u
              IL_0005:  call       "void C.M({{modifier}} int)"
              IL_000a:  ret
            }
            """);
    }
 
    [Fact]
    public void Invocation_CollectionInitializer()
    {
        var source = """
            struct S : System.Collections.IEnumerable
            {
                public int i;
                public System.Collections.IEnumerator GetEnumerator() => throw null;
            }
 
            static class MyStructExtension
            {
                public static void Add(ref this S s, ref readonly S other)
                {
                    s.i += other.i;
                }
            }
 
            static class Program
            {
                static readonly S ro = new S { i = 3 };
                static void Main()
                {
                    var rw = new S { i = 2 };
                    var s = new S
                    {
                        rw, // 1
                        ro  // 2
                    };
                    System.Console.Write(s.i);
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: "5", verify: Verification.Fails).VerifyDiagnostics();
    }
 
    [Fact]
    public void Invocation_CollectionInitializer_MoreArguments()
    {
        var source = """
            struct S : System.Collections.IEnumerable
            {
                public int i;
                public System.Collections.IEnumerator GetEnumerator() => throw null;
            }
 
            static class MyStructExtension
            {
                public static void Add(ref this S s, ref readonly S x, ref readonly S y)
                {
                    s.i += x.i + y.i;
                }
            }
 
            static class Program
            {
                static readonly S ro = new S { i = 3 };
                static void Main()
                {
                    var rw = new S { i = 2 };
                    var s = new S
                    {
                        { rw, ro }, // 1
                        { ro, rw }  // 2
                    };
                    System.Console.Write(s.i);
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: "10", verify: Verification.Fails).VerifyDiagnostics();
    }
 
    [Fact]
    public void Invocation_Delegate()
    {
        var source = """
            delegate void D(ref readonly int p);
            class C
            {
                static void M(ref readonly int p) => System.Console.WriteLine(p);
                static void Main()
                {
                    D d = M;
                    int x = 111;
                    d(ref x);
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: "111");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.Main", """
            {
              // Code size       38 (0x26)
              .maxstack  2
              .locals init (int V_0) //x
              IL_0000:  ldsfld     "D C.<>O.<0>__M"
              IL_0005:  dup
              IL_0006:  brtrue.s   IL_001b
              IL_0008:  pop
              IL_0009:  ldnull
              IL_000a:  ldftn      "void C.M(ref readonly int)"
              IL_0010:  newobj     "D..ctor(object, System.IntPtr)"
              IL_0015:  dup
              IL_0016:  stsfld     "D C.<>O.<0>__M"
              IL_001b:  ldc.i4.s   111
              IL_001d:  stloc.0
              IL_001e:  ldloca.s   V_0
              IL_0020:  callvirt   "void D.Invoke(ref readonly int)"
              IL_0025:  ret
            }
            """);
    }
 
    [Fact]
    public void Invocation_Dynamic_01()
    {
        var source = """
            class C
            {
                void M(ref readonly int p) => System.Console.Write(p);
                static void Main()
                {
                    dynamic d = 1;
                    var c = new C();
                    try
                    {
                        c.M(d);
                    }
                    catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException)
                    {
                        System.Console.Write("exception");
                    }
 
                    int i = 2;
                    dynamic cd = new C();
                    cd.M(ref i);
                }
                void M2(dynamic p) => M(p);
 
                void M(ref readonly long p) => System.Console.Write(p);
            }
            """;
        var verifier = CompileAndVerify(source, targetFramework: TargetFramework.StandardAndCSharp, expectedOutput: "exception2");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.M2", """
            {
              // Code size       92 (0x5c)
              .maxstack  9
              IL_0000:  ldsfld     "System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, C, dynamic>> C.<>o__2.<>p__0"
              IL_0005:  brtrue.s   IL_0045
              IL_0007:  ldc.i4     0x102
              IL_000c:  ldstr      "M"
              IL_0011:  ldnull
              IL_0012:  ldtoken    "C"
              IL_0017:  call       "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"
              IL_001c:  ldc.i4.2
              IL_001d:  newarr     "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo"
              IL_0022:  dup
              IL_0023:  ldc.i4.0
              IL_0024:  ldc.i4.1
              IL_0025:  ldnull
              IL_0026:  call       "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"
              IL_002b:  stelem.ref
              IL_002c:  dup
              IL_002d:  ldc.i4.1
              IL_002e:  ldc.i4.0
              IL_002f:  ldnull
              IL_0030:  call       "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"
              IL_0035:  stelem.ref
              IL_0036:  call       "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, string, System.Collections.Generic.IEnumerable<System.Type>, System.Type, System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)"
              IL_003b:  call       "System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, C, dynamic>> System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, C, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)"
              IL_0040:  stsfld     "System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, C, dynamic>> C.<>o__2.<>p__0"
              IL_0045:  ldsfld     "System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, C, dynamic>> C.<>o__2.<>p__0"
              IL_004a:  ldfld      "System.Action<System.Runtime.CompilerServices.CallSite, C, dynamic> System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, C, dynamic>>.Target"
              IL_004f:  ldsfld     "System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, C, dynamic>> C.<>o__2.<>p__0"
              IL_0054:  ldarg.0
              IL_0055:  ldarg.1
              IL_0056:  callvirt   "void System.Action<System.Runtime.CompilerServices.CallSite, C, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, C, dynamic)"
              IL_005b:  ret
            }
            """);
    }
 
    [Fact]
    public void Invocation_Dynamic_02()
    {
        var source = """
            class C
            {
                void M(ref readonly int p) => System.Console.Write(p);
                static void Main()
                {
                    dynamic d = 1;
                    var c = new C();
                    try
                    {
                        c.M(d);
                    }
                    catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException)
                    {
                        System.Console.Write("exception");
                    }
 
                    int i = 2;
                    dynamic cd = new C();
                    cd.M(ref i);
                }
                void M2(dynamic p) => M(p);
            }
            """;
        var verifier = CompileAndVerify(source, targetFramework: TargetFramework.StandardAndCSharp, expectedOutput: "exception2");
 
        verifier.VerifyDiagnostics();
 
        verifier.VerifyIL("C.M2", """
            {
              // Code size       92 (0x5c)
              .maxstack  9
              IL_0000:  ldsfld     "System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, C, dynamic>> C.<>o__2.<>p__0"
              IL_0005:  brtrue.s   IL_0045
              IL_0007:  ldc.i4     0x102
              IL_000c:  ldstr      "M"
              IL_0011:  ldnull
              IL_0012:  ldtoken    "C"
              IL_0017:  call       "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"
              IL_001c:  ldc.i4.2
              IL_001d:  newarr     "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo"
              IL_0022:  dup
              IL_0023:  ldc.i4.0
              IL_0024:  ldc.i4.1
              IL_0025:  ldnull
              IL_0026:  call       "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"
              IL_002b:  stelem.ref
              IL_002c:  dup
              IL_002d:  ldc.i4.1
              IL_002e:  ldc.i4.0
              IL_002f:  ldnull
              IL_0030:  call       "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"
              IL_0035:  stelem.ref
              IL_0036:  call       "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, string, System.Collections.Generic.IEnumerable<System.Type>, System.Type, System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)"
              IL_003b:  call       "System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, C, dynamic>> System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, C, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)"
              IL_0040:  stsfld     "System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, C, dynamic>> C.<>o__2.<>p__0"
              IL_0045:  ldsfld     "System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, C, dynamic>> C.<>o__2.<>p__0"
              IL_004a:  ldfld      "System.Action<System.Runtime.CompilerServices.CallSite, C, dynamic> System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, C, dynamic>>.Target"
              IL_004f:  ldsfld     "System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, C, dynamic>> C.<>o__2.<>p__0"
              IL_0054:  ldarg.0
              IL_0055:  ldarg.1
              IL_0056:  callvirt   "void System.Action<System.Runtime.CompilerServices.CallSite, C, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, C, dynamic)"
              IL_005b:  ret
            }
            """);
    }
 
    [Fact]
    public void Invocation_Dynamic_In()
    {
        var source = """
            class C
            {
                public void M(ref readonly int p) => System.Console.WriteLine(p);
                static void Main()
                {
                    int x = 1;
                    dynamic d = new C();
                    d.M(in x);
 
                    dynamic y = 2;
                    C c = new C();
                    c.M(in y);
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (8,16): error CS8364: Arguments with 'in' modifier cannot be used in dynamically dispatched expressions.
            //         d.M(in x);
            Diagnostic(ErrorCode.ERR_InDynamicMethodArg, "x").WithLocation(8, 16),
            // (12,16): error CS1503: Argument 1: cannot convert from 'in dynamic' to 'ref readonly int'
            //         c.M(in y);
            Diagnostic(ErrorCode.ERR_BadArgType, "y").WithArguments("1", "in dynamic", "ref readonly int").WithLocation(12, 16));
    }
 
    [Theory, CombinatorialData]
    public void VisualBasic_Invocation([CombinatorialValues("ref", "in", "ref readonly")] string modifier)
    {
        var source1 = $$"""
            public class C
            {
                public void M({{modifier}} int p) => System.Console.WriteLine(p);
            }
            """;
        var comp1 = CreateCompilation(source1, targetFramework: TargetFramework.Mscorlib40).VerifyDiagnostics();
 
        var source2 = """
            Public Module Program
                Public Sub Main()
                    Dim i = 123
                    Dim c = New C()
                    c.M(i)
                End Sub
            End Module
            """;
        var comp2 = CreateVisualBasicCompilation("Program", source2,
            compilationOptions: new VisualBasic.VisualBasicCompilationOptions(OutputKind.ConsoleApplication),
            referencedCompilations: new[] { comp1 });
        CompileAndVerify(comp2, expectedOutput: "123").VerifyDiagnostics();
    }
 
    [Theory, CombinatorialData]
    public void VisualBasic_Invocation_Virtual([CombinatorialValues("in", "ref readonly")] string modifier)
    {
        var source1 = $$"""
            public class C
            {
                public virtual void M({{modifier}} int p) => System.Console.WriteLine(p);
            }
            """;
        var comp1 = CreateCompilation(source1, targetFramework: TargetFramework.Mscorlib40).VerifyDiagnostics();
 
        var source2 = """
            Public Module Program
                Public Sub Main()
                    Dim i = 123
                    Dim c = New C()
                    c.M(i)
                End Sub
            End Module
            """;
        CreateVisualBasicCompilation("Program", source2, referencedCompilations: new[] { comp1 }).VerifyDiagnostics(
            // (5) : error BC30657: 'M' has a return type that is not supported or parameter types that are not supported.
            Diagnostic(30657, "M").WithArguments("M").WithLocation(5, 11));
    }
 
    [Theory, CombinatorialData]
    public void VisualBasic_Override([CombinatorialValues("in", "ref readonly")] string modifier)
    {
        var source1 = $$"""
            public class C
            {
                public virtual void M({{modifier}} int p) => System.Console.WriteLine(p);
            }
            """;
        var comp1 = CreateCompilation(source1, targetFramework: TargetFramework.Mscorlib40).VerifyDiagnostics();
 
        var source2 = """
            Public Class D
                Inherits C
                Public Overrides Sub M(ByRef p As Integer)
                End Sub
            End Class
            """;
        CreateVisualBasicCompilation("Program", source2, referencedCompilations: new[] { comp1 }).VerifyDiagnostics(
            // (3) : error BC30657: 'M' has a return type that is not supported or parameter types that are not supported.
            Diagnostic(30657, "M").WithArguments("M").WithLocation(3, 26));
    }
 
    [Fact]
    public void Overridden_RefReadonly_RefReadonly()
    {
        var source = """
            class B
            {
                protected virtual void M(ref readonly int x) => System.Console.WriteLine("B.M" + x);
            }
            class C : B
            {
                protected override void M(ref readonly int x) => System.Console.WriteLine("C.M" + x);
                static void Main()
                {
                    var x = 123;
                    var c = new C();
                    c.M(ref x);
                    c.M(in x);
                    c.M(x);
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: """
            C.M123
            C.M123
            C.M123
            """, sourceSymbolValidator: verify, symbolValidator: verify);
        verifier.VerifyDiagnostics(
            // (14,13): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         c.M(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(14, 13));
 
        static void verify(ModuleSymbol m)
        {
            VerifyRequiresLocationAttributeSynthesized(m);
 
            var p = m.GlobalNamespace.GetMember<MethodSymbol>("C.M").Parameters.Single();
            VerifyRefReadonlyParameter(p, customModifiers: VerifyModifiers.In);
        }
    }
 
    [Fact]
    public void Overridden_In_RefReadonly()
    {
        var source = """
            class B
            {
                protected virtual void M(in int x) => System.Console.WriteLine("B.M" + x);
            }
            class C : B
            {
                protected override void M(ref readonly int x) => System.Console.WriteLine("C.M" + x);
                static void Main()
                {
                    var x = 123;
                    var c = new C();
                    c.M(ref x);
                    c.M(in x);
                    c.M(x);
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: """
            C.M123
            C.M123
            C.M123
            """, sourceSymbolValidator: verify, symbolValidator: verify);
        verifier.VerifyDiagnostics(
            // (7,29): warning CS9196: Reference kind modifier of parameter 'ref readonly int x' doesn't match the corresponding parameter 'in int x' in overridden or implemented member.
            //     protected override void M(ref readonly int x) => System.Console.WriteLine("C.M" + x);
            Diagnostic(ErrorCode.WRN_OverridingDifferentRefness, "M").WithArguments("ref readonly int x", "in int x").WithLocation(7, 29),
            // (12,17): warning CS9191: The 'ref' modifier for argument 1 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
            //         c.M(ref x);
            Diagnostic(ErrorCode.WRN_BadArgRef, "x").WithArguments("1").WithLocation(12, 17));
 
        static void verify(ModuleSymbol m)
        {
            VerifyRequiresLocationAttributeSynthesized(m);
 
            var p = m.GlobalNamespace.GetMember<MethodSymbol>("C.M").Parameters.Single();
            VerifyRefReadonlyParameter(p, customModifiers: VerifyModifiers.In);
        }
    }
 
    [Fact]
    public void Overridden_In_RefReadonly_Indexer()
    {
        var source = """
            class B
            {
                protected virtual int this[in int x]
                {
                    get
                    {
                        System.Console.WriteLine("B" + x);
                        return 0;
                    }
                    set { }
                }
            }
            class C : B
            {
                protected override int this[ref readonly int x]
                {
                    get
                    {
                        System.Console.WriteLine("C" + x);
                        return 0;
                    }
                    set { }
                }
                static void Main()
                {
                    var x = 123;
                    var c = new C();
                    _ = c[ref x];
                    _ = c[in x];
                    _ = c[x];
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: """
            C123
            C123
            C123
            """, sourceSymbolValidator: verify, symbolValidator: verify);
        verifier.VerifyDiagnostics(
                // (17,9): warning CS9196: Reference kind modifier of parameter 'ref readonly int x' doesn't match the corresponding parameter 'in int x' in overridden or implemented member.
                //         get
                Diagnostic(ErrorCode.WRN_OverridingDifferentRefness, "get").WithArguments("ref readonly int x", "in int x").WithLocation(17, 9),
                // (22,9): warning CS9196: Reference kind modifier of parameter 'ref readonly int x' doesn't match the corresponding parameter 'in int x' in overridden or implemented member.
                //         set { }
                Diagnostic(ErrorCode.WRN_OverridingDifferentRefness, "set").WithArguments("ref readonly int x", "in int x").WithLocation(22, 9),
                // (28,19): warning CS9191: The 'ref' modifier for argument 1 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
                //         _ = c[ref x];
                Diagnostic(ErrorCode.WRN_BadArgRef, "x").WithArguments("1").WithLocation(28, 19));
 
        static void verify(ModuleSymbol m)
        {
            VerifyRequiresLocationAttributeSynthesized(m);
 
            var p = m.GlobalNamespace.GetMember<PropertySymbol>("C.this[]").Parameters.Single();
            VerifyRefReadonlyParameter(p, customModifiers: VerifyModifiers.In, isProperty: true);
        }
    }
 
    [Fact]
    public void Overridden_RefReadonly_In()
    {
        var source = """
            class B
            {
                protected virtual void M(ref readonly int x) => System.Console.WriteLine("B.M" + x);
            }
            class C : B
            {
                protected override void M(in int x) => System.Console.WriteLine("C.M" + x);
                static void Main()
                {
                    var x = 123;
                    var c = new C();
                    c.M(ref x);
                    c.M(in x);
                    c.M(x);
                }
            }
            """;
        var verifier = CompileAndVerify(source, expectedOutput: """
            C.M123
            C.M123
            C.M123
            """, sourceSymbolValidator: verify, symbolValidator: verify);
        verifier.VerifyDiagnostics(
            // (7,29): warning CS9196: Reference kind modifier of parameter 'in int x' doesn't match the corresponding parameter 'ref readonly int x' in overridden or implemented member.
            //     protected override void M(in int x) => System.Console.WriteLine("C.M" + x);
            Diagnostic(ErrorCode.WRN_OverridingDifferentRefness, "M").WithArguments("in int x", "ref readonly int x").WithLocation(7, 29),
            // (14,13): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         c.M(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(14, 13));
 
        static void verify(ModuleSymbol m)
        {
            VerifyRequiresLocationAttributeSynthesized(m);
 
            var p = m.GlobalNamespace.GetMember<MethodSymbol>("B.M").Parameters.Single();
            VerifyRefReadonlyParameter(p, customModifiers: VerifyModifiers.In);
        }
    }
 
    [Theory, CombinatorialData]
    public void Overridden_NotIn_RefReadonly([CombinatorialValues("ref", "out")] string modifier)
    {
        var source = $$"""
            class B
            {
                protected virtual void M({{modifier}} int x) => throw null!;
            }
            class C : B
            {
                protected override void M(ref readonly int x) { }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (7,29): error CS0115: 'C.M(ref readonly int)': no suitable method found to override
            //     protected override void M(ref readonly int x) { }
            Diagnostic(ErrorCode.ERR_OverrideNotExpected, "M").WithArguments("C.M(ref readonly int)").WithLocation(7, 29));
    }
 
    [Theory, CombinatorialData]
    public void Overridden_RefReadonly_NotIn([CombinatorialValues("ref", "out")] string modifier)
    {
        var source = $$"""
            class B
            {
                protected virtual void M(ref readonly int x) { }
            }
            class C : B
            {
                protected override void M({{modifier}} int x) => throw null!;
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (7,29): error CS0115: 'C.M(ref int)': no suitable method found to override
            //     protected override void M(ref int x) { }
            Diagnostic(ErrorCode.ERR_OverrideNotExpected, "M").WithArguments($"C.M({modifier} int)").WithLocation(7, 29));
    }
 
    [Theory, CombinatorialData]
    public void Overridden_GenericBase([CombinatorialValues("ref readonly", "in")] string modifier)
    {
        var source = $$"""
            class B<T>
            {
                protected virtual void M(in T x) => throw null;
                protected virtual void M(ref readonly int x) => throw null;
            }
            class C : B<int>
            {
                protected override void M({{modifier}} int x) => throw null;
            }
            """;
 
        CreateCompilation(source, targetFramework: TargetFramework.Net50).VerifyDiagnostics(
            // (8,29): error CS0462: The inherited members 'B<T>.M(in T)' and 'B<T>.M(ref readonly int)' have the same signature in type 'C', so they cannot be overridden
            //     protected override void M(ref readonly int x)
            Diagnostic(ErrorCode.ERR_AmbigOverride, "M").WithArguments("B<T>.M(in T)", "B<T>.M(ref readonly int)", "C").WithLocation(8, 29));
    }
 
    [Fact]
    public void Hiding_RefReadonly_RefReadonly()
    {
        var source = """
            class B
            {
                public void M(ref readonly int x) => System.Console.WriteLine("B" + x);
            }
            class C : B
            {
                public void M(ref readonly int x) => System.Console.WriteLine("C" + x);
                static void Main()
                {
                    var x = 111;
                    var c = new C();
                    c.M(ref x);
                    c.M(in x);
                    c.M(x);
                    ((B)c).M(in x);
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: """
            C111
            C111
            C111
            B111
            """).VerifyDiagnostics(
            // (7,17): warning CS0108: 'C.M(ref readonly int)' hides inherited member 'B.M(ref readonly int)'. Use the new keyword if hiding was intended.
            //     public void M(ref readonly int x) => System.Console.WriteLine("C" + x);
            Diagnostic(ErrorCode.WRN_NewRequired, "M").WithArguments("C.M(ref readonly int)", "B.M(ref readonly int)").WithLocation(7, 17),
            // (14,13): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         c.M(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(14, 13));
    }
 
    [Fact]
    public void Hiding_RefReadonly_RefReadonly_New()
    {
        var source = """
            class B
            {
                public void M(ref readonly int x) => System.Console.WriteLine("B" + x);
            }
            class C : B
            {
                public new void M(ref readonly int x) => System.Console.WriteLine("C" + x);
                static void Main()
                {
                    var x = 111;
                    var c = new C();
                    c.M(ref x);
                    c.M(in x);
                    c.M(x);
                    ((B)c).M(in x);
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: """
            C111
            C111
            C111
            B111
            """).VerifyDiagnostics(
            // (14,13): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         c.M(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(14, 13));
    }
 
    [Fact]
    public void Hiding_In_RefReadonly()
    {
        var source = """
            class B
            {
                public void M(in int x) => System.Console.WriteLine("B" + x);
            }
            class C : B
            {
                public void M(ref readonly int x) => System.Console.WriteLine("C" + x);
                static void Main()
                {
                    var x = 111;
                    var c = new C();
                    c.M(ref x);
                    c.M(in x);
                    c.M(x);
                    ((B)c).M(in x);
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: """
            C111
            C111
            C111
            B111
            """).VerifyDiagnostics(
            // (7,17): warning CS0108: 'C.M(ref readonly int)' hides inherited member 'B.M(in int)'. Use the new keyword if hiding was intended.
            //     public void M(ref readonly int x) => System.Console.WriteLine("C" + x);
            Diagnostic(ErrorCode.WRN_NewRequired, "M").WithArguments("C.M(ref readonly int)", "B.M(in int)").WithLocation(7, 17),
            // (7,17): warning CS9197: Reference kind modifier of parameter 'ref readonly int x' doesn't match the corresponding parameter 'in int x' in hidden member.
            //     public void M(ref readonly int x) => System.Console.WriteLine("C" + x);
            Diagnostic(ErrorCode.WRN_HidingDifferentRefness, "M").WithArguments("ref readonly int x", "in int x").WithLocation(7, 17),
            // (14,13): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         c.M(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(14, 13));
    }
 
    [Fact]
    public void Hiding_In_RefReadonly_New()
    {
        var source = """
            class B
            {
                public void M(in int x) => System.Console.WriteLine("B" + x);
            }
            class C : B
            {
                public new void M(ref readonly int x) => System.Console.WriteLine("C" + x);
                static void Main()
                {
                    var x = 111;
                    var c = new C();
                    c.M(ref x);
                    c.M(in x);
                    c.M(x);
                    ((B)c).M(in x);
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: """
            C111
            C111
            C111
            B111
            """).VerifyDiagnostics(
            // (7,21): warning CS9197: Reference kind modifier of parameter 'ref readonly int x' doesn't match the corresponding parameter 'in int x' in hidden member.
            //     public new void M(ref readonly int x) => System.Console.WriteLine("C" + x);
            Diagnostic(ErrorCode.WRN_HidingDifferentRefness, "M").WithArguments("ref readonly int x", "in int x").WithLocation(7, 21),
            // (14,13): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         c.M(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(14, 13));
    }
 
    [Fact]
    public void Hiding_In_RefReadonly_Indexer()
    {
        var source = """
            class B
            {
                public int this[in int x]
                {
                    get
                    {
                        System.Console.WriteLine("B" + x);
                        return 0;
                    }
                    set { }
                }
            }
            class C : B
            {
                public int this[ref readonly int x]
                {
                    get
                    {
                        System.Console.WriteLine("C" + x);
                        return 0;
                    }
                    set { }
                }
                static void Main()
                {
                    var x = 111;
                    var c = new C();
                    _ = c[ref x];
                    _ = c[in x];
                    _ = c[x];
                    _ = ((B)c)[in x];
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: """
            C111
            C111
            C111
            B111
            """).VerifyDiagnostics(
            // (15,16): warning CS0108: 'C.this[ref readonly int]' hides inherited member 'B.this[in int]'. Use the new keyword if hiding was intended.
            //     public int this[ref readonly int x]
            Diagnostic(ErrorCode.WRN_NewRequired, "this").WithArguments("C.this[ref readonly int]", "B.this[in int]").WithLocation(15, 16),
            // (17,9): warning CS9197: Reference kind modifier of parameter 'ref readonly int x' doesn't match the corresponding parameter 'in int x' in hidden member.
            //         get
            Diagnostic(ErrorCode.WRN_HidingDifferentRefness, "get").WithArguments("ref readonly int x", "in int x").WithLocation(17, 9),
            // (22,9): warning CS9197: Reference kind modifier of parameter 'ref readonly int x' doesn't match the corresponding parameter 'in int x' in hidden member.
            //         set { }
            Diagnostic(ErrorCode.WRN_HidingDifferentRefness, "set").WithArguments("ref readonly int x", "in int x").WithLocation(22, 9),
            // (30,15): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         _ = c[x];
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(30, 15));
    }
 
    [Fact]
    public void Hiding_In_RefReadonly_Indexer_New()
    {
        var source = """
            class B
            {
                public int this[in int x]
                {
                    get
                    {
                        System.Console.WriteLine("B" + x);
                        return 0;
                    }
                    set { }
                }
            }
            class C : B
            {
                public new int this[ref readonly int x]
                {
                    get
                    {
                        System.Console.WriteLine("C" + x);
                        return 0;
                    }
                    set { }
                }
                static void Main()
                {
                    var x = 111;
                    var c = new C();
                    _ = c[ref x];
                    _ = c[in x];
                    _ = c[x];
                    _ = ((B)c)[in x];
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: """
            C111
            C111
            C111
            B111
            """).VerifyDiagnostics(
            // (17,9): warning CS9197: Reference kind modifier of parameter 'ref readonly int x' doesn't match the corresponding parameter 'in int x' in hidden member.
            //         get
            Diagnostic(ErrorCode.WRN_HidingDifferentRefness, "get").WithArguments("ref readonly int x", "in int x").WithLocation(17, 9),
            // (22,9): warning CS9197: Reference kind modifier of parameter 'ref readonly int x' doesn't match the corresponding parameter 'in int x' in hidden member.
            //         set { }
            Diagnostic(ErrorCode.WRN_HidingDifferentRefness, "set").WithArguments("ref readonly int x", "in int x").WithLocation(22, 9),
            // (30,15): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         _ = c[x];
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(30, 15));
    }
 
    [Fact]
    public void Hiding_RefReadonly_In()
    {
        var source = """
            class B
            {
                public void M(ref readonly int x) => System.Console.WriteLine("B" + x);
            }
            class C : B
            {
                public void M(in int x) => System.Console.WriteLine("C" + x);
                static void Main()
                {
                    var x = 111;
                    var c = new C();
                    c.M(ref x);
                    c.M(in x);
                    c.M(x);
                    ((B)c).M(in x);
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: """
            C111
            C111
            C111
            B111
            """).VerifyDiagnostics(
            // (7,17): warning CS0108: 'C.M(in int)' hides inherited member 'B.M(ref readonly int)'. Use the new keyword if hiding was intended.
            //     public void M(in int x) => System.Console.WriteLine("C" + x);
            Diagnostic(ErrorCode.WRN_NewRequired, "M").WithArguments("C.M(in int)", "B.M(ref readonly int)").WithLocation(7, 17),
            // (7,17): warning CS9197: Reference kind modifier of parameter 'in int x' doesn't match the corresponding parameter 'ref readonly int x' in hidden member.
            //     public void M(in int x) => System.Console.WriteLine("C" + x);
            Diagnostic(ErrorCode.WRN_HidingDifferentRefness, "M").WithArguments("in int x", "ref readonly int x").WithLocation(7, 17),
            // (12,17): warning CS9191: The 'ref' modifier for argument 1 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
            //         c.M(ref x);
            Diagnostic(ErrorCode.WRN_BadArgRef, "x").WithArguments("1").WithLocation(12, 17));
    }
 
    [Fact]
    public void Hiding_RefReadonly_In_New()
    {
        var source = """
            class B
            {
                public void M(ref readonly int x) => System.Console.WriteLine("B" + x);
            }
            class C : B
            {
                public new void M(in int x) => System.Console.WriteLine("C" + x);
                static void Main()
                {
                    var x = 111;
                    var c = new C();
                    c.M(ref x);
                    c.M(in x);
                    c.M(x);
                    ((B)c).M(in x);
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: """
            C111
            C111
            C111
            B111
            """).VerifyDiagnostics(
            // (7,21): warning CS9197: Reference kind modifier of parameter 'in int x' doesn't match the corresponding parameter 'ref readonly int x' in hidden member.
            //     public new void M(in int x) => System.Console.WriteLine("C" + x);
            Diagnostic(ErrorCode.WRN_HidingDifferentRefness, "M").WithArguments("in int x", "ref readonly int x").WithLocation(7, 21),
            // (12,17): warning CS9191: The 'ref' modifier for argument 1 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
            //         c.M(ref x);
            Diagnostic(ErrorCode.WRN_BadArgRef, "x").WithArguments("1").WithLocation(12, 17));
    }
 
    [Fact]
    public void Hiding_RefReadonly_Ref()
    {
        var source = """
            class B
            {
                public void M1(ref int x) => System.Console.WriteLine("B.M1");
                public void M2(ref readonly int x) => System.Console.WriteLine("B.M2");
            }
            class C : B
            {
                public void M1(ref readonly int x) => System.Console.WriteLine("C.M1");
                public void M2(ref int x) => System.Console.WriteLine("C.M2");
                static void Main()
                {
                    var x = 1;
                    var c = new C();
                    c.M1(ref x);
                    c.M1(in x);
                    c.M1(x);
                    ((B)c).M1(ref x);
                    c.M2(ref x);
                    c.M2(in x);
                    c.M2(x);
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: """
            C.M1
            C.M1
            C.M1
            B.M1
            C.M2
            B.M2
            B.M2
            """).VerifyDiagnostics(
            // (16,14): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         c.M1(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(16, 14),
            // (20,14): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         c.M2(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(20, 14));
    }
 
    [Fact]
    public void Hiding_RefReadonly_Out()
    {
        var source = """
            class B
            {
                public void M1(out int x)
                {
                    x = 5;
                    System.Console.WriteLine("B.M1");
                }
                public void M2(ref readonly int x) => System.Console.WriteLine("B.M2");
            }
            class C : B
            {
                public void M1(ref readonly int x) => System.Console.WriteLine("C.M1");
                public void M2(out int x)
                {
                    x = 5;
                    System.Console.WriteLine("C.M2");
                }
                static void Main()
                {
                    var x = 1;
                    var c = new C();
                    c.M1(ref x);
                    c.M1(in x);
                    c.M1(x);
                    c.M1(out x);
                    c.M2(ref x);
                    c.M2(in x);
                    c.M2(x);
                    c.M2(out x);
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: """
            C.M1
            C.M1
            C.M1
            B.M1
            B.M2
            B.M2
            B.M2
            C.M2
            """).VerifyDiagnostics(
            // (24,14): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         c.M1(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(24, 14),
            // (28,14): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
            //         c.M2(x);
            Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(28, 14));
    }
 
    [Theory, CombinatorialData]
    public void Hiding_RefReadonly_NotIn_New([CombinatorialValues("ref", "out")] string modifier)
    {
        var source = $$"""
            class B
            {
                public void M1({{modifier}} int x) => throw null!;
                public void M2(ref readonly int x) { }
            }
            class C : B
            {
                public new void M1(ref readonly int x) { }
                public new void M2({{modifier}} int x) => throw null!;
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (8,21): warning CS0109: The member 'C.M1(ref readonly int)' does not hide an accessible member. The new keyword is not required.
            //     public new void M1(ref readonly int x) { }
            Diagnostic(ErrorCode.WRN_NewNotRequired, "M1").WithArguments("C.M1(ref readonly int)").WithLocation(8, 21),
            // (9,21): warning CS0109: The member 'C.M2(ref int)' does not hide an accessible member. The new keyword is not required.
            //     public new void M2(ref int x) => throw null!;
            Diagnostic(ErrorCode.WRN_NewNotRequired, "M2").WithArguments($"C.M2({modifier} int)").WithLocation(9, 21));
    }
 
    [Fact]
    public void Implementation_RefReadonly_RefReadonly()
    {
        var source = """
            interface I
            {
                void M(ref readonly int x);
            }
            class C : I
            {
                public void M(ref readonly int x) => System.Console.WriteLine("C.M" + x);
                static void Main()
                {
                    var x = 1;
                    I c = new C();
                    c.M(in x);
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: "C.M1").VerifyDiagnostics();
    }
 
    [Fact]
    public void Implementation_RefReadonly_RefReadonly_Explicit()
    {
        var source = """
            interface I
            {
                void M(ref readonly int x);
            }
            class C : I
            {
                void I.M(ref readonly int x) => System.Console.WriteLine("C.M" + x);
                static void Main()
                {
                    var x = 1;
                    I c = new C();
                    c.M(in x);
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: "C.M1").VerifyDiagnostics();
    }
 
    [Fact]
    public void Implementation_RefReadonly_In()
    {
        var source = """
            interface I
            {
                void M1(in int x);
                void M2(ref readonly int x);
            }
            class C : I
            {
                public void M1(ref readonly int x) => System.Console.WriteLine("C.M1" + x);
                public void M2(in int x) => System.Console.WriteLine("C.M2" + x);
                static void Main()
                {
                    var x = 1;
                    I c = new C();
                    c.M1(in x);
                    c.M2(in x);
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: """
            C.M11
            C.M21
            """).VerifyDiagnostics(
            // (8,17): warning CS9196: Reference kind modifier of parameter 'ref readonly int x' doesn't match the corresponding parameter 'in int x' in overridden or implemented member.
            //     public void M1(ref readonly int x) { }
            Diagnostic(ErrorCode.WRN_OverridingDifferentRefness, "M1").WithArguments("ref readonly int x", "in int x").WithLocation(8, 17),
            // (9,17): warning CS9196: Reference kind modifier of parameter 'in int x' doesn't match the corresponding parameter 'ref readonly int x' in overridden or implemented member.
            //     public void M2(in int x) { }
            Diagnostic(ErrorCode.WRN_OverridingDifferentRefness, "M2").WithArguments("in int x", "ref readonly int x").WithLocation(9, 17));
    }
 
    [Fact]
    public void Implementation_RefReadonly_In_Explicit()
    {
        var source = """
            interface I
            {
                void M1(in int x);
                void M2(ref readonly int x);
            }
            class C : I
            {
                void I.M1(ref readonly int x) => System.Console.WriteLine("C.M1" + x);
                void I.M2(in int x) => System.Console.WriteLine("C.M2" + x);
                static void Main()
                {
                    var x = 1;
                    I c = new C();
                    c.M1(in x);
                    c.M2(in x);
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: """
            C.M11
            C.M21
            """).VerifyDiagnostics(
            // (8,12): warning CS9196: Reference kind modifier of parameter 'ref readonly int x' doesn't match the corresponding parameter 'in int x' in overridden or implemented member.
            //     void I.M1(ref readonly int x) { }
            Diagnostic(ErrorCode.WRN_OverridingDifferentRefness, "M1").WithArguments("ref readonly int x", "in int x").WithLocation(8, 12),
            // (9,12): warning CS9196: Reference kind modifier of parameter 'in int x' doesn't match the corresponding parameter 'ref readonly int x' in overridden or implemented member.
            //     void I.M2(in int x) { }
            Diagnostic(ErrorCode.WRN_OverridingDifferentRefness, "M2").WithArguments("in int x", "ref readonly int x").WithLocation(9, 12));
    }
 
    [Theory, CombinatorialData]
    public void Implementation_RefReadonly_In_Explicit_Retargeting(bool emit)
    {
        var source1v1 = """
            public interface I
            {
                void M(in int x);
            }
            """;
        var comp1v1 = CreateCompilation(source1v1, assemblyName: "Assembly1");
        var comp1v1Ref = emit ? comp1v1.EmitToImageReference() : comp1v1.ToMetadataReference();
 
        var source1v2 = """
            public interface I
            {
                void M(ref readonly int x);
            }
            """;
        var comp1v2 = CreateCompilation(source1v2, assemblyName: "Assembly1");
        var comp1v2Ref = emit ? comp1v2.EmitToImageReference() : comp1v2.ToMetadataReference();
 
        var source2 = """
            public class C : I
            {
                void I.M(in int x) { }
            }
            """;
        var comp2 = CreateCompilation(source2, new[] { comp1v1Ref }, assemblyName: "Assembly2");
        var comp2Ref = emit ? comp2.EmitToImageReference() : comp2.ToMetadataReference();
 
        var comp3v1 = CreateCompilation("", new[] { comp2Ref, comp1v1Ref }, assemblyName: "Assembly3");
 
        var c1 = comp3v1.GetMember<NamedTypeSymbol>("C");
        var m1 = c1.GetMember<MethodSymbol>("I.M");
        Assert.True(m1 is not RetargetingMethodSymbol);
        Assert.Equal("I.M(in int)", m1.ExplicitInterfaceImplementations.Single().ToDisplayString());
 
        var comp3v2 = CreateCompilation("", new[] { comp2Ref, comp1v2Ref }, assemblyName: "Assembly3");
 
        var c2 = comp3v2.GetMember<NamedTypeSymbol>("C");
        var m2 = c2.GetMember<MethodSymbol>("I.M");
        Assert.Equal(!emit, m2 is RetargetingMethodSymbol);
        Assert.Equal("I.M(ref readonly int)", m2.ExplicitInterfaceImplementations.Single().ToDisplayString());
    }
 
    [Fact]
    public void Implementation_RefReadonly_In_Close()
    {
        var source = """
            interface I
            {
                void M1(in int x);
                void M2(ref readonly int x);
            }
            class C : I
            {
                void M1(ref readonly int x) { }
                void M2(in int x) { }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (6,11): error CS0737: 'C' does not implement interface member 'I.M1(in int)'. 'C.M1(ref readonly int)' cannot implement an interface member because it is not public.
            // class C : I
            Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberNotPublic, "I").WithArguments("C", "I.M1(in int)", "C.M1(ref readonly int)").WithLocation(6, 11),
            // (6,11): error CS0737: 'C' does not implement interface member 'I.M2(ref readonly int)'. 'C.M2(in int)' cannot implement an interface member because it is not public.
            // class C : I
            Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberNotPublic, "I").WithArguments("C", "I.M2(ref readonly int)", "C.M2(in int)").WithLocation(6, 11));
    }
 
    [Fact]
    public void Implementation_RefReadonly_In_Indexer()
    {
        var source = """
            interface I
            {
                int this[ref readonly int x] { get; set; }
            }
            class C : I
            {
                public int this[in int x]
                {
                    get
                    {
                        System.Console.WriteLine("get" + x);
                        return 0;
                    }
                    set
                    {
                        System.Console.WriteLine("set" + x);
                    }
                }
                static void Main()
                {
                    var x = 1;
                    I c = new C();
                    _ = c[in x];
                    c[in x] = 0;
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: """
            get1
            set1
            """).VerifyDiagnostics(
            // (9,9): warning CS9196: Reference kind modifier of parameter 'in int x' doesn't match the corresponding parameter 'ref readonly int x' in overridden or implemented member.
            //         get
            Diagnostic(ErrorCode.WRN_OverridingDifferentRefness, "get").WithArguments("in int x", "ref readonly int x").WithLocation(9, 9),
            // (14,9): warning CS9196: Reference kind modifier of parameter 'in int x' doesn't match the corresponding parameter 'ref readonly int x' in overridden or implemented member.
            //         set
            Diagnostic(ErrorCode.WRN_OverridingDifferentRefness, "set").WithArguments("in int x", "ref readonly int x").WithLocation(14, 9));
    }
 
    [Fact]
    public void Implementation_RefReadonly_In_Indexer_Explicit()
    {
        var source = """
            interface I
            {
                int this[ref readonly int x] { get; set; }
            }
            class C : I
            {
                int I.this[in int x]
                {
                    get
                    {
                        System.Console.WriteLine("get" + x);
                        return 0;
                    }
                    set
                    {
                        System.Console.WriteLine("set" + x);
                    }
                }
                static void Main()
                {
                    var x = 1;
                    I c = new C();
                    _ = c[in x];
                    c[in x] = 0;
                }
            }
            """;
        CompileAndVerify(source, expectedOutput: """
            get1
            set1
            """).VerifyDiagnostics(
            // (9,9): warning CS9196: Reference kind modifier of parameter 'in int x' doesn't match the corresponding parameter 'ref readonly int x' in overridden or implemented member.
            //         get
            Diagnostic(ErrorCode.WRN_OverridingDifferentRefness, "get").WithArguments("in int x", "ref readonly int x").WithLocation(9, 9),
            // (14,9): warning CS9196: Reference kind modifier of parameter 'in int x' doesn't match the corresponding parameter 'ref readonly int x' in overridden or implemented member.
            //         set
            Diagnostic(ErrorCode.WRN_OverridingDifferentRefness, "set").WithArguments("in int x", "ref readonly int x").WithLocation(14, 9));
    }
 
    [Theory, CombinatorialData]
    public void Implementation_RefReadonly_NotIn([CombinatorialValues("ref", "out")] string modifier)
    {
        var source = $$"""
            interface I
            {
                void M1({{modifier}} int x);
                void M2(ref readonly int x);
            }
            class C : I
            {
                public void M1(ref readonly int x) { }
                public void M2({{modifier}} int x) => throw null;
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (6,11): error CS0535: 'C' does not implement interface member 'I.M1(ref int)'
            // class C : I
            Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I").WithArguments("C", $"I.M1({modifier} int)").WithLocation(6, 11),
            // (6,11): error CS0535: 'C' does not implement interface member 'I.M2(ref readonly int)'
            // class C : I
            Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I").WithArguments("C", "I.M2(ref readonly int)").WithLocation(6, 11));
    }
 
    [Theory, CombinatorialData]
    public void Implementation_RefReadonly_NotIn_Explicit([CombinatorialValues("ref", "out")] string modifier)
    {
        var source = $$"""
            interface I
            {
                void M1({{modifier}} int x);
                void M2(ref readonly int x);
            }
            class C : I
            {
                void I.M1(ref readonly int x) { }
                void I.M2({{modifier}} int x) => throw null;
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (6,11): error CS0535: 'C' does not implement interface member 'I.M1(ref int)'
            // class C : I
            Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I").WithArguments("C", $"I.M1({modifier} int)").WithLocation(6, 11),
            // (6,11): error CS0535: 'C' does not implement interface member 'I.M2(ref readonly int)'
            // class C : I
            Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I").WithArguments("C", "I.M2(ref readonly int)").WithLocation(6, 11),
            // (8,12): error CS0539: 'C.M1(ref readonly int)' in explicit interface declaration is not found among members of the interface that can be implemented
            //     void I.M1(ref readonly int x) { }
            Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M1").WithArguments("C.M1(ref readonly int)").WithLocation(8, 12),
            // (9,12): error CS0539: 'C.M2(ref int)' in explicit interface declaration is not found among members of the interface that can be implemented
            //     void I.M2(ref int x) => throw null;
            Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M2").WithArguments($"C.M2({modifier} int)").WithLocation(9, 12));
    }
 
    [Theory, CombinatorialData]
    public void DuplicateMembers([CombinatorialValues("in", "ref", "out")] string modifier)
    {
        var source = $$"""
            class C
            {
                void M(ref readonly int x) { }
                void M({{modifier}} int x) => throw null;
                void M(int x) { }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (4,10): error CS0663: 'C' cannot define an overloaded method that differs only on parameter modifiers 'in' and 'ref readonly'
            //     void M(in int x) => throw null;
            Diagnostic(ErrorCode.ERR_OverloadRefKind, "M").WithArguments("C", "method", modifier, "ref readonly").WithLocation(4, 10));
    }
 
    [Fact]
    public void PartialMembers_RefReadonly()
    {
        var source = """
            partial class C
            {
                public partial void M(ref readonly int x);
            }
            partial class C
            {
                public partial void M(ref readonly int x) => throw null;
            }
            """;
        CreateCompilation(source).VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void PartialMembers_RefReadonly_Inverse()
    {
        var source = """
            partial class C
            {
                public partial void M(ref readonly int x) => throw null;
            }
            partial class C
            {
                public partial void M(ref readonly int x);
            }
            """;
        CreateCompilation(source).VerifyEmitDiagnostics();
    }
 
    [Theory, CombinatorialData]
    public void PartialMembers([CombinatorialValues("ref ", "out ", "in ", "")] string modifier)
    {
        var source = $$"""
            partial class C
            {
                public partial void M(ref readonly int x);
            }
            partial class C
            {
                public partial void M({{modifier}} int x) => throw null;
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (3,25): error CS8795: Partial method 'C.M(ref readonly int)' must have an implementation part because it has accessibility modifiers.
            //     public partial void M(ref readonly int x);
            Diagnostic(ErrorCode.ERR_PartialMethodWithAccessibilityModsMustHaveImplementation, "M").WithArguments("C.M(ref readonly int)").WithLocation(3, 25),
            // (7,25): error CS0759: No defining declaration found for implementing declaration of partial method 'C.M(ref int)'
            //     public partial void M(ref int x) => throw null;
            Diagnostic(ErrorCode.ERR_PartialMethodMustHaveLatent, "M").WithArguments($"C.M({modifier}int)").WithLocation(7, 25));
    }
 
    [Theory, CombinatorialData]
    public void PartialMembers_Inverse([CombinatorialValues("ref ", "out ", "in ", "")] string modifier)
    {
        var source = $$"""
            partial class C
            {
                public partial void M(ref readonly int x) => throw null;
            }
            partial class C
            {
                public partial void M({{modifier}} int x);
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (3,25): error CS0759: No defining declaration found for implementing declaration of partial method 'C.M(ref readonly int)'
            //     public partial void M(ref readonly int x) => throw null;
            Diagnostic(ErrorCode.ERR_PartialMethodMustHaveLatent, "M").WithArguments("C.M(ref readonly int)").WithLocation(3, 25),
            // (7,25): error CS8795: Partial method 'C.M(ref int)' must have an implementation part because it has accessibility modifiers.
            //     public partial void M(ref int x);
            Diagnostic(ErrorCode.ERR_PartialMethodWithAccessibilityModsMustHaveImplementation, "M").WithArguments($"C.M({modifier}int)").WithLocation(7, 25));
    }
 
    [Theory, CombinatorialData]
    public void PartialMembers_DifferentReturnType([CombinatorialValues("ref ", "out ", "in ", "")] string modifier)
    {
        var source = $$"""
            #nullable enable
            partial class C
            {
                public partial string M(ref readonly int x);
            }
            partial class C
            {
                public partial string? M({{modifier}} int x) => throw null!;
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (4,27): error CS8795: Partial method 'C.M(ref readonly int)' must have an implementation part because it has accessibility modifiers.
            //     public partial string M(ref readonly int x);
            Diagnostic(ErrorCode.ERR_PartialMethodWithAccessibilityModsMustHaveImplementation, "M").WithArguments("C.M(ref readonly int)").WithLocation(4, 27),
            // (8,28): error CS0759: No defining declaration found for implementing declaration of partial method 'C.M(out int)'
            //     public partial string? M(out int x) => throw null;
            Diagnostic(ErrorCode.ERR_PartialMethodMustHaveLatent, "M").WithArguments($"C.M({modifier}int)").WithLocation(8, 28));
    }
 
    [Theory, CombinatorialData]
    public void MethodGroupComparer([CombinatorialValues("ref", "in", "")] string modifier)
    {
        var source = $$"""
            class C
            {
                void M(ref readonly int x) { }
                void M2()
                {
                    var m = this.M;
                }
            }
            static class E1
            {
                public static void M(this C c, {{modifier}} int x) { }
            }
            """;
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(
            // (6,17): error CS8917: The delegate type could not be inferred.
            //         var m = this.M;
            Diagnostic(ErrorCode.ERR_CannotInferDelegateType, "this.M").WithLocation(6, 17));
 
        CreateCompilation(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics();
    }
 
    [Theory, CombinatorialData]
    public void MethodGroupComparer_Inverse([CombinatorialValues("ref", "in", "")] string modifier)
    {
        var source = $$"""
            class C
            {
                void M({{modifier}} int x) { }
                void M2()
                {
                    var m = this.M;
                }
            }
            static class E1
            {
                public static void M(this C c, ref readonly int x) { }
            }
            """;
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(
            // (6,17): error CS8917: The delegate type could not be inferred.
            //         var m = this.M;
            Diagnostic(ErrorCode.ERR_CannotInferDelegateType, "this.M").WithLocation(6, 17));
 
        CreateCompilation(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics();
    }
 
    [Theory, CombinatorialData]
    public void MethodGroupComparer_TwoExtensionMethods([CombinatorialValues("ref", "in", "")] string modifier)
    {
        var source = $$"""
            class C
            {
                void M2()
                {
                    var m = this.M;
                }
            }
            static class E1
            {
                public static void M(this C c, ref readonly int x) { }
            }
            static class E2
            {
                public static void M(this C c, {{modifier}} int x) { }
            }
            """;
 
        CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(
            // (5,17): error CS8917: The delegate type could not be inferred.
            //         var m = this.M;
            Diagnostic(ErrorCode.ERR_CannotInferDelegateType, "this.M").WithLocation(5, 17));
 
        CreateCompilation(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (5,17): error CS8917: The delegate type could not be inferred.
            //         var m = this.M;
            Diagnostic(ErrorCode.ERR_CannotInferDelegateType, "this.M").WithLocation(5, 17));
    }
 
    /// <summary>
    /// If <see cref="MemberSignatureComparer.CrefComparer"/> allowed 'ref readonly'/'in' mismatch,
    /// this would report ambiguous cref warning for 'in'.
    /// </summary>
    [Theory, CombinatorialData]
    public void CrefComparer([CombinatorialValues("ref", "in")] string modifier)
    {
        var refKind = modifier switch
        {
            "ref" => RefKind.Ref,
            "in" => RefKind.In,
            _ => throw ExceptionUtilities.UnexpectedValue(modifier)
        };
 
        var source = $$"""
            /// <summary>
            /// <see cref="M({{modifier}} int)"/>
            /// </summary>
            public class C
            {
                void M(ref readonly int x) { }
                void M({{modifier}} int x) { }
            }
            """;
        var comp = CreateCompilation(source, parseOptions: TestOptions.RegularPreview.WithDocumentationMode(DocumentationMode.Diagnose)).VerifyDiagnostics(
            // (7,10): error CS0663: 'C' cannot define an overloaded method that differs only on parameter modifiers 'ref' and 'ref readonly'
            //     void M(ref int x) { }
            Diagnostic(ErrorCode.ERR_OverloadRefKind, "M").WithArguments("C", "method", modifier, "ref readonly").WithLocation(7, 10));
        var tree = comp.SyntaxTrees.Single();
        var model = comp.GetSemanticModel(tree);
        var docComment = tree.GetCompilationUnitRoot().DescendantTrivia().Select(trivia => trivia.GetStructure()).OfType<DocumentationCommentTriviaSyntax>().Single();
        var cref = docComment.DescendantNodes().OfType<XmlCrefAttributeSyntax>().Select(attr => attr.Cref).Single();
        var info = model.GetSymbolInfo(cref);
        var methodFromCref = info.Symbol as IMethodSymbol;
        Assert.Equal(refKind, methodFromCref!.Parameters.Single().RefKind);
        var methodFromClass = comp.GetMembers("C.M").Cast<MethodSymbol>().Single(m => m.Parameters.Single().RefKind == refKind);
        Assert.Same(methodFromCref, methodFromClass.GetPublicSymbol());
    }
 
    [Theory, CombinatorialData]
    public void CrefComparer_RefReadonly([CombinatorialValues("ref", "in")] string modifier)
    {
        var source = $$"""
            /// <summary>
            /// <see cref="M(ref readonly int)"/>
            /// </summary>
            public class C
            {
                void M(ref readonly int x) { }
                void M({{modifier}} int x) { }
            }
            """;
        var comp = CreateCompilation(source, parseOptions: TestOptions.RegularPreview.WithDocumentationMode(DocumentationMode.Diagnose)).VerifyDiagnostics(
            // (7,10): error CS0663: 'C' cannot define an overloaded method that differs only on parameter modifiers 'ref' and 'ref readonly'
            //     void M(ref int x) { }
            Diagnostic(ErrorCode.ERR_OverloadRefKind, "M").WithArguments("C", "method", modifier, "ref readonly").WithLocation(7, 10));
        var tree = comp.SyntaxTrees.Single();
        var model = comp.GetSemanticModel(tree);
        var docComment = tree.GetCompilationUnitRoot().DescendantTrivia().Select(trivia => trivia.GetStructure()).OfType<DocumentationCommentTriviaSyntax>().Single();
        var cref = docComment.DescendantNodes().OfType<XmlCrefAttributeSyntax>().Select(attr => attr.Cref).Single();
        var info = model.GetSymbolInfo(cref);
        var methodFromCref = info.Symbol as IMethodSymbol;
        Assert.Equal(RefKind.RefReadOnlyParameter, methodFromCref!.Parameters.Single().RefKind);
        var methodFromClass = comp.GetMembers("C.M").Cast<MethodSymbol>().Single(m => m.Parameters.Single().RefKind == RefKind.RefReadOnlyParameter);
        Assert.Same(methodFromCref, methodFromClass.GetPublicSymbol());
    }
 
    [Fact]
    public void NoPia()
    {
        var source1 = """
            using System;
            using System.Runtime.InteropServices;
            [assembly: ImportedFromTypeLib("test.dll")]
            [assembly: Guid("EB40B9A2-B368-4001-93E4-8571A8AB3215")]
            [ComImport, Guid("EB40B9A2-B368-4001-93E4-8571A8AB3215")]
            public interface Test
            {
                void Method(ref readonly int x);
            }
            """;
        var comp1 = CreateCompilationWithMscorlib40(source1).VerifyDiagnostics();
        var comp1Ref = comp1.ToMetadataReference(embedInteropTypes: true);
 
        var source2 = """
            class Program
            {
                public void M(Test p)
                {
                    var x = 1;
                    p.Method(in x);
                }
            }
            """;
        var comp2 = CreateCompilationWithMscorlib40(source2, new[] { comp1Ref });
        CompileAndVerify(comp2, symbolValidator: verify).VerifyDiagnostics();
 
        static void verify(ModuleSymbol module)
        {
            Assert.Null(module.GlobalNamespace.GetMember<NamedTypeSymbol>(RequiresLocationAttributeQualifiedName));
 
            var method = module.GlobalNamespace.GetMember<MethodSymbol>("Test.Method");
            var parameter = method.Parameters.Single();
            // Because no attribute is embedded with the parameter, it's decoded as `ref`, not `ref readonly`,
            // and combined with `modreq(In)` that results in a use site error. Same thing happens for `in` parameters.
            VerifyRefReadonlyParameter(parameter, refKind: false, customModifiers: VerifyModifiers.In, useSiteError: true);
            Assert.Equal(RefKind.Ref, parameter.RefKind);
        }
    }
 
    [Theory]
    [InlineData("", "", true)]
    [InlineData("", "ref", false)]
    [InlineData("", "in", false)]
    [InlineData("", "out", false)]
    [InlineData("", "ref readonly", null, false)]
    [InlineData("ref", "in", false, false)]
    [InlineData("ref", "out", false)]
    [InlineData("ref", "ref readonly", null, false)]
    [InlineData("in", "out", false)]
    [InlineData("in", "ref readonly", null, true)]
    [InlineData("out", "ref readonly", null, false)]
    public void Conversions(string x, string y, bool? validInCSharp11, bool? validInCSharp12 = null)
    {
        var source = $$"""
            X x = C.X;
            Y y = C.Y;
 
            var i = 1;
            x({{getArgumentModifier(x)}} i);
            y({{getArgumentModifier(y)}} i);
 
            x = C.Y;
            y = C.X;
 
            x({{getArgumentModifier(x)}} i);
            y({{getArgumentModifier(y)}} i);
 
            class C
            {
                public static void X({{x}} int p) {{getCode(x, "X")}}
                public static void Y({{y}} int p) {{getCode(y, "Y")}}
            }
 
            delegate void X({{x}} int p);
            delegate void Y({{y}} int p);
            """;
 
        var expectedOutput = "XYYX";
 
        var expectedDiagnostics = new[]
        {
            // (8,7): error CS0123: No overload for 'Y' matches delegate 'X'
            // x = C.Y;
            Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "Y").WithArguments("Y", "X").WithLocation(8, 7),
            // (9,7): error CS0123: No overload for 'X' matches delegate 'Y'
            // y = C.X;
            Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "X").WithArguments("X", "Y").WithLocation(9, 7)
        };
 
        if (validInCSharp11 == true)
        {
            CompileAndVerify(source, expectedOutput: expectedOutput, parseOptions: TestOptions.Regular11).VerifyDiagnostics();
        }
        else if (validInCSharp11 == false)
        {
            CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(expectedDiagnostics);
        }
        else
        {
            Assert.NotNull(validInCSharp12);
        }
 
        if (validInCSharp12 ?? validInCSharp11 == true)
        {
            var expectedWarnings = (x, y) is ("in", "ref readonly") or ("ref", "in") or ("ref", "ref readonly")
                ? new[]
                {
                    // (8,5): warning CS9198: Reference kind modifier of parameter 'ref readonly int p' doesn't match the corresponding parameter 'in int p' in target.
                    // x = C.Y;
                    Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "C.Y").WithArguments($"{y} int p", $"{x} int p").WithLocation(8, 5),
                    // (9,5): warning CS9198: Reference kind modifier of parameter 'in int p' doesn't match the corresponding parameter 'ref readonly int p' in target.
                    // y = C.X;
                    Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "C.X").WithArguments($"{x} int p", $"{y} int p").WithLocation(9, 5)
                }
                : Array.Empty<DiagnosticDescription>();
 
            CompileAndVerify(source, expectedOutput: expectedOutput, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedWarnings);
            CompileAndVerify(source, expectedOutput: expectedOutput, parseOptions: TestOptions.RegularPreview).VerifyDiagnostics(expectedWarnings);
        }
        else
        {
            if (x is "ref" && y is "in" or "ref readonly")
            {
                expectedDiagnostics = new[]
                {
                    // (8,5): warning CS9198: Reference kind modifier of parameter 'in int p' doesn't match the corresponding parameter 'ref int p' in target.
                    // x = C.Y;
                    Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "C.Y").WithArguments($"{y} int p", "ref int p").WithLocation(8, 5),
                    // (9,7): error CS0123: No overload for 'X' matches delegate 'Y'
                    // y = C.X;
                    Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "X").WithArguments("X", "Y").WithLocation(9, 7)
                };
            }
 
            CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
            CreateCompilation(source, parseOptions: TestOptions.RegularPreview).VerifyDiagnostics(expectedDiagnostics);
        }
 
        static string getCode(string modifier, string output)
        {
            return modifier == "out"
                ? $$"""{ p = 0; System.Console.Write("{{output}}"); }"""
                : $$"""=> System.Console.Write("{{output}}");""";
        }
 
        static string getArgumentModifier(string modifier)
        {
            return modifier switch
            {
                "ref readonly" => "in",
                _ => modifier
            };
        }
    }
 
    [Theory, CombinatorialData]
    public void Conversion_ExtensionMethod([CombinatorialValues("in", "ref")] string modifier)
    {
        var source1 = $$"""
            class C
            {
                public void X1(ref readonly int p) => System.Console.Write("X1 ");
                public void Y1({{modifier}} int p) => System.Console.Write("Y1 ");
            }
 
            static class E
            {
                public static void X2(this C c, ref readonly int p) => System.Console.Write("X2 ");
                public static void Y2(this C c, {{modifier}} int p) => System.Console.Write("Y2 ");
            }
 
            delegate void X(ref readonly int p);
            delegate void Y({{modifier}} int p);
            """;
 
        var source2 = """
            var c = new C();
            X x = c.X1;
            var i = 1;
            x(in i);
            x = c.Y1;
            x(in i);
            x = c.Y2;
            x(in i);
            """;
 
        if (modifier == "ref")
        {
            CreateCompilation(new[] { source1, source2 }).VerifyDiagnostics(
                // 1.cs(5,7): error CS0123: No overload for 'Y1' matches delegate 'X'
                // x = c.Y1;
                Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "Y1").WithArguments("Y1", "X").WithLocation(5, 7),
                // 1.cs(7,7): error CS0123: No overload for 'Y2' matches delegate 'X'
                // x = c.Y2;
                Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "Y2").WithArguments("Y2", "X").WithLocation(7, 7));
        }
        else
        {
            CompileAndVerify(new[] { source1, source2 }, expectedOutput: "X1 Y1 Y2").VerifyDiagnostics(
                // 1.cs(5,5): warning CS9198: Reference kind modifier of parameter 'in int p' doesn't match the corresponding parameter 'ref readonly int p' in target.
                // x = c.Y1;
                Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "c.Y1").WithArguments("in int p", "ref readonly int p").WithLocation(5, 5),
                // 1.cs(7,5): warning CS9198: Reference kind modifier of parameter 'in int p' doesn't match the corresponding parameter 'ref readonly int p' in target.
                // x = c.Y2;
                Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "c.Y2").WithArguments("in int p", "ref readonly int p").WithLocation(7, 5));
        }
 
        var source3 = $"""
            var c = new C();
            Y y = c.Y1;
            var i = 1;
            y({modifier} i);
            y = c.X1;
            y({modifier} i);
            y = c.X2;
            y({modifier} i);
            """;
 
        CompileAndVerify(new[] { source1, source3 }, expectedOutput: "Y1 X1 X2").VerifyDiagnostics(
            // 1.cs(5,5): warning CS9198: Reference kind modifier of parameter 'ref readonly int p' doesn't match the corresponding parameter 'in int p' in target.
            // y = c.X1;
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "c.X1").WithArguments("ref readonly int p", $"{modifier} int p").WithLocation(5, 5),
            // 1.cs(7,5): warning CS9198: Reference kind modifier of parameter 'ref readonly int p' doesn't match the corresponding parameter 'in int p' in target.
            // y = c.X2;
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "c.X2").WithArguments("ref readonly int p", $"{modifier} int p").WithLocation(7, 5));
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Tuple([CombinatorialValues("in", "ref")] string modifier)
    {
        var source = $$"""
            (X x, Y y) = (C.X, C.Y);
            
            var i = 1;
            x(in i);
            y({{modifier}} i);
            
            (x, y) = (C.Y, C.X);
            
            x(in i);
            y({{modifier}} i);
            
            class C
            {
                public static void X(ref readonly int p) => System.Console.Write("X");
                public static void Y({{modifier}} int p) => System.Console.Write("Y");
            }
            
            delegate void X(ref readonly int p);
            delegate void Y({{modifier}} int p);
            """;
 
        if (modifier == "ref")
        {
            CreateCompilation(source).VerifyDiagnostics(
                // (7,13): error CS0123: No overload for 'Y' matches delegate 'X'
                // (x, y) = (C.Y, C.X);
                Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "Y").WithArguments("Y", "X").WithLocation(7, 13));
        }
        else
        {
            CompileAndVerify(source, expectedOutput: "XYYX").VerifyDiagnostics(
                // (7,11): warning CS9198: Reference kind modifier of parameter 'in int p' doesn't match the corresponding parameter 'ref readonly int p' in target.
                // (x, y) = (C.Y, C.X);
                Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "C.Y").WithArguments($"{modifier} int p", "ref readonly int p").WithLocation(7, 11),
                // (7,16): warning CS9198: Reference kind modifier of parameter 'ref readonly int p' doesn't match the corresponding parameter 'in int p' in target.
                // (x, y) = (C.Y, C.X);
                Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "C.X").WithArguments("ref readonly int p", $"{modifier} int p").WithLocation(7, 16));
        }
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Cast([CombinatorialValues("in", "ref")] string modifier)
    {
        var source1 = $$"""
            class C
            {
                public static void X(ref readonly int p) => System.Console.Write("X");
                public static void Y({{modifier}} int p) => System.Console.Write("Y");
            }
 
            delegate void X(ref readonly int p);
            delegate void Y({{modifier}} int p);
            """;
 
        var source2 = """
            X x = C.X;
            var i = 1;
            x(in i);
            x = (X)C.Y;
            x(in i);
            """;
 
        if (modifier == "ref")
        {
            CreateCompilation(new[] { source1, source2 }).VerifyDiagnostics(
                // 1.cs(4,5): error CS0123: No overload for 'Y' matches delegate 'X'
                // x = (X)C.Y;
                Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "(X)C.Y").WithArguments("Y", "X").WithLocation(4, 5));
        }
        else
        {
            CompileAndVerify(new[] { source1, source2 }, expectedOutput: "XY").VerifyDiagnostics(
                // 1.cs(4,5): warning CS9198: Reference kind modifier of parameter 'in int p' doesn't match the corresponding parameter 'ref readonly int p' in target.
                // x = (X)C.Y;
                Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "(X)C.Y").WithArguments("in int p", "ref readonly int p").WithLocation(4, 5));
        }
 
        var source3 = $"""
            Y y = C.Y;
            var i = 1;
            y({modifier} i);
            y = (Y)C.X;
            y({modifier} i);
            """;
 
        CompileAndVerify(new[] { source1, source3 }, expectedOutput: "YX").VerifyDiagnostics(
            // 1.cs(4,5): warning CS9198: Reference kind modifier of parameter 'ref readonly int p' doesn't match the corresponding parameter 'in int p' in target.
            // y = (Y)C.X;
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "(Y)C.X").WithArguments("ref readonly int p", $"{modifier} int p").WithLocation(4, 5));
    }
 
    [Theory, CombinatorialData]
    public void Conversion_DelegateConstruction([CombinatorialValues("in", "ref")] string modifier)
    {
        var source1 = $$"""
            class C
            {
                public static void X(ref readonly int p) => System.Console.Write("X");
                public static void Y({{modifier}} int p) => System.Console.Write("Y");
            }
 
            delegate void X(ref readonly int p);
            delegate void Y({{modifier}} int p);
            """;
 
        var source2 = """
            X x = C.X;
            var i = 1;
            x(in i);
            x = new X(C.Y);
            x(in i);
            """;
 
        if (modifier == "ref")
        {
            CreateCompilation(new[] { source1, source2 }).VerifyDiagnostics(
                // 1.cs(4,5): error CS0123: No overload for 'Y' matches delegate 'X'
                // x = new X(C.Y);
                Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "new X(C.Y)").WithArguments("Y", "X").WithLocation(4, 5));
        }
        else
        {
            CompileAndVerify(new[] { source1, source2 }, expectedOutput: "XY").VerifyDiagnostics(
                // 1.cs(4,11): warning CS9198: Reference kind modifier of parameter 'in int p' doesn't match the corresponding parameter 'ref readonly int p' in target.
                // x = new X(C.Y);
                Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "C.Y").WithArguments("in int p", "ref readonly int p").WithLocation(4, 11));
        }
 
        var source3 = $"""
            Y y = C.Y;
            var i = 1;
            y({modifier} i);
            y = new Y(C.X);
            y({modifier} i);
            """;
 
        CompileAndVerify(new[] { source1, source3 }, expectedOutput: "YX").VerifyDiagnostics(
            // 1.cs(4,11): warning CS9198: Reference kind modifier of parameter 'ref readonly int p' doesn't match the corresponding parameter 'in int p' in target.
            // y = new Y(C.X);
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "C.X").WithArguments("ref readonly int p", $"{modifier} int p").WithLocation(4, 11));
    }
 
    [Theory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void Conversion_OverloadResolution_01([CombinatorialValues("ref", "in", "ref readonly")] string modifier)
    {
        var source = $$"""
            class C
            {
                void M(ref readonly int x) => System.Console.Write("C");
                void Run()
                {
                    D1 m1 = this.M;
                    D2 m2 = this.M;
 
                    var i = 1;
                    m1(in i);
                    m2({{(modifier == "ref readonly" ? "in" : modifier)}} i);
                }
                static void Main() => new C().Run();
            }
            static class E
            {
                public static void M(this C c, {{modifier}} int x) => System.Console.Write("E");
            }
            delegate void D1(ref readonly int x);
            delegate void D2({{modifier}} int x);
            """;
        var verifier = CompileAndVerify(source, expectedOutput: "CC");
        if (modifier != "ref readonly")
        {
            verifier.VerifyDiagnostics(
                // (7,17): warning CS9198: Reference kind modifier of parameter 'ref readonly int x' doesn't match the corresponding parameter 'in int x' in target.
                //         D2 m2 = this.M;
                Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "this.M").WithArguments("ref readonly int x", $"{modifier} int x").WithLocation(7, 17));
        }
        else
        {
            verifier.VerifyDiagnostics();
        }
    }
 
    [Theory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void Conversion_OverloadResolution_02([CombinatorialValues("ref", "in", "ref readonly")] string modifier)
    {
        var source = $$"""
            class C
            {
                void M({{modifier}} int x) => System.Console.Write("C");
                void Run()
                {
                    D1 m1 = this.M;
                    D2 m2 = this.M;
 
                    var i = 1;
                    m1({{(modifier == "ref readonly" ? "in" : modifier)}} i);
                    m2(in i);
                }
                static void Main() => new C().Run();
            }
            static class E
            {
                public static void M(this C c, ref readonly int x) => System.Console.Write("E");
            }
            delegate void D1({{modifier}} int x);
            delegate void D2(ref readonly int x);
            """;
        var verifier = CompileAndVerify(source,
            expectedOutput: modifier == "ref" ? "CE" : "CC");
        if (modifier == "in")
        {
            verifier.VerifyDiagnostics(
                // (7,17): warning CS9198: Reference kind modifier of parameter 'in int x' doesn't match the corresponding parameter 'ref readonly int x' in target.
                //         D2 m2 = this.M;
                Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "this.M").WithArguments("in int x", "ref readonly int x").WithLocation(7, 17));
        }
        else
        {
            verifier.VerifyDiagnostics();
        }
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void Conversion_OverloadResolution_03()
    {
        static string getSource(string body) => $$"""
            class C
            {
                void M(I1 o, ref readonly int x) => System.Console.Write("1");
                void M(I2 o, ref int x) => System.Console.Write("2");
                void Run()
                {
                    var i = 1;
                    {{body}}
                }
                static void Main() => new C().Run();
            }
            interface I1 { }
            interface I2 { }
            class X : I1, I2 { }
            delegate void D1(X s, ref readonly int x);
            delegate void D2(X s, ref int x);
            """;
 
        var source1 = getSource("""
            D1 m1 = this.M;
            m1(null, in i);
            """);
 
        CompileAndVerify(source1, expectedOutput: "1").VerifyDiagnostics();
 
        var source2 = getSource("""
            D2 m2 = this.M;
            m2(null, ref i);
            """);
 
        CreateCompilation(source2).VerifyDiagnostics(
            // (8,17): error CS0121: The call is ambiguous between the following methods or properties: 'C.M(I1, ref readonly int)' and 'C.M(I2, ref int)'
            //         D2 m2 = this.M;
            Diagnostic(ErrorCode.ERR_AmbigCall, "this.M").WithArguments("C.M(I1, ref readonly int)", "C.M(I2, ref int)").WithLocation(8, 17));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69229")]
    public void Conversion_OverloadResolution_04()
    {
        static string getSource(string body) => $$"""
            class C
            {
                void M(I1 o, in int x) => System.Console.Write("1");
                void M(I2 o, ref int x) => System.Console.Write("2");
                void Run()
                {
                    var i = 1;
                    {{body}}
                }
                static void Main() => new C().Run();
            }
            interface I1 { }
            interface I2 { }
            class X : I1, I2 { }
            delegate void D1(X s, in int x);
            delegate void D2(X s, ref int x);
            """;
 
        var source1 = getSource("""
            D1 m1 = this.M;
            D2 m2 = this.M;
            m1(null, in i);
            m2(null, ref i);
            """);
 
        CompileAndVerify(source1, expectedOutput: "12", parseOptions: TestOptions.Regular11).VerifyDiagnostics();
 
        var source2 = getSource("""
            D1 m1 = this.M;
            m1(null, in i);
            """);
 
        var expectedOutput = "1";
 
        CompileAndVerify(source2, expectedOutput: expectedOutput, parseOptions: TestOptions.Regular12).VerifyDiagnostics();
        CompileAndVerify(source2, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        var source3 = getSource("""
            D2 m2 = this.M;
            m2(null, ref i);
            """);
 
        var expectedDiagnostics = new[]
        {
            // (8,17): error CS0121: The call is ambiguous between the following methods or properties: 'C.M(I1, in int)' and 'C.M(I2, ref int)'
            //         D2 m2 = this.M;
            Diagnostic(ErrorCode.ERR_AmbigCall, "this.M").WithArguments("C.M(I1, in int)", "C.M(I2, ref int)").WithLocation(8, 17)
        };
 
        CreateCompilation(source3, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source3).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Theory, CombinatorialData]
    public void Conversion_LangVersion([CombinatorialValues("in", "ref")] string modifier)
    {
        var source1 = $$"""
            public class C
            {
                public static void X(ref readonly int p) => System.Console.Write("X");
                public static void Y({{modifier}} int p) => System.Console.Write("Y");
            }
 
            public delegate void X(ref readonly int p);
            public delegate void Y({{modifier}} int p);
            """;
        var comp1 = CreateCompilation(source1).VerifyDiagnostics();
        var comp1Ref = comp1.ToMetadataReference();
 
        DiagnosticDescription[] expectedDiagnostics;
        string expectedOutput;
 
        var source2 = """
            X x = C.X;
            var i = 1;
            x(in i);
            x = C.Y;
            x(in i);
            """;
 
        if (modifier == "ref")
        {
            CreateCompilation(source2, new[] { comp1Ref }, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
                // (3,6): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
                // x(in i);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "i").WithArguments("ref readonly parameters", "12.0").WithLocation(3, 6),
                // (4,7): error CS0123: No overload for 'Y' matches delegate 'X'
                // x = C.Y;
                Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "Y").WithArguments("Y", "X").WithLocation(4, 7),
                // (5,6): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
                // x(in i);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "i").WithArguments("ref readonly parameters", "12.0").WithLocation(5, 6));
 
            expectedDiagnostics = new[]
            {
                // (4,7): error CS0123: No overload for 'Y' matches delegate 'X'
                // x = C.Y;
                Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "Y").WithArguments("Y", "X").WithLocation(4, 7)
            };
 
            CreateCompilation(source2, new[] { comp1Ref }, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
            CreateCompilation(source2, new[] { comp1Ref }).VerifyDiagnostics(expectedDiagnostics);
        }
        else
        {
            CreateCompilation(source2, new[] { comp1Ref }, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
                // (3,6): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
                // x(in i);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "i").WithArguments("ref readonly parameters", "12.0").WithLocation(3, 6),
                // (4,5): warning CS9198: Reference kind modifier of parameter 'in int p' doesn't match the corresponding parameter 'ref readonly int p' in target.
                // x = C.Y;
                Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "C.Y").WithArguments("in int p", "ref readonly int p").WithLocation(4, 5),
                // (5,6): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
                // x(in i);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "i").WithArguments("ref readonly parameters", "12.0").WithLocation(5, 6));
 
            expectedDiagnostics = new[]
            {
                // (4,5): warning CS9198: Reference kind modifier of parameter 'in int p' doesn't match the corresponding parameter 'ref readonly int p' in target.
                // x = C.Y;
                Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "C.Y").WithArguments("in int p", "ref readonly int p").WithLocation(4, 5)
            };
 
            expectedOutput = "XY";
 
            CompileAndVerify(source2, new[] { comp1Ref }, expectedOutput: expectedOutput, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
            CompileAndVerify(source2, new[] { comp1Ref }, expectedOutput: expectedOutput).VerifyDiagnostics(expectedDiagnostics);
        }
 
        var source3 = $"""
            Y y = C.Y;
            var i = 1;
            y({modifier} i);
            y = C.X;
            y({modifier} i);
            """;
 
        CreateCompilation(source3, new[] { comp1Ref }, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (4,5): warning CS9198: Reference kind modifier of parameter 'ref readonly int p' doesn't match the corresponding parameter 'in int p' in target.
            // y = C.X;
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "C.X").WithArguments("ref readonly int p", $"{modifier} int p").WithLocation(4, 5));
 
        expectedDiagnostics = new[]
        {
            // (4,5): warning CS9198: Reference kind modifier of parameter 'ref readonly int p' doesn't match the corresponding parameter 'in int p' in target.
            // y = C.X;
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "C.X").WithArguments("ref readonly int p", $"{modifier} int p").WithLocation(4, 5)
        };
 
        expectedOutput = "YX";
 
        CompileAndVerify(source3, new[] { comp1Ref }, expectedOutput: expectedOutput, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CompileAndVerify(source3, new[] { comp1Ref }, expectedOutput: expectedOutput).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Conversion_LangVersion_RefIn()
    {
        var source1 = """
            public class C
            {
                public static void X(ref int p) => System.Console.Write("X");
                public static void Y(in int p) => System.Console.Write("Y");
            }
 
            public delegate void X(ref int p);
            public delegate void Y(in int p);
            """;
        var comp1 = CreateCompilation(source1).VerifyDiagnostics();
        var comp1Ref = comp1.ToMetadataReference();
 
        var source2 = """
            X x = C.X;
            var i = 1;
            x(ref i);
            x = C.Y;
            x(ref i);
            """;
 
        var source3 = """
            Y y = C.Y;
            var j = 1;
            y(in j);
            y = C.X;
            y(in j);
            """;
 
        CreateCompilation(source2 + Environment.NewLine + source3, new[] { comp1Ref }, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (4,7): error CS0123: No overload for 'Y' matches delegate 'X'
            // x = C.Y;
            Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "Y").WithArguments("Y", "X").WithLocation(4, 7),
            // (9,7): error CS0123: No overload for 'X' matches delegate 'Y'
            // y = C.X;
            Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "X").WithArguments("X", "Y").WithLocation(9, 7));
 
        var expectedDiagnostics = new[]
        {
            // (4,5): warning CS9198: Reference kind modifier of parameter 'in int p' doesn't match the corresponding parameter 'ref int p' in target.
            // x = C.Y;
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "C.Y").WithArguments("in int p", "ref int p").WithLocation(4, 5)
        };
 
        var expectedOutput = "XY";
 
        CompileAndVerify(source2, new[] { comp1Ref }, expectedOutput: expectedOutput, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CompileAndVerify(source2, new[] { comp1Ref }, expectedOutput: expectedOutput).VerifyDiagnostics(expectedDiagnostics);
 
        expectedDiagnostics = new[]
        {
            // (4,7): error CS0123: No overload for 'X' matches delegate 'Y'
            // y = C.X;
            Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "X").WithArguments("X", "Y").WithLocation(4, 7)
        };
 
        CreateCompilation(source3, new[] { comp1Ref }, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source3, new[] { comp1Ref }).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Conversion_FunctionPointer_Assignment()
    {
        var source = """
            unsafe
            {
                delegate*<int, void> v = null;
                delegate*<ref readonly int, void> rr = null;
                delegate*<in int, void> i = null;
                delegate*<ref int, void> r = null;
                delegate*<out int, void> o = null;
 
                v = rr;
                i = rr;
                r = rr;
                o = rr;
                r = i;
                i = r;
                rr = r;
                rr = i;
                rr = o;
                rr = v;
                delegate*<ref readonly int, void> rr2 = rr;
            }
            """;
        CreateCompilation(new[] { source, RequiresLocationAttributeDefinition }, options: TestOptions.UnsafeDebugExe).VerifyDiagnostics(
            // 0.cs(9,9): error CS0266: Cannot implicitly convert type 'delegate*<ref readonly int, void>' to 'delegate*<int, void>'. An explicit conversion exists (are you missing a cast?)
            //     v = rr;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "rr").WithArguments("delegate*<ref readonly int, void>", "delegate*<int, void>").WithLocation(9, 9),
            // 0.cs(10,9): error CS0266: Cannot implicitly convert type 'delegate*<ref readonly int, void>' to 'delegate*<in int, void>'. An explicit conversion exists (are you missing a cast?)
            //     i = rr;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "rr").WithArguments("delegate*<ref readonly int, void>", "delegate*<in int, void>").WithLocation(10, 9),
            // 0.cs(11,9): error CS0266: Cannot implicitly convert type 'delegate*<ref readonly int, void>' to 'delegate*<ref int, void>'. An explicit conversion exists (are you missing a cast?)
            //     r = rr;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "rr").WithArguments("delegate*<ref readonly int, void>", "delegate*<ref int, void>").WithLocation(11, 9),
            // 0.cs(12,9): error CS0266: Cannot implicitly convert type 'delegate*<ref readonly int, void>' to 'delegate*<out int, void>'. An explicit conversion exists (are you missing a cast?)
            //     o = rr;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "rr").WithArguments("delegate*<ref readonly int, void>", "delegate*<out int, void>").WithLocation(12, 9),
            // 0.cs(13,9): error CS0266: Cannot implicitly convert type 'delegate*<in int, void>' to 'delegate*<ref int, void>'. An explicit conversion exists (are you missing a cast?)
            //     r = i;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "i").WithArguments("delegate*<in int, void>", "delegate*<ref int, void>").WithLocation(13, 9),
            // 0.cs(14,9): error CS0266: Cannot implicitly convert type 'delegate*<ref int, void>' to 'delegate*<in int, void>'. An explicit conversion exists (are you missing a cast?)
            //     i = r;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "r").WithArguments("delegate*<ref int, void>", "delegate*<in int, void>").WithLocation(14, 9),
            // 0.cs(15,10): error CS0266: Cannot implicitly convert type 'delegate*<ref int, void>' to 'delegate*<ref readonly int, void>'. An explicit conversion exists (are you missing a cast?)
            //     rr = r;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "r").WithArguments("delegate*<ref int, void>", "delegate*<ref readonly int, void>").WithLocation(15, 10),
            // 0.cs(16,10): error CS0266: Cannot implicitly convert type 'delegate*<in int, void>' to 'delegate*<ref readonly int, void>'. An explicit conversion exists (are you missing a cast?)
            //     rr = i;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "i").WithArguments("delegate*<in int, void>", "delegate*<ref readonly int, void>").WithLocation(16, 10),
            // 0.cs(17,10): error CS0266: Cannot implicitly convert type 'delegate*<out int, void>' to 'delegate*<ref readonly int, void>'. An explicit conversion exists (are you missing a cast?)
            //     rr = o;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "o").WithArguments("delegate*<out int, void>", "delegate*<ref readonly int, void>").WithLocation(17, 10),
            // 0.cs(18,10): error CS0266: Cannot implicitly convert type 'delegate*<int, void>' to 'delegate*<ref readonly int, void>'. An explicit conversion exists (are you missing a cast?)
            //     rr = v;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "v").WithArguments("delegate*<int, void>", "delegate*<ref readonly int, void>").WithLocation(18, 10));
    }
 
    [Fact]
    public void Conversion_FunctionPointer_Assignment_Cast()
    {
        var source = """
            unsafe
            {
                delegate*<int, void> v = &V;
                delegate*<ref readonly int, void> rr = &RR;
                delegate*<in int, void> i = &I;
                delegate*<ref int, void> r = &R;
                delegate*<out int, void> o = &O;
 
                var x = 1;
 
                rr = (delegate*<ref readonly int, void>)r; rr(in x);
                rr = (delegate*<ref readonly int, void>)i; rr(in x);
                rr = (delegate*<ref readonly int, void>)o; rr(in x);
                rr = (delegate*<ref readonly int, void>)v; rr(in x);
                r = (delegate*<ref int, void>)i; r(ref x);
                i = (delegate*<in int, void>)r; i(in x);
                v = (delegate*<int, void>)rr; v(x);
                i = (delegate*<in int, void>)rr; i(in x);
                r = (delegate*<ref int, void>)rr; r(ref x);
                o = (delegate*<out int, void>)rr; o(out x);
                delegate*<ref readonly int, void> rr2 = (delegate*<ref readonly int, void>)rr; rr2(in x);
            }
 
            static void V(int p) => System.Console.Write("v ");
            static void RR(ref readonly int p) => System.Console.Write("rr ");
            static void I(in int p) => System.Console.Write("i ");
            static void R(ref int p) => System.Console.Write("r ");
            static void O(out int p) { p = 0; System.Console.Write("o "); }
            """;
        CompileAndVerify(new[] { source, RequiresLocationAttributeDefinition }, verify: Verification.Fails,
            expectedOutput: "r i o v i i v v v v v", options: TestOptions.UnsafeDebugExe).VerifyDiagnostics();
    }
 
    [Theory, CombinatorialData]
    public void Conversion_FunctionPointer_Assignment_LangVersion([CombinatorialValues("in", "ref")] string modifier)
    {
        var source1 = $$"""
            public unsafe class C
            {
                public static delegate*<ref readonly int, void> X1 = &x1;
                public static delegate*<{{modifier}} int, void> Y1 = &y1;
 
                public static delegate*<ref readonly int, void> X2 = &x2;
                public static delegate*<{{modifier}} int, void> Y2 = &y2;
 
                static void x1(ref readonly int p) => System.Console.Write("X1 ");
                static void y1({{modifier}} int p) => System.Console.Write("Y1 ");
 
                static void x2(ref readonly int p) => System.Console.Write("X2 ");
                static void y2({{modifier}} int p) => System.Console.Write("Y2 ");
            }
            """;
        var comp1 = CreateCompilation(new[] { source1, RequiresLocationAttributeDefinition }, options: TestOptions.UnsafeDebugDll);
        comp1.VerifyDiagnostics();
        var comp1Ref = comp1.ToMetadataReference();
 
        var source2 = $$"""
            unsafe
            {
                var i = 1;
                C.X2(in i);
                C.Y2({{modifier}} i);
 
                C.X2 = C.X1;
                C.Y2 = C.Y1;
 
                C.X2(in i);
                C.Y2({{modifier}} i);
 
                C.Y2 = C.X1;
                C.X2 = C.Y1;
 
                C.X2(in i);
                C.Y2({{modifier}} i);
            }
            """;
 
        CreateCompilation(source2, new[] { comp1Ref }, parseOptions: TestOptions.Regular11, options: TestOptions.UnsafeDebugExe).VerifyDiagnostics(
            // (4,13): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //     C.X2(in i);
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "i").WithArguments("ref readonly parameters", "12.0").WithLocation(4, 13),
            // (10,13): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //     C.X2(in i);
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "i").WithArguments("ref readonly parameters", "12.0").WithLocation(10, 13),
            // (13,12): error CS0266: Cannot implicitly convert type 'delegate*<ref readonly int, void>' to 'delegate*<ref int, void>'. An explicit conversion exists (are you missing a cast?)
            //     C.Y2 = C.X1;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "C.X1").WithArguments("delegate*<ref readonly int, void>", $"delegate*<{modifier} int, void>").WithLocation(13, 12),
            // (14,12): error CS0266: Cannot implicitly convert type 'delegate*<ref int, void>' to 'delegate*<ref readonly int, void>'. An explicit conversion exists (are you missing a cast?)
            //     C.X2 = C.Y1;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "C.Y1").WithArguments($"delegate*<{modifier} int, void>", "delegate*<ref readonly int, void>").WithLocation(14, 12),
            // (16,13): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            //     C.X2(in i);
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "i").WithArguments("ref readonly parameters", "12.0").WithLocation(16, 13));
 
        var expectedDiagnostics = new[]
        {
            // (13,12): error CS0266: Cannot implicitly convert type 'delegate*<ref readonly int, void>' to 'delegate*<in int, void>'. An explicit conversion exists (are you missing a cast?)
            //     C.Y2 = C.X1;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "C.X1").WithArguments("delegate*<ref readonly int, void>", $"delegate*<{modifier} int, void>").WithLocation(13, 12),
            // (14,12): error CS0266: Cannot implicitly convert type 'delegate*<in int, void>' to 'delegate*<ref readonly int, void>'. An explicit conversion exists (are you missing a cast?)
            //     C.X2 = C.Y1;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "C.Y1").WithArguments($"delegate*<{modifier} int, void>", "delegate*<ref readonly int, void>").WithLocation(14, 12)
        };
 
        CreateCompilation(source2, new[] { comp1Ref }, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeDebugExe).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source2, new[] { comp1Ref }, options: TestOptions.UnsafeDebugExe).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Conversion_FunctionPointer_Assignment_LangVersion_RefIn()
    {
        var source1 = """
            public unsafe class C
            {
                public static delegate*<ref int, void> X1 = &x1;
                public static delegate*<in int, void> Y1 = &y1;
 
                public static delegate*<ref int, void> X2 = &x2;
                public static delegate*<in int, void> Y2 = &y2;
 
                static void x1(ref int p) => System.Console.Write("X1 ");
                static void y1(in int p) => System.Console.Write("Y1 ");
 
                static void x2(ref int p) => System.Console.Write("X2 ");
                static void y2(in int p) => System.Console.Write("Y2 ");
            }
            """;
        var comp1 = CreateCompilation(new[] { source1, RequiresLocationAttributeDefinition }, options: TestOptions.UnsafeDebugDll);
        comp1.VerifyDiagnostics();
        var comp1Ref = comp1.ToMetadataReference();
 
        var source2 = """
            unsafe
            {
                var i = 1;
                C.X2(ref i);
                C.Y2(in i);
 
                C.X2 = C.X1;
                C.Y2 = C.Y1;
 
                C.X2(ref i);
                C.Y2(in i);
 
                C.Y2 = C.X1;
                C.X2 = C.Y1;
 
                C.X2(ref i);
                C.Y2(in i);
            }
            """;
 
        var expectedDiagnostics = new[]
        {
            // (13,12): error CS0266: Cannot implicitly convert type 'delegate*<ref int, void>' to 'delegate*<in int, void>'. An explicit conversion exists (are you missing a cast?)
            //     C.Y2 = C.X1;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "C.X1").WithArguments("delegate*<ref int, void>", "delegate*<in int, void>").WithLocation(13, 12),
            // (14,12): error CS0266: Cannot implicitly convert type 'delegate*<in int, void>' to 'delegate*<ref int, void>'. An explicit conversion exists (are you missing a cast?)
            //     C.X2 = C.Y1;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "C.Y1").WithArguments("delegate*<in int, void>", "delegate*<ref int, void>").WithLocation(14, 12)
        };
 
        CreateCompilation(source2, new[] { comp1Ref }, parseOptions: TestOptions.Regular11, options: TestOptions.UnsafeDebugExe).VerifyDiagnostics(expectedDiagnostics); CreateCompilation(source2, new[] { comp1Ref }, parseOptions: TestOptions.Regular11, options: TestOptions.UnsafeDebugExe).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source2, new[] { comp1Ref }, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeDebugExe).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source2, new[] { comp1Ref }, options: TestOptions.UnsafeDebugExe).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Conversion_FunctionPointer_MethodGroup()
    {
        var source = """
            unsafe
            {
                delegate*<int, void> v = &V;
                delegate*<ref readonly int, void> rr = &RR;
                delegate*<in int, void> i = &I;
                delegate*<ref int, void> r = &R;
                delegate*<out int, void> o = &O;
 
                rr = &V;
                rr = &R;
                rr = &I;
                rr = &O;
                v = &RR;
                i = &RR;
                r = &RR;
                o = &RR;
                r = &I;
                i = &R;
 
                static void V(int p) => throw null;
                static void RR(ref readonly int p) => throw null;
                static void I(in int p) => throw null;
                static void R(ref int p) => throw null;
                static void O(out int p) => throw null;
            }
            """;
        CreateCompilation(new[] { source, RequiresLocationAttributeDefinition }, options: TestOptions.UnsafeDebugExe).VerifyDiagnostics(
            // 0.cs(9,10): error CS8757: No overload for 'V' matches function pointer 'delegate*<ref readonly int, void>'
            //     rr = &V;
            Diagnostic(ErrorCode.ERR_MethFuncPtrMismatch, "&V").WithArguments("V", "delegate*<ref readonly int, void>").WithLocation(9, 10),
            // 0.cs(10,10): error CS8757: No overload for 'R' matches function pointer 'delegate*<ref readonly int, void>'
            //     rr = &R;
            Diagnostic(ErrorCode.ERR_MethFuncPtrMismatch, "&R").WithArguments("R", "delegate*<ref readonly int, void>").WithLocation(10, 10),
            // 0.cs(11,10): warning CS9198: Reference kind modifier of parameter 'in int p' doesn't match the corresponding parameter 'ref readonly int' in target.
            //     rr = &I;
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "&I").WithArguments("in int p", "ref readonly int").WithLocation(11, 10),
            // 0.cs(12,10): error CS8757: No overload for 'O' matches function pointer 'delegate*<ref readonly int, void>'
            //     rr = &O;
            Diagnostic(ErrorCode.ERR_MethFuncPtrMismatch, "&O").WithArguments("O", "delegate*<ref readonly int, void>").WithLocation(12, 10),
            // 0.cs(13,9): error CS8757: No overload for 'RR' matches function pointer 'delegate*<int, void>'
            //     v = &RR;
            Diagnostic(ErrorCode.ERR_MethFuncPtrMismatch, "&RR").WithArguments("RR", "delegate*<int, void>").WithLocation(13, 9),
            // 0.cs(14,9): warning CS9198: Reference kind modifier of parameter 'ref readonly int p' doesn't match the corresponding parameter 'in int' in target.
            //     i = &RR;
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "&RR").WithArguments("ref readonly int p", "in int").WithLocation(14, 9),
            // 0.cs(15,9): warning CS9198: Reference kind modifier of parameter 'ref readonly int p' doesn't match the corresponding parameter 'ref int' in target.
            //     r = &RR;
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "&RR").WithArguments("ref readonly int p", "ref int").WithLocation(15, 9),
            // 0.cs(16,9): error CS8757: No overload for 'RR' matches function pointer 'delegate*<out int, void>'
            //     o = &RR;
            Diagnostic(ErrorCode.ERR_MethFuncPtrMismatch, "&RR").WithArguments("RR", "delegate*<out int, void>").WithLocation(16, 9),
            // 0.cs(17,9): warning CS9198: Reference kind modifier of parameter 'in int p' doesn't match the corresponding parameter 'ref int' in target.
            //     r = &I;
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "&I").WithArguments("in int p", "ref int").WithLocation(17, 9),
            // 0.cs(18,9): error CS8757: No overload for 'R' matches function pointer 'delegate*<in int, void>'
            //     i = &R;
            Diagnostic(ErrorCode.ERR_MethFuncPtrMismatch, "&R").WithArguments("R", "delegate*<in int, void>").WithLocation(18, 9));
    }
 
    [Theory, CombinatorialData]
    public void Conversion_FunctionPointer_MethodGroup_Cast([CombinatorialValues("in", "ref")] string modifier)
    {
        string getSource(string body) => $$"""
            unsafe
            {
                delegate*<ref readonly int, void> x = &X;
                delegate*<{{modifier}} int, void> y = &Y;
 
                var i = 1;
                x(in i);
                y({{modifier}} i);
 
                {{body}}
 
                x(in i);
                y({{modifier}} i);
 
                static void X(ref readonly int p) => System.Console.Write("X");
                static void Y({{modifier}} int p) => System.Console.Write("Y");
            }
            """;
 
        var source1 = getSource("x = (delegate*<ref readonly int, void>)&Y;");
 
        if (modifier == "ref")
        {
            CreateCompilation(new[] { source1, RequiresLocationAttributeDefinition }, options: TestOptions.UnsafeDebugExe).VerifyDiagnostics(
                // 0.cs(10,9): error CS8757: No overload for 'Y' matches function pointer 'delegate*<ref readonly int, void>'
                //     x = (delegate*<ref readonly int, void>)&Y;
                Diagnostic(ErrorCode.ERR_MethFuncPtrMismatch, "(delegate*<ref readonly int, void>)&Y").WithArguments("Y", "delegate*<ref readonly int, void>").WithLocation(10, 9));
        }
        else
        {
            CompileAndVerify(new[] { source1, RequiresLocationAttributeDefinition }, verify: Verification.Fails,
                expectedOutput: "XYYY", options: TestOptions.UnsafeDebugExe).VerifyDiagnostics(
                // 0.cs(10,9): warning CS9198: Reference kind modifier of parameter 'in int p' doesn't match the corresponding parameter 'ref readonly int' in target.
                //     x = (delegate*<ref readonly int, void>)&Y;
                Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "(delegate*<ref readonly int, void>)&Y").WithArguments("in int p", "ref readonly int").WithLocation(10, 9));
        }
 
        var source2 = getSource($"y = (delegate*<{modifier} int, void>)&X;");
 
        CompileAndVerify(new[] { source2, RequiresLocationAttributeDefinition }, verify: Verification.Fails,
            expectedOutput: "XYXX", options: TestOptions.UnsafeDebugExe).VerifyDiagnostics(
            // 0.cs(10,9): warning CS9198: Reference kind modifier of parameter 'ref readonly int p' doesn't match the corresponding parameter 'in int' in target.
            //     y = (delegate*<in int, void>)&X;
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, $"(delegate*<{modifier} int, void>)&X").WithArguments("ref readonly int p", $"{modifier} int").WithLocation(10, 9));
    }
 
    [Theory, CombinatorialData]
    public void Conversion_FunctionPointer_MethodGroup_LangVersion([CombinatorialValues("in", "ref")] string modifier)
    {
        var source1 = $$"""
            public unsafe class C
            {
                public static void X1(ref readonly int p) => System.Console.Write("X");
                public static void Y1({{modifier}} int p) => System.Console.Write("Y");
 
                public static delegate*<ref readonly int, void> X2;
                public static delegate*<{{modifier}} int, void> Y2;
            }
            """;
        var comp1 = CreateCompilation(new[] { source1, RequiresLocationAttributeDefinition }, options: TestOptions.UnsafeDebugDll);
        comp1.VerifyDiagnostics();
        var comp1Ref = comp1.ToMetadataReference();
 
        DiagnosticDescription[] expectedDiagnostics;
        string expectedOutput;
 
        var source2 = """
            unsafe
            {
                C.X2 = &C.X1;
                var i = 1;
                C.X2(in i);
                C.X2 = &C.Y1;
                C.X2(in i);
            }
            """;
 
        var comp = CreateCompilation(source2, new[] { comp1Ref }, parseOptions: TestOptions.Regular11, options: TestOptions.UnsafeDebugExe);
        if (modifier == "ref")
        {
            comp.VerifyDiagnostics(
                // (5,13): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
                //     C.X2(in i);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "i").WithArguments("ref readonly parameters", "12.0").WithLocation(5, 13),
                // (6,12): error CS8757: No overload for 'Y1' matches function pointer 'delegate*<ref readonly int, void>'
                //     C.X2 = &C.Y1;
                Diagnostic(ErrorCode.ERR_MethFuncPtrMismatch, "&C.Y1").WithArguments("Y1", "delegate*<ref readonly int, void>").WithLocation(6, 12),
                // (7,13): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
                //     C.X2(in i);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "i").WithArguments("ref readonly parameters", "12.0").WithLocation(7, 13));
 
            expectedDiagnostics = new[]
            {
                // (6,12): error CS8757: No overload for 'Y1' matches function pointer 'delegate*<ref readonly int, void>'
                //     C.X2 = &C.Y1;
                Diagnostic(ErrorCode.ERR_MethFuncPtrMismatch, "&C.Y1").WithArguments("Y1", "delegate*<ref readonly int, void>").WithLocation(6, 12)
            };
 
            CreateCompilation(source2, new[] { comp1Ref }, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeDebugExe).VerifyDiagnostics(expectedDiagnostics);
            CreateCompilation(source2, new[] { comp1Ref }, options: TestOptions.UnsafeDebugExe).VerifyDiagnostics(expectedDiagnostics);
        }
        else
        {
            comp.VerifyDiagnostics(
                // (5,13): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
                //     C.X2(in i);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "i").WithArguments("ref readonly parameters", "12.0").WithLocation(5, 13),
                // (6,12): warning CS9198: Reference kind modifier of parameter 'in int p' doesn't match the corresponding parameter 'ref readonly int' in target.
                //     C.X2 = &C.Y1;
                Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "&C.Y1").WithArguments("in int p", "ref readonly int").WithLocation(6, 12),
                // (7,13): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
                //     C.X2(in i);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "i").WithArguments("ref readonly parameters", "12.0").WithLocation(7, 13));
 
            expectedDiagnostics = new[]
            {
                // (6,12): warning CS9198: Reference kind modifier of parameter 'in int p' doesn't match the corresponding parameter 'ref readonly int' in target.
                //     C.X2 = &C.Y1;
                Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "&C.Y1").WithArguments("in int p", "ref readonly int").WithLocation(6, 12)
            };
 
            expectedOutput = "XY";
 
            CompileAndVerify(source2, new[] { comp1Ref }, verify: Verification.Fails, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeDebugExe,
                expectedOutput: expectedOutput).VerifyDiagnostics(expectedDiagnostics);
            CompileAndVerify(source2, new[] { comp1Ref }, verify: Verification.Fails, options: TestOptions.UnsafeDebugExe,
                expectedOutput: expectedOutput).VerifyDiagnostics(expectedDiagnostics);
        }
 
        var source3 = $$"""
            unsafe
            {
                C.Y2 = &C.Y1;
                var i = 1;
                C.Y2({{modifier}} i);
                C.Y2 = &C.X1;
                C.Y2({{modifier}} i);
            }
            """;
 
        CompileAndVerify(source3, new[] { comp1Ref }, verify: Verification.Fails, parseOptions: TestOptions.Regular11, options: TestOptions.UnsafeDebugExe,
            expectedOutput: "YX").VerifyDiagnostics(
            // (6,12): warning CS9198: Reference kind modifier of parameter 'ref readonly int p' doesn't match the corresponding parameter 'in int' in target.
            //     C.Y2 = &C.X1;
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "&C.X1").WithArguments("ref readonly int p", $"{modifier} int").WithLocation(6, 12));
 
        expectedDiagnostics = new[]
        {
            // (6,12): warning CS9198: Reference kind modifier of parameter 'ref readonly int p' doesn't match the corresponding parameter 'in int' in target.
            //     C.Y2 = &C.X1;
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "&C.X1").WithArguments("ref readonly int p", $"{modifier} int").WithLocation(6, 12)
        };
 
        expectedOutput = "YX";
 
        CompileAndVerify(source3, new[] { comp1Ref }, verify: Verification.Fails, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeDebugExe,
            expectedOutput: expectedOutput).VerifyDiagnostics(expectedDiagnostics);
        CompileAndVerify(source3, new[] { comp1Ref }, verify: Verification.Fails, options: TestOptions.UnsafeDebugExe,
            expectedOutput: expectedOutput).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Conversion_FunctionPointer_MethodGroup_LangVersion_RefIn()
    {
        var source1 = """
            public unsafe class C
            {
                public static void X1(ref int p) => System.Console.Write("X");
                public static void Y1(in int p) => System.Console.Write("Y");
 
                public static delegate*<ref int, void> X2;
                public static delegate*<in int, void> Y2;
            }
            """;
        var comp1 = CreateCompilation(source1, options: TestOptions.UnsafeDebugDll);
        comp1.VerifyDiagnostics();
        var comp1Ref = comp1.ToMetadataReference();
 
        var source2 = """
            unsafe
            {
                C.X2 = &C.X1;
                var i = 1;
                C.X2(ref i);
                C.X2 = &C.Y1;
                C.X2(ref i);
            }
            """;
 
        CreateCompilation(source2, new[] { comp1Ref }, parseOptions: TestOptions.Regular11, options: TestOptions.UnsafeDebugExe).VerifyDiagnostics(
            // (6,12): error CS8757: No overload for 'Y1' matches function pointer 'delegate*<ref int, void>'
            //     C.X2 = &C.Y1;
            Diagnostic(ErrorCode.ERR_MethFuncPtrMismatch, "&C.Y1").WithArguments("Y1", "delegate*<ref int, void>").WithLocation(6, 12));
 
        var expectedDiagnostics = new[]
        {
            // (6,12): warning CS9198: Reference kind modifier of parameter 'in int p' doesn't match the corresponding parameter 'ref int' in target.
            //     C.X2 = &C.Y1;
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "&C.Y1").WithArguments("in int p", "ref int").WithLocation(6, 12)
        };
 
        var expectedOutput = "XY";
 
        CompileAndVerify(source2, new[] { comp1Ref }, verify: Verification.Fails, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeDebugExe,
            expectedOutput: expectedOutput).VerifyDiagnostics(expectedDiagnostics);
        CompileAndVerify(source2, new[] { comp1Ref }, verify: Verification.Fails, options: TestOptions.UnsafeDebugExe,
            expectedOutput: expectedOutput).VerifyDiagnostics(expectedDiagnostics);
 
        var source3 = """
            unsafe
            {
                C.Y2 = &C.Y1;
                var i = 1;
                C.Y2(in i);
                C.Y2 = &C.X1;
                C.Y2(in i);
            }
            """;
 
        CreateCompilation(source3, new[] { comp1Ref }, parseOptions: TestOptions.Regular11, options: TestOptions.UnsafeDebugExe).VerifyDiagnostics(
            // (6,12): error CS8757: No overload for 'X1' matches function pointer 'delegate*<in int, void>'
            //     C.Y2 = &C.X1;
            Diagnostic(ErrorCode.ERR_MethFuncPtrMismatch, "&C.X1").WithArguments("X1", "delegate*<in int, void>").WithLocation(6, 12));
 
        expectedDiagnostics = new[]
        {
            // (6,12): error CS8757: No overload for 'X1' matches function pointer 'delegate*<in int, void>'
            //     C.Y2 = &C.X1;
            Diagnostic(ErrorCode.ERR_MethFuncPtrMismatch, "&C.X1").WithArguments("X1", "delegate*<in int, void>").WithLocation(6, 12)
        };
 
        CreateCompilation(source3, new[] { comp1Ref }, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeDebugExe).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source3, new[] { comp1Ref }, options: TestOptions.UnsafeDebugExe).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Conversion_Lambda()
    {
        var source = """
            V v = (int x) => throw null;
            RR rr = (ref readonly int x) => throw null;
            I i = (in int x) => throw null;
            R r = (ref int x) => throw null;
            O o = (out int x) => throw null;
 
            rr = (int x) => throw null;
            rr = (ref int x) => throw null;
            rr = (in int x) => throw null;
            rr = (out int x) => throw null;
            v = (ref readonly int x) => throw null;
            i = (ref readonly int x) => throw null;
            r = (ref readonly int x) => throw null;
            o = (ref readonly int x) => throw null;
            r = (in int x) => throw null;
            i = (ref int x) => throw null;
 
            rr = (int x) => throw null;
            rr = x => throw null;
 
            delegate void V(int p);
            delegate void RR(ref readonly int p);
            delegate void I(in int p);
            delegate void R(ref int p);
            delegate void O(out int p);
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (7,11): error CS1676: Parameter 1 must be declared with the 'ref readonly' keyword
            // rr = (int x) => throw null;
            Diagnostic(ErrorCode.ERR_BadParamRef, "x").WithArguments("1", "ref readonly").WithLocation(7, 11),
            // (7,14): error CS1661: Cannot convert lambda expression to type 'RR' because the parameter types do not match the delegate parameter types
            // rr = (int x) => throw null;
            Diagnostic(ErrorCode.ERR_CantConvAnonMethParams, "=>").WithArguments("lambda expression", "RR").WithLocation(7, 14),
            // (8,15): error CS1676: Parameter 1 must be declared with the 'ref readonly' keyword
            // rr = (ref int x) => throw null;
            Diagnostic(ErrorCode.ERR_BadParamRef, "x").WithArguments("1", "ref readonly").WithLocation(8, 15),
            // (8,18): error CS1661: Cannot convert lambda expression to type 'RR' because the parameter types do not match the delegate parameter types
            // rr = (ref int x) => throw null;
            Diagnostic(ErrorCode.ERR_CantConvAnonMethParams, "=>").WithArguments("lambda expression", "RR").WithLocation(8, 18),
            // (9,6): warning CS9198: Reference kind modifier of parameter 'in int x' doesn't match the corresponding parameter 'ref readonly int p' in target.
            // rr = (in int x) => throw null;
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "(in int x) => throw null").WithArguments("in int x", "ref readonly int p").WithLocation(9, 6),
            // (10,15): error CS1676: Parameter 1 must be declared with the 'ref readonly' keyword
            // rr = (out int x) => throw null;
            Diagnostic(ErrorCode.ERR_BadParamRef, "x").WithArguments("1", "ref readonly").WithLocation(10, 15),
            // (10,18): error CS1661: Cannot convert lambda expression to type 'RR' because the parameter types do not match the delegate parameter types
            // rr = (out int x) => throw null;
            Diagnostic(ErrorCode.ERR_CantConvAnonMethParams, "=>").WithArguments("lambda expression", "RR").WithLocation(10, 18),
            // (11,23): error CS1677: Parameter 1 should not be declared with the 'ref readonly' keyword
            // v = (ref readonly int x) => throw null;
            Diagnostic(ErrorCode.ERR_BadParamExtraRef, "x").WithArguments("1", "ref readonly").WithLocation(11, 23),
            // (11,26): error CS1661: Cannot convert lambda expression to type 'V' because the parameter types do not match the delegate parameter types
            // v = (ref readonly int x) => throw null;
            Diagnostic(ErrorCode.ERR_CantConvAnonMethParams, "=>").WithArguments("lambda expression", "V").WithLocation(11, 26),
            // (12,5): warning CS9198: Reference kind modifier of parameter 'ref readonly int x' doesn't match the corresponding parameter 'in int p' in target.
            // i = (ref readonly int x) => throw null;
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "(ref readonly int x) => throw null").WithArguments("ref readonly int x", "in int p").WithLocation(12, 5),
            // (13,5): warning CS9198: Reference kind modifier of parameter 'ref readonly int x' doesn't match the corresponding parameter 'ref int p' in target.
            // r = (ref readonly int x) => throw null;
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "(ref readonly int x) => throw null").WithArguments("ref readonly int x", "ref int p").WithLocation(13, 5),
            // (14,23): error CS1676: Parameter 1 must be declared with the 'out' keyword
            // o = (ref readonly int x) => throw null;
            Diagnostic(ErrorCode.ERR_BadParamRef, "x").WithArguments("1", "out").WithLocation(14, 23),
            // (14,26): error CS1661: Cannot convert lambda expression to type 'O' because the parameter types do not match the delegate parameter types
            // o = (ref readonly int x) => throw null;
            Diagnostic(ErrorCode.ERR_CantConvAnonMethParams, "=>").WithArguments("lambda expression", "O").WithLocation(14, 26),
            // (15,5): warning CS9198: Reference kind modifier of parameter 'in int x' doesn't match the corresponding parameter 'ref int p' in target.
            // r = (in int x) => throw null;
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, "(in int x) => throw null").WithArguments("in int x", "ref int p").WithLocation(15, 5),
            // (16,14): error CS1676: Parameter 1 must be declared with the 'in' keyword
            // i = (ref int x) => throw null;
            Diagnostic(ErrorCode.ERR_BadParamRef, "x").WithArguments("1", "in").WithLocation(16, 14),
            // (16,17): error CS1661: Cannot convert lambda expression to type 'I' because the parameter types do not match the delegate parameter types
            // i = (ref int x) => throw null;
            Diagnostic(ErrorCode.ERR_CantConvAnonMethParams, "=>").WithArguments("lambda expression", "I").WithLocation(16, 17),
            // (18,11): error CS1676: Parameter 1 must be declared with the 'ref readonly' keyword
            // rr = (int x) => throw null;
            Diagnostic(ErrorCode.ERR_BadParamRef, "x").WithArguments("1", "ref readonly").WithLocation(18, 11),
            // (18,14): error CS1661: Cannot convert lambda expression to type 'RR' because the parameter types do not match the delegate parameter types
            // rr = (int x) => throw null;
            Diagnostic(ErrorCode.ERR_CantConvAnonMethParams, "=>").WithArguments("lambda expression", "RR").WithLocation(18, 14),
            // (19,6): error CS1676: Parameter 1 must be declared with the 'ref readonly' keyword
            // rr = x => throw null;
            Diagnostic(ErrorCode.ERR_BadParamRef, "x").WithArguments("1", "ref readonly").WithLocation(19, 6));
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Lambda_Cast([CombinatorialValues("in", "ref")] string modifier)
    {
        string getSource(string body) => $$"""
            X x = (X)((ref readonly int p) => System.Console.Write("1"));
            Y y = (Y)(({{modifier}} int p) => System.Console.Write("2"));
 
            var i = 1;
            x(in i);
            y({{modifier}} i);
 
            {{body}}
 
            x(in i);
            y({{modifier}} i);
 
            delegate void X(ref readonly int p);
            delegate void Y({{modifier}} int p);
            """;
 
        var source1 = getSource($"""x = (X)(({modifier} int p) => System.Console.Write("3"));""");
 
        if (modifier == "ref")
        {
            CreateCompilation(source1).VerifyDiagnostics(
                // (8,18): error CS1676: Parameter 1 must be declared with the 'ref readonly' keyword
                // x = (X)((ref int p) => System.Console.Write("3"));
                Diagnostic(ErrorCode.ERR_BadParamRef, "p").WithArguments("1", "ref readonly").WithLocation(8, 18),
                // (8,21): error CS1661: Cannot convert lambda expression to type 'X' because the parameter types do not match the delegate parameter types
                // x = (X)((ref int p) => System.Console.Write("3"));
                Diagnostic(ErrorCode.ERR_CantConvAnonMethParams, "=>").WithArguments("lambda expression", "X").WithLocation(8, 21));
        }
        else
        {
            CompileAndVerify(source1, expectedOutput: "1232").VerifyDiagnostics(
                // (8,5): warning CS9198: Reference kind modifier of parameter 'in int p' doesn't match the corresponding parameter 'ref readonly int p' in target.
                // x = (X)((in int p) => System.Console.Write("3"));
                Diagnostic(ErrorCode.WRN_TargetDifferentRefness, @"(X)((in int p) => System.Console.Write(""3""))").WithArguments("in int p", "ref readonly int p").WithLocation(8, 5));
        }
 
        var source2 = getSource("""y = (Y)((ref readonly int p) => System.Console.Write("4"));""");
 
        CompileAndVerify(source2, expectedOutput: "1214").VerifyDiagnostics(
            // (8,5): warning CS9198: Reference kind modifier of parameter 'ref readonly int p' doesn't match the corresponding parameter 'in int p' in target.
            // y = (Y)((ref readonly int p) => System.Console.Write("4"));
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, @"(Y)((ref readonly int p) => System.Console.Write(""4""))").WithArguments("ref readonly int p", $"{modifier} int p").WithLocation(8, 5));
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Lambda_LangVersion([CombinatorialValues("in", "ref")] string modifier)
    {
        var source1 = $$"""
            public class C
            {
                public static void X(X x) { System.Console.Write("X"); int i = 1; x(in i); }
                public static void Y(Y y) { System.Console.Write("Y"); int i = 1; y({{modifier}} i); }
            }
 
            public delegate void X(ref readonly int p);
            public delegate void Y({{modifier}} int p);
            """;
        var comp1 = CreateCompilation(source1);
        comp1.VerifyDiagnostics();
        var comp1Ref = comp1.ToMetadataReference();
 
        var source2 = $$"""
            C.X((ref readonly int p) => System.Console.Write("1"));
            C.Y(({{modifier}} int p) => System.Console.Write("2"));
            C.Y((ref readonly int p) => System.Console.Write("3"));
            """;
 
        CreateCompilation(source2, new[] { comp1Ref }, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (1,10): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            // C.X((ref readonly int p) => System.Console.Write("1"));
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "readonly").WithArguments("ref readonly parameters", "12.0").WithLocation(1, 10),
            // (3,5): warning CS9198: Reference kind modifier of parameter 'ref readonly int p' doesn't match the corresponding parameter 'in int p' in target.
            // C.Y((ref readonly int p) => System.Console.Write("3"));
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, @"(ref readonly int p) => System.Console.Write(""3"")").WithArguments("ref readonly int p", $"{modifier} int p").WithLocation(3, 5),
            // (3,10): error CS9058: Feature 'ref readonly parameters' is not available in C# 11.0. Please use language version 12.0 or greater.
            // C.Y((ref readonly int p) => System.Console.Write("3"));
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "readonly").WithArguments("ref readonly parameters", "12.0").WithLocation(3, 10));
 
        var expectedDiagnostics = new[]
        {
            // (3,5): warning CS9198: Reference kind modifier of parameter 'ref readonly int p' doesn't match the corresponding parameter 'in int p' in target.
            // C.Y((ref readonly int p) => System.Console.Write("3"));
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, @"(ref readonly int p) => System.Console.Write(""3"")").WithArguments("ref readonly int p", $"{modifier} int p").WithLocation(3, 5)
        };
 
        var expectedOutput = "X1Y2Y3";
 
        CompileAndVerify(source2, new[] { comp1Ref }, expectedOutput: expectedOutput, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CompileAndVerify(source2, new[] { comp1Ref }, expectedOutput: expectedOutput).VerifyDiagnostics(expectedDiagnostics);
 
        var source3 = $$"""
            C.X(({{modifier}} int p) => System.Console.Write("4"));
            """;
 
        if (modifier == "ref")
        {
            CreateCompilation(source3, new[] { comp1Ref }, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
                // (1,14): error CS1676: Parameter 1 must be declared with the 'ref readonly' keyword
                // C.X((ref int p) => System.Console.Write("4"));
                Diagnostic(ErrorCode.ERR_BadParamRef, "p").WithArguments("1", "ref readonly").WithLocation(1, 14),
                // (1,17): error CS1661: Cannot convert lambda expression to type 'X' because the parameter types do not match the delegate parameter types
                // C.X((ref int p) => System.Console.Write("4"));
                Diagnostic(ErrorCode.ERR_CantConvAnonMethParams, "=>").WithArguments("lambda expression", "X").WithLocation(1, 17));
 
            expectedDiagnostics = new[]
            {
                // (1,14): error CS1676: Parameter 1 must be declared with the 'ref readonly' keyword
                // C.X((ref int p) => System.Console.Write("4"));
                Diagnostic(ErrorCode.ERR_BadParamRef, "p").WithArguments("1", "ref readonly").WithLocation(1, 14),
                // (1,17): error CS1661: Cannot convert lambda expression to type 'X' because the parameter types do not match the delegate parameter types
                // C.X((ref int p) => System.Console.Write("4"));
                Diagnostic(ErrorCode.ERR_CantConvAnonMethParams, "=>").WithArguments("lambda expression", "X").WithLocation(1, 17)
            };
 
            CreateCompilation(source3, new[] { comp1Ref }, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
            CreateCompilation(source3, new[] { comp1Ref }).VerifyDiagnostics(expectedDiagnostics);
        }
        else
        {
            expectedOutput = "X4";
 
            CompileAndVerify(source3, new[] { comp1Ref }, expectedOutput: expectedOutput, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
                // (1,5): warning CS9198: Reference kind modifier of parameter 'in int p' doesn't match the corresponding parameter 'ref readonly int p' in target.
                // C.X((in int p) => System.Console.Write("4"));
                Diagnostic(ErrorCode.WRN_TargetDifferentRefness, @"(in int p) => System.Console.Write(""4"")").WithArguments("in int p", "ref readonly int p").WithLocation(1, 5));
 
            expectedDiagnostics = new[]
            {
                // (1,5): warning CS9198: Reference kind modifier of parameter 'in int p' doesn't match the corresponding parameter 'ref readonly int p' in target.
                // C.X((in int p) => System.Console.Write("4"));
                Diagnostic(ErrorCode.WRN_TargetDifferentRefness, @"(in int p) => System.Console.Write(""4"")").WithArguments("in int p", "ref readonly int p").WithLocation(1, 5)
            };
 
            CompileAndVerify(source3, new[] { comp1Ref }, expectedOutput: expectedOutput, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
            CompileAndVerify(source3, new[] { comp1Ref }, expectedOutput: expectedOutput).VerifyDiagnostics(expectedDiagnostics);
        }
    }
 
    [Fact]
    public void Conversion_Lambda_LangVersion_RefIn()
    {
        var source1 = """
            public class C
            {
                public static void X(X x) { System.Console.Write("X"); int i = 1; x(ref i); }
                public static void Y(Y y) { System.Console.Write("Y"); int i = 1; y(in i); }
            }
 
            public delegate void X(ref int p);
            public delegate void Y(in int p);
            """;
        var comp1 = CreateCompilation(source1);
        comp1.VerifyDiagnostics();
        var comp1Ref = comp1.ToMetadataReference();
 
        var source2 = """
            C.X((ref int p) => System.Console.Write("1"));
            C.Y((in int p) => System.Console.Write("2"));
 
            C.X((in int p) => System.Console.Write("3"));
            """;
 
        var source3 = """
            C.Y((ref int p) => System.Console.Write("4"));
            """;
 
        CreateCompilation(source2 + Environment.NewLine + source3, new[] { comp1Ref }, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
            // (4,13): error CS1676: Parameter 1 must be declared with the 'ref' keyword
            // C.X((in int p) => System.Console.Write("3"));
            Diagnostic(ErrorCode.ERR_BadParamRef, "p").WithArguments("1", "ref").WithLocation(4, 13),
            // (4,16): error CS1661: Cannot convert lambda expression to type 'X' because the parameter types do not match the delegate parameter types
            // C.X((in int p) => System.Console.Write("3"));
            Diagnostic(ErrorCode.ERR_CantConvAnonMethParams, "=>").WithArguments("lambda expression", "X").WithLocation(4, 16),
            // (5,14): error CS1676: Parameter 1 must be declared with the 'in' keyword
            // C.Y((ref int p) => System.Console.Write("4"));
            Diagnostic(ErrorCode.ERR_BadParamRef, "p").WithArguments("1", "in").WithLocation(5, 14),
            // (5,17): error CS1661: Cannot convert lambda expression to type 'Y' because the parameter types do not match the delegate parameter types
            // C.Y((ref int p) => System.Console.Write("4"));
            Diagnostic(ErrorCode.ERR_CantConvAnonMethParams, "=>").WithArguments("lambda expression", "Y").WithLocation(5, 17));
 
        var expectedDiagnostics = new[]
        {
            // (4,5): warning CS9198: Reference kind modifier of parameter 'in int p' doesn't match the corresponding parameter 'ref int p' in target.
            // C.X((in int p) => System.Console.Write("3"));
            Diagnostic(ErrorCode.WRN_TargetDifferentRefness, @"(in int p) => System.Console.Write(""3"")").WithArguments("in int p", "ref int p").WithLocation(4, 5)
        };
 
        var expectedOutput = "X1Y2X3";
 
        CompileAndVerify(source2, new[] { comp1Ref }, expectedOutput: expectedOutput, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CompileAndVerify(source2, new[] { comp1Ref }, expectedOutput: expectedOutput).VerifyDiagnostics(expectedDiagnostics);
 
        expectedDiagnostics = new[]
        {
            // (1,14): error CS1676: Parameter 1 must be declared with the 'in' keyword
            // C.Y((ref int p) => System.Console.Write("4"));
            Diagnostic(ErrorCode.ERR_BadParamRef, "p").WithArguments("1", "in").WithLocation(1, 14),
            // (1,17): error CS1661: Cannot convert lambda expression to type 'Y' because the parameter types do not match the delegate parameter types
            // C.Y((ref int p) => System.Console.Write("4"));
            Diagnostic(ErrorCode.ERR_CantConvAnonMethParams, "=>").WithArguments("lambda expression", "Y").WithLocation(1, 17)
        };
 
        CreateCompilation(source3, new[] { comp1Ref }, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source3, new[] { comp1Ref }).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71383")]
    public void Conversion_ReadonlySemantics()
    {
        var source = """
            class Program
            {
                static readonly int f = 123;
                static void Main()
                {
                    var d = (in int x) => { };
                    d = (ref int x) => { x = 42; }; // should be an error
                    d(f);
                    System.Console.WriteLine(f);
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (7,22): error CS1676: Parameter 1 must be declared with the 'in' keyword
            //         d = (ref int x) => { x = 42; }; // should be an error
            Diagnostic(ErrorCode.ERR_BadParamRef, "x").WithArguments("1", "in").WithLocation(7, 22),
            // (7,25): error CS1661: Cannot convert lambda expression to type '<anonymous delegate>' because the parameter types do not match the delegate parameter types
            //         d = (ref int x) => { x = 42; }; // should be an error
            Diagnostic(ErrorCode.ERR_CantConvAnonMethParams, "=>").WithArguments("lambda expression", "<anonymous delegate>").WithLocation(7, 25));
    }
}