File: Semantics\RefFieldTests.cs
Web Access
Project: ..\..\..\src\Compilers\CSharp\Test\Semantic\Microsoft.CodeAnalysis.CSharp.Semantic.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Semantic.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE;
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
{
    public class RefFieldTests : CSharpTestBase
    {
        private static string IncludeExpectedOutput(string expectedOutput) => ExecutionConditionUtil.IsMonoOrCoreClr ? expectedOutput : null;
 
        [CombinatorialData]
        [Theory]
        public void LanguageVersionDiagnostics(bool useCompilationReference)
        {
            var sourceA =
@"public ref struct S<T>
{
    public ref T F1;
    public ref readonly T F2;
    public S(ref T t)
    {
        F1 = ref t;
        F2 = ref t;
    }
    S(object unused, T t0)
    {
        this = default;
        this = new S<T>();
        this = new S<T> { F1 = t0 };
    }
    static void M1(T t1)
    {
        S<T> s1;
        s1 = default;
        s1 = new S<T>();
        s1 = new S<T> { F1 = t1 };
    }
    static void M2(ref T t2)
    {
        scoped S<T> s2;
        s2 = new S<T>(ref t2);
        s2 = new S<T> { F1 = t2 };
    }
    static void M3(S<T> s3)
    {
        var other = s3;
        M1(s3.F1);
        M1(s3.F2);
        M2(ref s3.F1);
    }
    void M4(T t4)
    {
        this = default;
        this = new S<T>();
        this = new S<T> { F1 = t4 };
    }
    void M5(S<T> s5)
    {
        var other = this;
        M1(F1);
        M1(F2);
        M2(ref F1);
        M1(this.F1);
        M1(this.F2);
        M2(ref this.F1);
        M1(s5.F1);
        M1(s5.F2);
        M2(ref s5.F1);
    }
}";
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular10, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (3,12): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     public ref T F1;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "ref T").WithArguments("ref fields", "11.0").WithLocation(3, 12),
                // (4,12): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     public ref readonly T F2;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "ref readonly T").WithArguments("ref fields", "11.0").WithLocation(4, 12),
                // (25,9): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         scoped S<T> s2;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(25, 9));
 
            comp = CreateCompilation(sourceA, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class Program
{
    static void M1<T>(T t)
    {
        S<T> s1;
        s1 = default;
        s1 = new S<T>();
        s1 = new S<T> { F1 = t };
    }
    static void M2<T>(ref T t)
    {
        scoped S<T> s2;
        s2 = new S<T>(ref t);
        s2 = new S<T> { F1 = t };
    }
    static void M3<T>(S<T> s)
    {
        var s3 = s;
        M1(s.F1);
        M1(s.F2);
        M2(ref s.F1);
    }
}";
 
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular10, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (8,25): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         s1 = new S<T> { F1 = t };
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "F1").WithArguments("ref fields", "11.0").WithLocation(8, 25),
                // (12,9): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         scoped S<T> s2;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(12, 9),
                // (14,25): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         s2 = new S<T> { F1 = t };
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "F1").WithArguments("ref fields", "11.0").WithLocation(14, 25),
                // (19,12): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         M1(s.F1);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "s.F1").WithArguments("ref fields", "11.0").WithLocation(19, 12),
                // (20,12): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         M1(s.F2);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "s.F2").WithArguments("ref fields", "11.0").WithLocation(20, 12),
                // (21,16): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         M2(ref s.F1);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "s.F1").WithArguments("ref fields", "11.0").WithLocation(21, 16));
 
            VerifyFieldSymbol(comp.GetMember<FieldSymbol>("S.F1"), "ref T S<T>.F1", RefKind.Ref, new string[0]);
            VerifyFieldSymbol(comp.GetMember<FieldSymbol>("S.F2"), "ref readonly T S<T>.F2", RefKind.RefReadOnly, new string[0]);
 
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular11, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
 
            VerifyFieldSymbol(comp.GetMember<FieldSymbol>("S.F1"), "ref T S<T>.F1", RefKind.Ref, new string[0]);
            VerifyFieldSymbol(comp.GetMember<FieldSymbol>("S.F2"), "ref readonly T S<T>.F2", RefKind.RefReadOnly, new string[0]);
        }
 
        [CombinatorialData]
        [Theory]
        public void RefField(bool useCompilationReference)
        {
            var sourceA =
@"public ref struct S<T>
{
    public ref T F;
    public S(ref T t) { F = ref t; }
}";
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular10, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (3,12): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     public ref T F;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "ref T").WithArguments("ref fields", "11.0").WithLocation(3, 12));
 
            VerifyFieldSymbol(comp.GetMember<FieldSymbol>("S.F"), "ref T S<T>.F", RefKind.Ref, new string[0]);
 
            comp = CreateCompilation(sourceA, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
            VerifyFieldSymbol(comp.GetMember<FieldSymbol>("S.F"), "ref T S<T>.F", RefKind.Ref, new string[0]);
 
            var sourceB =
@"using System;
class Program
{
    static void Main()
    {
        int x = 1;
        var s = new S<int>(ref x);
        s.F = 2;
        Console.WriteLine(s.F);
        Console.WriteLine(x);
        x = 3;
        Console.WriteLine(s.F);
        Console.WriteLine(x);
    }
}";
 
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular10, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (8,9): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         s.F = 2;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "s.F").WithArguments("ref fields", "11.0").WithLocation(8, 9),
                // (9,27): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         Console.WriteLine(s.F);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "s.F").WithArguments("ref fields", "11.0").WithLocation(9, 27),
                // (12,27): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         Console.WriteLine(s.F);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "s.F").WithArguments("ref fields", "11.0").WithLocation(12, 27));
 
            VerifyFieldSymbol(comp.GetMember<FieldSymbol>("S.F"), "ref T S<T>.F", RefKind.Ref, new string[0]);
 
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular11, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput(
@"2
2
3
3
"));
            comp = (CSharpCompilation)verifier.Compilation;
            VerifyFieldSymbol(comp.GetMember<FieldSymbol>("S.F"), "ref T S<T>.F", RefKind.Ref, new string[0]);
        }
 
        [CombinatorialData]
        [Theory]
        public void RefReadonlyField(bool useCompilationReference)
        {
            var sourceA =
@"public ref struct S<T>
{
    public ref readonly T F;
    public S(in T t)
    {
        F = ref t;
    }
}";
 
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular10, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (3,12): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     public ref readonly T F;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "ref readonly T").WithArguments("ref fields", "11.0").WithLocation(3, 12));
 
            VerifyFieldSymbol(comp.GetMember<FieldSymbol>("S.F"), "ref readonly T S<T>.F", RefKind.RefReadOnly, new string[0]);
 
            comp = CreateCompilation(sourceA, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
            VerifyFieldSymbol(comp.GetMember<FieldSymbol>("S.F"), "ref readonly T S<T>.F", RefKind.RefReadOnly, new string[0]);
 
            var sourceB =
@"using System;
class A
{
    internal int G;
}
class Program
{
    static void Main()
    {
        A a = new A();
        a.G = 1;
        var s = new S<A>(in a);
        s.F.G = 2;
        Console.WriteLine(s.F.G);
        Console.WriteLine(a.G);
        a.G = 3;
        Console.WriteLine(s.F.G);
        Console.WriteLine(a.G);
    }
}";
 
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular10, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (13,9): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         s.F.G = 2;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "s.F").WithArguments("ref fields", "11.0").WithLocation(13, 9),
                // (14,27): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         Console.WriteLine(s.F.G);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "s.F").WithArguments("ref fields", "11.0").WithLocation(14, 27),
                // (17,27): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         Console.WriteLine(s.F.G);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "s.F").WithArguments("ref fields", "11.0").WithLocation(17, 27));
 
            VerifyFieldSymbol(comp.GetMember<FieldSymbol>("S.F"), "ref readonly T S<T>.F", RefKind.RefReadOnly, new string[0]);
 
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular11, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput(
@"2
2
3
3
"));
            comp = (CSharpCompilation)verifier.Compilation;
            VerifyFieldSymbol(comp.GetMember<FieldSymbol>("S.F"), "ref readonly T S<T>.F", RefKind.RefReadOnly, new string[0]);
        }
 
        [Fact]
        public void SubstitutedField()
        {
            var sourceA =
@".class public A<T>
{
  .field public !0& modopt(object) modopt(int8) F
}";
            var refA = CompileIL(sourceA);
 
            var sourceB =
@"#pragma warning disable 169
class B
{
    static A<int> A;
}";
            var comp = CreateCompilation(sourceB, new[] { refA });
            comp.VerifyEmitDiagnostics();
            CompileAndVerify(comp);
 
            var field = (SubstitutedFieldSymbol)comp.GetMember<FieldSymbol>("B.A").Type.GetMember("F");
            VerifyFieldSymbol(field, "ref modopt(System.SByte) modopt(System.Object) System.Int32 A<System.Int32>.F", RefKind.Ref, new[] { "System.SByte", "System.Object" });
        }
 
        [Fact]
        public void RetargetingField()
        {
            var sourceA =
@"public ref struct A
{
    public ref readonly int F;
}
";
            var comp = CreateCompilation(sourceA, targetFramework: TargetFramework.Mscorlib40);
            var refA = comp.ToMetadataReference();
 
            var sourceB =
@"#pragma warning disable 169
ref struct B
{
    A A;
}";
            comp = CreateCompilation(sourceB, new[] { refA }, targetFramework: TargetFramework.Mscorlib45);
            comp.VerifyEmitDiagnostics();
            CompileAndVerify(comp, verify: Verification.Skipped);
 
            var field = (RetargetingFieldSymbol)comp.GetMember<FieldSymbol>("B.A").Type.GetMember("F");
            // Currently, source symbols cannot declare RefCustomModifiers. If that
            // changes, update this test to verify retargeting of RefCutomModifiers.
            VerifyFieldSymbol(field, "ref readonly System.Int32 A.F", RefKind.RefReadOnly, new string[0]);
        }
 
        [WorkItem(64682, "https://github.com/dotnet/roslyn/issues/64682")]
        [Fact]
        public void RefFieldInNonRefStruct()
        {
            var sourceA =
@".class public A<T>
{
  .field public !0& F1
}
.class public sealed S extends [mscorlib]System.ValueType
{
  .field public int32& F2
}";
            var refA = CompileIL(sourceA);
 
            var sourceB =
@"class Program
{
    static ref int F1(ref A<int> a) => ref a.F1; // 1
    static ref int F2(ref S s) => ref s.F2; // 2
}";
            // https://github.com/dotnet/roslyn/issues/64682: Should report use-site errors.
            var comp = CreateCompilation(sourceB, new[] { refA }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
            CompileAndVerify(comp, verify: Verification.Skipped);
        }
 
        [Fact]
        public void RefAndReadonlyRefStruct_01()
        {
            var source =
@"#pragma warning disable 169
ref struct A
{
    ref int A1;
    ref readonly int A2;
    readonly ref int A3;
    readonly ref readonly int A4;
}
readonly ref struct B
{
    ref int B1;
    ref readonly int B2;
    readonly ref int B3;
    readonly ref readonly int B4;
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (11,13): error CS8340: Instance fields of readonly structs must be readonly.
                //     ref int B1;
                Diagnostic(ErrorCode.ERR_FieldsInRoStruct, "B1").WithLocation(11, 13),
                // (12,22): error CS8340: Instance fields of readonly structs must be readonly.
                //     ref readonly int B2;
                Diagnostic(ErrorCode.ERR_FieldsInRoStruct, "B2").WithLocation(12, 22));
        }
 
        /// <summary>
        /// ref readonly fields emitted as initonly.
        /// ref readonly fields emitted with System.Runtime.CompilerServices.IsReadOnlyAttribute.
        /// </summary>
        [Fact]
        public void RefAndReadonlyRefStruct_02()
        {
            var source =
@"#pragma warning disable 169
ref struct A
{
    ref int A1;
    ref readonly int A2;
    readonly ref int A3;
    readonly ref readonly int A4;
}
readonly ref struct B
{
    readonly ref int B3;
    readonly ref readonly int B4;
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped);
            verifier.VerifyTypeIL("A",
@".class private sequential ansi sealed beforefieldinit A
	extends [System.Runtime]System.ValueType
{
	.custom instance void [System.Runtime]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = (
		01 00 00 00
	)
	.custom instance void [System.Runtime]System.ObsoleteAttribute::.ctor(string, bool) = (
		01 00 52 54 79 70 65 73 20 77 69 74 68 20 65 6d
		62 65 64 64 65 64 20 72 65 66 65 72 65 6e 63 65
		73 20 61 72 65 20 6e 6f 74 20 73 75 70 70 6f 72
		74 65 64 20 69 6e 20 74 68 69 73 20 76 65 72 73
		69 6f 6e 20 6f 66 20 79 6f 75 72 20 63 6f 6d 70
		69 6c 65 72 2e 01 00 00
	)
	.custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute::.ctor(string) = (
		01 00 0a 52 65 66 53 74 72 75 63 74 73 00 00
	)
	// Fields
	.field private int32& A1
	.field private int32& A2
	.custom instance void [System.Runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = (
		01 00 00 00
	)
	.field private initonly int32& A3
	.field private initonly int32& A4
	.custom instance void [System.Runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = (
		01 00 00 00
	)
} // end of class A
");
            verifier.VerifyTypeIL("B",
@".class private sequential ansi sealed beforefieldinit B
	extends [System.Runtime]System.ValueType
{
	.custom instance void [System.Runtime]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = (
		01 00 00 00
	)
	.custom instance void [System.Runtime]System.ObsoleteAttribute::.ctor(string, bool) = (
		01 00 52 54 79 70 65 73 20 77 69 74 68 20 65 6d
		62 65 64 64 65 64 20 72 65 66 65 72 65 6e 63 65
		73 20 61 72 65 20 6e 6f 74 20 73 75 70 70 6f 72
		74 65 64 20 69 6e 20 74 68 69 73 20 76 65 72 73
		69 6f 6e 20 6f 66 20 79 6f 75 72 20 63 6f 6d 70
		69 6c 65 72 2e 01 00 00
	)
	.custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute::.ctor(string) = (
		01 00 0a 52 65 66 53 74 72 75 63 74 73 00 00
	)
	.custom instance void [System.Runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = (
		01 00 00 00
	)
	// Fields
	.field private initonly int32& B3
	.field private initonly int32& B4
	.custom instance void [System.Runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = (
		01 00 00 00
	)
} // end of class B
");
        }
 
        [Fact]
        public void TupleField()
        {
            var sourceA =
@".class public sealed System.ValueTuple`2<T1, T2> extends [mscorlib]System.ValueType
{
  .field public !T1& Item1
  .field public !T2& modopt(int8) modopt(object) Item2
}";
            var refA = CompileIL(sourceA);
 
            var sourceB =
@"class B
{
    static (int, object) F() => default;
}";
            var comp = CreateCompilation(sourceB, targetFramework: TargetFramework.Mscorlib40, references: new[] { refA });
            comp.VerifyEmitDiagnostics();
 
            var tupleType = (NamedTypeSymbol)comp.GetMember<MethodSymbol>("B.F").ReturnType;
            VerifyFieldSymbol(tupleType.GetField("Item1"), "ref System.Int32 (System.Int32, System.Object).Item1", RefKind.Ref, new string[0] { });
            VerifyFieldSymbol(tupleType.GetField("Item2"), "ref modopt(System.Object) modopt(System.SByte) System.Object (System.Int32, System.Object).Item2", RefKind.Ref, new[] { "System.Object", "System.SByte" });
        }
 
        [ConditionalFact(typeof(WindowsDesktopOnly), Reason = ConditionalSkipReason.NoPiaNeedsDesktop)]
        public void EmbeddedField()
        {
            var sourceA =
@".assembly extern mscorlib { .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89) }
.assembly A
{
  .custom instance void [mscorlib]System.Runtime.InteropServices.ImportedFromTypeLibAttribute::.ctor(string) = {string('_.dll')}
  .custom instance void [mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string) = {string('EE8A431D-7D0C-4E13-80C7-52B9C93B9B76')}
}
.class public sealed S extends [mscorlib]System.ValueType
{
  .field public int32& modopt(object) modopt(int32) F
}";
            var refA = CompileIL(sourceA, prependDefaultHeader: false, embedInteropTypes: true);
 
            var sourceB =
@"class Program
{
    static void Main()
    {
        F(new S());
    }
    static void F(object o)
    {
    }
}";
            var comp = CreateCompilation(sourceB, references: new[] { refA, CSharpRef });
            var refB = comp.EmitToImageReference();
 
            comp = CreateCompilation("", new[] { refB });
            var module = (PEModuleSymbol)comp.GetReferencedAssemblySymbol(refB).Modules[0];
            // Read from metadata directly to inspect the embedded type.
            var decoder = new MetadataDecoder(module);
            var reader = module.Module.MetadataReader;
            var fieldHandle = reader.FieldDefinitions.Single(handle => reader.GetString(reader.GetFieldDefinition(handle).Name) == "F");
            var fieldInfo = decoder.DecodeFieldSignature(fieldHandle);
            Assert.True(fieldInfo.IsByRef);
            Assert.Equal(new[] { "System.Int32", "System.Object" }, fieldInfo.RefCustomModifiers.SelectAsArray(m => m.Modifier.ToTestDisplayString()));
        }
 
        [Fact]
        public void FixedField_01()
        {
            var source =
@"unsafe ref struct S
{
    public fixed ref int F1[3];
    public fixed ref readonly int F2[3];
}";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (3,26): error CS9049: A fixed field must not be a ref field.
                //     public fixed ref int F1[3];
                Diagnostic(ErrorCode.ERR_FixedFieldMustNotBeRef, "F1").WithLocation(3, 26),
                // (4,35): error CS9049: A fixed field must not be a ref field.
                //     public fixed ref readonly int F2[3];
                Diagnostic(ErrorCode.ERR_FixedFieldMustNotBeRef, "F2").WithLocation(4, 35));
        }
 
        [Fact]
        public void FixedField_02()
        {
            var sourceA =
@".class public sealed S extends [mscorlib]System.ValueType
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = (01 00 00 00)
  .class sequential nested public sealed FixedBuffer extends [mscorlib]System.ValueType
  {
    .pack 0
    .size 12
    .field public int32 FixedElementField
  }
  .field public valuetype S/FixedBuffer& F
  .custom instance void [mscorlib]System.Runtime.CompilerServices.FixedBufferAttribute::.ctor(class [mscorlib]System.Type, int32) = { type([mscorlib]System.Int32) int32(3) }
}";
            var refA = CompileIL(sourceA);
 
            var sourceB =
@"using System;
class Program
{
    unsafe static void Main()
    {
        var s = new S();
        Console.WriteLine(s.F[1]);
    }
}";
            var comp = CreateCompilation(sourceB, references: new[] { refA }, options: TestOptions.UnsafeReleaseExe, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (7,29): error CS0570: 'S.F' is not supported by the language
                //         Console.WriteLine(s.F[1]);
                Diagnostic(ErrorCode.ERR_BindToBogus, "F").WithArguments("S.F").WithLocation(7, 29));
        }
 
        [Fact]
        public void Volatile()
        {
            var sourceA =
@".class public sealed R extends [mscorlib]System.ValueType
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = (01 00 00 00)
  .field public int32& modreq([mscorlib]System.Runtime.CompilerServices.IsVolatile) F1
  .field public int32 modreq([mscorlib]System.Runtime.CompilerServices.IsVolatile)& F2
}";
            var refA = CompileIL(sourceA);
 
            var sourceB =
@"using System;
class Program
{
    static void Main()
    {
        var r = new R();
        Console.WriteLine(r.F1);
        Console.WriteLine(r.F2);
    }
}";
            var comp = CreateCompilation(sourceB, references: new[] { refA }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (7,29): error CS0570: 'R.F1' is not supported by the language
                //         Console.WriteLine(r.F1);
                Diagnostic(ErrorCode.ERR_BindToBogus, "F1").WithArguments("R.F1").WithLocation(7, 29),
                // (8,29): error CS0570: 'R.F2' is not supported by the language
                //         Console.WriteLine(r.F2);
                Diagnostic(ErrorCode.ERR_BindToBogus, "F2").WithArguments("R.F2").WithLocation(8, 29));
        }
 
        [Fact]
        public void Modifiers()
        {
            var source =
@"#pragma warning disable 0169
ref struct R
{
    static ref int _s1;
    static ref readonly int _s2;
    const ref int _c1 = default;
    const ref readonly int _c2 = default;
    volatile ref int _v1;
    volatile ref readonly int _v2;
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (4,20): error CS0106: The modifier 'static' is not valid for this item
                //     static ref int _s1;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "_s1").WithArguments("static").WithLocation(4, 20),
                // (5,29): error CS0106: The modifier 'static' is not valid for this item
                //     static ref readonly int _s2;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "_s2").WithArguments("static").WithLocation(5, 29),
                // (6,19): error CS0106: The modifier 'static' is not valid for this item
                //     const ref int _c1 = default;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "_c1").WithArguments("static").WithLocation(6, 19),
                // (6,19): error CS0106: The modifier 'const' is not valid for this item
                //     const ref int _c1 = default;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "_c1").WithArguments("const").WithLocation(6, 19),
                // (6,23): error CS8172: Cannot initialize a by-reference variable with a value
                //     const ref int _c1 = default;
                Diagnostic(ErrorCode.ERR_InitializeByReferenceVariableWithValue, "= default").WithLocation(6, 23),
                // (6,25): error CS1510: A ref or out value must be an assignable variable
                //     const ref int _c1 = default;
                Diagnostic(ErrorCode.ERR_RefLvalueExpected, "default").WithLocation(6, 25),
                // (7,28): error CS0106: The modifier 'static' is not valid for this item
                //     const ref readonly int _c2 = default;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "_c2").WithArguments("static").WithLocation(7, 28),
                // (7,28): error CS0106: The modifier 'const' is not valid for this item
                //     const ref readonly int _c2 = default;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "_c2").WithArguments("const").WithLocation(7, 28),
                // (7,32): error CS8172: Cannot initialize a by-reference variable with a value
                //     const ref readonly int _c2 = default;
                Diagnostic(ErrorCode.ERR_InitializeByReferenceVariableWithValue, "= default").WithLocation(7, 32),
                // (7,34): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                //     const ref readonly int _c2 = default;
                Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "default").WithLocation(7, 34),
                // (8,22): error CS0106: The modifier 'volatile' is not valid for this item
                //     volatile ref int _v1;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "_v1").WithArguments("volatile").WithLocation(8, 22),
                // (9,31): error CS0106: The modifier 'volatile' is not valid for this item
                //     volatile ref readonly int _v2;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "_v2").WithArguments("volatile").WithLocation(9, 31));
        }
 
        [Fact]
        public void UnsafeContext_PointerType_MethodParameter()
        {
            var source = @"
public ref struct S
{
    public int F1;
}
public ref struct S2
{
    public ref int F1;
}
 
class C
{
    void M(
        S* s, // 1
        S2* s2, // 2, 3
        C* c) // 4, 5
    {
    }
 
    unsafe void M2(
        S* s,
        S2* s2, // 6
        C* c) // 7
    {
    }
}
";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (14,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //         S* s, // 1
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "S*").WithLocation(14, 9),
                // (15,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //         S2* s2, // 2, 3
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "S2*").WithLocation(15, 9),
                // (15,13): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         S2* s2, // 2, 3
                Diagnostic(ErrorCode.WRN_ManagedAddr, "s2").WithArguments("S2").WithLocation(15, 13),
                // (16,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //         C* c) // 4, 5
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "C*").WithLocation(16, 9),
                // (16,12): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //         C* c) // 4, 5
                Diagnostic(ErrorCode.WRN_ManagedAddr, "c").WithArguments("C").WithLocation(16, 12),
                // (22,13): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         S2* s2, // 6
                Diagnostic(ErrorCode.WRN_ManagedAddr, "s2").WithArguments("S2").WithLocation(22, 13),
                // (23,12): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //         C* c) // 7
                Diagnostic(ErrorCode.WRN_ManagedAddr, "c").WithArguments("C").WithLocation(23, 12)
                );
        }
 
        [Fact]
        public void UnsafeContext_PointerType_MethodReturnType()
        {
            var source = @"
public ref struct S
{
    public int F1;
}
public ref struct S2
{
    public ref int F1;
}
 
unsafe class C
{
    S* M1() => (S*)null;
    S2* M2() => (S2*)null; // 1
    C* M3() => (C*)null; // 2
}
";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (14,9): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //     S2* M2() => (S2*)null; // 1
                Diagnostic(ErrorCode.WRN_ManagedAddr, "M2").WithArguments("S2").WithLocation(14, 9),
                // (14,18): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //     S2* M2() => (S2*)null; // 1
                Diagnostic(ErrorCode.WRN_ManagedAddr, "S2*").WithArguments("S2").WithLocation(14, 18),
                // (15,8): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //     C* M3() => (C*)null; // 2
                Diagnostic(ErrorCode.WRN_ManagedAddr, "M3").WithArguments("C").WithLocation(15, 8),
                // (15,17): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //     C* M3() => (C*)null; // 2
                Diagnostic(ErrorCode.WRN_ManagedAddr, "C*").WithArguments("C").WithLocation(15, 17)
                );
        }
 
        [Fact]
        public void UnsafeContext_PointerType_LocalDeclaration()
        {
            var source = @"
public ref struct S
{
    public int F1;
}
public ref struct S2
{
    public ref int F1;
}
 
class C
{
    unsafe S M2()
    {
        S* s = null;
        return *s;
    }
    unsafe S2 M3()
    {
        S2* s2 = null; // 1
        return *s2;
    }
    unsafe C M4()
    {
        C* c = null; // 2
        return *c;
    }
}
";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (20,9): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         S2* s2 = null; // 1
                Diagnostic(ErrorCode.WRN_ManagedAddr, "S2*").WithArguments("S2").WithLocation(20, 9),
                // (25,9): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //         C* c = null; // 2
                Diagnostic(ErrorCode.WRN_ManagedAddr, "C*").WithArguments("C").WithLocation(25, 9)
                );
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped);
            verifier.VerifyIL("C.M3", @"
{
  // Code size       10 (0xa)
  .maxstack  1
  .locals init (S2* V_0) //s2
  IL_0000:  ldc.i4.0
  IL_0001:  conv.u
  IL_0002:  stloc.0
  IL_0003:  ldloc.0
  IL_0004:  ldobj      ""S2""
  IL_0009:  ret
}
");
            verifier.VerifyIL("C.M4", @"
{
  // Code size        6 (0x6)
  .maxstack  1
  .locals init (C* V_0) //c
  IL_0000:  ldc.i4.0
  IL_0001:  conv.u
  IL_0002:  stloc.0
  IL_0003:  ldloc.0
  IL_0004:  ldind.ref
  IL_0005:  ret
}
");
        }
 
        [Fact]
        public void UnsafeContext_PointerType_FixedStatement()
        {
            var source = @"
public ref struct S
{
    public int F1;
}
public ref struct S2
{
    public ref int F1;
}
 
class C
{
    ref S Prop { get => throw null; }
    ref S2 Prop2 { get => throw null; }
    ref C Prop3 { get => throw null; }
 
    unsafe void M()
    {
        fixed (S* x1 = &Prop) { }
    }
    unsafe void M2()
    {
        fixed (S2* x2 = &Prop2) { } // 1
    }
    unsafe void M3()
    {
        fixed (void* y2 = &Prop2) { } // 2
    }
    unsafe void M4()
    {
        fixed (C* x3 = &Prop3) { } // 3
    }
    unsafe void M5()
    {
        fixed (void* y3 = &Prop3) { } // 4
    }
}
";
            // SPEC:
            // A fixed_pointer_initializer can be one of the following:
            // The token “&” followed by a variable_reference to a moveable variable of type T,
            // provided the type T* is implicitly convertible to the pointer type given in the fixed statement.
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (23,16): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         fixed (S2* x2 = &Prop2) { } // 1
                Diagnostic(ErrorCode.WRN_ManagedAddr, "S2*").WithArguments("S2").WithLocation(23, 16),
                // (23,25): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         fixed (S2* x2 = &Prop2) { } // 1
                Diagnostic(ErrorCode.WRN_ManagedAddr, "&Prop2").WithArguments("S2").WithLocation(23, 25),
                // (23,25): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         fixed (S2* x2 = &Prop2) { } // 1
                Diagnostic(ErrorCode.WRN_ManagedAddr, "&Prop2").WithArguments("S2").WithLocation(23, 25),
                // (27,27): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         fixed (void* y2 = &Prop2) { } // 2
                Diagnostic(ErrorCode.WRN_ManagedAddr, "&Prop2").WithArguments("S2").WithLocation(27, 27),
                // (27,27): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         fixed (void* y2 = &Prop2) { } // 2
                Diagnostic(ErrorCode.WRN_ManagedAddr, "&Prop2").WithArguments("S2").WithLocation(27, 27),
                // (31,16): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //         fixed (C* x3 = &Prop3) { } // 3
                Diagnostic(ErrorCode.WRN_ManagedAddr, "C*").WithArguments("C").WithLocation(31, 16),
                // (31,24): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //         fixed (C* x3 = &Prop3) { } // 3
                Diagnostic(ErrorCode.WRN_ManagedAddr, "&Prop3").WithArguments("C").WithLocation(31, 24),
                // (31,24): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //         fixed (C* x3 = &Prop3) { } // 3
                Diagnostic(ErrorCode.WRN_ManagedAddr, "&Prop3").WithArguments("C").WithLocation(31, 24),
                // (35,27): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //         fixed (void* y3 = &Prop3) { } // 4
                Diagnostic(ErrorCode.WRN_ManagedAddr, "&Prop3").WithArguments("C").WithLocation(35, 27),
                // (35,27): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //         fixed (void* y3 = &Prop3) { } // 4
                Diagnostic(ErrorCode.WRN_ManagedAddr, "&Prop3").WithArguments("C").WithLocation(35, 27)
                );
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped);
            verifier.VerifyIL("C.M2", @"
{
  // Code size       13 (0xd)
  .maxstack  1
  .locals init (pinned S2& V_0)
  IL_0000:  ldarg.0
  IL_0001:  call       ""ref S2 C.Prop2.get""
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  pop
  IL_0009:  ldc.i4.0
  IL_000a:  conv.u
  IL_000b:  stloc.0
  IL_000c:  ret
}
");
            verifier.VerifyIL("C.M4", @"
{
  // Code size       13 (0xd)
  .maxstack  1
  .locals init (pinned C& V_0)
  IL_0000:  ldarg.0
  IL_0001:  call       ""ref C C.Prop3.get""
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  pop
  IL_0009:  ldc.i4.0
  IL_000a:  conv.u
  IL_000b:  stloc.0
  IL_000c:  ret
}
");
        }
 
        [Fact]
        public void UnsafeContext_PointerType_Cast()
        {
            var source = @"
public ref struct S
{
    public int F1;
}
public ref struct S2
{
    public ref int F1;
}
 
class C
{
    void M(void* p)
    {
        _ = (S*)p; // 1
        _ = (S2*)p; // 2
        _ = (C*)p; // 3
    }
 
    unsafe void M2(void* p)
    {
        _ = (S*)p;
        _ = (S2*)p; // 4
        _ = (C*)p; // 5
    }
}
";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (13,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //     void M(void* p)
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "void*").WithLocation(13, 12),
                // (15,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //         _ = (S*)p; // 1
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "_ = (S*)p").WithLocation(15, 9),
                // (15,13): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //         _ = (S*)p; // 1
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "(S*)p").WithLocation(15, 13),
                // (15,14): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //         _ = (S*)p; // 1
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "S*").WithLocation(15, 14),
                // (15,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //         _ = (S*)p; // 1
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "p").WithLocation(15, 17),
                // (16,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //         _ = (S2*)p; // 2
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "_ = (S2*)p").WithLocation(16, 9),
                // (16,13): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //         _ = (S2*)p; // 2
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "(S2*)p").WithLocation(16, 13),
                // (16,14): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //         _ = (S2*)p; // 2
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "S2*").WithLocation(16, 14),
                // (16,14): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         _ = (S2*)p; // 2
                Diagnostic(ErrorCode.WRN_ManagedAddr, "S2*").WithArguments("S2").WithLocation(16, 14),
                // (16,18): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //         _ = (S2*)p; // 2
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "p").WithLocation(16, 18),
                // (17,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //         _ = (C*)p; // 3
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "_ = (C*)p").WithLocation(17, 9),
                // (17,13): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //         _ = (C*)p; // 3
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "(C*)p").WithLocation(17, 13),
                // (17,14): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //         _ = (C*)p; // 3
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "C*").WithLocation(17, 14),
                // (17,14): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //         _ = (C*)p; // 3
                Diagnostic(ErrorCode.WRN_ManagedAddr, "C*").WithArguments("C").WithLocation(17, 14),
                // (17,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //         _ = (C*)p; // 3
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "p").WithLocation(17, 17),
                // (23,14): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         _ = (S2*)p; // 4
                Diagnostic(ErrorCode.WRN_ManagedAddr, "S2*").WithArguments("S2").WithLocation(23, 14),
                // (24,14): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //         _ = (C*)p; // 5
                Diagnostic(ErrorCode.WRN_ManagedAddr, "C*").WithArguments("C").WithLocation(24, 14)
                );
        }
 
        [Fact]
        public void UnsafeContext_SizeOf()
        {
            var source = @"
public ref struct S
{
    public int F1;
}
public ref struct S2
{
    public ref int F1;
}
 
class C
{
    unsafe int M1()
    {
        return sizeof(S*);
    }
    unsafe int M2()
    {
        return sizeof(S2*); // 1
    }
    unsafe int M3()
    {
        return sizeof(C*); // 2
    }
    unsafe int M4()
    {
        return sizeof(S2); // 3
    }
    unsafe int M5()
    {
        return sizeof(C); // 4
    }
}
";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (19,23): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         return sizeof(S2*); // 1
                Diagnostic(ErrorCode.WRN_ManagedAddr, "S2*").WithArguments("S2").WithLocation(19, 23),
                // (23,23): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //         return sizeof(C*); // 2
                Diagnostic(ErrorCode.WRN_ManagedAddr, "C*").WithArguments("C").WithLocation(23, 23),
                // (27,16): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         return sizeof(S2); // 3
                Diagnostic(ErrorCode.WRN_ManagedAddr, "sizeof(S2)").WithArguments("S2").WithLocation(27, 16),
                // (31,16): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //         return sizeof(C); // 4
                Diagnostic(ErrorCode.WRN_ManagedAddr, "sizeof(C)").WithArguments("C").WithLocation(31, 16)
                );
 
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped);
            verifier.VerifyIL("C.M2", @"
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  sizeof     ""S2*""
  IL_0006:  ret
}
");
 
            verifier.VerifyIL("C.M4", @"
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  sizeof     ""S2""
  IL_0006:  ret
}
");
        }
 
        [Fact]
        public void UnsafeContext_TypeOf()
        {
            var source = @"
public ref struct S
{
    public int F1;
}
public ref struct S2
{
    public ref int F1;
}
 
class C
{
    unsafe object M()
    {
        return typeof(S*);
    }
    unsafe object M2()
    {
        return typeof(S2*); // 1
    }
    unsafe object M3()
    {
        return typeof(C*); // 2
    }
}
";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (19,23): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         return typeof(S2*); // 1
                Diagnostic(ErrorCode.WRN_ManagedAddr, "S2*").WithArguments("S2").WithLocation(19, 23),
                // (23,23): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //         return typeof(C*); // 2
                Diagnostic(ErrorCode.WRN_ManagedAddr, "C*").WithArguments("C").WithLocation(23, 23)
                );
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped);
            verifier.VerifyIL("C.M2", @"
{
  // Code size       11 (0xb)
  .maxstack  1
  IL_0000:  ldtoken    ""S2*""
  IL_0005:  call       ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)""
  IL_000a:  ret
}
");
 
            verifier.VerifyIL("C.M3", @"
{
  // Code size       11 (0xb)
  .maxstack  1
  IL_0000:  ldtoken    ""C*""
  IL_0005:  call       ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)""
  IL_000a:  ret
}
");
        }
 
        [Fact]
        public void UnsafeContext_AddressOf()
        {
            var source = @"
ref struct S
{
    int F1;
}
ref struct S2
{
    ref int F1;
}
 
class C
{
    void M(S s)
    {
        var x = &s; // 1
    }
    void M2(S2 s)
    {
        var x = &s; // 2
    }
    void M3(ref S2 s)
    {
        var x = &s; // 3
    }
}
 
unsafe class C2
{
    void M(S s)
    {
        var x = &s;
    }
    void M2(S2 s)
    {
        var x = &s; // 4
    }
    void M3(ref S2 s)
    {
        var x = &s; // 5
    }
}
";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (15,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //         var x = &s; // 1
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "&s").WithLocation(15, 17),
                // (19,17): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         var x = &s; // 2
                Diagnostic(ErrorCode.WRN_ManagedAddr, "&s").WithArguments("S2").WithLocation(19, 17),
                // (19,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                //         var x = &s; // 2
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "&s").WithLocation(19, 17),
                // (23,17): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         var x = &s; // 3
                Diagnostic(ErrorCode.WRN_ManagedAddr, "&s").WithArguments("S2").WithLocation(23, 17),
                // (23,17): error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer
                //         var x = &s; // 3
                Diagnostic(ErrorCode.ERR_FixedNeeded, "&s").WithLocation(23, 17),
                // (35,17): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         var x = &s; // 4
                Diagnostic(ErrorCode.WRN_ManagedAddr, "&s").WithArguments("S2").WithLocation(35, 17),
                // (39,17): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         var x = &s; // 5
                Diagnostic(ErrorCode.WRN_ManagedAddr, "&s").WithArguments("S2").WithLocation(39, 17),
                // (39,17): error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer
                //         var x = &s; // 5
                Diagnostic(ErrorCode.ERR_FixedNeeded, "&s").WithLocation(39, 17)
                );
 
            source = @"
ref struct S2
{
    ref int F1;
}
 
unsafe class C2
{
    void* M2(S2 s)
    {
        var x = &s; // 1
        return x;
    }
}
";
            comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (11,17): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         var x = &s; // 1
                Diagnostic(ErrorCode.WRN_ManagedAddr, "&s").WithArguments("S2").WithLocation(11, 17)
                );
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped);
            verifier.VerifyIL("C2.M2", @"
{
  // Code size        4 (0x4)
  .maxstack  1
  IL_0000:  ldarga.s   V_1
  IL_0002:  conv.u
  IL_0003:  ret
}
");
        }
 
        [Fact]
        public void UnsafeContext_AddressOf_CastToIntPtrPointer()
        {
            var source = @"
using System;
 
ref struct S2
{
    ref int F1;
}
 
unsafe class C2
{
    IntPtr* M2(S2 s)
    {
        return (IntPtr*)&s; // 1
    }
}
";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (13,25): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         return (IntPtr*)&s; // 1
                Diagnostic(ErrorCode.WRN_ManagedAddr, "&s").WithArguments("S2").WithLocation(13, 25)
                );
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped);
            verifier.VerifyIL("C2.M2", @"
{
  // Code size        4 (0x4)
  .maxstack  1
  IL_0000:  ldarga.s   V_1
  IL_0002:  conv.u
  IL_0003:  ret
}
");
        }
 
        [Fact]
        public void UnsafeContext_Assignment()
        {
            var source = @"
using System;
 
public ref struct S2
{
    public ref int F1;
 
    unsafe static void Assign(IntPtr* p, ref S2 r)
    {
        *(S2*)p = r;
    }
}
";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (10,11): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         *(S2*)p = r;
                Diagnostic(ErrorCode.WRN_ManagedAddr, "S2*").WithArguments("S2").WithLocation(10, 11)
                );
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped);
            verifier.VerifyIL("S2.Assign", @"
{
  // Code size       13 (0xd)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  ldobj      ""S2""
  IL_0007:  stobj      ""S2""
  IL_000c:  ret
}
");
        }
 
        [Fact]
        public void UnsafeContext_PointerMemberAccess()
        {
            var source = @"
public ref struct S
{
    public int F1;
}
public ref struct S2
{
    public ref int F1;
}
 
unsafe class C
{
    void M(S s)
    {
        _ = (&s)->F1; // 1
    }
    int M2(S2 s)
    {
        return (&s)->F1; // 2
    }
}
";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (19,17): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         return (&s)->F1; // 2
                Diagnostic(ErrorCode.WRN_ManagedAddr, "&s").WithArguments("S2").WithLocation(19, 17)
                );
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped);
            verifier.VerifyIL("C.M2", @"
{
  // Code size       10 (0xa)
  .maxstack  1
  IL_0000:  ldarga.s   V_1
  IL_0002:  conv.u
  IL_0003:  ldfld      ""ref int S2.F1""
  IL_0008:  ldind.i4
  IL_0009:  ret
}
");
        }
 
        [Fact]
        public void UnsafeContext_PointerElementAccess()
        {
            var source = @"
public ref struct S
{
    public int F1;
}
public ref struct S2
{
    public ref int F1;
}
 
unsafe class C
{
    S M(S s)
    {
        return (&s)[0];
    }
    S2 M2(S2 s)
    {
        return (&s)[0]; // 1
    }
}
";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (19,17): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         return (&s)[0]; // 1
                Diagnostic(ErrorCode.WRN_ManagedAddr, "&s").WithArguments("S2").WithLocation(19, 17)
                );
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped);
            verifier.VerifyIL("C.M2", @"
{
  // Code size        9 (0x9)
  .maxstack  1
  IL_0000:  ldarga.s   V_1
  IL_0002:  conv.u
  IL_0003:  ldobj      ""S2""
  IL_0008:  ret
}
");
        }
 
        [Fact]
        public void UnsafeContext_Stackalloc()
        {
            var source = @"
public ref struct S
{
    public int F1;
}
public ref struct S2
{
    public ref int F1;
}
 
class C
{
    unsafe void M()
    {
        var x1 = stackalloc S[0];
        var x2 = stackalloc S2[0]; // 1
        var x3 = stackalloc C[0]; // 2
 
        S* y1 = stackalloc S[0];
        S2* y2 = stackalloc S2[0]; // 3
        C* y3 = stackalloc C[0]; // 4
    }
}
";
 
            var spanReference = CreateCompilation(SpanSource, options: TestOptions.UnsafeReleaseDll);
            var comp = CreateCompilation(source, references: new[] { spanReference.EmitToImageReference() }, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (16,29): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2')
                //         var x2 = stackalloc S2[0]; // 1
                Diagnostic(ErrorCode.ERR_ManagedAddr, "S2").WithArguments("S2").WithLocation(16, 29),
                // (17,29): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C')
                //         var x3 = stackalloc C[0]; // 2
                Diagnostic(ErrorCode.ERR_ManagedAddr, "C").WithArguments("C").WithLocation(17, 29),
                // (20,9): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         S2* y2 = stackalloc S2[0]; // 3
                Diagnostic(ErrorCode.WRN_ManagedAddr, "S2*").WithArguments("S2").WithLocation(20, 9),
                // (20,29): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2')
                //         S2* y2 = stackalloc S2[0]; // 3
                Diagnostic(ErrorCode.ERR_ManagedAddr, "S2").WithArguments("S2").WithLocation(20, 29),
                // (21,9): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //         C* y3 = stackalloc C[0]; // 4
                Diagnostic(ErrorCode.WRN_ManagedAddr, "C*").WithArguments("C").WithLocation(21, 9),
                // (21,28): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C')
                //         C* y3 = stackalloc C[0]; // 4
                Diagnostic(ErrorCode.ERR_ManagedAddr, "C").WithArguments("C").WithLocation(21, 28)
                );
        }
 
        [Fact]
        public void UnsafeContext_Stackalloc_ImplicitType()
        {
            var source = @"
public ref struct S
{
    public int F1;
}
public ref struct S2
{
    public ref int F1;
}
 
class C
{
    unsafe void M()
    {
        var x1 = stackalloc[] { new S() };
        var x2 = stackalloc[] { new S2() }; // 1
        var x3 = stackalloc[] { new C() }; // 2
 
        S* y1 = stackalloc[] { new S() };
        S2* y2 = stackalloc[] { new S2() }; // 3
    }
    unsafe C M2()
    {
        C* y3 = stackalloc[] { new C() }; // 4
        return y3[0];
    }
}
";
 
            var spanReference = CreateCompilation(SpanSource, options: TestOptions.UnsafeReleaseDll);
            var comp = CreateCompilation(source, references: new[] { spanReference.EmitToImageReference() }, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (16,18): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2')
                //         var x2 = stackalloc[] { new S2() }; // 1
                Diagnostic(ErrorCode.ERR_ManagedAddr, "stackalloc[] { new S2() }").WithArguments("S2").WithLocation(16, 18),
                // (17,18): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C')
                //         var x3 = stackalloc[] { new C() }; // 2
                Diagnostic(ErrorCode.ERR_ManagedAddr, "stackalloc[] { new C() }").WithArguments("C").WithLocation(17, 18),
                // (20,9): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         S2* y2 = stackalloc[] { new S2() }; // 3
                Diagnostic(ErrorCode.WRN_ManagedAddr, "S2*").WithArguments("S2").WithLocation(20, 9),
                // (20,18): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2')
                //         S2* y2 = stackalloc[] { new S2() }; // 3
                Diagnostic(ErrorCode.ERR_ManagedAddr, "stackalloc[] { new S2() }").WithArguments("S2").WithLocation(20, 18),
                // (24,9): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //         C* y3 = stackalloc[] { new C() }; // 4
                Diagnostic(ErrorCode.WRN_ManagedAddr, "C*").WithArguments("C").WithLocation(24, 9),
                // (24,17): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C')
                //         C* y3 = stackalloc[] { new C() }; // 4
                Diagnostic(ErrorCode.ERR_ManagedAddr, "stackalloc[] { new C() }").WithArguments("C").WithLocation(24, 17)
                );
        }
 
        [Fact]
        public void UnsafeContext_Stackalloc_PointerElementType()
        {
            var source = @"
public ref struct S
{
    public int F1;
}
public ref struct S2
{
    public ref int F1;
}
 
class C
{
    unsafe void M()
    {
        var x1 = stackalloc S*[0];
        var x2 = stackalloc S2*[0]; // 1
        var x3 = stackalloc C*[0]; // 2
 
        S** y1 = stackalloc S*[0];
        S2** y2 = stackalloc S2*[0]; // 3
        C** y3 = stackalloc C*[0]; // 4
    }
}
";
 
            var spanReference = CreateCompilation(SpanSource, options: TestOptions.UnsafeReleaseDll);
            var comp = CreateCompilation(source, references: new[] { spanReference.EmitToImageReference() }, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (16,29): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         var x2 = stackalloc S2*[0]; // 1
                Diagnostic(ErrorCode.WRN_ManagedAddr, "S2*").WithArguments("S2").WithLocation(16, 29),
                // (17,29): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //         var x3 = stackalloc C*[0]; // 2
                Diagnostic(ErrorCode.WRN_ManagedAddr, "C*").WithArguments("C").WithLocation(17, 29),
                // (20,9): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         S2** y2 = stackalloc S2*[0]; // 3
                Diagnostic(ErrorCode.WRN_ManagedAddr, "S2*").WithArguments("S2").WithLocation(20, 9),
                // (20,30): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         S2** y2 = stackalloc S2*[0]; // 3
                Diagnostic(ErrorCode.WRN_ManagedAddr, "S2*").WithArguments("S2").WithLocation(20, 30),
                // (21,9): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //         C** y3 = stackalloc C*[0]; // 4
                Diagnostic(ErrorCode.WRN_ManagedAddr, "C*").WithArguments("C").WithLocation(21, 9),
                // (21,29): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //         C** y3 = stackalloc C*[0]; // 4
                Diagnostic(ErrorCode.WRN_ManagedAddr, "C*").WithArguments("C").WithLocation(21, 29)
                );
        }
 
        [Fact]
        public void UnsafeContext_Stackalloc_PointerElementType_ImplicitType()
        {
            var source = @"
public ref struct S
{
    public int F1;
}
public ref struct S2
{
    public ref int F1;
}
 
class C
{
    unsafe void M()
    {
        var s1 = (S*)null;
        var s2 = (S2*)null; // 1
        var s3 = (C*)null; // 2
 
        var x1 = stackalloc[] { s1 };
        var x2 = stackalloc[] { s2 };
        var x3 = stackalloc[] { s3 };
 
        S** y1 = stackalloc[] { s1 };
        S2** y2 = stackalloc[] { s2 }; // 3
        C** y3 = stackalloc[] { s3 }; // 4
    }
}
";
 
            var spanReference = CreateCompilation(SpanSource, options: TestOptions.UnsafeReleaseDll);
            var comp = CreateCompilation(source, references: new[] { spanReference.EmitToImageReference() }, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (16,19): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         var s2 = (S2*)null; // 1
                Diagnostic(ErrorCode.WRN_ManagedAddr, "S2*").WithArguments("S2").WithLocation(16, 19),
                // (17,19): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //         var s3 = (C*)null; // 2
                Diagnostic(ErrorCode.WRN_ManagedAddr, "C*").WithArguments("C").WithLocation(17, 19),
                // (24,9): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2')
                //         S2** y2 = stackalloc[] { s2 }; // 3
                Diagnostic(ErrorCode.WRN_ManagedAddr, "S2*").WithArguments("S2").WithLocation(24, 9),
                // (25,9): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C')
                //         C** y3 = stackalloc[] { s3 }; // 4
                Diagnostic(ErrorCode.WRN_ManagedAddr, "C*").WithArguments("C").WithLocation(25, 9)
                );
        }
 
        [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")]
        public void InitRefField_AutoDefault()
        {
            var source = """
using System;
 
var x = 42;
scoped var r = new R();
r.field = ref x;
 
ref struct R
{
    public ref int field;
 
    public R()
    {
        Console.WriteLine("explicit ctor");
    }
}
""";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor"));
            verifier.VerifyIL("R..ctor()", @"
{
  // Code size       19 (0x13)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.0
  IL_0002:  conv.u
  IL_0003:  stfld      ""ref int R.field""
  IL_0008:  ldstr      ""explicit ctor""
  IL_000d:  call       ""void System.Console.WriteLine(string)""
  IL_0012:  ret
}");
        }
 
        [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")]
        public void InitRefField_UnsafeNullRef()
        {
            var source = """
using System;
 
var x = 42;
scoped var r = new R();
r.field = ref x;
 
ref struct R
{
    public ref int field;
 
    public R()
    {
        field = ref System.Runtime.CompilerServices.Unsafe.NullRef<int>();
        Console.WriteLine("explicit ctor");
    }
}
""";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70, options: TestOptions.ReleaseExe);
            comp.VerifyDiagnostics();
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor"));
            verifier.VerifyIL("R..ctor()", @"
{
  // Code size       22 (0x16)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  call       ""ref int System.Runtime.CompilerServices.Unsafe.NullRef<int>()""
  IL_0006:  stfld      ""ref int R.field""
  IL_000b:  ldstr      ""explicit ctor""
  IL_0010:  call       ""void System.Console.WriteLine(string)""
  IL_0015:  ret
}");
        }
 
        [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")]
        public void InitRefField_AutoDefault_RefReadonly()
        {
            var source = """
using System;
 
var x = 42;
scoped var r = new R();
r.field = ref x;
 
ref struct R
{
    public ref readonly int field;
 
    public R()
    {
        Console.WriteLine("explicit ctor");
    }
}
""";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
 
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor"));
            verifier.VerifyIL("R..ctor()", @"
{
  // Code size       19 (0x13)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.0
  IL_0002:  conv.u
  IL_0003:  stfld      ""ref readonly int R.field""
  IL_0008:  ldstr      ""explicit ctor""
  IL_000d:  call       ""void System.Console.WriteLine(string)""
  IL_0012:  ret
}");
        }
 
        [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")]
        public void InitRefField_AutoDefault_ReadonlyRef()
        {
            var source = """
using System;
 
var r = new R();
 
ref struct R
{
    public readonly ref int field;
 
    public R()
    {
        Console.WriteLine("explicit ctor");
    }
}
""";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (7,29): warning CS0649: Field 'R.field' is never assigned to, and will always have its default value 0
                //     public readonly ref int field;
                Diagnostic(ErrorCode.WRN_UnassignedInternalField, "field").WithArguments("R.field", "0").WithLocation(7, 29)
                );
 
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor"));
            verifier.VerifyIL("R..ctor()", @"
{
  // Code size       19 (0x13)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.0
  IL_0002:  conv.u
  IL_0003:  stfld      ""ref int R.field""
  IL_0008:  ldstr      ""explicit ctor""
  IL_000d:  call       ""void System.Console.WriteLine(string)""
  IL_0012:  ret
}");
        }
 
        [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")]
        public void InitRefField_AutoDefault_WithOtherFieldInitializer()
        {
            var source = """
using System;
 
var x = 42;
scoped var r = new R();
r.field = ref x;
 
ref struct R
{
    public ref int field;
    public int otherField = 42;
 
    public R()
    {
        Console.WriteLine("explicit ctor");
    }
}
""";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular11, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor"));
            verifier.VerifyIL("R..ctor()", @"
 {
  // Code size       27 (0x1b)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.0
  IL_0002:  conv.u
  IL_0003:  stfld      ""ref int R.field""
  IL_0008:  ldarg.0
  IL_0009:  ldc.i4.s   42
  IL_000b:  stfld      ""int R.otherField""
  IL_0010:  ldstr      ""explicit ctor""
  IL_0015:  call       ""void System.Console.WriteLine(string)""
  IL_001a:  ret
}");
        }
 
        /// <summary>
        /// Unexpected modreq().
        /// </summary>
        [Fact]
        public void RefCustomModifiers_UseSiteDiagnostic_02()
        {
            var sourceA =
@".class public sealed A extends [mscorlib]System.ValueType
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = (01 00 00 00)
  .field public int32& modreq(int32) F
}";
            var refA = CompileIL(sourceA);
 
            var sourceB =
@"using System;
class Program
{
    static void Main()
    {
        var a = new A();
        Console.WriteLine(a.F);
    }
}";
            var comp = CreateCompilation(sourceB, new[] { refA }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (7,29): error CS0570: 'A.F' is not supported by the language
                //         Console.WriteLine(a.F);
                Diagnostic(ErrorCode.ERR_BindToBogus, "F").WithArguments("A.F").WithLocation(7, 29));
        }
 
        /// <summary>
        /// modreq(System.Runtime.InteropServices.InAttribute).
        /// Should we allow this modreq() even though it is not generated by the compiler?
        /// </summary>
        [Fact]
        public void RefCustomModifiers_UseSiteDiagnostic_01()
        {
            var sourceA =
@".class public sealed A extends [mscorlib]System.ValueType
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = (01 00 00 00)
  .field public int32& modreq([mscorlib]System.Runtime.InteropServices.InAttribute) F
}";
            var refA = CompileIL(sourceA);
 
            var sourceB =
@"using System;
class Program
{
    static void Main()
    {
        var a = new A();
        Console.WriteLine(a.F);
    }
}";
            var comp = CreateCompilation(sourceB, new[] { refA }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (7,29): error CS0570: 'A.F' is not supported by the language
                //         Console.WriteLine(a.F);
                Diagnostic(ErrorCode.ERR_BindToBogus, "F").WithArguments("A.F").WithLocation(7, 29));
        }
 
        /// <summary>
        /// modopt() with missing type.
        /// </summary>
        [Fact]
        public void RefCustomModifiers_UseSiteDiagnostic_03()
        {
            var sourceA =
@".assembly extern mscorlib { }
.assembly A { }
.class public A
{
}";
            var refA = CompileIL(sourceA, prependDefaultHeader: false);
 
            var sourceB =
@".assembly extern A { }
.class public sealed B extends [mscorlib]System.ValueType
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = (01 00 00 00)
  .field public int32& modopt(int8) modopt([A]A) F
}";
            var refB = CompileIL(sourceB);
 
            var sourceC =
@"using System;
class Program
{
    static void Main()
    {
        var b = new B();
        Console.WriteLine(b.F);
    }
}";
            var comp = CreateCompilation(sourceC, new[] { refB }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (7,29): error CS0012: The type 'A' is defined in an assembly that is not referenced. You must add a reference to assembly 'A, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
                //         Console.WriteLine(b.F);
                Diagnostic(ErrorCode.ERR_NoTypeDef, "F").WithArguments("A", "A, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(7, 29));
        }
 
        [Fact]
        public void MemberRefMetadataDecoder_FindFieldBySignature()
        {
            var sourceA =
@".class public sealed R<T> extends [mscorlib]System.ValueType
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = (01 00 00 00)
  .field private !0 F1
  .field public !0& F1
  .field private !0& modopt(int32) F2
  .field public !0& modopt(object) F2
  .field private int32& F3
  .field public int8& F3
}";
            var refA = CompileIL(sourceA);
 
            var sourceB =
@"class B
{
    static object F1() => new R<object>().F1;
    static object F2() => new R<object>().F2;
    static int F3() => new R<object>().F3;
}";
            var compB = CreateCompilation(sourceB, references: new[] { refA }, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(compB, verify: Verification.Skipped);
            // MemberRefMetadataDecoder.FindFieldBySignature() is used to find fields when realIL: true.
            verifier.VerifyIL("B.F1", realIL: true, expectedIL:
@"{
  // Code size       16 (0x10)
  .maxstack  1
  .locals init (R<object> V_0)
  IL_0000:  ldloca.s   V_0
  IL_0002:  initobj    ""R<object>""
  IL_0008:  ldloc.0
  IL_0009:  ldfld      ""ref object R<object>.F1""
  IL_000e:  ldind.ref
  IL_000f:  ret
}");
 
            var refB = verifier.Compilation.EmitToImageReference();
 
            var comp = CreateCompilation("", references: new[] { refA, refB });
            comp.VerifyEmitDiagnostics();
 
            // Call MemberRefMetadataDecoder.FindFieldBySignature() indirectly from MetadataDecoder.GetSymbolForILToken().
            var module = (PEModuleSymbol)comp.GetReferencedAssemblySymbol(refB).Modules[0];
 
            var decoder = new MetadataDecoder(module);
            var reader = module.Module.MetadataReader;
            var fieldReferences = reader.MemberReferences.
                Where(handle => reader.GetString(reader.GetMemberReference(handle).Name) is "F1" or "F2" or "F3").
                Select(handle => decoder.GetSymbolForILToken(handle)).
                ToArray();
 
            var containingType = fieldReferences[0].ContainingType;
            var fieldMembers = containingType.GetMembers().WhereAsArray(m => m.Kind == SymbolKind.Field);
            var expectedMembers = new[]
            {
                "System.Object R<System.Object>.F1",
                "ref System.Object R<System.Object>.F1",
                "ref modopt(System.Int32) System.Object R<System.Object>.F2",
                "ref modopt(System.Object) System.Object R<System.Object>.F2",
                "ref System.Int32 R<System.Object>.F3",
                "ref System.SByte R<System.Object>.F3"
            };
            AssertEx.Equal(expectedMembers, fieldMembers.ToTestDisplayStrings());
 
            var expectedReferences = new[]
            {
                "ref System.Object R<System.Object>.F1",
                "ref modopt(System.Object) System.Object R<System.Object>.F2",
                "ref System.SByte R<System.Object>.F3"
            };
            AssertEx.Equal(expectedReferences, fieldReferences.ToTestDisplayStrings());
        }
 
        [WorkItem(62596, "https://github.com/dotnet/roslyn/issues/62596")]
        [Theory]
        [InlineData("class")]
        [InlineData("struct")]
        [InlineData("record")]
        [InlineData("record struct")]
        public void NonRefStructContainer(string type)
        {
            var source =
$@"#pragma warning disable 169
{type} R
{{
    ref int F;
}}";
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (4,5): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     ref int F;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "ref int").WithArguments("ref fields", "11.0").WithLocation(4, 5),
                // (4,13): error CS9059: A ref field can only be declared in a ref struct.
                //     ref int F;
                Diagnostic(ErrorCode.ERR_RefFieldInNonRefStruct, "F").WithLocation(4, 13));
 
            comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (4,13): error CS9059: A ref field can only be declared in a ref struct.
                //     ref int F;
                Diagnostic(ErrorCode.ERR_RefFieldInNonRefStruct, "F").WithLocation(4, 13));
        }
 
        /// <summary>
        /// Determination of enum underlying type should ignore ref fields
        /// and fields with required custom modifiers.
        /// </summary>
        [Fact]
        public void EnumUnderlyingType()
        {
            var sourceA =
@".class public sealed E extends [mscorlib]System.Enum
{
  .field public int64 modreq(object) value1
  .field public int32& modopt(object) value2
  .field public int32& value3
  .field public int16 value4
  .field public static literal valuetype E A = int16(0x01)
}";
            var refA = CompileIL(sourceA);
 
            var sourceB =
@"class Program
{
    static void Main()
    {
        _ = E.A;
    }
}";
            var comp = CreateCompilation(sourceB, references: new[] { refA });
            comp.VerifyEmitDiagnostics();
 
            var type = (NamedTypeSymbol)comp.GetTypeByMetadataName("E");
            Assert.Equal(SpecialType.System_Int16, type.EnumUnderlyingType.SpecialType);
        }
 
        private static void VerifyFieldSymbol(FieldSymbol field, string expectedDisplayString, RefKind expectedRefKind, string[] expectedRefCustomModifiers)
        {
            Assert.Equal(expectedRefKind, field.RefKind);
            Assert.Equal(expectedRefCustomModifiers, field.RefCustomModifiers.SelectAsArray(m => m.Modifier.ToTestDisplayString()));
            Assert.Equal(expectedDisplayString, field.ToTestDisplayString());
        }
 
        [WorkItem(62131, "https://github.com/dotnet/roslyn/issues/62131")]
        [CombinatorialData]
        [Theory]
        public void RuntimeFeature(bool useCompilationReference)
        {
            var sourceA =
@"namespace System
{
    public class Object { }
    public abstract class ValueType { }
    public class String { }
    public struct Void { }
    public struct Boolean { }
    public struct Int32 { }
    public class Attribute { }
    public class AttributeUsageAttribute : Attribute
    {
        public AttributeUsageAttribute(AttributeTargets validOn) { }
        public bool AllowMultiple { get; set; }
        public bool Inherited { get; set; }
    }
    public struct Enum { }
    public enum AttributeTargets { }
}";
            var sourceB =
@"namespace System.Runtime.CompilerServices
{
    public static class RuntimeFeature
    {
        public const string ByRefFields = nameof(ByRefFields);
    }
}";
            var comp = CreateEmptyCompilation(new[] { sourceA }, parseOptions: TestOptions.Regular10);
            var refA = AsReference(comp, useCompilationReference);
 
            comp = CreateEmptyCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular10);
            var refAB = AsReference(comp, useCompilationReference);
 
            var source =
@"ref struct R<T>
{
    public ref T F;
    public R(ref T t) { F = ref t; }
}
class Program
{
    static ref T F<T>(R<T> r)
    {
        return ref r.F;
    }
}";
 
            comp = CreateEmptyCompilation(source, references: new[] { refA }, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(
                // (3,12): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     public ref T F;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "ref T").WithArguments("ref fields", "11.0").WithLocation(3, 12),
                // (3,18): error CS9064: Target runtime doesn't support ref fields.
                //     public ref T F;
                Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportRefFields, "F").WithLocation(3, 18),
                // (10,20): error CS8167: Cannot return by reference a member of parameter 'r' because it is not a ref or out parameter
                //         return ref r.F;
                Diagnostic(ErrorCode.ERR_RefReturnParameter2, "r").WithArguments("r").WithLocation(10, 20));
            Assert.False(comp.Assembly.RuntimeSupportsByRefFields);
            Assert.False(comp.SupportsRuntimeCapability(RuntimeCapability.ByRefFields));
 
            comp = CreateEmptyCompilation(source, references: new[] { refAB }, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(
                // (3,12): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     public ref T F;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "ref T").WithArguments("ref fields", "11.0").WithLocation(3, 12));
            Assert.True(comp.Assembly.RuntimeSupportsByRefFields);
            Assert.True(comp.SupportsRuntimeCapability(RuntimeCapability.ByRefFields));
 
            comp = CreateEmptyCompilation(source, references: new[] { refA });
            comp.VerifyDiagnostics(
                // (3,18): error CS9064: Target runtime doesn't support ref fields.
                //     public ref T F;
                Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportRefFields, "F").WithLocation(3, 18));
            Assert.False(comp.Assembly.RuntimeSupportsByRefFields);
            Assert.False(comp.SupportsRuntimeCapability(RuntimeCapability.ByRefFields));
 
            comp = CreateEmptyCompilation(source, references: new[] { refAB });
            comp.VerifyDiagnostics();
            Assert.True(comp.Assembly.RuntimeSupportsByRefFields);
            Assert.True(comp.SupportsRuntimeCapability(RuntimeCapability.ByRefFields));
        }
 
        [ConditionalTheory(typeof(CoreClrOnly))]
        [CombinatorialData]
        public void RefAssembly(bool includePrivateMembers)
        {
            var sourceA =
@"public ref struct R1<T, U>
{
    private ref T _f1;
    private ref readonly U _f2;
    public R1(ref T t, ref U u)
    {
        _f1 = ref t;
        _f2 = ref u;
    }
    public override string ToString() => (_f1, _f2).ToString();
}
public ref struct R2<T, U>
{
    public ref T F1;
    public ref readonly U F2;
    public R2(ref T t, ref U u)
    {
        F1 = ref t;
        F2 = ref u;
    }
    public override string ToString() => (F1, F2).ToString();
}";
            var compA = CreateCompilation(sourceA, targetFramework: TargetFramework.Net70);
            var emitOptions = Microsoft.CodeAnalysis.Emit.EmitOptions.Default.WithEmitMetadataOnly(true).WithIncludePrivateMembers(includePrivateMembers);
            var refA = compA.EmitToImageReference(emitOptions);
 
            var sourceB =
@"using System;
public class B
{
    public static void M()
    {
        int i = 1;
        double d = 2.0;
        var r1 = new R1<int, double>(ref i, ref d);
        var r2 = new R2<double, int>(ref d, ref i);
        i = 3;
        d = 4.0;
        Console.WriteLine((r1.ToString(), r2.ToString()));
    }
}";
            var compB = CreateCompilation(sourceB, references: new[] { refA }, targetFramework: TargetFramework.Net70);
            var refB = compB.EmitToImageReference();
            verifyFields(compB.GetMember<NamedTypeSymbol>("R1"), new[] { "ref T R1<T, U>._f1", "ref readonly U R1<T, U>._f2" });
            verifyFields(compB.GetMember<NamedTypeSymbol>("R2"), new[] { "ref T R2<T, U>.F1", "ref readonly U R2<T, U>.F2" });
 
            var sourceC =
@"class Program
{
    static void Main()
    {
        B.M();
    }
}";
            // Requires full assembly for A at runtime.
            CompileAndVerify(
                sourceC,
                references: new[] { refB, compA.EmitToImageReference() },
                targetFramework: TargetFramework.Net70,
                verify: Verification.Skipped,
                expectedOutput: @"((3, 4), (4, 3))");
 
            static void verifyFields(NamedTypeSymbol type, string[] expectedFields)
            {
                var actualFields = type.GetMembers().OfType<FieldSymbol>().Select(f => f.ToTestDisplayString()).ToList();
                AssertEx.Equal(actualFields, expectedFields);
            }
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        [InlineData(LanguageVersion.Latest)]
        public void RequiredField_01(LanguageVersion languageVersion)
        {
            var source = """
                #pragma warning disable 169
                #pragma warning disable 649
                ref struct R<T, U>
                {
                    public required ref T F1;
                    public required ref readonly U F2;
                }
                """;
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), targetFramework: TargetFramework.Net70);
            if (languageVersion == LanguageVersion.CSharp10)
            {
                comp.VerifyEmitDiagnostics(
                    // (5,21): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                    //     public required ref T F1;
                    Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "ref T").WithArguments("ref fields", "11.0").WithLocation(5, 21),
                    // (5,27): error CS8936: Feature 'required members' is not available in C# 10.0. Please use language version 11.0 or greater.
                    //     public required ref T F1;
                    Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "F1").WithArguments("required members", "11.0").WithLocation(5, 27),
                    // (6,21): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                    //     public required ref readonly U F2;
                    Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "ref readonly U").WithArguments("ref fields", "11.0").WithLocation(6, 21),
                    // (6,36): error CS8936: Feature 'required members' is not available in C# 10.0. Please use language version 11.0 or greater.
                    //     public required ref readonly U F2;
                    Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "F2").WithArguments("required members", "11.0").WithLocation(6, 36));
            }
            else
            {
                comp.VerifyEmitDiagnostics();
            }
        }
 
        [Theory]
        [CombinatorialData]
        public void RequiredField_02(bool useCompilationReference)
        {
            var sourceA = """
                public ref struct R<T, U>
                {
                    private static U _u;
                    public required ref T F1;
                    public required ref readonly U F2;
                    public R()
                    {
                        F2 = ref _u;
                    }
                    public R(ref T t)
                    {
                        F1 = ref t;
                    }
                    public R(ref T t, ref U u)
                    {
                        F1 = ref t;
                        F2 = ref u;
                    }
                }
                """;
            var comp = CreateCompilation(sourceA, targetFramework: TargetFramework.Net70);
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB = """
                class Program
                {
                    static void Main()
                    {
                        int i = 1;
                        double d = 2.0;
                        scoped R<int, double> r;
                        r = default;
                        r = new(); // 1
                        r = new() { }; // 2
                        r = new() { F1 = ref i }; // 3
                        r = new() { F2 = ref d }; // 4
                        r = new() { F1 = ref i, F2 = ref d };
                        r = new R<int, double>(); // 5
                        r = new R<int, double> { }; // 6
                        r = new(ref i); // 7
                        r = new(ref i, ref d);
                        r = new(ref i) { F1 = ref i }; // 8
                        r = new(ref i) { F2 = ref d }; // 9
                    }
                }
                """;
            comp = CreateCompilation(sourceB, references: new[] { refA }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (9,13): error CS9035: Required member 'R<int, double>.F2' must be set in the object initializer or attribute constructor.
                //         r = new(); // 1
                Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSet, "new").WithArguments("R<int, double>.F2").WithLocation(9, 13),
                // (9,13): error CS9035: Required member 'R<int, double>.F1' must be set in the object initializer or attribute constructor.
                //         r = new(); // 1
                Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSet, "new").WithArguments("R<int, double>.F1").WithLocation(9, 13),
                // (10,13): error CS9035: Required member 'R<int, double>.F2' must be set in the object initializer or attribute constructor.
                //         r = new() { }; // 2
                Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSet, "new").WithArguments("R<int, double>.F2").WithLocation(10, 13),
                // (10,13): error CS9035: Required member 'R<int, double>.F1' must be set in the object initializer or attribute constructor.
                //         r = new() { }; // 2
                Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSet, "new").WithArguments("R<int, double>.F1").WithLocation(10, 13),
                // (11,13): error CS9035: Required member 'R<int, double>.F2' must be set in the object initializer or attribute constructor.
                //         r = new() { F1 = ref i };
                Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSet, "new").WithArguments("R<int, double>.F2").WithLocation(11, 13),
                // (12,13): error CS9035: Required member 'R<int, double>.F1' must be set in the object initializer or attribute constructor.
                //         r = new() { F2 = ref d }; // 3
                Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSet, "new").WithArguments("R<int, double>.F1").WithLocation(12, 13),
                // (14,17): error CS9035: Required member 'R<int, double>.F2' must be set in the object initializer or attribute constructor.
                //         r = new R<int, double>(); // 4
                Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSet, "R<int, double>").WithArguments("R<int, double>.F2").WithLocation(14, 17),
                // (14,17): error CS9035: Required member 'R<int, double>.F1' must be set in the object initializer or attribute constructor.
                //         r = new R<int, double>(); // 4
                Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSet, "R<int, double>").WithArguments("R<int, double>.F1").WithLocation(14, 17),
                // (15,17): error CS9035: Required member 'R<int, double>.F2' must be set in the object initializer or attribute constructor.
                //         r = new R<int, double> { } // 5
                Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSet, "R<int, double>").WithArguments("R<int, double>.F2").WithLocation(15, 17),
                // (15,17): error CS9035: Required member 'R<int, double>.F1' must be set in the object initializer or attribute constructor.
                //         r = new R<int, double> { } // 5
                Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSet, "R<int, double>").WithArguments("R<int, double>.F1").WithLocation(15, 17),
                // (16,13): error CS9035: Required member 'R<int, double>.F2' must be set in the object initializer or attribute constructor.
                //         r = new(ref i); // 6
                Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSet, "new").WithArguments("R<int, double>.F2").WithLocation(16, 13),
                // (16,13): error CS9035: Required member 'R<int, double>.F1' must be set in the object initializer or attribute constructor.
                //         r = new(ref i); // 6
                Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSet, "new").WithArguments("R<int, double>.F1").WithLocation(16, 13),
                // (17,13): error CS9035: Required member 'R<int, double>.F2' must be set in the object initializer or attribute constructor.
                //         r = new(ref i, ref d);
                Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSet, "new").WithArguments("R<int, double>.F2").WithLocation(17, 13),
                // (17,13): error CS9035: Required member 'R<int, double>.F1' must be set in the object initializer or attribute constructor.
                //         r = new(ref i, ref d);
                Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSet, "new").WithArguments("R<int, double>.F1").WithLocation(17, 13),
                // (18,13): error CS9035: Required member 'R<int, double>.F2' must be set in the object initializer or attribute constructor.
                //         r = new(ref i) { F1 = ref i }; // 7
                Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSet, "new").WithArguments("R<int, double>.F2").WithLocation(18, 13),
                // (19,13): error CS9035: Required member 'R<int, double>.F1' must be set in the object initializer or attribute constructor.
                //         r = new(ref i) { F2 = ref d };
                Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSet, "new").WithArguments("R<int, double>.F1").WithLocation(19, 13));
        }
 
        /// <summary>
        /// Ref fields of ref struct type are not supported.
        /// </summary>
        [Fact]
        public void RefFieldTypeRefStruct_01()
        {
            var source =
@"#pragma warning disable 169
 
ref struct R1<T>
{
}
ref struct R2<T>
{
    public ref R1<T> F;
}
class Program
{
    static void F(ref R1<int> r1)
    {
        var r2 = new R2<int>();
        r2.F = ref r1;
    }
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (8,12): error CS9050: A ref field cannot refer to a ref struct.
                //     public ref R1<T> F;
                Diagnostic(ErrorCode.ERR_RefFieldCannotReferToRefStruct, "ref R1<T>").WithLocation(8, 12),
                // (15,9): error CS9079: Cannot ref-assign 'r1' to 'F' because 'r1' can only escape the current method through a return statement.
                //         r2.F = ref r1;
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "r2.F = ref r1").WithArguments("F", "r1").WithLocation(15, 9));
        }
 
        /// <summary>
        /// Ref fields of ref struct type are not supported.
        /// </summary>
        [Fact]
        public void RefFieldTypeRefStruct_02()
        {
            var sourceA =
@".class public sealed R1 extends [mscorlib]System.ValueType
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = (01 00 00 00)
}
.class public sealed R2 extends [mscorlib]System.ValueType
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = (01 00 00 00)
  .field public valuetype R1& F
}
";
            var refA = CompileIL(sourceA);
 
            var sourceB =
@"class Program
{
    static void F(ref R1 r1)
    {
        var r2 = new R2();
        r2.F = ref r1;
    }
}";
            var comp = CreateCompilation(sourceB, references: new[] { refA }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (6,12): error CS0570: 'R2.F' is not supported by the language
                //         r2.F = ref r1;
                Diagnostic(ErrorCode.ERR_BindToBogus, "F").WithArguments("R2.F").WithLocation(6, 12));
        }
 
        [Fact]
        public void RefFields_RefEscape()
        {
            var source =
@"ref struct R<T>
{
    ref T F;
    R(ref T t) { F = ref t; }
    ref T F0() => ref this.F;
    static ref T F1(R<T> r1)
    {
        return ref r1.F;
    }
    static ref T F2(T t)
    {
        var r2 = new R<T>(ref t);
        return ref r2.F;
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (3,5): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     ref T F;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "ref T").WithArguments("ref fields", "11.0").WithLocation(3, 5),
                // (13,20): error CS8352: Cannot use variable 'r2' in this context because it may expose referenced variables outside of their declaration scope
                //         return ref r2.F;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r2.F").WithArguments("r2").WithLocation(13, 20));
 
            comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (13,20): error CS8352: Cannot use variable 'r2' in this context because it may expose referenced variables outside of their declaration scope
                //         return ref r2.F;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r2.F").WithArguments("r2").WithLocation(13, 20));
        }
 
        [Fact]
        public void RefFields_RefEscape_UnsafeContext()
        {
            var source =
@"ref struct R<T>
{
    ref T F;
    R(ref T t) { F = ref t; }
    ref T F0() => ref this.F;
    static unsafe ref T F2(T t)
    {
        var r2 = new R<T>(ref t);
        return ref r2.F;
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70, options: TestOptions.UnsafeDebugDll);
            comp.VerifyEmitDiagnostics(
                // (9,20): warning CS9077: Use of variable 'r2' in this context may expose referenced variables outside of their declaration scope
                //         return ref r2.F;
                Diagnostic(ErrorCode.WRN_EscapeVariable, "r2.F").WithArguments("r2").WithLocation(9, 20));
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped);
            verifier.VerifyIL("R<T>.F2", @"
{
  // Code size       21 (0x15)
  .maxstack  1
  .locals init (R<T> V_0, //r2
                T& V_1)
  IL_0000:  nop
  IL_0001:  ldarga.s   V_0
  IL_0003:  newobj     ""R<T>..ctor(ref T)""
  IL_0008:  stloc.0
  IL_0009:  ldloca.s   V_0
  IL_000b:  ldfld      ""ref T R<T>.F""
  IL_0010:  stloc.1
  IL_0011:  br.s       IL_0013
  IL_0013:  ldloc.1
  IL_0014:  ret
}
");
        }
 
        [Fact]
        public void RefFields_RefReassignment_01()
        {
            var source =
@"ref struct R<T>
{
    ref T F;
    R(ref T t) { F = ref t; }
    R<T> F0(ref T t)
    {
        F = ref t;
        return this;
    }
    static R<T> F1(R<T> r1, ref T t)
    {
        r1.F = ref t;
        return r1;
    }
    static R<T> F2(R<T> r2)
    {
        T t = default;
        r2.F = ref t;
        return r2;
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (3,5): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     ref T F;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "ref T").WithArguments("ref fields", "11.0").WithLocation(3, 5),
                // (7,9): error CS9079: Cannot ref-assign 't' to 'F' because 't' can only escape the current method through a return statement.
                //         F = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "F = ref t").WithArguments("F", "t").WithLocation(7, 9),
                // (12,9): error CS9079: Cannot ref-assign 't' to 'F' because 't' can only escape the current method through a return statement.
                //         r1.F = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "r1.F = ref t").WithArguments("F", "t").WithLocation(12, 9),
                // (18,9): error CS8374: Cannot ref-assign 't' to 'F' because 't' has a narrower escape scope than 'F'.
                //         r2.F = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r2.F = ref t").WithArguments("F", "t").WithLocation(18, 9)
                );
 
            comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (7,9): error CS9079: Cannot ref-assign 't' to 'F' because 't' can only escape the current method through a return statement.
                //         F = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "F = ref t").WithArguments("F", "t").WithLocation(7, 9),
                // (12,9): error CS9079: Cannot ref-assign 't' to 'F' because 't' can only escape the current method through a return statement.
                //         r1.F = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "r1.F = ref t").WithArguments("F", "t").WithLocation(12, 9),
                // (18,9): error CS8374: Cannot ref-assign 't' to 'F' because 't' has a narrower escape scope than 'F'.
                //         r2.F = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r2.F = ref t").WithArguments("F", "t").WithLocation(18, 9)
                );
        }
 
        [Fact]
        [WorkItem(63434, "https://github.com/dotnet/roslyn/issues/63434")]
        public void RefFields_RefReassignment_02()
        {
            var source =
@"
using System;
 
class Program
{
    static void Main()
    {
        int i = 42;
        var r = new R() { Field = ref i };
        Console.WriteLine(r.Field);
        i = 43;
        Console.WriteLine(r.Field);
    }
}
 
ref struct R
{
    public ref int Field;
}
";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput(
@"42
43")).VerifyDiagnostics().
                VerifyIL("Program.Main",
@"
{
  // Code size       48 (0x30)
  .maxstack  2
  .locals init (int V_0, //i
                R V_1)
  IL_0000:  ldc.i4.s   42
  IL_0002:  stloc.0
  IL_0003:  ldloca.s   V_1
  IL_0005:  initobj    ""R""
  IL_000b:  ldloca.s   V_1
  IL_000d:  ldloca.s   V_0
  IL_000f:  stfld      ""ref int R.Field""
  IL_0014:  ldloc.1
  IL_0015:  dup
  IL_0016:  ldfld      ""ref int R.Field""
  IL_001b:  ldind.i4
  IL_001c:  call       ""void System.Console.WriteLine(int)""
  IL_0021:  ldc.i4.s   43
  IL_0023:  stloc.0
  IL_0024:  ldfld      ""ref int R.Field""
  IL_0029:  ldind.i4
  IL_002a:  call       ""void System.Console.WriteLine(int)""
  IL_002f:  ret
}
");
        }
 
        [Fact]
        public void RefFields_RefReassignment_03()
        {
            var source =
@"
using System;
 
class Program
{
    static void Main()
    {
        int i = 42;
        var r = new R();
        r.Field = ref i;
        Console.WriteLine(r.Field);
    }
}
 
ref struct R
{
    public ref int Field;
}
";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (10,9): error CS8374: Cannot ref-assign 'i' to 'Field' because 'i' has a narrower escape scope than 'Field'.
                //         r.Field = ref i;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r.Field = ref i").WithArguments("Field", "i").WithLocation(10, 9)
                );
        }
 
        [Fact]
        [WorkItem(63434, "https://github.com/dotnet/roslyn/issues/63434")]
        public void RefFields_RefReassignment_04()
        {
            var source =
@"
using System;
 
class Program
{
    static void Main()
    {
        int i = 42;
        Test(ref i);
    }
 
    static void Test(ref int i)
    {
        var r = new R() { Field = ref i };
        Console.WriteLine(r.Field);
    }
}
 
ref struct R
{
    public ref int Field;
}
";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("42")).VerifyDiagnostics().
                VerifyIL("Program.Test",
@"
{
  // Code size       29 (0x1d)
  .maxstack  2
  .locals init (R V_0)
  IL_0000:  ldloca.s   V_0
  IL_0002:  initobj    ""R""
  IL_0008:  ldloca.s   V_0
  IL_000a:  ldarg.0
  IL_000b:  stfld      ""ref int R.Field""
  IL_0010:  ldloc.0
  IL_0011:  ldfld      ""ref int R.Field""
  IL_0016:  ldind.i4
  IL_0017:  call       ""void System.Console.WriteLine(int)""
  IL_001c:  ret
}
");
        }
 
        [Fact]
        public void RefFields_RefReassignment_05()
        {
            var source =
@"
using System;
 
class Program
{
    static void Main()
    {
        int i = 42;
        Test(ref i);
    }
 
    static void Test(ref int i)
    {
        scoped var r = new R();
        r.Field = ref i;
        Console.WriteLine(r.Field);
    }
}
 
ref struct R
{
    public ref int Field;
}
";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("42")).VerifyDiagnostics().
                VerifyIL("Program.Test",
@"
{
  // Code size       29 (0x1d)
  .maxstack  2
  .locals init (R V_0) //r
  IL_0000:  ldloca.s   V_0
  IL_0002:  initobj    ""R""
  IL_0008:  ldloca.s   V_0
  IL_000a:  ldarg.0
  IL_000b:  stfld      ""ref int R.Field""
  IL_0010:  ldloc.0
  IL_0011:  ldfld      ""ref int R.Field""
  IL_0016:  ldind.i4
  IL_0017:  call       ""void System.Console.WriteLine(int)""
  IL_001c:  ret
}
");
        }
 
        [Fact]
        public void RefThis()
        {
            var source =
@"struct S<T>
{
    ref S<T> F() => ref this;
}
ref struct R<T>
{
    ref R<T> F() => ref this;
}";
 
            var expectedDiagnostics = new DiagnosticDescription[]
            {
                // (3,25): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //     ref S<T> F() => ref this;
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "this").WithLocation(3, 25),
                // (7,25): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //     ref R<T> F() => ref this;
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "this").WithLocation(7, 25)
            };
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(expectedDiagnostics);
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(expectedDiagnostics);
        }
 
        [Fact]
        public void RefThis_UnsafeContext()
        {
            var source =
@"struct S<T>
{
    unsafe ref S<T> F() => ref this;
}
ref struct R<T>
{
    unsafe ref R<T> F() => ref this;
}";
 
            var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugDll);
            comp.VerifyEmitDiagnostics(
                // (3,32): warning CS9081: Struct member returns 'this' or other instance members by reference
                //     unsafe ref S<T> F() => ref this;
                Diagnostic(ErrorCode.WRN_RefReturnStructThis, "this").WithLocation(3, 32),
                // (7,32): warning CS9081: Struct member returns 'this' or other instance members by reference
                //     unsafe ref R<T> F() => ref this;
                Diagnostic(ErrorCode.WRN_RefReturnStructThis, "this").WithLocation(7, 32)
                );
        }
 
        [Fact]
        public void RefParameter()
        {
            var source =
@"class C { }
struct S { }
ref struct R { }
class Program
{
    static ref C F1(ref C c) => ref c;
    static ref S F2(ref S s) => ref s;
    static ref R F3(ref R r) => ref r;
    static ref readonly C F4(in C c) => ref c;
    static ref readonly S F5(in S s) => ref s;
    static ref readonly R F6(in R r) => ref r;
    static ref C F7(out C c) { c = default; return ref c; } // 1
    static ref S F8(out S s) { s = default; return ref s; } // 2
    static ref R F9(out R r) { r = default; return ref r; } // 3
}";
 
            var expectedLegacyDiagnostics = new DiagnosticDescription[]
            {
            };
 
            var expectedUpdatedDiagnostics = new DiagnosticDescription[]
            {
                // (12,56): error CS9075: Cannot return a parameter by reference 'c' because it is scoped to the current method
                //     static ref C F7(out C c) { c = default; return ref c; } // 1
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "c").WithArguments("c").WithLocation(12, 56),
                // (13,56): error CS9075: Cannot return a parameter by reference 's' because it is scoped to the current method
                //     static ref S F8(out S s) { s = default; return ref s; } // 2
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "s").WithArguments("s").WithLocation(13, 56),
                // (14,56): error CS9075: Cannot return a parameter by reference 'r' because it is scoped to the current method
                //     static ref R F9(out R r) { r = default; return ref r; } // 3
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "r").WithArguments("r").WithLocation(14, 56)
            };
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(comp.Assembly.RuntimeSupportsByRefFields ? expectedUpdatedDiagnostics : expectedLegacyDiagnostics);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(expectedUpdatedDiagnostics);
        }
 
        [Fact]
        public void MethodInvocation_Lvalue_01()
        {
            var source =
@"struct S
{
    internal ref T F0<T>(T t) => throw null;
    internal ref T F1<T>(ref T t) => throw null;
    internal ref T F2<T>(in T t) => throw null;
    internal ref T F3<T>(out T t) => throw null;
}
class Program
{
    static ref T F00<T>() { S s = default; T t = default; return ref s.F0(t); }
    static ref T F01<T>() { S s = default; T t = default; return ref s.F1(ref t); } // 1
    static ref T F02<T>() { S s = default; T t = default; return ref s.F2(in t); } // 2
    static ref T F03<T>() { S s = default; T t = default; return ref s.F2(t); } // 3
    static ref T F04<T>() { S s = default; T t = default; return ref s.F3(out t); }
    static ref T F10<T>(ref T t) { S s = default; return ref s.F0(t); }
    static ref T F11<T>(ref T t) { S s = default; return ref s.F1(ref t); }
    static ref T F12<T>(ref T t) { S s = default; return ref s.F2(in t); }
    static ref T F13<T>(ref T t) { S s = default; return ref s.F2(t); }
    static ref T F14<T>(ref T t) { S s = default; return ref s.F3(out t); }
    static ref T F20<T>(in T t) { S s = default; return ref s.F0(t); }
    static ref T F22<T>(in T t) { S s = default; return ref s.F2(in t); }
    static ref T F23<T>(in T t) { S s = default; return ref s.F2(t); }
    static ref T F30<T>(out T t) { S s = default; t = default; return ref s.F0(t); }
    static ref T F31<T>(out T t) { S s = default; t = default; return ref s.F1(ref t); } // 4
    static ref T F32<T>(out T t) { S s = default; t = default; return ref s.F2(in t); } // 5
    static ref T F33<T>(out T t) { S s = default; t = default; return ref s.F2(t); } // 6
    static ref T F34<T>(out T t) { S s = default; t = default; return ref s.F3(out t); }
    static ref T F41<T>(ref S s) { T t = default; return ref s.F0(t); }
    static ref T F42<T>(in S s) { T t = default; return ref s.F1(ref t); } // 7
    static ref T F43<T>(out S s) { s = default; T t = default; return ref s.F2(in t); } // 8
    static ref T F51<T>(ref S s, ref T t) { return ref s.F0(t); }
    static ref T F52<T>(in S s, ref T t) { return ref s.F1(ref t); }
    static ref T F53<T>(out S s, ref T t) { s = default; return ref s.F2(in t); }
}";
 
            var expectedLegacyDiagnostics = new DiagnosticDescription[]
            {
                // (11,70): error CS8347: Cannot use a result of 'S.F1<T>(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static ref T F01<T>() { S s = default; T t = default; return ref s.F1(ref t); } // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F1(ref t)").WithArguments("S.F1<T>(ref T)", "t").WithLocation(11, 70),
                // (11,79): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     static ref T F01<T>() { S s = default; T t = default; return ref s.F1(ref t); } // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(11, 79),
                // (12,70): error CS8347: Cannot use a result of 'S.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static ref T F02<T>() { S s = default; T t = default; return ref s.F2(in t); } // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F2(in t)").WithArguments("S.F2<T>(in T)", "t").WithLocation(12, 70),
                // (12,78): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     static ref T F02<T>() { S s = default; T t = default; return ref s.F2(in t); } // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(12, 78),
                // (13,70): error CS8347: Cannot use a result of 'S.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static ref T F03<T>() { S s = default; T t = default; return ref s.F2(t); } // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F2(t)").WithArguments("S.F2<T>(in T)", "t").WithLocation(13, 70),
                // (13,75): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     static ref T F03<T>() { S s = default; T t = default; return ref s.F2(t); } // 3
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(13, 75),
                // (14,70): error CS8347: Cannot use a result of 'S.F3<T>(out T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static ref T F04<T>() { S s = default; T t = default; return ref s.F3(out t); }
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F3(out t)").WithArguments("S.F3<T>(out T)", "t").WithLocation(14, 70),
                // (14,79): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     static ref T F04<T>() { S s = default; T t = default; return ref s.F3(out t); }
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(14, 79),
                // (29,61): error CS8347: Cannot use a result of 'S.F1<T>(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static ref T F42<T>(in S s) { T t = default; return ref s.F1(ref t); } // 7
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F1(ref t)").WithArguments("S.F1<T>(ref T)", "t").WithLocation(29, 61),
                // (29,70): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     static ref T F42<T>(in S s) { T t = default; return ref s.F1(ref t); } // 7
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(29, 70),
                // (30,75): error CS8347: Cannot use a result of 'S.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static ref T F43<T>(out S s) { s = default; T t = default; return ref s.F2(in t); } // 8
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F2(in t)").WithArguments("S.F2<T>(in T)", "t").WithLocation(30, 75),
                // (30,83): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     static ref T F43<T>(out S s) { s = default; T t = default; return ref s.F2(in t); } // 8
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(30, 83)
            };
 
            var expectedUpdatedDiagnostics = new DiagnosticDescription[]
            {
                // (11,70): error CS8347: Cannot use a result of 'S.F1<T>(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static ref T F01<T>() { S s = default; T t = default; return ref s.F1(ref t); } // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F1(ref t)").WithArguments("S.F1<T>(ref T)", "t").WithLocation(11, 70),
                // (11,79): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     static ref T F01<T>() { S s = default; T t = default; return ref s.F1(ref t); } // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(11, 79),
                // (12,70): error CS8347: Cannot use a result of 'S.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static ref T F02<T>() { S s = default; T t = default; return ref s.F2(in t); } // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F2(in t)").WithArguments("S.F2<T>(in T)", "t").WithLocation(12, 70),
                // (12,78): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     static ref T F02<T>() { S s = default; T t = default; return ref s.F2(in t); } // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(12, 78),
                // (13,70): error CS8347: Cannot use a result of 'S.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static ref T F03<T>() { S s = default; T t = default; return ref s.F2(t); } // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F2(t)").WithArguments("S.F2<T>(in T)", "t").WithLocation(13, 70),
                // (13,75): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     static ref T F03<T>() { S s = default; T t = default; return ref s.F2(t); } // 3
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(13, 75),
                // (24,75): error CS8347: Cannot use a result of 'S.F1<T>(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static ref T F31<T>(out T t) { S s = default; t = default; return ref s.F1(ref t); } // 4
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F1(ref t)").WithArguments("S.F1<T>(ref T)", "t").WithLocation(24, 75),
                // (24,84): error CS9075: Cannot return a parameter by reference 't' because it is scoped to the current method
                //     static ref T F31<T>(out T t) { S s = default; t = default; return ref s.F1(ref t); } // 4
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "t").WithArguments("t").WithLocation(24, 84),
                // (25,75): error CS8347: Cannot use a result of 'S.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static ref T F32<T>(out T t) { S s = default; t = default; return ref s.F2(in t); } // 5
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F2(in t)").WithArguments("S.F2<T>(in T)", "t").WithLocation(25, 75),
                // (25,83): error CS9075: Cannot return a parameter by reference 't' because it is scoped to the current method
                //     static ref T F32<T>(out T t) { S s = default; t = default; return ref s.F2(in t); } // 5
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "t").WithArguments("t").WithLocation(25, 83),
                // (26,75): error CS8347: Cannot use a result of 'S.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static ref T F33<T>(out T t) { S s = default; t = default; return ref s.F2(t); } // 6
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F2(t)").WithArguments("S.F2<T>(in T)", "t").WithLocation(26, 75),
                // (26,80): error CS9075: Cannot return a parameter by reference 't' because it is scoped to the current method
                //     static ref T F33<T>(out T t) { S s = default; t = default; return ref s.F2(t); } // 6
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "t").WithArguments("t").WithLocation(26, 80),
                // (29,61): error CS8347: Cannot use a result of 'S.F1<T>(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static ref T F42<T>(in S s) { T t = default; return ref s.F1(ref t); } // 7
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F1(ref t)").WithArguments("S.F1<T>(ref T)", "t").WithLocation(29, 61),
                // (29,70): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     static ref T F42<T>(in S s) { T t = default; return ref s.F1(ref t); } // 7
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(29, 70),
                // (30,75): error CS8347: Cannot use a result of 'S.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static ref T F43<T>(out S s) { s = default; T t = default; return ref s.F2(in t); } // 8
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F2(in t)").WithArguments("S.F2<T>(in T)", "t").WithLocation(30, 75),
                // (30,83): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     static ref T F43<T>(out S s) { s = default; T t = default; return ref s.F2(in t); } // 8
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(30, 83)
            };
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(comp.Assembly.RuntimeSupportsByRefFields ? expectedUpdatedDiagnostics : expectedLegacyDiagnostics);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(expectedUpdatedDiagnostics);
        }
 
        [Fact]
        public void MethodInvocation_Lvalue_02()
        {
            var source =
@"class C
{
    ref T F0<T>(T t) => throw null;
    ref T F1<T>(ref T t) => throw null;
    ref T F2<T>(in T t) => throw null;
    ref T F3<T>(out T t) => throw null;
 
    ref T F00<T>() { T t = default; return ref F0(t); }
    ref T F01<T>() { T t = default; return ref F1(ref t); } // 1
    ref T F02<T>() { T t = default; return ref F2(in t); } // 2
    ref T F03<T>() { T t = default; return ref F2(t); } // 3
    ref T F04<T>() { T t = default; return ref F3(out t); }
    ref T F10<T>(ref T t) { return ref F0(t); }
    ref T F11<T>(ref T t) { return ref F1(ref t); }
    ref T F12<T>(ref T t) { return ref F2(in t); }
    ref T F13<T>(ref T t) { return ref F2(t); }
    ref T F14<T>(ref T t) { return ref F3(out t); }
    ref T F20<T>(in T t) { return ref F0(t); }
    ref T F22<T>(in T t) { return ref F2(in t); }
    ref T F23<T>(in T t) { return ref F2(t); }
    ref T F30<T>(out T t) { t = default; return ref F0(t); }
    ref T F31<T>(out T t) { t = default; return ref F1(ref t); } // 4
    ref T F32<T>(out T t) { t = default; return ref F2(in t); } // 5
    ref T F33<T>(out T t) { t = default; return ref F2(t); } // 6
    ref T F34<T>(out T t) { t = default; return ref F3(out t); }
}";
 
            var expectedLegacyDiagnostics = new DiagnosticDescription[]
            {
                // (9,48): error CS8347: Cannot use a result of 'C.F1<T>(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     ref T F01<T>() { T t = default; return ref F1(ref t); } // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "F1(ref t)").WithArguments("C.F1<T>(ref T)", "t").WithLocation(9, 48),
                // (9,55): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     ref T F01<T>() { T t = default; return ref F1(ref t); } // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(9, 55),
                // (10,48): error CS8347: Cannot use a result of 'C.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     ref T F02<T>() { T t = default; return ref F2(in t); } // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "F2(in t)").WithArguments("C.F2<T>(in T)", "t").WithLocation(10, 48),
                // (10,54): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     ref T F02<T>() { T t = default; return ref F2(in t); } // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(10, 54),
                // (11,48): error CS8347: Cannot use a result of 'C.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     ref T F03<T>() { T t = default; return ref F2(t); } // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "F2(t)").WithArguments("C.F2<T>(in T)", "t").WithLocation(11, 48),
                // (11,51): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     ref T F03<T>() { T t = default; return ref F2(t); } // 3
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(11, 51),
                // (12,48): error CS8347: Cannot use a result of 'C.F3<T>(out T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     ref T F04<T>() { T t = default; return ref F3(out t); }
                Diagnostic(ErrorCode.ERR_EscapeCall, "F3(out t)").WithArguments("C.F3<T>(out T)", "t").WithLocation(12, 48),
                // (12,55): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     ref T F04<T>() { T t = default; return ref F3(out t); }
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(12, 55)
            };
 
            var expectedUpdatedDiagnostics = new DiagnosticDescription[]
            {
                // (9,48): error CS8347: Cannot use a result of 'C.F1<T>(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     ref T F01<T>() { T t = default; return ref F1(ref t); } // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "F1(ref t)").WithArguments("C.F1<T>(ref T)", "t").WithLocation(9, 48),
                // (9,55): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     ref T F01<T>() { T t = default; return ref F1(ref t); } // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(9, 55),
                // (10,48): error CS8347: Cannot use a result of 'C.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     ref T F02<T>() { T t = default; return ref F2(in t); } // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "F2(in t)").WithArguments("C.F2<T>(in T)", "t").WithLocation(10, 48),
                // (10,54): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     ref T F02<T>() { T t = default; return ref F2(in t); } // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(10, 54),
                // (11,48): error CS8347: Cannot use a result of 'C.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     ref T F03<T>() { T t = default; return ref F2(t); } // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "F2(t)").WithArguments("C.F2<T>(in T)", "t").WithLocation(11, 48),
                // (11,51): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     ref T F03<T>() { T t = default; return ref F2(t); } // 3
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(11, 51),
                // (22,53): error CS8347: Cannot use a result of 'C.F1<T>(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     ref T F31<T>(out T t) { t = default; return ref F1(ref t); } // 4
                Diagnostic(ErrorCode.ERR_EscapeCall, "F1(ref t)").WithArguments("C.F1<T>(ref T)", "t").WithLocation(22, 53),
                // (22,60): error CS9075: Cannot return a parameter by reference 't' because it is scoped to the current method
                //     ref T F31<T>(out T t) { t = default; return ref F1(ref t); } // 4
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "t").WithArguments("t").WithLocation(22, 60),
                // (23,53): error CS8347: Cannot use a result of 'C.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     ref T F32<T>(out T t) { t = default; return ref F2(in t); } // 5
                Diagnostic(ErrorCode.ERR_EscapeCall, "F2(in t)").WithArguments("C.F2<T>(in T)", "t").WithLocation(23, 53),
                // (23,59): error CS9075: Cannot return a parameter by reference 't' because it is scoped to the current method
                //     ref T F32<T>(out T t) { t = default; return ref F2(in t); } // 5
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "t").WithArguments("t").WithLocation(23, 59),
                // (24,53): error CS8347: Cannot use a result of 'C.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     ref T F33<T>(out T t) { t = default; return ref F2(t); } // 6
                Diagnostic(ErrorCode.ERR_EscapeCall, "F2(t)").WithArguments("C.F2<T>(in T)", "t").WithLocation(24, 53),
                // (24,56): error CS9075: Cannot return a parameter by reference 't' because it is scoped to the current method
                //     ref T F33<T>(out T t) { t = default; return ref F2(t); } // 6
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "t").WithArguments("t").WithLocation(24, 56)
            };
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(comp.Assembly.RuntimeSupportsByRefFields ? expectedUpdatedDiagnostics : expectedLegacyDiagnostics);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(expectedUpdatedDiagnostics);
        }
 
        [Fact]
        public void MethodInvocation_Lvalue_03()
        {
            var source =
@"class Program
{
    static ref T F0<T, U>(T t, U u) => throw null;
    static ref T F1<T, U>(T t, ref U u) => throw null;
    static ref T F2<T, U>(T t, in U u) => throw null;
    static ref T F3<T, U>(T t, out U u) => throw null;
    static ref T F4<T, U>(ref T t, ref U u) => throw null;
    static ref T F5<T, U>(ref T t, in U u) => throw null;
    static ref T F6<T, U>(ref T t, out U u) => throw null;
    static ref T F7<T, U>(in T t, in U u) => throw null;
    static ref T F8<T, U>(in T t, out U u) => throw null;
    static ref T F9<T, U>(out T t, out U u) => throw null;
    static ref T G0<T, U>()
    {
        T t = default;
        U u = default;
        return ref F0(t, u);
    }
    static ref T G1<T, U>()
    {
        T t = default;
        U u = default;
        return ref F1(t, ref u); // 1
    }
    static ref T G2A<T, U>()
    {
        T t = default;
        U u = default;
        return ref F2(t, in u); // 2
    }
    static ref T G2B<T, U>()
    {
        T t = default;
        U u = default;
        return ref F2(t, u); // 3
    }
    static ref T G3<T, U>()
    {
        T t = default;
        U u = default;
        return ref F3(t, out u); // *
    }
    static ref T G4<T, U>()
    {
        T t = default;
        U u = default;
        return ref F4(ref t, ref u); // 4
    }
    static ref T G5A<T, U>()
    {
        T t = default;
        U u = default;
        return ref F5(ref t, in u); // 5
    }
    static ref T G5B<T, U>()
    {
        T t = default;
        U u = default;
        return ref F5(ref t, u); // 6
    }
    static ref T G6<T, U>()
    {
        T t = default;
        U u = default;
        return ref F6(ref t, out u); // 7
    }
    static ref T G7A<T, U>()
    {
        T t = default;
        U u = default;
        return ref F7(in t, in u); // 8
    }
    static ref T G7B<T, U>()
    {
        T t = default;
        U u = default;
        return ref F7(t, u); // 9
    }
    static ref T G8A<T, U>()
    {
        T t = default;
        U u = default;
        return ref F8(in t, out u); // 10
    }
    static ref T G8B<T, U>()
    {
        T t = default;
        U u = default;
        return ref F8(t, out u); // 11
    }
    static ref T G9<T, U>()
    {
        T t = default;
        U u = default;
        return ref F9(out t, out u); // *
    }
}";
 
            var expectedLegacyDiagnostics = new DiagnosticDescription[]
            {
                // (23,20): error CS8347: Cannot use a result of 'Program.F1<T, U>(T, ref U)' in this context because it may expose variables referenced by parameter 'u' outside of their declaration scope
                //         return ref F1(t, ref u); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "F1(t, ref u)").WithArguments("Program.F1<T, U>(T, ref U)", "u").WithLocation(23, 20),
                // (23,30): error CS8168: Cannot return local 'u' by reference because it is not a ref local
                //         return ref F1(t, ref u); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "u").WithArguments("u").WithLocation(23, 30),
                // (29,20): error CS8347: Cannot use a result of 'Program.F2<T, U>(T, in U)' in this context because it may expose variables referenced by parameter 'u' outside of their declaration scope
                //         return ref F2(t, in u); // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "F2(t, in u)").WithArguments("Program.F2<T, U>(T, in U)", "u").WithLocation(29, 20),
                // (29,29): error CS8168: Cannot return local 'u' by reference because it is not a ref local
                //         return ref F2(t, in u); // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "u").WithArguments("u").WithLocation(29, 29),
                // (35,20): error CS8347: Cannot use a result of 'Program.F2<T, U>(T, in U)' in this context because it may expose variables referenced by parameter 'u' outside of their declaration scope
                //         return ref F2(t, u); // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "F2(t, u)").WithArguments("Program.F2<T, U>(T, in U)", "u").WithLocation(35, 20),
                // (35,26): error CS8168: Cannot return local 'u' by reference because it is not a ref local
                //         return ref F2(t, u); // 3
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "u").WithArguments("u").WithLocation(35, 26),
                // (41,20): error CS8347: Cannot use a result of 'Program.F3<T, U>(T, out U)' in this context because it may expose variables referenced by parameter 'u' outside of their declaration scope
                //         return ref F3(t, out u); // *
                Diagnostic(ErrorCode.ERR_EscapeCall, "F3(t, out u)").WithArguments("Program.F3<T, U>(T, out U)", "u").WithLocation(41, 20),
                // (41,30): error CS8168: Cannot return local 'u' by reference because it is not a ref local
                //         return ref F3(t, out u); // *
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "u").WithArguments("u").WithLocation(41, 30),
                // (47,20): error CS8347: Cannot use a result of 'Program.F4<T, U>(ref T, ref U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F4(ref t, ref u); // 4
                Diagnostic(ErrorCode.ERR_EscapeCall, "F4(ref t, ref u)").WithArguments("Program.F4<T, U>(ref T, ref U)", "t").WithLocation(47, 20),
                // (47,27): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return ref F4(ref t, ref u); // 4
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(47, 27),
                // (53,20): error CS8347: Cannot use a result of 'Program.F5<T, U>(ref T, in U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F5(ref t, in u); // 5
                Diagnostic(ErrorCode.ERR_EscapeCall, "F5(ref t, in u)").WithArguments("Program.F5<T, U>(ref T, in U)", "t").WithLocation(53, 20),
                // (53,27): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return ref F5(ref t, in u); // 5
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(53, 27),
                // (59,20): error CS8347: Cannot use a result of 'Program.F5<T, U>(ref T, in U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F5(ref t, u); // 6
                Diagnostic(ErrorCode.ERR_EscapeCall, "F5(ref t, u)").WithArguments("Program.F5<T, U>(ref T, in U)", "t").WithLocation(59, 20),
                // (59,27): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return ref F5(ref t, u); // 6
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(59, 27),
                // (65,20): error CS8347: Cannot use a result of 'Program.F6<T, U>(ref T, out U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F6(ref t, out u); // 7
                Diagnostic(ErrorCode.ERR_EscapeCall, "F6(ref t, out u)").WithArguments("Program.F6<T, U>(ref T, out U)", "t").WithLocation(65, 20),
                // (65,27): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return ref F6(ref t, out u); // 7
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(65, 27),
                // (71,20): error CS8347: Cannot use a result of 'Program.F7<T, U>(in T, in U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F7(in t, in u); // 8
                Diagnostic(ErrorCode.ERR_EscapeCall, "F7(in t, in u)").WithArguments("Program.F7<T, U>(in T, in U)", "t").WithLocation(71, 20),
                // (71,26): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return ref F7(in t, in u); // 8
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(71, 26),
                // (77,20): error CS8347: Cannot use a result of 'Program.F7<T, U>(in T, in U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F7(t, u); // 9
                Diagnostic(ErrorCode.ERR_EscapeCall, "F7(t, u)").WithArguments("Program.F7<T, U>(in T, in U)", "t").WithLocation(77, 20),
                // (77,23): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return ref F7(t, u); // 9
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(77, 23),
                // (83,20): error CS8347: Cannot use a result of 'Program.F8<T, U>(in T, out U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F8(in t, out u); // 10
                Diagnostic(ErrorCode.ERR_EscapeCall, "F8(in t, out u)").WithArguments("Program.F8<T, U>(in T, out U)", "t").WithLocation(83, 20),
                // (83,26): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return ref F8(in t, out u); // 10
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(83, 26),
                // (89,20): error CS8347: Cannot use a result of 'Program.F8<T, U>(in T, out U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F8(t, out u); // 11
                Diagnostic(ErrorCode.ERR_EscapeCall, "F8(t, out u)").WithArguments("Program.F8<T, U>(in T, out U)", "t").WithLocation(89, 20),
                // (89,23): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return ref F8(t, out u); // 11
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(89, 23),
                // (95,20): error CS8347: Cannot use a result of 'Program.F9<T, U>(out T, out U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F9(out t, out u); // *
                Diagnostic(ErrorCode.ERR_EscapeCall, "F9(out t, out u)").WithArguments("Program.F9<T, U>(out T, out U)", "t").WithLocation(95, 20),
                // (95,27): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return ref F9(out t, out u); // *
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(95, 27)
            };
 
            var expectedUpdatedDiagnostics = new DiagnosticDescription[]
            {
                // (23,20): error CS8347: Cannot use a result of 'Program.F1<T, U>(T, ref U)' in this context because it may expose variables referenced by parameter 'u' outside of their declaration scope
                //         return ref F1(t, ref u); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "F1(t, ref u)").WithArguments("Program.F1<T, U>(T, ref U)", "u").WithLocation(23, 20),
                // (23,30): error CS8168: Cannot return local 'u' by reference because it is not a ref local
                //         return ref F1(t, ref u); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "u").WithArguments("u").WithLocation(23, 30),
                // (29,20): error CS8347: Cannot use a result of 'Program.F2<T, U>(T, in U)' in this context because it may expose variables referenced by parameter 'u' outside of their declaration scope
                //         return ref F2(t, in u); // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "F2(t, in u)").WithArguments("Program.F2<T, U>(T, in U)", "u").WithLocation(29, 20),
                // (29,29): error CS8168: Cannot return local 'u' by reference because it is not a ref local
                //         return ref F2(t, in u); // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "u").WithArguments("u").WithLocation(29, 29),
                // (35,20): error CS8347: Cannot use a result of 'Program.F2<T, U>(T, in U)' in this context because it may expose variables referenced by parameter 'u' outside of their declaration scope
                //         return ref F2(t, u); // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "F2(t, u)").WithArguments("Program.F2<T, U>(T, in U)", "u").WithLocation(35, 20),
                // (35,26): error CS8168: Cannot return local 'u' by reference because it is not a ref local
                //         return ref F2(t, u); // 3
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "u").WithArguments("u").WithLocation(35, 26),
                // (47,20): error CS8347: Cannot use a result of 'Program.F4<T, U>(ref T, ref U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F4(ref t, ref u); // 4
                Diagnostic(ErrorCode.ERR_EscapeCall, "F4(ref t, ref u)").WithArguments("Program.F4<T, U>(ref T, ref U)", "t").WithLocation(47, 20),
                // (47,27): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return ref F4(ref t, ref u); // 4
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(47, 27),
                // (53,20): error CS8347: Cannot use a result of 'Program.F5<T, U>(ref T, in U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F5(ref t, in u); // 5
                Diagnostic(ErrorCode.ERR_EscapeCall, "F5(ref t, in u)").WithArguments("Program.F5<T, U>(ref T, in U)", "t").WithLocation(53, 20),
                // (53,27): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return ref F5(ref t, in u); // 5
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(53, 27),
                // (59,20): error CS8347: Cannot use a result of 'Program.F5<T, U>(ref T, in U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F5(ref t, u); // 6
                Diagnostic(ErrorCode.ERR_EscapeCall, "F5(ref t, u)").WithArguments("Program.F5<T, U>(ref T, in U)", "t").WithLocation(59, 20),
                // (59,27): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return ref F5(ref t, u); // 6
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(59, 27),
                // (65,20): error CS8347: Cannot use a result of 'Program.F6<T, U>(ref T, out U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F6(ref t, out u); // 7
                Diagnostic(ErrorCode.ERR_EscapeCall, "F6(ref t, out u)").WithArguments("Program.F6<T, U>(ref T, out U)", "t").WithLocation(65, 20),
                // (65,27): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return ref F6(ref t, out u); // 7
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(65, 27),
                // (71,20): error CS8347: Cannot use a result of 'Program.F7<T, U>(in T, in U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F7(in t, in u); // 8
                Diagnostic(ErrorCode.ERR_EscapeCall, "F7(in t, in u)").WithArguments("Program.F7<T, U>(in T, in U)", "t").WithLocation(71, 20),
                // (71,26): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return ref F7(in t, in u); // 8
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(71, 26),
                // (77,20): error CS8347: Cannot use a result of 'Program.F7<T, U>(in T, in U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F7(t, u); // 9
                Diagnostic(ErrorCode.ERR_EscapeCall, "F7(t, u)").WithArguments("Program.F7<T, U>(in T, in U)", "t").WithLocation(77, 20),
                // (77,23): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return ref F7(t, u); // 9
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(77, 23),
                // (83,20): error CS8347: Cannot use a result of 'Program.F8<T, U>(in T, out U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F8(in t, out u); // 10
                Diagnostic(ErrorCode.ERR_EscapeCall, "F8(in t, out u)").WithArguments("Program.F8<T, U>(in T, out U)", "t").WithLocation(83, 20),
                // (83,26): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return ref F8(in t, out u); // 10
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(83, 26),
                // (89,20): error CS8347: Cannot use a result of 'Program.F8<T, U>(in T, out U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F8(t, out u); // 11
                Diagnostic(ErrorCode.ERR_EscapeCall, "F8(t, out u)").WithArguments("Program.F8<T, U>(in T, out U)", "t").WithLocation(89, 20),
                // (89,23): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return ref F8(t, out u); // 11
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(89, 23)
            };
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(comp.Assembly.RuntimeSupportsByRefFields ? expectedUpdatedDiagnostics : expectedLegacyDiagnostics);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(expectedUpdatedDiagnostics);
        }
 
        [Fact]
        public void MethodInvocation_Rvalue_01()
        {
            var source =
@"struct S
{
    internal T F0<T>(T t) => throw null;
    internal T F1<T>(ref T t) => throw null;
    internal T F2<T>(in T t) => throw null;
    internal T F3<T>(out T t) => throw null;
}
class Program
{
    static T F00<T>() { S s = default; T t = default; return s.F0(t); }
    static T F01<T>() { S s = default; T t = default; return s.F1(ref t); }
    static T F02<T>() { S s = default; T t = default; return s.F2(in t); }
    static T F03<T>() { S s = default; T t = default; return s.F2(t); }
    static T F04<T>() { S s = default; T t = default; return s.F3(out t); }
    static T F10<T>(ref T t) { S s = default; return s.F0(t); }
    static T F11<T>(ref T t) { S s = default; return s.F1(ref t); }
    static T F12<T>(ref T t) { S s = default; return s.F2(in t); }
    static T F13<T>(ref T t) { S s = default; return s.F2(t); }
    static T F14<T>(ref T t) { S s = default; return s.F3(out t); }
    static T F20<T>(in T t) { S s = default; return s.F0(t); }
    static T F22<T>(in T t) { S s = default; return s.F2(in t); }
    static T F23<T>(in T t) { S s = default; return s.F2(t); }
    static T F30<T>(out T t) { S s = default; t = default; return s.F0(t); }
    static T F31<T>(out T t) { S s = default; t = default; return s.F1(ref t); }
    static T F32<T>(out T t) { S s = default; t = default; return s.F2(in t); }
    static T F33<T>(out T t) { S s = default; t = default; return s.F2(t); }
    static T F34<T>(out T t) { S s = default; t = default; return s.F3(out t); }
    static T F41<T>(ref S s) { T t = default; return s.F0(t); }
    static T F42<T>(in S s) { T t = default; return s.F1(ref t); }
    static T F43<T>(out S s) { s = default; T t = default; return s.F2(in t); }
    static T F51<T>(ref S s, ref T t) { return s.F0(t); }
    static T F52<T>(in S s, ref T t) { return s.F1(ref t); }
    static T F53<T>(out S s, ref T t) { s = default; return s.F2(in t); }
}";
 
            var expectedLegacyDiagnostics = new DiagnosticDescription[]
            {
            };
 
            var expectedUpdatedDiagnostics = new DiagnosticDescription[]
            {
            };
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(comp.Assembly.RuntimeSupportsByRefFields ? expectedUpdatedDiagnostics : expectedLegacyDiagnostics);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(expectedUpdatedDiagnostics);
        }
 
        [Fact]
        public void MethodInvocation_Rvalue_02()
        {
            var source =
@"class C
{
    T F0<T>(T t) => throw null;
    T F1<T>(ref T t) => throw null;
    T F2<T>(in T t) => throw null;
    T F3<T>(out T t) => throw null;
 
    T F00<T>() { T t = default; return F0(t); }
    T F01<T>() { T t = default; return F1(ref t); }
    T F02<T>() { T t = default; return F2(in t); }
    T F03<T>() { T t = default; return F2(t); }
    T F04<T>() { T t = default; return F3(out t); }
    T F10<T>(ref T t) { return F0(t); }
    T F11<T>(ref T t) { return F1(ref t); }
    T F12<T>(ref T t) { return F2(in t); }
    T F13<T>(ref T t) { return F2(t); }
    T F14<T>(ref T t) { return F3(out t); }
    T F20<T>(in T t) { return F0(t); }
    T F22<T>(in T t) { return F2(in t); }
    T F23<T>(in T t) { return F2(t); }
    T F30<T>(out T t) { t = default; return F0(t); }
    T F31<T>(out T t) { t = default; return F1(ref t); }
    T F32<T>(out T t) { t = default; return F2(in t); }
    T F33<T>(out T t) { t = default; return F2(t); }
    T F34<T>(out T t) { t = default; return F3(out t); }
}";
 
            var expectedLegacyDiagnostics = new DiagnosticDescription[]
            {
            };
 
            var expectedUpdatedDiagnostics = new DiagnosticDescription[]
            {
            };
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(comp.Assembly.RuntimeSupportsByRefFields ? expectedUpdatedDiagnostics : expectedLegacyDiagnostics);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(expectedUpdatedDiagnostics);
        }
 
        [Fact]
        public void MethodInvocation_Rvalue_03()
        {
            var source =
@"class Program
{
    static T F0<T, U>(T t, U u) => throw null;
    static T F1<T, U>(T t, ref U u) => throw null;
    static T F2<T, U>(T t, in U u) => throw null;
    static T F3<T, U>(T t, out U u) => throw null;
    static T F4<T, U>(ref T t, ref U u) => throw null;
    static T F5<T, U>(ref T t, in U u) => throw null;
    static T F6<T, U>(ref T t, out U u) => throw null;
    static T F7<T, U>(in T t, in U u) => throw null;
    static T F8<T, U>(in T t, out U u) => throw null;
    static T F9<T, U>(out T t, out U u) => throw null;
 
    static T G0<T, U>()
    {
        T t = default;
        U u = default;
        return F0(t, u);
    }
    static T G1<T, U>()
    {
        T t = default;
        U u = default;
        return F1(t, ref u);
    }
    static T G2A<T, U>()
    {
        T t = default;
        U u = default;
        return F2(t, in u);
    }
    static T G2B<T, U>()
    {
        T t = default;
        U u = default;
        return F2(t, u);
    }
    static T G3<T, U>()
    {
        T t = default;
        U u = default;
        return F3(t, out u);
    }
    static T G4<T, U>()
    {
        T t = default;
        U u = default;
        return F4(ref t, ref u);
    }
    static T G5A<T, U>()
    {
        T t = default;
        U u = default;
        return F5(ref t, in u);
    }
    static T G5B<T, U>()
    {
        T t = default;
        U u = default;
        return F5(ref t, u);
    }
    static T G6<T, U>()
    {
        T t = default;
        U u = default;
        return F6(ref t, out u);
    }
    static T G7A<T, U>()
    {
        T t = default;
        U u = default;
        return F7(in t, in u);
    }
    static T G7B<T, U>()
    {
        T t = default;
        U u = default;
        return F7(t, u);
    }
    static T G8A<T, U>()
    {
        T t = default;
        U u = default;
        return F8(in t, out u);
    }
    static T G8B<T, U>()
    {
        T t = default;
        U u = default;
        return F8(t, out u);
    }
    static T G9<T, U>()
    {
        T t = default;
        U u = default;
        return F9(out t, out u);
    }
}";
 
            var expectedLegacyDiagnostics = new DiagnosticDescription[]
            {
            };
 
            var expectedUpdatedDiagnostics = new DiagnosticDescription[]
            {
            };
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(comp.Assembly.RuntimeSupportsByRefFields ? expectedUpdatedDiagnostics : expectedLegacyDiagnostics);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(expectedUpdatedDiagnostics);
        }
 
        [Fact]
        public void MethodInvocation_Rvalue_04()
        {
            var source =
@"ref struct R<T>
{
}
struct S
{
    internal R<T> F0<T>(T t) => throw null;
    internal R<T> F1<T>(ref T t) => throw null;
    internal R<T> F2<T>(in T t) => throw null;
    internal R<T> F3<T>(out T t) => throw null;
}
class Program
{
    static R<T> F00<T>() { S s = default; T t = default; return s.F0(t); }
    static R<T> F01<T>() { S s = default; T t = default; return s.F1(ref t); } // 1
    static R<T> F02<T>() { S s = default; T t = default; return s.F2(in t); } // 2
    static R<T> F03<T>() { S s = default; T t = default; return s.F2(t); } // 3
    static R<T> F04<T>() { S s = default; T t = default; return s.F3(out t); }
    static R<T> F10<T>(ref T t) { S s = default; return s.F0(t); }
    static R<T> F11<T>(ref T t) { S s = default; return s.F1(ref t); }
    static R<T> F12<T>(ref T t) { S s = default; return s.F2(in t); }
    static R<T> F13<T>(ref T t) { S s = default; return s.F2(t); }
    static R<T> F14<T>(ref T t) { S s = default; return s.F3(out t); }
    static R<T> F20<T>(in T t) { S s = default; return s.F0(t); }
    static R<T> F22<T>(in T t) { S s = default; return s.F2(in t); }
    static R<T> F23<T>(in T t) { S s = default; return s.F2(t); }
    static R<T> F30<T>(out T t) { S s = default; t = default; return s.F0(t); }
    static R<T> F31<T>(out T t) { S s = default; t = default; return s.F1(ref t); } // 4
    static R<T> F32<T>(out T t) { S s = default; t = default; return s.F2(in t); } // 5
    static R<T> F33<T>(out T t) { S s = default; t = default; return s.F2(t); } // 6
    static R<T> F34<T>(out T t) { S s = default; t = default; return s.F3(out t); }
    static R<T> F40<T>(ref S s) { T t = default; return s.F0(t); }
    static R<T> F41<T>(in S s) { T t = default; return s.F1(ref t); } // 7
    static R<T> F42<T>(out S s) { s = default; T t = default; return s.F2(in t); } // 8
    static R<T> F43<T>(out S s) { s = default; T t = default; return s.F2(t); } // 9
    static R<T> F44<T>(out S s) { s = default; T t = default; return s.F3(out t); }
    static R<T> F50<T>(ref S s, ref T t) { return s.F0(t); }
    static R<T> F51<T>(in S s, ref T t) { return s.F1(ref t); }
    static R<T> F52<T>(out S s, ref T t) { s = default; return s.F2(in t); }
    static R<T> F53<T>(out S s, ref T t) { s = default; return s.F2(t); }
    static R<T> F54<T>(out S s, ref T t) { s = default; return s.F3(out t); }
}";
 
            var expectedLegacyDiagnostics = new DiagnosticDescription[]
            {
            };
 
            var expectedUpdatedDiagnostics = new DiagnosticDescription[]
            {
                // (14,65): error CS8347: Cannot use a result of 'S.F1<T>(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static R<T> F01<T>() { S s = default; T t = default; return s.F1(ref t); } // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F1(ref t)").WithArguments("S.F1<T>(ref T)", "t").WithLocation(14, 65),
                // (14,74): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     static R<T> F01<T>() { S s = default; T t = default; return s.F1(ref t); } // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(14, 74),
                // (15,65): error CS8347: Cannot use a result of 'S.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static R<T> F02<T>() { S s = default; T t = default; return s.F2(in t); } // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F2(in t)").WithArguments("S.F2<T>(in T)", "t").WithLocation(15, 65),
                // (15,73): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     static R<T> F02<T>() { S s = default; T t = default; return s.F2(in t); } // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(15, 73),
                // (16,65): error CS8347: Cannot use a result of 'S.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static R<T> F03<T>() { S s = default; T t = default; return s.F2(t); } // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F2(t)").WithArguments("S.F2<T>(in T)", "t").WithLocation(16, 65),
                // (16,70): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     static R<T> F03<T>() { S s = default; T t = default; return s.F2(t); } // 3
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(16, 70),
                // (27,70): error CS8347: Cannot use a result of 'S.F1<T>(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static R<T> F31<T>(out T t) { S s = default; t = default; return s.F1(ref t); } // 4
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F1(ref t)").WithArguments("S.F1<T>(ref T)", "t").WithLocation(27, 70),
                // (27,79): error CS9075: Cannot return a parameter by reference 't' because it is scoped to the current method
                //     static R<T> F31<T>(out T t) { S s = default; t = default; return s.F1(ref t); } // 4
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "t").WithArguments("t").WithLocation(27, 79),
                // (28,70): error CS8347: Cannot use a result of 'S.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static R<T> F32<T>(out T t) { S s = default; t = default; return s.F2(in t); } // 5
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F2(in t)").WithArguments("S.F2<T>(in T)", "t").WithLocation(28, 70),
                // (28,78): error CS9075: Cannot return a parameter by reference 't' because it is scoped to the current method
                //     static R<T> F32<T>(out T t) { S s = default; t = default; return s.F2(in t); } // 5
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "t").WithArguments("t").WithLocation(28, 78),
                // (29,70): error CS8347: Cannot use a result of 'S.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static R<T> F33<T>(out T t) { S s = default; t = default; return s.F2(t); } // 6
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F2(t)").WithArguments("S.F2<T>(in T)", "t").WithLocation(29, 70),
                // (29,75): error CS9075: Cannot return a parameter by reference 't' because it is scoped to the current method
                //     static R<T> F33<T>(out T t) { S s = default; t = default; return s.F2(t); } // 6
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "t").WithArguments("t").WithLocation(29, 75),
                // (32,56): error CS8347: Cannot use a result of 'S.F1<T>(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static R<T> F41<T>(in S s) { T t = default; return s.F1(ref t); } // 7
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F1(ref t)").WithArguments("S.F1<T>(ref T)", "t").WithLocation(32, 56),
                // (32,65): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     static R<T> F41<T>(in S s) { T t = default; return s.F1(ref t); } // 7
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(32, 65),
                // (33,70): error CS8347: Cannot use a result of 'S.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static R<T> F42<T>(out S s) { s = default; T t = default; return s.F2(in t); } // 8
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F2(in t)").WithArguments("S.F2<T>(in T)", "t").WithLocation(33, 70),
                // (33,78): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     static R<T> F42<T>(out S s) { s = default; T t = default; return s.F2(in t); } // 8
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(33, 78),
                // (34,70): error CS8347: Cannot use a result of 'S.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static R<T> F43<T>(out S s) { s = default; T t = default; return s.F2(t); } // 9
                Diagnostic(ErrorCode.ERR_EscapeCall, "s.F2(t)").WithArguments("S.F2<T>(in T)", "t").WithLocation(34, 70),
                // (34,75): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     static R<T> F43<T>(out S s) { s = default; T t = default; return s.F2(t); } // 9
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(34, 75)
            };
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(comp.Assembly.RuntimeSupportsByRefFields ? expectedUpdatedDiagnostics : expectedLegacyDiagnostics);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(expectedUpdatedDiagnostics);
        }
 
        [Fact]
        public void MethodInvocation_Rvalue_05()
        {
            var source =
@"ref struct R
{
}
class C
{
    R F0<T>(T t) => throw null;
    R F1<T>(ref T t) => throw null;
    R F2<T>(in T t) => throw null;
    R F3<T>(out T t) => throw null;
 
    R F00<T>() { T t = default; return F0(t); }
    R F01<T>() { T t = default; return F1(ref t); } // 1
    R F02<T>() { T t = default; return F2(in t); } // 2
    R F03<T>() { T t = default; return F2(t); } // 3
    R F04<T>() { T t = default; return F3(out t); }
    R F10<T>(ref T t) { return F0(t); }
    R F11<T>(ref T t) { return F1(ref t); }
    R F12<T>(ref T t) { return F2(in t); }
    R F13<T>(ref T t) { return F2(t); }
    R F14<T>(ref T t) { return F3(out t); }
    R F20<T>(in T t) { return F0(t); }
    R F22<T>(in T t) { return F2(in t); }
    R F23<T>(in T t) { return F2(t); }
    R F30<T>(out T t) { t = default; return F0(t); }
    R F31<T>(out T t) { t = default; return F1(ref t); } // 4
    R F32<T>(out T t) { t = default; return F2(in t); } // 5
    R F33<T>(out T t) { t = default; return F2(t); } // 6
    R F34<T>(out T t) { t = default; return F3(out t); }
}";
 
            var expectedLegacyDiagnostics = new DiagnosticDescription[]
            {
            };
 
            var expectedUpdatedDiagnostics = new DiagnosticDescription[]
            {
                // (12,40): error CS8347: Cannot use a result of 'C.F1<T>(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     R F01<T>() { T t = default; return F1(ref t); } // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "F1(ref t)").WithArguments("C.F1<T>(ref T)", "t").WithLocation(12, 40),
                // (12,47): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     R F01<T>() { T t = default; return F1(ref t); } // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(12, 47),
                // (13,40): error CS8347: Cannot use a result of 'C.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     R F02<T>() { T t = default; return F2(in t); } // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "F2(in t)").WithArguments("C.F2<T>(in T)", "t").WithLocation(13, 40),
                // (13,46): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     R F02<T>() { T t = default; return F2(in t); } // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(13, 46),
                // (14,40): error CS8347: Cannot use a result of 'C.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     R F03<T>() { T t = default; return F2(t); } // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "F2(t)").WithArguments("C.F2<T>(in T)", "t").WithLocation(14, 40),
                // (14,43): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //     R F03<T>() { T t = default; return F2(t); } // 3
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(14, 43),
                // (25,45): error CS8347: Cannot use a result of 'C.F1<T>(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     R F31<T>(out T t) { t = default; return F1(ref t); } // 4
                Diagnostic(ErrorCode.ERR_EscapeCall, "F1(ref t)").WithArguments("C.F1<T>(ref T)", "t").WithLocation(25, 45),
                // (25,52): error CS9075: Cannot return a parameter by reference 't' because it is scoped to the current method
                //     R F31<T>(out T t) { t = default; return F1(ref t); } // 4
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "t").WithArguments("t").WithLocation(25, 52),
                // (26,45): error CS8347: Cannot use a result of 'C.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     R F32<T>(out T t) { t = default; return F2(in t); } // 5
                Diagnostic(ErrorCode.ERR_EscapeCall, "F2(in t)").WithArguments("C.F2<T>(in T)", "t").WithLocation(26, 45),
                // (26,51): error CS9075: Cannot return a parameter by reference 't' because it is scoped to the current method
                //     R F32<T>(out T t) { t = default; return F2(in t); } // 5
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "t").WithArguments("t").WithLocation(26, 51),
                // (27,45): error CS8347: Cannot use a result of 'C.F2<T>(in T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     R F33<T>(out T t) { t = default; return F2(t); } // 6
                Diagnostic(ErrorCode.ERR_EscapeCall, "F2(t)").WithArguments("C.F2<T>(in T)", "t").WithLocation(27, 45),
                // (27,48): error CS9075: Cannot return a parameter by reference 't' because it is scoped to the current method
                //     R F33<T>(out T t) { t = default; return F2(t); } // 6
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "t").WithArguments("t").WithLocation(27, 48)
            };
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(comp.Assembly.RuntimeSupportsByRefFields ? expectedUpdatedDiagnostics : expectedLegacyDiagnostics);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(expectedUpdatedDiagnostics);
        }
 
        [Fact]
        public void MethodInvocation_Rvalue_06()
        {
            var source =
@"ref struct R<T>
{
}
class Program
{
    static R<T> F0<T, U>(T t, U u) => throw null;
    static R<T> F1<T, U>(T t, ref U u) => throw null;
    static R<T> F2<T, U>(T t, in U u) => throw null;
    static R<T> F3<T, U>(T t, out U u) => throw null;
    static R<T> F4<T, U>(ref T t, ref U u) => throw null;
    static R<T> F5<T, U>(ref T t, in U u) => throw null;
    static R<T> F6<T, U>(ref T t, out U u) => throw null;
    static R<T> F7<T, U>(in T t, in U u) => throw null;
    static R<T> F8<T, U>(in T t, out U u) => throw null;
    static R<T> F9<T, U>(out T t, out U u) => throw null;
    static R<T> G0<T, U>()
    {
        T t = default;
        U u = default;
        return F0(t, u);
    }
    static R<T> G1<T, U>()
    {
        T t = default;
        U u = default;
        return F1(t, ref u); // 1
    }
    static R<T> G2A<T, U>()
    {
        T t = default;
        U u = default;
        return F2(t, in u); // 2
    }
    static R<T> G2B<T, U>()
    {
        T t = default;
        U u = default;
        return F2(t, u); // 3
    }
    static R<T> G3<T, U>()
    {
        T t = default;
        U u = default;
        return F3(t, out u);
    }
    static R<T> G4<T, U>()
    {
        T t = default;
        U u = default;
        return F4(ref t, ref u); // 4
    }
    static R<T> G5A<T, U>()
    {
        T t = default;
        U u = default;
        return F5(ref t, in u); // 5
    }
    static R<T> G5B<T, U>()
    {
        T t = default;
        U u = default;
        return F5(ref t, u); // 6
    }
    static R<T> G6<T, U>()
    {
        T t = default;
        U u = default;
        return F6(ref t, out u); // 7
    }
    static R<T> G7A<T, U>()
    {
        T t = default;
        U u = default;
        return F7(in t, in u); // 8
    }
    static R<T> G7B<T, U>()
    {
        T t = default;
        U u = default;
        return F7(t, u); // 9
    }
    static R<T> G8A<T, U>()
    {
        T t = default;
        U u = default;
        return F8(in t, out u); // 10
    }
    static R<T> G8B<T, U>()
    {
        T t = default;
        U u = default;
        return F8(t, out u); // 11
    }
    static R<T> G9<T, U>()
    {
        T t = default;
        U u = default;
        return F9(out t, out u);
    }
}";
 
            var expectedLegacyDiagnostics = new DiagnosticDescription[]
            {
            };
 
            var expectedUpdatedDiagnostics = new DiagnosticDescription[]
            {
                // (26,16): error CS8347: Cannot use a result of 'Program.F1<T, U>(T, ref U)' in this context because it may expose variables referenced by parameter 'u' outside of their declaration scope
                //         return F1(t, ref u); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "F1(t, ref u)").WithArguments("Program.F1<T, U>(T, ref U)", "u").WithLocation(26, 16),
                // (26,26): error CS8168: Cannot return local 'u' by reference because it is not a ref local
                //         return F1(t, ref u); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "u").WithArguments("u").WithLocation(26, 26),
                // (32,16): error CS8347: Cannot use a result of 'Program.F2<T, U>(T, in U)' in this context because it may expose variables referenced by parameter 'u' outside of their declaration scope
                //         return F2(t, in u); // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "F2(t, in u)").WithArguments("Program.F2<T, U>(T, in U)", "u").WithLocation(32, 16),
                // (32,25): error CS8168: Cannot return local 'u' by reference because it is not a ref local
                //         return F2(t, in u); // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "u").WithArguments("u").WithLocation(32, 25),
                // (38,16): error CS8347: Cannot use a result of 'Program.F2<T, U>(T, in U)' in this context because it may expose variables referenced by parameter 'u' outside of their declaration scope
                //         return F2(t, u); // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "F2(t, u)").WithArguments("Program.F2<T, U>(T, in U)", "u").WithLocation(38, 16),
                // (38,22): error CS8168: Cannot return local 'u' by reference because it is not a ref local
                //         return F2(t, u); // 3
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "u").WithArguments("u").WithLocation(38, 22),
                // (50,16): error CS8347: Cannot use a result of 'Program.F4<T, U>(ref T, ref U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return F4(ref t, ref u); // 4
                Diagnostic(ErrorCode.ERR_EscapeCall, "F4(ref t, ref u)").WithArguments("Program.F4<T, U>(ref T, ref U)", "t").WithLocation(50, 16),
                // (50,23): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return F4(ref t, ref u); // 4
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(50, 23),
                // (56,16): error CS8347: Cannot use a result of 'Program.F5<T, U>(ref T, in U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return F5(ref t, in u); // 5
                Diagnostic(ErrorCode.ERR_EscapeCall, "F5(ref t, in u)").WithArguments("Program.F5<T, U>(ref T, in U)", "t").WithLocation(56, 16),
                // (56,23): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return F5(ref t, in u); // 5
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(56, 23),
                // (62,16): error CS8347: Cannot use a result of 'Program.F5<T, U>(ref T, in U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return F5(ref t, u); // 6
                Diagnostic(ErrorCode.ERR_EscapeCall, "F5(ref t, u)").WithArguments("Program.F5<T, U>(ref T, in U)", "t").WithLocation(62, 16),
                // (62,23): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return F5(ref t, u); // 6
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(62, 23),
                // (68,16): error CS8347: Cannot use a result of 'Program.F6<T, U>(ref T, out U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return F6(ref t, out u); // 7
                Diagnostic(ErrorCode.ERR_EscapeCall, "F6(ref t, out u)").WithArguments("Program.F6<T, U>(ref T, out U)", "t").WithLocation(68, 16),
                // (68,23): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return F6(ref t, out u); // 7
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(68, 23),
                // (74,16): error CS8347: Cannot use a result of 'Program.F7<T, U>(in T, in U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return F7(in t, in u); // 8
                Diagnostic(ErrorCode.ERR_EscapeCall, "F7(in t, in u)").WithArguments("Program.F7<T, U>(in T, in U)", "t").WithLocation(74, 16),
                // (74,22): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return F7(in t, in u); // 8
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(74, 22),
                // (80,16): error CS8347: Cannot use a result of 'Program.F7<T, U>(in T, in U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return F7(t, u); // 9
                Diagnostic(ErrorCode.ERR_EscapeCall, "F7(t, u)").WithArguments("Program.F7<T, U>(in T, in U)", "t").WithLocation(80, 16),
                // (80,19): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return F7(t, u); // 9
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(80, 19),
                // (86,16): error CS8347: Cannot use a result of 'Program.F8<T, U>(in T, out U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return F8(in t, out u); // 10
                Diagnostic(ErrorCode.ERR_EscapeCall, "F8(in t, out u)").WithArguments("Program.F8<T, U>(in T, out U)", "t").WithLocation(86, 16),
                // (86,22): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return F8(in t, out u); // 10
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(86, 22),
                // (92,16): error CS8347: Cannot use a result of 'Program.F8<T, U>(in T, out U)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return F8(t, out u); // 11
                Diagnostic(ErrorCode.ERR_EscapeCall, "F8(t, out u)").WithArguments("Program.F8<T, U>(in T, out U)", "t").WithLocation(92, 16),
                // (92,19): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return F8(t, out u); // 11
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(92, 19)
            };
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(comp.Assembly.RuntimeSupportsByRefFields ? expectedUpdatedDiagnostics : expectedLegacyDiagnostics);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(expectedUpdatedDiagnostics);
        }
 
        [Fact]
        public void MethodInvocation_Scoped_Lvalue()
        {
            var source =
@"
using System.Diagnostics.CodeAnalysis;
class Program
{
    static ref T F0<T>(ref R<T> x, ref R<T> y) => throw null;
    static ref T F2<T>(ref R<T> x, scoped ref R<T> y) => throw null;
    static ref T F5<T>(scoped ref R<T> x, scoped ref R<T> y) => throw null;
 
    static ref T F00<T>(ref R<T> x) { R<T> y = default; return ref F0(ref x, ref y); } // 1
    static ref T F02<T>(ref R<T> x) { R<T> y = default; return ref F2(ref x, ref y); }
    static ref T F05<T>(ref R<T> x) { R<T> y = default; return ref F5(ref x, ref y); }
 
    static ref T F20<T>(scoped ref R<T> x) { R<T> y = default; return ref F0(ref x, ref y); } // 2
    static ref T F22<T>(scoped ref R<T> x) { R<T> y = default; return ref F2(ref x, ref y); } // 3
    static ref T F25<T>(scoped ref R<T> x) { R<T> y = default; return ref F5(ref x, ref y); }
}
ref struct R<T> { }
";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (9,68): error CS8347: Cannot use a result of 'Program.F0<T>(ref R<T>, ref R<T>)' in this context because it may expose variables referenced by parameter 'y' outside of their declaration scope
                //     static ref T F00<T>(ref R<T> x) { R<T> y = default; return ref F0(ref x, ref y); } // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "F0(ref x, ref y)").WithArguments("Program.F0<T>(ref R<T>, ref R<T>)", "y").WithLocation(9, 68),
                // (9,82): error CS8168: Cannot return local 'y' by reference because it is not a ref local
                //     static ref T F00<T>(ref R<T> x) { R<T> y = default; return ref F0(ref x, ref y); } // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "y").WithArguments("y").WithLocation(9, 82),
                // (13,75): error CS8347: Cannot use a result of 'Program.F0<T>(ref R<T>, ref R<T>)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //     static ref T F20<T>(scoped ref R<T> x) { R<T> y = default; return ref F0(ref x, ref y); } // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "F0(ref x, ref y)").WithArguments("Program.F0<T>(ref R<T>, ref R<T>)", "x").WithLocation(13, 75),
                // (13,82): error CS9075: Cannot return a parameter by reference 'x' because it is scoped to the current method
                //     static ref T F20<T>(scoped ref R<T> x) { R<T> y = default; return ref F0(ref x, ref y); } // 2
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "x").WithArguments("x").WithLocation(13, 82),
                // (14,75): error CS8347: Cannot use a result of 'Program.F2<T>(ref R<T>, scoped ref R<T>)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //     static ref T F22<T>(scoped ref R<T> x) { R<T> y = default; return ref F2(ref x, ref y); } // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "F2(ref x, ref y)").WithArguments("Program.F2<T>(ref R<T>, scoped ref R<T>)", "x").WithLocation(14, 75),
                // (14,82): error CS9075: Cannot return a parameter by reference 'x' because it is scoped to the current method
                //     static ref T F22<T>(scoped ref R<T> x) { R<T> y = default; return ref F2(ref x, ref y); } // 3
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "x").WithArguments("x").WithLocation(14, 82));
        }
 
        [Fact]
        public void MethodInvocation_Scoped_Rvalue()
        {
            var source =
@"ref struct R
{
    public R(ref int i) { }
}
class Program
{
    static R F0(R x, R y) => throw null;
    static R F1(R x, scoped R y) => throw null;
    static R F2(scoped R x, scoped R y) => throw null;
 
    static R F00(R x, int i) { var y = new R(ref i); return F0(x, y); } // 1
    static R F01(R x, int i) { var y = new R(ref i); return F1(x, y); }
    static R F02(R x, int i) { var y = new R(ref i); return F2(x, y); }
 
    static R F10(scoped R x, int i) { var y = new R(ref i); return F0(x, y); } // 2
    static R F11(scoped R x, int i) { var y = new R(ref i); return F1(x, y); } // 3
    static R F12(scoped R x, int i) { var y = new R(ref i); return F2(x, y); }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (11,61): error CS8347: Cannot use a result of 'Program.F0(R, R)' in this context because it may expose variables referenced by parameter 'y' outside of their declaration scope
                //     static R F00(R x, int i) { var y = new R(ref i); return F0(x, y); } // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "F0(x, y)").WithArguments("Program.F0(R, R)", "y").WithLocation(11, 61),
                // (11,67): error CS8352: Cannot use variable 'y' in this context because it may expose referenced variables outside of their declaration scope
                //     static R F00(R x, int i) { var y = new R(ref i); return F0(x, y); } // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y").WithArguments("y").WithLocation(11, 67),
                // (15,68): error CS8347: Cannot use a result of 'Program.F0(R, R)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //     static R F10(scoped R x, int i) { var y = new R(ref i); return F0(x, y); } // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "F0(x, y)").WithArguments("Program.F0(R, R)", "x").WithLocation(15, 68),
                // (15,71): error CS8352: Cannot use variable 'scoped R x' in this context because it may expose referenced variables outside of their declaration scope
                //     static R F10(scoped R x, int i) { var y = new R(ref i); return F0(x, y); } // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "x").WithArguments("scoped R x").WithLocation(15, 71),
                // (16,68): error CS8347: Cannot use a result of 'Program.F1(R, scoped R)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //     static R F11(scoped R x, int i) { var y = new R(ref i); return F1(x, y); } // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "F1(x, y)").WithArguments("Program.F1(R, scoped R)", "x").WithLocation(16, 68),
                // (16,71): error CS8352: Cannot use variable 'scoped R x' in this context because it may expose referenced variables outside of their declaration scope
                //     static R F11(scoped R x, int i) { var y = new R(ref i); return F1(x, y); } // 3
                Diagnostic(ErrorCode.ERR_EscapeVariable, "x").WithArguments("scoped R x").WithLocation(16, 71));
        }
 
        [Fact]
        public void MethodInvocation_Params()
        {
            var source =
@"ref struct R
{
    public R(ref int i) { }
}
class Program
{
    static R M1(R input, params object[] array)
    {
        return input;
    }
    static R M2()
    {
        int i = 42;
        var r = new R(ref i);
        return M1(r);
    }
    static R M3()
    {
        int i = 42;
        var r = new R(ref i);
        return M1(r, 0, 1, 2);
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (15,16): error CS8347: Cannot use a result of 'Program.M1(R, params object[])' in this context because it may expose variables referenced by parameter 'input' outside of their declaration scope
                //         return M1(r);
                Diagnostic(ErrorCode.ERR_EscapeCall, "M1(r)").WithArguments("Program.M1(R, params object[])", "input").WithLocation(15, 16),
                // (15,19): error CS8352: Cannot use variable 'r' in this context because it may expose referenced variables outside of their declaration scope
                //         return M1(r);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r").WithArguments("r").WithLocation(15, 19),
                // (21,16): error CS8347: Cannot use a result of 'Program.M1(R, params object[])' in this context because it may expose variables referenced by parameter 'input' outside of their declaration scope
                //         return M1(r, 0, 1, 2);
                Diagnostic(ErrorCode.ERR_EscapeCall, "M1(r, 0, 1, 2)").WithArguments("Program.M1(R, params object[])", "input").WithLocation(21, 16),
                // (21,19): error CS8352: Cannot use variable 'r' in this context because it may expose referenced variables outside of their declaration scope
                //         return M1(r, 0, 1, 2);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r").WithArguments("r").WithLocation(21, 19));
        }
 
        [Fact]
        public void MethodArgumentsMustMatch_01()
        {
            var source =
@"ref struct R
{
    public void F0(ref R r) => throw null;
    public void F2(scoped ref R r) => throw null;
}
class Program
{
    static void F00(ref R x, ref R y) { x.F0(ref y); }
    static void F02(ref R x, ref R y) { x.F2(ref y); }
 
    static void F20(ref R x, scoped ref R y) { x.F0(ref y); }
    static void F22(ref R x, scoped ref R y) { x.F2(ref y); }
 
    static void F60(scoped ref R x, ref R y) { x.F0(ref y); }
    static void F62(scoped ref R x, ref R y) { x.F2(ref y); }
 
    static void F80(scoped ref R x, scoped ref R y) { x.F0(ref y); }
    static void F82(scoped ref R x, scoped ref R y) { x.F2(ref y); }
}";
            var comp = CreateCompilation(source);
            // Should we also report ErrorCode.ERR_CallArgMixing for 3, 4, 5, 6? See the call to
            // CheckValEscape() for the receiver at the end of CheckInvocationArgMixing().
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void MethodArgumentsMustMatch_02()
        {
            var source =
@"ref struct R
{
}
class Program
{
    static void F0(ref R a, ref R b) => throw null;
    static void F2(ref R a, scoped ref R b) => throw null;
    static void F5(scoped ref R a, scoped ref R b) => throw null;
 
    static void F00(ref R x, ref R y) { F0(ref x, ref y); }
    static void F02(ref R x, ref R y) { F2(ref x, ref y); }
    static void F05(ref R x, ref R y) { F5(ref x, ref y); }
 
    static void F20(ref R x, scoped ref R y) { F0(ref x, ref y); }
    static void F22(ref R x, scoped ref R y) { F2(ref x, ref y); }
    static void F25(ref R x, scoped ref R y) { F5(ref x, ref y); }
 
    static void F50(scoped ref R x, scoped ref R y) { F0(ref x, ref y); }
    static void F52(scoped ref R x, scoped ref R y) { F2(ref x, ref y); }
    static void F55(scoped ref R x, scoped ref R y) { F5(ref x, ref y); }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void MethodArgumentsMustMatch_03()
        {
            var source =
@"ref struct R<T>
{
    public R(ref T t) { }
}
class Program
{
    static void F0<T>(ref R<T> a, ref R<T> b) => throw null;
    static void F2<T>(ref R<T> a, scoped ref R<T> b) => throw null;
    static void F5<T>(scoped ref R<T> a, scoped ref R<T> b) => throw null;
 
    static void F<T>(ref R<T> x)
    {
        T t = default;
        R<T> y = new R<T>(ref t);
 
        F0(ref x, ref x);
        F2(ref x, ref x);
        F5(ref x, ref x);
 
        F0(ref x, ref y); // 1
        F2(ref x, ref y); // 2
        F5(ref x, ref y); // 3
 
        F0(ref y, ref x); // 4
        F2(ref y, ref x); // 5
        F5(ref y, ref x); // 6
 
        F0(ref y, ref y);
        F2(ref y, ref y);
        F5(ref y, ref y);
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (20,9): error CS8350: This combination of arguments to 'Program.F0<T>(ref R<T>, ref R<T>)' is disallowed because it may expose variables referenced by parameter 'b' outside of their declaration scope
                //         F0(ref x, ref y); // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F0(ref x, ref y)").WithArguments("Program.F0<T>(ref R<T>, ref R<T>)", "b").WithLocation(20, 9),
                // (20,23): error CS8352: Cannot use variable 'y' in this context because it may expose referenced variables outside of their declaration scope
                //         F0(ref x, ref y); // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y").WithArguments("y").WithLocation(20, 23),
                // (21,9): error CS8350: This combination of arguments to 'Program.F2<T>(ref R<T>, scoped ref R<T>)' is disallowed because it may expose variables referenced by parameter 'b' outside of their declaration scope
                //         F2(ref x, ref y); // 2
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F2(ref x, ref y)").WithArguments("Program.F2<T>(ref R<T>, scoped ref R<T>)", "b").WithLocation(21, 9),
                // (21,23): error CS8352: Cannot use variable 'y' in this context because it may expose referenced variables outside of their declaration scope
                //         F2(ref x, ref y); // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y").WithArguments("y").WithLocation(21, 23),
                // (22,9): error CS8350: This combination of arguments to 'Program.F5<T>(scoped ref R<T>, scoped ref R<T>)' is disallowed because it may expose variables referenced by parameter 'b' outside of their declaration scope
                //         F5(ref x, ref y); // 3
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F5(ref x, ref y)").WithArguments("Program.F5<T>(scoped ref R<T>, scoped ref R<T>)", "b").WithLocation(22, 9),
                // (22,23): error CS8352: Cannot use variable 'y' in this context because it may expose referenced variables outside of their declaration scope
                //         F5(ref x, ref y); // 3
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y").WithArguments("y").WithLocation(22, 23),
                // (24,9): error CS8350: This combination of arguments to 'Program.F0<T>(ref R<T>, ref R<T>)' is disallowed because it may expose variables referenced by parameter 'a' outside of their declaration scope
                //         F0(ref y, ref x); // 4
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F0(ref y, ref x)").WithArguments("Program.F0<T>(ref R<T>, ref R<T>)", "a").WithLocation(24, 9),
                // (24,16): error CS8352: Cannot use variable 'y' in this context because it may expose referenced variables outside of their declaration scope
                //         F0(ref y, ref x); // 4
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y").WithArguments("y").WithLocation(24, 16),
                // (25,9): error CS8350: This combination of arguments to 'Program.F2<T>(ref R<T>, scoped ref R<T>)' is disallowed because it may expose variables referenced by parameter 'a' outside of their declaration scope
                //         F2(ref y, ref x); // 5
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F2(ref y, ref x)").WithArguments("Program.F2<T>(ref R<T>, scoped ref R<T>)", "a").WithLocation(25, 9),
                // (25,16): error CS8352: Cannot use variable 'y' in this context because it may expose referenced variables outside of their declaration scope
                //         F2(ref y, ref x); // 5
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y").WithArguments("y").WithLocation(25, 16),
                // (26,9): error CS8350: This combination of arguments to 'Program.F5<T>(scoped ref R<T>, scoped ref R<T>)' is disallowed because it may expose variables referenced by parameter 'a' outside of their declaration scope
                //         F5(ref y, ref x); // 6
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F5(ref y, ref x)").WithArguments("Program.F5<T>(scoped ref R<T>, scoped ref R<T>)", "a").WithLocation(26, 9),
                // (26,16): error CS8352: Cannot use variable 'y' in this context because it may expose referenced variables outside of their declaration scope
                //         F5(ref y, ref x); // 6
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y").WithArguments("y").WithLocation(26, 16));
        }
 
        [Fact]
        public void MethodArgumentsMustMatch_04()
        {
            var source =
@"ref struct R { }
class Program
{
    static void F0(ref R x, in R y) => throw null;
    static void F2(ref R x, scoped in R y) => throw null;
 
    static void F00(ref R x, in R y) { F0(ref x, in y); }
    static void F02(ref R x, in R y) { F2(ref x, in y); }
    static void F20(ref R x, scoped in R y) { F0(ref x, in y); }
    static void F22(ref R x, scoped in R y) { F2(ref x, in y); }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void MethodArgumentsMustMatch_05()
        {
            var source =
@"ref struct R { }
class Program
{
    static void F0(ref R x, out R y) => throw null;
    static void F2(ref R x, scoped out R y) => throw null;
 
    static void F00(ref R x, out R y) { F0(ref x, out y); }
    static void F02(ref R x, out R y) { F2(ref x, out y); }
    static void F20(ref R x, scoped out R y) { F0(ref x, out y); }
    static void F22(ref R x, scoped out R y) { F2(ref x, out y); }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void MethodArgumentsMustMatch_06()
        {
            var source =
@"ref struct R { }
class Program
{
    static void F0(__arglist) { }
    static void F1(ref R a, __arglist) { }
 
    static void F00(ref R x, ref R y) { F0(__arglist(ref x, ref y)); } // 1
    static void F01(ref R x, ref R y) { F1(ref x, __arglist(ref y)); } // 2
    static void F20(ref R x, scoped ref R y) { F0(__arglist(ref x, ref y)); } // 3
    static void F21(ref R x, scoped ref R y) { F1(ref x, __arglist(ref y)); } // 4
    static void F50(scoped ref R x, scoped ref R y) { F0(__arglist(ref x, ref y)); } // 5
    static void F51(scoped ref R x, scoped ref R y) { F1(ref x, __arglist(ref y)); } // 6
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void MethodArgumentsMustMatch_07_1()
        {
            var source =
@"
ref struct R { }
class Program
{
    static void F0(__arglist) { }
    static void F1(scoped ref R a, __arglist) { }
 
    static void F00(scoped ref R x, scoped ref R y) { F0(__arglist(ref x, ref y)); } // 1
    static void F01(scoped ref R x, scoped ref R y) { F1(ref x, __arglist(ref y)); } // 2
    static void F20(scoped ref R x, ref R y) { F0(__arglist(ref x, ref y)); } // 3
    static void F21(scoped ref R x, ref R y) { F1(ref x, __arglist(ref y)); } // 4
    static void F50(ref R x, ref R y) { F0(__arglist(ref x, ref y)); } // 5
    static void F51(ref R x, ref R y) { F1(ref x, __arglist(ref y)); } // 6
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact(Skip = "https://github.com/dotnet/roslyn/issues/64471")]
        public void MethodArgumentsMustMatch_07_2()
        {
            var source =
@"
using System.Diagnostics.CodeAnalysis;
using System;
 
ref struct R
{
    public byte B;
    public ref byte RB;
}
 
class Program
{
    static R F0(__arglist)
    {
        var args = new ArgIterator(__arglist);
        ref R r = ref __refvalue(args.GetNextArg(), R);
        r.RB = ref r.B; // 1
        return r;
    }
 
    static void F1(scoped ref R y) { F0(__arglist(ref y)); } // 2
    static void F2(ref R y) { F0(__arglist(ref y)); } // 3
 
    static R F3(scoped ref R y) { return F0(__arglist(ref y)); } // 4
    static R F4(ref R y) { return F0(__arglist(ref y)); } // 5
}";
            // __refvalue operators can only ref-escape to current method.
            // The __arglist operator here assumes that `F0` could do `y.RB = ref y`.
            // These assumptions are contradictory, but it just ends up being more strict in both directions.
            // Tracking in https://github.com/dotnet/roslyn/issues/64130
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (17,9): error CS8374: Cannot ref-assign 'r.B' to 'RB' because 'r.B' has a narrower escape scope than 'RB'.
                //         r.RB = ref r.B; // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r.RB = ref r.B").WithArguments("RB", "r.B").WithLocation(17, 9));
        }
 
        [Fact(Skip = "https://github.com/dotnet/roslyn/issues/64471")]
        public void MethodArgumentsMustMatch_07_3()
        {
            // demonstrate the non-ref-fields behavior.
            var source =
@"
using System;
 
class Program
{
    static ref int F0(__arglist)
    {
        var args = new ArgIterator(__arglist);
        ref int r = ref __refvalue(args.GetNextArg(), int);
        return ref r; // 1
    }
 
    static void F1(scoped ref int y) { F0(__arglist(ref y)); }
    static void F2(ref int y) { F0(__arglist(ref y)); }
 
    static ref int F3(scoped ref int y) { return ref F0(__arglist(ref y)); }
    static ref int F4(ref int y) { return ref F0(__arglist(ref y)); }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (10,20): error CS8157: Cannot return 'r' by reference because it was initialized to a value that cannot be returned by reference
                //         return ref r; // 1
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "r").WithArguments("r").WithLocation(10, 20));
        }
 
        /// <summary>
        /// ref to ref struct in __arglist is unscoped ref.
        /// </summary>
        [Fact]
        public void MethodArgumentsMustMatch_08()
        {
            var source =
@"ref struct R<T>
{
    public R(ref T t) { }
}
class Program
{
    static void F0(__arglist) { }
    static void F1()
    {
        var x = new R<int>();
        int i = 1;
        var y = new R<int>(ref i);
        F0(__arglist(ref x)); // 1
        F0(__arglist(ref y));
        F0(__arglist(ref x, ref x)); // 2
        F0(__arglist(ref x, ref y)); // 3
        F0(__arglist(ref y, ref x)); // 4
        F0(__arglist(ref y, ref y));
    }
}";
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics();
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (16,9): error CS8350: This combination of arguments to 'Program.F0(__arglist)' is disallowed because it may expose variables referenced by parameter '__arglist' outside of their declaration scope
                //         F0(__arglist(ref x, ref y)); // 3
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F0(__arglist(ref x, ref y))").WithArguments("Program.F0(__arglist)", "__arglist").WithLocation(16, 9),
                // (16,33): error CS8352: Cannot use variable 'y' in this context because it may expose referenced variables outside of their declaration scope
                //         F0(__arglist(ref x, ref y)); // 3
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y").WithArguments("y").WithLocation(16, 33),
                // (17,9): error CS8350: This combination of arguments to 'Program.F0(__arglist)' is disallowed because it may expose variables referenced by parameter '__arglist' outside of their declaration scope
                //         F0(__arglist(ref y, ref x)); // 4
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F0(__arglist(ref y, ref x))").WithArguments("Program.F0(__arglist)", "__arglist").WithLocation(17, 9),
                // (17,26): error CS8352: Cannot use variable 'y' in this context because it may expose referenced variables outside of their declaration scope
                //         F0(__arglist(ref y, ref x)); // 4
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y").WithArguments("y").WithLocation(17, 26));
        }
 
        /// <summary>
        /// ref to ref struct in __arglist is unscoped ref.
        /// </summary>
        [Fact]
        public void MethodArgumentsMustMatch_09()
        {
            var source =
@"ref struct R<T>
{
    public R(ref T t) { }
}
class Program
{
    static void F0(ref R<int> a, __arglist) { }
    static void F1()
    {
        var x = new R<int>();
        int i = 1;
        var y = new R<int>(ref i);
        F0(ref x, __arglist(ref x)); // 1
        F0(ref x, __arglist(ref y)); // 2
        F0(ref y, __arglist(ref x)); // 3
        F0(ref y, __arglist(ref y));
    }
}";
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics();
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (14,9): error CS8350: This combination of arguments to 'Program.F0(ref R<int>, __arglist)' is disallowed because it may expose variables referenced by parameter '__arglist' outside of their declaration scope
                //         F0(ref x, __arglist(ref y)); // 2
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F0(ref x, __arglist(ref y))").WithArguments("Program.F0(ref R<int>, __arglist)", "__arglist").WithLocation(14, 9),
                // (14,33): error CS8352: Cannot use variable 'y' in this context because it may expose referenced variables outside of their declaration scope
                //         F0(ref x, __arglist(ref y)); // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y").WithArguments("y").WithLocation(14, 33),
                // (15,9): error CS8350: This combination of arguments to 'Program.F0(ref R<int>, __arglist)' is disallowed because it may expose variables referenced by parameter 'a' outside of their declaration scope
                //         F0(ref y, __arglist(ref x)); // 3
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F0(ref y, __arglist(ref x))").WithArguments("Program.F0(ref R<int>, __arglist)", "a").WithLocation(15, 9),
                // (15,16): error CS8352: Cannot use variable 'y' in this context because it may expose referenced variables outside of their declaration scope
                //         F0(ref y, __arglist(ref x)); // 3
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y").WithArguments("y").WithLocation(15, 16));
        }
 
        [Fact]
        public void MethodArgumentsMustMatch_10()
        {
            var source =
@"
ref struct R
{
    public R(ref int i) { }
}
class Program
{
    static void F1()
    {
        R r1 = default;
        F2(ref r1);
        F3(ref r1);
    }
    static void F2(scoped ref R r2)
    {
    }
    static void F3(ref R r3)
    {
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void MethodArgumentsMustMatch_11()
        {
            var source =
@"
ref struct R
{
    public R(ref int i) { }
}
class Program
{
    static void F1()
    {
        R x1 = default;
        R y1 = default;
        F2(ref x1, ref y1);
        F2(ref y1, ref x1);
    }
    static void F2(scoped ref R x2, ref R y2)
    {
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void MethodArgumentsMustMatch_12()
        {
            var source =
@"ref struct R
{
    public R(ref int i) { }
}
class Program
{
    static void F1()
    {
        R x1 = default;
        int i = 42;
        R y1 = new R(ref i); // implicitly scoped
        F2(ref x1, ref y1); // 1
        F2(ref y1, ref x1); // 2
    }
    static void F2(ref R x2, ref R y2)
    {
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (12,9): error CS8350: This combination of arguments to 'Program.F2(ref R, ref R)' is disallowed because it may expose variables referenced by parameter 'y2' outside of their declaration scope
                //         F2(ref x1, ref y1); // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F2(ref x1, ref y1)").WithArguments("Program.F2(ref R, ref R)", "y2").WithLocation(12, 9),
                // (12,24): error CS8352: Cannot use variable 'y1' in this context because it may expose referenced variables outside of their declaration scope
                //         F2(ref x1, ref y1); // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y1").WithArguments("y1").WithLocation(12, 24),
                // (13,9): error CS8350: This combination of arguments to 'Program.F2(ref R, ref R)' is disallowed because it may expose variables referenced by parameter 'x2' outside of their declaration scope
                //         F2(ref y1, ref x1); // 2
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F2(ref y1, ref x1)").WithArguments("Program.F2(ref R, ref R)", "x2").WithLocation(13, 9),
                // (13,16): error CS8352: Cannot use variable 'y1' in this context because it may expose referenced variables outside of their declaration scope
                //         F2(ref y1, ref x1); // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y1").WithArguments("y1").WithLocation(13, 16));
        }
 
        /// <summary>
        /// Ensure that readonly members / types are properly accounted for
        /// </summary>
        [Fact]
        public void MethodArgumentsMustMatch_13()
        {
            var source = """
                ref struct RWRS
                {
                    public void M1(RS rs) { }
                    public readonly void M2(RS rs) { }
                }
                readonly ref struct RORS
                {
                    public void M3(RS rs) { }
                }
                ref struct RS
                {
                    static void Test()
                    {
                        scoped RS local = default;
                        RWRS rwLocal = default;
                        rwLocal.M1(local); // 1
                        rwLocal.M2(local);
                        RORS roLocal = default;
                        roLocal.M3(local);
                    }
                }
                """;
 
            var comp = CreateCompilation(new[] { source });
            comp.VerifyDiagnostics(
                // (16,9): error CS8350: This combination of arguments to 'RWRS.M1(RS)' is disallowed because it may expose variables referenced by parameter 'rs' outside of their declaration scope
                //         rwLocal.M1(local); // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, "rwLocal.M1(local)").WithArguments("RWRS.M1(RS)", "rs").WithLocation(16, 9),
                // (16,20): error CS8352: Cannot use variable 'local' in this context because it may expose referenced variables outside of their declaration scope
                //         rwLocal.M1(local); // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "local").WithArguments("local").WithLocation(16, 20));
        }
 
        [Fact]
        public void MethodArgumentsMustMatch_14()
        {
            var source = """
                using System.Diagnostics.CodeAnalysis;
                ref struct R
                {
                    public R(ref int i) { }
                }
                class Program
                {
                    static void F0(ref R r0, [UnscopedRef] ref int i0)
                    {
                    }
                    static void F1(ref R x1)
                    {
                        int i1 = 1;
                        F0(ref x1, ref i1); // 1
                        R y1 = default;
                        F0(ref y1, ref i1); // 2
                        scoped R z1 = default;
                        F0(ref z1, ref i1);
                    }
                    static void F2(ref R x2, ref int i2)
                    {
                        F0(ref x2, ref i2); // 3
                        R y2 = default;
                        F0(ref y2, ref i2); // 4
                        scoped R z2 = default;
                        F0(ref z2, ref i2);
                    }
                    static void F3(ref R x3, [UnscopedRef] ref int i3)
                    {
                        F0(ref x3, ref i3);
                        R y3 = default;
                        F0(ref y3, ref i3);
                        scoped R z3 = default;
                        F0(ref z3, ref i3);
                    }
                }
                """;
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (14,9): error CS8350: This combination of arguments to 'Program.F0(ref R, ref int)' is disallowed because it may expose variables referenced by parameter 'i0' outside of their declaration scope
                //         F0(ref x1, ref i1); // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F0(ref x1, ref i1)").WithArguments("Program.F0(ref R, ref int)", "i0").WithLocation(14, 9),
                // (14,24): error CS8168: Cannot return local 'i1' by reference because it is not a ref local
                //         F0(ref x1, ref i1); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i1").WithArguments("i1").WithLocation(14, 24),
                // (16,9): error CS8350: This combination of arguments to 'Program.F0(ref R, ref int)' is disallowed because it may expose variables referenced by parameter 'i0' outside of their declaration scope
                //         F0(ref y1, ref i1); // 2
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F0(ref y1, ref i1)").WithArguments("Program.F0(ref R, ref int)", "i0").WithLocation(16, 9),
                // (16,24): error CS8168: Cannot return local 'i1' by reference because it is not a ref local
                //         F0(ref y1, ref i1); // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i1").WithArguments("i1").WithLocation(16, 24),
                // (22,9): error CS8350: This combination of arguments to 'Program.F0(ref R, ref int)' is disallowed because it may expose variables referenced by parameter 'i0' outside of their declaration scope
                //         F0(ref x2, ref i2); // 3
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F0(ref x2, ref i2)").WithArguments("Program.F0(ref R, ref int)", "i0").WithLocation(22, 9),
                // (22,24): error CS9077: Cannot return a parameter by reference 'i2' through a ref parameter; it can only be returned in a return statement
                //         F0(ref x2, ref i2); // 3
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "i2").WithArguments("i2").WithLocation(22, 24),
                // (24,9): error CS8350: This combination of arguments to 'Program.F0(ref R, ref int)' is disallowed because it may expose variables referenced by parameter 'i0' outside of their declaration scope
                //         F0(ref y2, ref i2); // 4
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F0(ref y2, ref i2)").WithArguments("Program.F0(ref R, ref int)", "i0").WithLocation(24, 9),
                // (24,24): error CS9077: Cannot return a parameter by reference 'i2' through a ref parameter; it can only be returned in a return statement
                //         F0(ref y2, ref i2); // 4
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "i2").WithArguments("i2").WithLocation(24, 24));
        }
 
        // As above, but with in parameters.
        [Fact]
        public void MethodArgumentsMustMatch_15()
        {
            var source = """
                using System.Diagnostics.CodeAnalysis;
                ref struct R
                {
                    public R(in int i) { }
                }
                class Program
                {
                    static void F0(ref R r0, [UnscopedRef] in int i0)
                    {
                    }
                    static void F1(ref R x1)
                    {
                        int i1 = 1;
                        F0(ref x1, in i1); // 1
                        R y1 = default;
                        F0(ref y1, in i1); // 2
                        scoped R z1 = default;
                        F0(ref z1, in i1);
                    }
                    static void F2(ref R x2, in int i2)
                    {
                        F0(ref x2, in i2); // 3
                        R y2 = default;
                        F0(ref y2, in i2); // 4
                        scoped R z2 = default;
                        F0(ref z2, in i2);
                    }
                    static void F3(ref R x3, [UnscopedRef] in int i3)
                    {
                        F0(ref x3, in i3);
                        R y3 = default;
                        F0(ref y3, in i3);
                        scoped R z3 = default;
                        F0(ref z3, in i3);
                    }
                }
                """;
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (14,9): error CS8350: This combination of arguments to 'Program.F0(ref R, in int)' is disallowed because it may expose variables referenced by parameter 'i0' outside of their declaration scope
                //         F0(ref x1, in i1); // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F0(ref x1, in i1)").WithArguments("Program.F0(ref R, in int)", "i0").WithLocation(14, 9),
                // (14,23): error CS8168: Cannot return local 'i1' by reference because it is not a ref local
                //         F0(ref x1, in i1); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i1").WithArguments("i1").WithLocation(14, 23),
                // (16,9): error CS8350: This combination of arguments to 'Program.F0(ref R, in int)' is disallowed because it may expose variables referenced by parameter 'i0' outside of their declaration scope
                //         F0(ref y1, in i1); // 2
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F0(ref y1, in i1)").WithArguments("Program.F0(ref R, in int)", "i0").WithLocation(16, 9),
                // (16,23): error CS8168: Cannot return local 'i1' by reference because it is not a ref local
                //         F0(ref y1, in i1); // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i1").WithArguments("i1").WithLocation(16, 23),
                // (22,9): error CS8350: This combination of arguments to 'Program.F0(ref R, in int)' is disallowed because it may expose variables referenced by parameter 'i0' outside of their declaration scope
                //         F0(ref x2, in i2); // 3
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F0(ref x2, in i2)").WithArguments("Program.F0(ref R, in int)", "i0").WithLocation(22, 9),
                // (22,23): error CS9077: Cannot return a parameter by reference 'i2' through a ref parameter; it can only be returned in a return statement
                //         F0(ref x2, in i2); // 3
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "i2").WithArguments("i2").WithLocation(22, 23),
                // (24,9): error CS8350: This combination of arguments to 'Program.F0(ref R, in int)' is disallowed because it may expose variables referenced by parameter 'i0' outside of their declaration scope
                //         F0(ref y2, in i2); // 4
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F0(ref y2, in i2)").WithArguments("Program.F0(ref R, in int)", "i0").WithLocation(24, 9),
                // (24,23): error CS9077: Cannot return a parameter by reference 'i2' through a ref parameter; it can only be returned in a return statement
                //         F0(ref y2, in i2); // 4
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "i2").WithArguments("i2").WithLocation(24, 23));
        }
 
        [Fact]
        public void MethodArgumentsMustMatch_16()
        {
            var source = """
                using System.Diagnostics.CodeAnalysis;
                ref struct R
                {
                    public ref int FA() => throw null;
                    [UnscopedRef] public ref int FB() => throw null;
                }
                class Program
                {
                    static void F1(ref R r1, ref int i1) { }
                    static void F2(ref R r2, [UnscopedRef] ref int i2) { }
                    static void F(ref R x)
                    {
                        R y = default;
                        F1(ref x, ref y.FA());
                        F1(ref x, ref y.FB());
                        F2(ref x, ref y.FA());
                        F2(ref x, ref y.FB()); // 1
                    }
                }
                """;
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (17,9): error CS8350: This combination of arguments to 'Program.F2(ref R, ref int)' is disallowed because it may expose variables referenced by parameter 'i2' outside of their declaration scope
                //         F2(ref x, ref y.FB()); // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F2(ref x, ref y.FB())").WithArguments("Program.F2(ref R, ref int)", "i2").WithLocation(17, 9),
                // (17,23): error CS8168: Cannot return local 'y' by reference because it is not a ref local
                //         F2(ref x, ref y.FB()); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "y").WithArguments("y").WithLocation(17, 23));
        }
 
        // As above, but with in parameters.
        [Fact]
        public void MethodArgumentsMustMatch_17()
        {
            var source = """
                using System.Diagnostics.CodeAnalysis;
                ref struct R
                {
                    public ref int FA() => throw null;
                    [UnscopedRef] public ref int FB() => throw null;
                }
                class Program
                {
                    static void F1(ref R r1, in int i1) { }
                    static void F2(ref R r2, [UnscopedRef] in int i2) { }
                    static void F(ref R x)
                    {
                        R y = default;
                        F1(ref x, y.FA());
                        F1(ref x, y.FB());
                        F2(ref x, y.FA());
                        F2(ref x, y.FB()); // 1
                        F1(ref x, in y.FA());
                        F1(ref x, in y.FB());
                        F2(ref x, in y.FA());
                        F2(ref x, in y.FB()); // 2
                    }
                }
                """;
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (17,9): error CS8350: This combination of arguments to 'Program.F2(ref R, in int)' is disallowed because it may expose variables referenced by parameter 'i2' outside of their declaration scope
                //         F2(ref x, y.FB()); // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F2(ref x, y.FB())").WithArguments("Program.F2(ref R, in int)", "i2").WithLocation(17, 9),
                // (17,19): error CS8168: Cannot return local 'y' by reference because it is not a ref local
                //         F2(ref x, y.FB()); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "y").WithArguments("y").WithLocation(17, 19),
                // (21,9): error CS8350: This combination of arguments to 'Program.F2(ref R, in int)' is disallowed because it may expose variables referenced by parameter 'i2' outside of their declaration scope
                //         F2(ref x, in y.FB()); // 2
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F2(ref x, in y.FB())").WithArguments("Program.F2(ref R, in int)", "i2").WithLocation(21, 9),
                // (21,22): error CS8168: Cannot return local 'y' by reference because it is not a ref local
                //         F2(ref x, in y.FB()); // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "y").WithArguments("y").WithLocation(21, 22));
        }
 
        // As above, but with ref readonly returns.
        [Fact]
        public void MethodArgumentsMustMatch_18()
        {
            var source = """
                using System.Diagnostics.CodeAnalysis;
                ref struct R
                {
                    public ref readonly int FA() => throw null;
                    [UnscopedRef] public ref readonly int FB() => throw null;
                }
                class Program
                {
                    static void F1(ref R r1, in int i1) { }
                    static void F2(ref R r2, [UnscopedRef] in int i2) { }
                    static void F(ref R x)
                    {
                        R y = default;
                        F1(ref x, y.FA());
                        F1(ref x, y.FB());
                        F2(ref x, y.FA());
                        F2(ref x, y.FB()); // 1
                        F1(ref x, in y.FA());
                        F1(ref x, in y.FB());
                        F2(ref x, in y.FA());
                        F2(ref x, in y.FB()); // 2
                    }
                }
                """;
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (17,9): error CS8350: This combination of arguments to 'Program.F2(ref R, in int)' is disallowed because it may expose variables referenced by parameter 'i2' outside of their declaration scope
                //         F2(ref x, y.FB()); // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F2(ref x, y.FB())").WithArguments("Program.F2(ref R, in int)", "i2").WithLocation(17, 9),
                // (17,19): error CS8168: Cannot return local 'y' by reference because it is not a ref local
                //         F2(ref x, y.FB()); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "y").WithArguments("y").WithLocation(17, 19),
                // (21,9): error CS8350: This combination of arguments to 'Program.F2(ref R, in int)' is disallowed because it may expose variables referenced by parameter 'i2' outside of their declaration scope
                //         F2(ref x, in y.FB()); // 2
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F2(ref x, in y.FB())").WithArguments("Program.F2(ref R, in int)", "i2").WithLocation(21, 9),
                // (21,22): error CS8168: Cannot return local 'y' by reference because it is not a ref local
                //         F2(ref x, in y.FB()); // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "y").WithArguments("y").WithLocation(21, 22));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Arglist_RefToRefStruct(LanguageVersion languageVersion)
        {
            var source =
@"using System;
ref struct R<T>
{
}
class Program
{
    static ref R<int> F(__arglist)
    {
        var args = new ArgIterator(__arglist);
        ref R<int> r = ref __refvalue(args.GetNextArg(), R<int>);
        return ref r;
    }
}";
            var comp = CreateCompilationWithMscorlib45(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics(
                // (11,20): error CS8157: Cannot return 'r' by reference because it was initialized to a value that cannot be returned by reference
                //         return ref r;
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "r").WithArguments("r").WithLocation(11, 20));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Arglist_RefReturnedAsRef(LanguageVersion languageVersion)
        {
            var source =
@"using System;
class Program
{
    static ref int F1(__arglist)
    {
        var args = new ArgIterator(__arglist);
        return ref __refvalue(args.GetNextArg(), int);
    }
    static ref int F2()
    {
        int i = 2;
        return ref F1(__arglist(ref i));
    }
}";
            var comp = CreateCompilationWithMscorlib45(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics(
                // (7,20): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                //         return ref __refvalue(args.GetNextArg(), int);
                Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "__refvalue(args.GetNextArg(), int)").WithLocation(7, 20));
        }
 
        [Fact]
        public void Arglist_RefReturnedAsRefStruct()
        {
            var source =
@"using System;
ref struct R<T>
{
    public R(ref T t) { }
}
class Program
{
    static R<int> F1(__arglist)
    {
        var args = new ArgIterator(__arglist);
        ref int i = ref __refvalue(args.GetNextArg(), int);
        return new R<int>(ref i);
    }
    static R<int> F2()
    {
        int i = 2;
        return F1(__arglist(ref i));
    }
}";
 
            var comp = CreateCompilationWithMscorlib45(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics();
 
            comp = CreateCompilationWithMscorlib45(source);
            comp.VerifyEmitDiagnostics(
                // (12,16): error CS8347: Cannot use a result of 'R<int>.R(ref int)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return new R<int>(ref i);
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R<int>(ref i)").WithArguments("R<int>.R(ref int)", "t").WithLocation(12, 16),
                // (12,31): error CS8157: Cannot return 'i' by reference because it was initialized to a value that cannot be returned by reference
                //         return new R<int>(ref i);
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "i").WithArguments("i").WithLocation(12, 31));
        }
 
        [Fact]
        public void ImplicitIn_01()
        {
            var source =
@"ref struct R<T>
{
    public void F(in T t)  { }
}
class Program
{
    static R<int> F1()
    {
        var r1 = new R<int>();
        int i = 1;
        r1.F(in i);
        return r1;
    }
    static R<int> F2()
    {
        var r2 = new R<int>();
        int i = 2;
        r2.F(i);
        return r2;
    }
    static R<int> F3()
    {
        var r3 = new R<int>();
        r3.F(3);
        return r3;
    }
}";
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics();
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void ImplicitIn_02(LanguageVersion languageVersion)
        {
            var source =
@"class Program
{
    static ref readonly T F<T>(in T t)
    {
        return ref t;
    }
    static ref readonly int F1()
    {
        int i1 = 1;
        return ref F(in i1); // 1
    }
    static ref readonly int F2()
    {
        int i2 = 2;
        return ref F(i2); // 2
    }
    static ref readonly int F3()
    {
        return ref F(3); // 3
    }
}";
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics(
                // (10,20): error CS8347: Cannot use a result of 'Program.F<int>(in int)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F(in i1); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "F(in i1)").WithArguments("Program.F<int>(in int)", "t").WithLocation(10, 20),
                // (10,25): error CS8168: Cannot return local 'i1' by reference because it is not a ref local
                //         return ref F(in i1); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i1").WithArguments("i1").WithLocation(10, 25),
                // (15,20): error CS8347: Cannot use a result of 'Program.F<int>(in int)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F(i2); // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "F(i2)").WithArguments("Program.F<int>(in int)", "t").WithLocation(15, 20),
                // (15,22): error CS8168: Cannot return local 'i2' by reference because it is not a ref local
                //         return ref F(i2); // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i2").WithArguments("i2").WithLocation(15, 22),
                // (19,20): error CS8347: Cannot use a result of 'Program.F<int>(in int)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F(3); // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "F(3)").WithArguments("Program.F<int>(in int)", "t").WithLocation(19, 20),
                // (19,22): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                //         return ref F(3); // 3
                Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "3").WithLocation(19, 22));
        }
 
        [Fact]
        public void ImplicitIn_03()
        {
            var source =
@"class Program
{
    static ref readonly T F<T>(in T x, scoped in T y)
    {
        return ref x;
    }
    static ref readonly int F1()
    {
        int x1 = 1;
        int y1 = 1;
        return ref F(in x1, in y1); // 1
    }
    static ref readonly int F2()
    {
        int x2 = 2;
        int y2 = 2;
        return ref F(x2, in y2); // 2
    }
    static ref readonly int F3()
    {
        int y3 = 3;
        return ref F(3, in y3); // 3
    }
}";
 
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (11,20): error CS8347: Cannot use a result of 'Program.F<int>(in int, scoped in int)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //         return ref F(in x1, in y1); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "F(in x1, in y1)").WithArguments("Program.F<int>(in int, scoped in int)", "x").WithLocation(11, 20),
                // (11,25): error CS8168: Cannot return local 'x1' by reference because it is not a ref local
                //         return ref F(in x1, in y1); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "x1").WithArguments("x1").WithLocation(11, 25),
                // (17,20): error CS8347: Cannot use a result of 'Program.F<int>(in int, scoped in int)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //         return ref F(x2, in y2); // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "F(x2, in y2)").WithArguments("Program.F<int>(in int, scoped in int)", "x").WithLocation(17, 20),
                // (17,22): error CS8168: Cannot return local 'x2' by reference because it is not a ref local
                //         return ref F(x2, in y2); // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "x2").WithArguments("x2").WithLocation(17, 22),
                // (22,20): error CS8347: Cannot use a result of 'Program.F<int>(in int, scoped in int)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //         return ref F(3, in y3); // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "F(3, in y3)").WithArguments("Program.F<int>(in int, scoped in int)", "x").WithLocation(22, 20),
                // (22,22): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                //         return ref F(3, in y3); // 3
                Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "3").WithLocation(22, 22));
        }
 
        [Fact]
        public void RefToRefStruct_InstanceMethods()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
ref struct R
{
    public R(ref R other) { }
    public void F1(ref R other) { }
    [UnscopedRef] public void F2(ref R other) { }
}
class Program
{
    static R F0()
    {
        var x0 = new R();
        var y0 = new R(ref x0);
        return x0;
    }
    static R F1()
    {
        var x1 = new R();
        var y1 = new R();
        y1.F1(ref x1);
        return x1;
    }
    static R F2()
    {
        var x2 = new R();
        var y2 = new R();
        y2.F2(ref x2);
        return x2;
    }
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void RefToRefStruct_ConstructorInitializer()
        {
            var source =
@"ref struct R
{
    public R(ref R other) { }
    public R(ref R other, int i) :
        this(ref other)
    {
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void NestedFieldAccessor()
        {
            var source =
@"ref struct R<T>
{
    private ref T _t;
    public R(ref T t) { _t = t; }
    public ref T F0() => ref _t;
    ref T F1() => ref F0();
}
class Program
{
    static ref T F2<T>(ref R<T> r) => ref r.F0();
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void Constructors()
        {
            var source =
@"ref struct S<T>
{
    public ref T F;
    public S(ref T t)
    {
        F = ref t;
    }
    S(object unused, T t0)
    {
        this = default;
        this = new S<T>();
        this = new S<T>(ref t0);
        this = new S<T> { F = t0 };
    }
    void M1(T t1)
    {
        this = default;
        this = new S<T>();
        this = new S<T>(ref t1);
        this = new S<T> { F = t1 };
    }
    static void M2(T t2)
    {
        S<T> s2;
        s2 = default;
        s2 = new S<T>();
        s2 = new S<T>(ref t2);
        s2 = new S<T> { F = t2 };
    }
    static void M3(ref T t3)
    {
        scoped S<T> s3;
        s3 = new S<T>(ref t3);
        s3 = new S<T> { F = t3 };
    }
    static void M4(T t4)
    {
        S<T> s;
        s = new S<T>();
        s = new S<T>(ref t4);
        s = new S<T> { F = t4 };
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (12,16): error CS8347: Cannot use a result of 'S<T>.S(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         this = new S<T>(ref t0);
                Diagnostic(ErrorCode.ERR_EscapeCall, "new S<T>(ref t0)").WithArguments("S<T>.S(ref T)", "t").WithLocation(12, 16),
                // (12,29): error CS8166: Cannot return a parameter by reference 't0' because it is not a ref parameter
                //         this = new S<T>(ref t0);
                Diagnostic(ErrorCode.ERR_RefReturnParameter, "t0").WithArguments("t0").WithLocation(12, 29),
                // (19,16): error CS8347: Cannot use a result of 'S<T>.S(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         this = new S<T>(ref t1);
                Diagnostic(ErrorCode.ERR_EscapeCall, "new S<T>(ref t1)").WithArguments("S<T>.S(ref T)", "t").WithLocation(19, 16),
                // (19,29): error CS8166: Cannot return a parameter by reference 't1' because it is not a ref parameter
                //         this = new S<T>(ref t1);
                Diagnostic(ErrorCode.ERR_RefReturnParameter, "t1").WithArguments("t1").WithLocation(19, 29),
                // (27,14): error CS8347: Cannot use a result of 'S<T>.S(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         s2 = new S<T>(ref t2);
                Diagnostic(ErrorCode.ERR_EscapeCall, "new S<T>(ref t2)").WithArguments("S<T>.S(ref T)", "t").WithLocation(27, 14),
                // (27,27): error CS8166: Cannot return a parameter by reference 't2' because it is not a ref parameter
                //         s2 = new S<T>(ref t2);
                Diagnostic(ErrorCode.ERR_RefReturnParameter, "t2").WithArguments("t2").WithLocation(27, 27),
                // (40,13): error CS8347: Cannot use a result of 'S<T>.S(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         s = new S<T>(ref t4);
                Diagnostic(ErrorCode.ERR_EscapeCall, "new S<T>(ref t4)").WithArguments("S<T>.S(ref T)", "t").WithLocation(40, 13),
                // (40,26): error CS8166: Cannot return a parameter by reference 't4' because it is not a ref parameter
                //         s = new S<T>(ref t4);
                Diagnostic(ErrorCode.ERR_RefReturnParameter, "t4").WithArguments("t4").WithLocation(40, 26));
        }
 
        [Fact]
        public void Constructors_UnsafeContext()
        {
            var source = @"
unsafe ref struct S<T>
{
    public ref T F;
    public S(ref T t)
    {
        F = ref t;
    }
    S(object unused, T t0)
    {
        this = default;
        this = new S<T>();
        this = new S<T>(ref t0);
        this = new S<T> { F = t0 };
    }
    void M1(T t1)
    {
        this = default;
        this = new S<T>();
        this = new S<T>(ref t1);
        this = new S<T> { F = t1 };
    }
    static void M2(T t2)
    {
        S<T> s2;
        s2 = default;
        s2 = new S<T>();
        s2 = new S<T>(ref t2);
        s2 = new S<T> { F = t2 };
    }
    static void M3(ref T t3)
    {
        scoped S<T> s3;
        s3 = new S<T>(ref t3);
        s3 = new S<T> { F = t3 };
    }
    static void M4(T t4)
    {
        S<T> s;
        s = new S<T>();
        s = new S<T>(ref t4);
        s = new S<T> { F = t4 };
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70, options: TestOptions.UnsafeDebugDll);
            comp.VerifyEmitDiagnostics(
                // (13,29): warning CS9084: This returns a parameter by reference 't0' but it is not a ref parameter
                //         this = new S<T>(ref t0);
                Diagnostic(ErrorCode.WRN_RefReturnParameter, "t0").WithArguments("t0").WithLocation(13, 29),
                // (20,29): warning CS9084: This returns a parameter by reference 't1' but it is not a ref parameter
                //         this = new S<T>(ref t1);
                Diagnostic(ErrorCode.WRN_RefReturnParameter, "t1").WithArguments("t1").WithLocation(20, 29),
                // (28,27): warning CS9084: This returns a parameter by reference 't2' but it is not a ref parameter
                //         s2 = new S<T>(ref t2);
                Diagnostic(ErrorCode.WRN_RefReturnParameter, "t2").WithArguments("t2").WithLocation(28, 27),
                // (41,26): warning CS9084: This returns a parameter by reference 't4' but it is not a ref parameter
                //         s = new S<T>(ref t4);
                Diagnostic(ErrorCode.WRN_RefReturnParameter, "t4").WithArguments("t4").WithLocation(41, 26));
        }
 
        [Fact]
        public void Constructors_02()
        {
            var source = """
                ref struct R
                {
                    public R(ref int i) { }
                    public int this[R r] { get { return 0; } set { } }
                }
                class Program
                {
                    static R F()
                    {
                        int i = 0;
                        R x = new R(ref i);
                        R y = default;
                        y = new R { [x] = 1 }; // 1
                        y[x] = 1; // 2
                        return y;
                    }
                }
                """;
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (13,22): error CS8352: Cannot use variable 'x' in this context because it may expose referenced variables outside of their declaration scope
                //         y = new R { [x] = 1 }; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "x").WithArguments("x").WithLocation(13, 22),
                // (14,9): error CS8350: This combination of arguments to 'R.this[R]' is disallowed because it may expose variables referenced by parameter 'r' outside of their declaration scope
                //         y[x] = 1; // 2
                Diagnostic(ErrorCode.ERR_CallArgMixing, "y[x]").WithArguments("R.this[R]", "r").WithLocation(14, 9),
                // (14,11): error CS8352: Cannot use variable 'x' in this context because it may expose referenced variables outside of their declaration scope
                //         y[x] = 1; // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "x").WithArguments("x").WithLocation(14, 11));
        }
 
        [Fact]
        public void DefiniteAssignment_01()
        {
            var source =
@"ref struct S1<T>
{
    public ref T F;
}
ref struct S2<T>
{
    public ref T F;
    public S2(ref T t) { }
}
ref struct S3<T>
{
    public ref T F;
    public S3(ref T t) : this() { }
}
ref struct S4<T>
{
    public ref T F;
    public S4(ref T t)
    {
        this = default;
    }
}
class Program
{
    static void F<T>(ref T t)
    {
        new S1<T>().F = ref t;
        new S2<T>().F = ref t;
        new S3<T>().F = ref t;
        new S4<T>().F = ref t;
        new S1<T>().F = t;
        new S2<T>().F = t;
        new S3<T>().F = t;
        new S4<T>().F = t;
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (27,9): error CS0131: The left-hand side of an assignment must be a variable, property or indexer
                //         new S1<T>().F = ref t;
                Diagnostic(ErrorCode.ERR_AssgLvalueExpected, "new S1<T>().F").WithLocation(27, 9),
                // (28,9): error CS0131: The left-hand side of an assignment must be a variable, property or indexer
                //         new S2<T>().F = ref t;
                Diagnostic(ErrorCode.ERR_AssgLvalueExpected, "new S2<T>().F").WithLocation(28, 9),
                // (29,9): error CS0131: The left-hand side of an assignment must be a variable, property or indexer
                //         new S3<T>().F = ref t;
                Diagnostic(ErrorCode.ERR_AssgLvalueExpected, "new S3<T>().F").WithLocation(29, 9),
                // (30,9): error CS0131: The left-hand side of an assignment must be a variable, property or indexer
                //         new S4<T>().F = ref t;
                Diagnostic(ErrorCode.ERR_AssgLvalueExpected, "new S4<T>().F").WithLocation(30, 9));
        }
 
        [Fact]
        public void DefiniteAssignment_02()
        {
            // Should we report a warning when assigning a value rather than a ref in the
            // constructor, because a NullReferenceException will be thrown at runtime?
            var source =
@"ref struct S<T>
{
    public ref T F;
    public S(ref T t)
    {
        F = t;
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void AssignLocal()
        {
            var source =
@"ref struct S<T>
{
    public ref T F1;
    public ref readonly T F2;
    public readonly ref T F3;
    public readonly ref readonly T F4;
    public S()
    {
        T t = default;
        F1 = ref t;
        F2 = ref t;
        F3 = ref t;
        F4 = ref t;
    }
}
class Program
{
    static void M<T>(ref S<T> x)
    {
        T t = default;
        x.F1 = ref t;
        x.F2 = ref t;
        x.F3 = ref t;
        x.F4 = ref t;
        S<T> y = new S<T>();
        y.F1 = ref t;
        y.F2 = ref t;
        y.F3 = ref t;
        y.F4 = ref t;
    }
}";
            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (10,9): error CS8374: Cannot ref-assign 't' to 'F1' because 't' has a narrower escape scope than 'F1'.
                //         F1 = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "F1 = ref t").WithArguments("F1", "t").WithLocation(10, 9),
                // (11,9): error CS8374: Cannot ref-assign 't' to 'F2' because 't' has a narrower escape scope than 'F2'.
                //         F2 = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "F2 = ref t").WithArguments("F2", "t").WithLocation(11, 9),
                // (12,9): error CS8374: Cannot ref-assign 't' to 'F3' because 't' has a narrower escape scope than 'F3'.
                //         F3 = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "F3 = ref t").WithArguments("F3", "t").WithLocation(12, 9),
                // (13,9): error CS8374: Cannot ref-assign 't' to 'F4' because 't' has a narrower escape scope than 'F4'.
                //         F4 = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "F4 = ref t").WithArguments("F4", "t").WithLocation(13, 9),
                // (21,9): error CS8374: Cannot ref-assign 't' to 'F1' because 't' has a narrower escape scope than 'F1'.
                //         x.F1 = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "x.F1 = ref t").WithArguments("F1", "t").WithLocation(21, 9),
                // (22,9): error CS8374: Cannot ref-assign 't' to 'F2' because 't' has a narrower escape scope than 'F2'.
                //         x.F2 = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "x.F2 = ref t").WithArguments("F2", "t").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)
                //         x.F3 = ref t;
                Diagnostic(ErrorCode.ERR_AssgReadonly, "x.F3").WithLocation(23, 9),
                // (24,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)
                //         x.F4 = ref t;
                Diagnostic(ErrorCode.ERR_AssgReadonly, "x.F4").WithLocation(24, 9),
                // (26,9): error CS8374: Cannot ref-assign 't' to 'F1' because 't' has a narrower escape scope than 'F1'.
                //         y.F1 = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "y.F1 = ref t").WithArguments("F1", "t").WithLocation(26, 9),
                // (27,9): error CS8374: Cannot ref-assign 't' to 'F2' because 't' has a narrower escape scope than 'F2'.
                //         y.F2 = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "y.F2 = ref t").WithArguments("F2", "t").WithLocation(27, 9),
                // (28,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)
                //         y.F3 = ref t;
                Diagnostic(ErrorCode.ERR_AssgReadonly, "y.F3").WithLocation(28, 9),
                // (29,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)
                //         y.F4 = ref t;
                Diagnostic(ErrorCode.ERR_AssgReadonly, "y.F4").WithLocation(29, 9));
        }
 
        [Fact]
        public void AssignValueTo_InstanceMethod_RefField()
        {
            var source =
@"ref struct S<T>
{
    public ref T F;
    public S(T tValue, ref T tRef, out T tOut, in T tIn)
    {
        tOut = default;
        F = tValue;
        F = tRef;
        F = tOut;
        F = tIn;
    }
    object P
    {
        init
        {
            F = GetValue();
            F = GetRef();
            F = GetRefReadonly();
        }
    }
    static T GetValue() => throw null;
    static ref T GetRef() => throw null;
    static ref readonly T GetRefReadonly() => throw null;
}";
            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void AssignValueTo_InstanceMethod_RefReadonlyField()
        {
            var source =
@"ref struct S<T>
{
    public ref readonly T F;
    public S(T tValue, ref T tRef, out T tOut, in T tIn)
    {
        tOut = default;
        F = tValue; // 1
        F = tRef; // 2
        F = tOut; // 3
        F = tIn; // 4
    }
    object P
    {
        init
        {
            F = GetValue(); // 5
            F = GetRef(); // 6
            F = GetRefReadonly(); // 7
        }
    }
    static T GetValue() => throw null;
    static ref T GetRef() => throw null;
    static ref readonly T GetRefReadonly() => throw null;
}";
            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (7,9): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         F = tValue; // 1
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(7, 9),
                // (8,9): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         F = tRef; // 2
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(8, 9),
                // (9,9): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         F = tOut; // 3
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(9, 9),
                // (10,9): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         F = tIn; // 4
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(10, 9),
                // (16,13): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //             F = GetValue(); // 5
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(16, 13),
                // (17,13): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //             F = GetRef(); // 6
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(17, 13),
                // (18,13): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //             F = GetRefReadonly(); // 7
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(18, 13));
        }
 
        [Fact]
        public void AssignValueTo_InstanceMethod_ReadonlyRefField()
        {
            var source =
@"ref struct S<T>
{
    public readonly ref T F;
    public S(T tValue, ref T tRef, out T tOut, in T tIn)
    {
        tOut = default;
        F = tValue;
        F = tRef;
        F = tOut;
        F = tIn;
    }
    object P
    {
        init
        {
            F = GetValue();
            F = GetRef();
            F = GetRefReadonly();
        }
    }
    static T GetValue() => throw null;
    static ref T GetRef() => throw null;
    static ref readonly T GetRefReadonly() => throw null;
}";
            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void AssignValueTo_InstanceMethod_ReadonlyRefReadonlyField()
        {
            var source =
@"ref struct S<T>
{
    public readonly ref readonly T F;
    public S(T tValue, ref T tRef, out T tOut, in T tIn)
    {
        tOut = default;
        F = tValue; // 1
        F = tRef; // 2
        F = tOut; // 3
        F = tIn; // 4
    }
    object P
    {
        init
        {
            F = GetValue(); // 5
            F = GetRef(); // 6
            F = GetRefReadonly(); // 7
        }
    }
    static T GetValue() => throw null;
    static ref T GetRef() => throw null;
    static ref readonly T GetRefReadonly() => throw null;
}";
            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (7,9): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         F = tValue; // 1
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(7, 9),
                // (8,9): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         F = tRef; // 2
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(8, 9),
                // (9,9): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         F = tOut; // 3
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(9, 9),
                // (10,9): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         F = tIn; // 4
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(10, 9),
                // (16,13): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //             F = GetValue(); // 5
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(16, 13),
                // (17,13): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //             F = GetRef(); // 6
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(17, 13),
                // (18,13): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //             F = GetRefReadonly(); // 7
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(18, 13));
        }
 
        [Fact]
        public void AssignRefTo_InstanceMethod_RefField()
        {
            var source =
@"ref struct S<T>
{
    public ref T F;
    public S(T tValue, ref T tRef, out T tOut, in T tIn)
    {
        tOut = default;
        F = ref tValue; // 1
        F = ref tRef;
        F = ref tOut; // 2
        F = ref tIn; // 3
    }
    T P
    {
        init
        {
            F = ref value; // 4
            F = ref GetRef();
            F = ref GetRefReadonly(); // 5
        }
    }
    static ref T GetRef() => throw null;
    static ref readonly T GetRefReadonly() => throw null;
}";
            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (7,9): error CS8374: Cannot ref-assign 'tValue' to 'F' because 'tValue' has a narrower escape scope than 'F'.
                //         F = ref tValue; // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "F = ref tValue").WithArguments("F", "tValue").WithLocation(7, 9),
                // (9,9): error CS8374: Cannot ref-assign 'tOut' to 'F' because 'tOut' has a narrower escape scope than 'F'.
                //         F = ref tOut; // 2
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "F = ref tOut").WithArguments("F", "tOut").WithLocation(9, 9),
                // (10,17): error CS8331: Cannot assign to variable 'tIn' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         F = ref tIn; // 3
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "tIn").WithArguments("variable", "tIn").WithLocation(10, 17),
                // (16,13): error CS8374: Cannot ref-assign 'value' to 'F' because 'value' has a narrower escape scope than 'F'.
                //             F = ref value; // 4
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "F = ref value").WithArguments("F", "value").WithLocation(16, 13),
                // (18,21): error CS8331: Cannot assign to method 'GetRefReadonly' or use it as the right hand side of a ref assignment because it is a readonly variable
                //             F = ref GetRefReadonly(); // 5
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "GetRefReadonly()").WithArguments("method", "GetRefReadonly").WithLocation(18, 21));
        }
 
        [Fact]
        public void AssignRefTo_InstanceMethod_RefReadonlyField()
        {
            var source =
@"ref struct S<T>
{
    public ref readonly T F;
    public S(T tValue, ref T tRef, out T tOut, in T tIn)
    {
        tOut = default;
        F = ref tValue; // 1
        F = ref tRef;
        F = ref tOut; // 2
        F = ref tIn;
    }
    T P
    {
        init
        {
            F = ref value; // 3
            F = ref GetRef();
            F = ref GetRefReadonly();
        }
    }
    static ref T GetRef() => throw null;
    static ref readonly T GetRefReadonly() => throw null;
}";
            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (7,9): error CS8374: Cannot ref-assign 'tValue' to 'F' because 'tValue' has a narrower escape scope than 'F'.
                //         F = ref tValue; // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "F = ref tValue").WithArguments("F", "tValue").WithLocation(7, 9),
                // (9,9): error CS8374: Cannot ref-assign 'tOut' to 'F' because 'tOut' has a narrower escape scope than 'F'.
                //         F = ref tOut; // 2
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "F = ref tOut").WithArguments("F", "tOut").WithLocation(9, 9),
                // (16,13): error CS8374: Cannot ref-assign 'value' to 'F' because 'value' has a narrower escape scope than 'F'.
                //             F = ref value; // 3
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "F = ref value").WithArguments("F", "value").WithLocation(16, 13));
        }
 
        [Fact]
        public void AssignRefTo_InstanceMethod_ReadonlyRefField()
        {
            var source =
@"ref struct S<T>
{
    public readonly ref T F;
    public S(T tValue, ref T tRef, out T tOut, in T tIn)
    {
        tOut = default;
        F = ref tValue; // 1
        F = ref tRef;
        F = ref tOut; // 2
        F = ref tIn; // 3
    }
    T P
    {
        init
        {
            F = ref value; // 4
            F = ref GetRef();
            F = ref GetRefReadonly(); // 5
        }
    }
    static ref T GetRef() => throw null;
    static ref readonly T GetRefReadonly() => throw null;
}";
            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (7,9): error CS8374: Cannot ref-assign 'tValue' to 'F' because 'tValue' has a narrower escape scope than 'F'.
                //         F = ref tValue; // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "F = ref tValue").WithArguments("F", "tValue").WithLocation(7, 9),
                // (9,9): error CS8374: Cannot ref-assign 'tOut' to 'F' because 'tOut' has a narrower escape scope than 'F'.
                //         F = ref tOut; // 2
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "F = ref tOut").WithArguments("F", "tOut").WithLocation(9, 9),
                // (10,17): error CS8331: Cannot assign to variable 'tIn' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         F = ref tIn; // 3
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "tIn").WithArguments("variable", "tIn").WithLocation(10, 17),
                // (16,13): error CS8374: Cannot ref-assign 'value' to 'F' because 'value' has a narrower escape scope than 'F'.
                //             F = ref value; // 4
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "F = ref value").WithArguments("F", "value").WithLocation(16, 13),
                // (18,21): error CS8331: Cannot assign to method 'GetRefReadonly' or use it as the right hand side of a ref assignment because it is a readonly variable
                //             F = ref GetRefReadonly(); // 5
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "GetRefReadonly()").WithArguments("method", "GetRefReadonly").WithLocation(18, 21));
        }
 
        [Fact]
        public void AssignRefTo_InstanceMethod_ReadonlyRefReadonlyField()
        {
            var source =
@"ref struct S<T>
{
    public readonly ref readonly T F;
    public S(T tValue, ref T tRef, out T tOut, in T tIn)
    {
        tOut = default;
        F = ref tValue; // 1
        F = ref tRef;
        F = ref tOut; // 2
        F = ref tIn;
    }
    T P
    {
        init
        {
            F = ref value; // 3
            F = ref GetRef();
            F = ref GetRefReadonly();
        }
    }
    static ref T GetRef() => throw null;
    static ref readonly T GetRefReadonly() => throw null;
}";
            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (7,9): error CS8374: Cannot ref-assign 'tValue' to 'F' because 'tValue' has a narrower escape scope than 'F'.
                //         F = ref tValue; // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "F = ref tValue").WithArguments("F", "tValue").WithLocation(7, 9),
                // (9,9): error CS8374: Cannot ref-assign 'tOut' to 'F' because 'tOut' has a narrower escape scope than 'F'.
                //         F = ref tOut; // 2
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "F = ref tOut").WithArguments("F", "tOut").WithLocation(9, 9),
                // (16,13): error CS8374: Cannot ref-assign 'value' to 'F' because 'value' has a narrower escape scope than 'F'.
                //             F = ref value; // 3
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "F = ref value").WithArguments("F", "value").WithLocation(16, 13));
        }
 
        [Fact]
        public void AssignValueTo_RefField()
        {
            var source =
@"using System;
 
ref struct S<T>
{
    public ref T F;
    public S(ref T t) { F = ref t; }
}
 
class Program
{
    static void AssignValueToValue<T>(S<T> s, T tValue) { s.F = tValue; }
    static void AssignRefToValue<T>(S<T> s, ref T tRef) { s.F = tRef; }
    static void AssignOutToValue<T>(S<T> s, out T tOut) { tOut = default; s.F = tOut; }
    static void AssignInToValue<T>(S<T> s, in T tIn)    { s.F = tIn; }
 
    static void AssignValueToRef<T>(ref S<T> sRef, T tValue) { sRef.F = tValue; }
    static void AssignRefToRef<T>(ref S<T> sRef, ref T tRef) { sRef.F = tRef; }
    static void AssignOutToRef<T>(ref S<T> sRef, out T tOut) { tOut = default; sRef.F = tOut; }
    static void AssignInToRef<T>(ref S<T> sRef, in T tIn)    { sRef.F = tIn; }
 
    static void AssignValueToOut<T>(out S<T> sOut, S<T> sInit, T tValue) { sOut = sInit; sOut.F = tValue; }
    static void AssignRefToOut<T>(out S<T> sOut, S<T> sInit, ref T tRef) { sOut = sInit; sOut.F = tRef; }
    static void AssignOutToOut<T>(out S<T> sOut, S<T> sInit, out T tOut) { sOut = sInit; tOut = default; sOut.F = tOut; }
    static void AssignInToOut<T>(out S<T> sOut, S<T> sInit, in T tIn)    { sOut = sInit; sOut.F = tIn; }
 
    static void AssignValueToIn<T>(in S<T> sIn, T tValue) { sIn.F = tValue; }
    static void AssignRefToIn<T>(in S<T> sIn, ref T tRef) { sIn.F = tRef; }
    static void AssignOutToIn<T>(in S<T> sIn, out T tOut) { tOut = default; sIn.F = tOut; }
    static void AssignInToIn<T>(in S<T> sIn, in T tIn)    { sIn.F = tIn; }
 
    static void Main()
    {
        int x, y;
        scoped S<int> s;
 
        x = 1; y = 2;
        s = new S<int>(ref x);
        AssignValueToValue(s, y);
        Console.WriteLine(s.F);
        x = 1; y = 2;
        s = new S<int>(ref x);
        AssignRefToValue(s, ref y);
        Console.WriteLine(s.F);
        x = 1; y = 2;
        s = new S<int>(ref x);
        AssignOutToValue(s, out y);
        Console.WriteLine(s.F);
        x = 1; y = 2;
        s = new S<int>(ref x);
        AssignInToValue(s, y);
        Console.WriteLine(s.F);
 
        x = 3; y = 4;
        s = new S<int>(ref x);
        AssignValueToRef(ref s, y);
        Console.WriteLine(s.F);
        x = 3; y = 4;
        s = new S<int>(ref x);
        AssignRefToRef(ref s, ref y);
        Console.WriteLine(s.F);
        x = 3; y = 4;
        s = new S<int>(ref x);
        AssignOutToRef(ref s, out y);
        Console.WriteLine(s.F);
        x = 3; y = 4;
        s = new S<int>(ref x);
        AssignInToRef(ref s, y);
        Console.WriteLine(s.F);
 
        x = 5; y = 6;
        s = new S<int>(ref x);
        AssignValueToOut(out s, new S<int>(ref x), y);
        Console.WriteLine(s.F);
        x = 5; y = 6;
        s = new S<int>(ref x);
        AssignRefToOut(out s, new S<int>(ref x), ref y);
        Console.WriteLine(s.F);
        x = 5; y = 6;
        s = new S<int>(ref x);
        AssignOutToOut(out s, new S<int>(ref x), out y);
        Console.WriteLine(s.F);
        x = 5; y = 6;
        s = new S<int>(ref x);
        AssignInToOut(out s, new S<int>(ref x), y);
        Console.WriteLine(s.F);
 
        x = 7; y = 8;
        s = new S<int>(ref x);
        AssignValueToIn(s, y);
        Console.WriteLine(s.F);
        x = 7; y = 8;
        s = new S<int>(ref x);
        AssignRefToIn(s, ref y);
        Console.WriteLine(s.F);
        x = 7; y = 8;
        s = new S<int>(ref x);
        AssignOutToIn(s, out y);
        Console.WriteLine(s.F);
        x = 7; y = 8;
        s = new S<int>(ref x);
        AssignInToIn(s, y);
        Console.WriteLine(s.F);
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput(
@"2
2
0
2
4
4
0
4
6
6
0
6
8
8
0
8"));
            verifier.VerifyILMultiple(
                "Program.AssignValueToValue<T>",
@"{
  // Code size       13 (0xd)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.F""
  IL_0006:  ldarg.1
  IL_0007:  stobj      ""T""
  IL_000c:  ret
}",
                "Program.AssignRefToValue<T>",
@"{
  // Code size       18 (0x12)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.F""
  IL_0006:  ldarg.1
  IL_0007:  ldobj      ""T""
  IL_000c:  stobj      ""T""
  IL_0011:  ret
}",
                "Program.AssignOutToValue<T>",
@"{
  // Code size       25 (0x19)
  .maxstack  2
  IL_0000:  ldarg.1
  IL_0001:  initobj    ""T""
  IL_0007:  ldarg.0
  IL_0008:  ldfld      ""ref T S<T>.F""
  IL_000d:  ldarg.1
  IL_000e:  ldobj      ""T""
  IL_0013:  stobj      ""T""
  IL_0018:  ret
}",
                "Program.AssignInToValue<T>",
@"{
  // Code size       18 (0x12)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.F""
  IL_0006:  ldarg.1
  IL_0007:  ldobj      ""T""
  IL_000c:  stobj      ""T""
  IL_0011:  ret
}",
                "Program.AssignValueToRef<T>",
@"{
  // Code size       13 (0xd)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.F""
  IL_0006:  ldarg.1
  IL_0007:  stobj      ""T""
  IL_000c:  ret
}",
                "Program.AssignRefToRef<T>",
@"{
  // Code size       18 (0x12)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.F""
  IL_0006:  ldarg.1
  IL_0007:  ldobj      ""T""
  IL_000c:  stobj      ""T""
  IL_0011:  ret
}",
                "Program.AssignOutToRef<T>",
@"{
  // Code size       25 (0x19)
  .maxstack  2
  IL_0000:  ldarg.1
  IL_0001:  initobj    ""T""
  IL_0007:  ldarg.0
  IL_0008:  ldfld      ""ref T S<T>.F""
  IL_000d:  ldarg.1
  IL_000e:  ldobj      ""T""
  IL_0013:  stobj      ""T""
  IL_0018:  ret
}",
                "Program.AssignInToRef<T>",
@"{
  // Code size       18 (0x12)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.F""
  IL_0006:  ldarg.1
  IL_0007:  ldobj      ""T""
  IL_000c:  stobj      ""T""
  IL_0011:  ret
}",
                "Program.AssignValueToOut<T>",
@"{
  // Code size       20 (0x14)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  stobj      ""S<T>""
  IL_0007:  ldarg.0
  IL_0008:  ldfld      ""ref T S<T>.F""
  IL_000d:  ldarg.2
  IL_000e:  stobj      ""T""
  IL_0013:  ret
}",
                "Program.AssignRefToOut<T>",
@"{
  // Code size       25 (0x19)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  stobj      ""S<T>""
  IL_0007:  ldarg.0
  IL_0008:  ldfld      ""ref T S<T>.F""
  IL_000d:  ldarg.2
  IL_000e:  ldobj      ""T""
  IL_0013:  stobj      ""T""
  IL_0018:  ret
}",
                "Program.AssignOutToOut<T>",
@"{
  // Code size       32 (0x20)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  stobj      ""S<T>""
  IL_0007:  ldarg.2
  IL_0008:  initobj    ""T""
  IL_000e:  ldarg.0
  IL_000f:  ldfld      ""ref T S<T>.F""
  IL_0014:  ldarg.2
  IL_0015:  ldobj      ""T""
  IL_001a:  stobj      ""T""
  IL_001f:  ret
}",
                "Program.AssignInToOut<T>",
@"{
  // Code size       25 (0x19)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  stobj      ""S<T>""
  IL_0007:  ldarg.0
  IL_0008:  ldfld      ""ref T S<T>.F""
  IL_000d:  ldarg.2
  IL_000e:  ldobj      ""T""
  IL_0013:  stobj      ""T""
  IL_0018:  ret
}",
                "Program.AssignValueToIn<T>",
@"{
  // Code size       13 (0xd)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.F""
  IL_0006:  ldarg.1
  IL_0007:  stobj      ""T""
  IL_000c:  ret
}",
                "Program.AssignRefToIn<T>",
@"{
  // Code size       18 (0x12)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.F""
  IL_0006:  ldarg.1
  IL_0007:  ldobj      ""T""
  IL_000c:  stobj      ""T""
  IL_0011:  ret
}",
                "Program.AssignOutToIn<T>",
@"{
  // Code size       25 (0x19)
  .maxstack  2
  IL_0000:  ldarg.1
  IL_0001:  initobj    ""T""
  IL_0007:  ldarg.0
  IL_0008:  ldfld      ""ref T S<T>.F""
  IL_000d:  ldarg.1
  IL_000e:  ldobj      ""T""
  IL_0013:  stobj      ""T""
  IL_0018:  ret
}",
                "Program.AssignInToIn<T>",
@"{
  // Code size       18 (0x12)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.F""
  IL_0006:  ldarg.1
  IL_0007:  ldobj      ""T""
  IL_000c:  stobj      ""T""
  IL_0011:  ret
}");
        }
 
        [Fact]
        public void AssignValueTo_RefReadonlyField()
        {
            var source =
@"ref struct S<T>
{
    public ref readonly T F;
    public S(ref T t) { F = ref t; }
}
 
class Program
{
    static void AssignValueToValue<T>(S<T> s, T tValue) { s.F = tValue; } // 1
    static void AssignRefToValue<T>(S<T> s, ref T tRef) { s.F = tRef; } // 2
    static void AssignOutToValue<T>(S<T> s, out T tOut) { tOut = default; s.F = tOut; } // 3
    static void AssignInToValue<T>(S<T> s, in T tIn)    { s.F = tIn; } // 4
 
    static void AssignValueToRef<T>(ref S<T> sRef, T tValue) { sRef.F = tValue; } // 5
    static void AssignRefToRef<T>(ref S<T> sRef, ref T tRef) { sRef.F = tRef; } // 6
    static void AssignOutToRef<T>(ref S<T> sRef, out T tOut) { tOut = default; sRef.F = tOut; } // 7
    static void AssignInToRef<T>(ref S<T> sRef, in T tIn)    { sRef.F = tIn; } // 8
 
    static void AssignValueToOut<T>(out S<T> sOut, T tValue) { sOut = default; sOut.F = tValue; } // 9
    static void AssignRefToOut<T>(out S<T> sOut, ref T tRef) { sOut = default; sOut.F = tRef; } // 10
    static void AssignOutToOut<T>(out S<T> sOut, out T tOut) { sOut = default; tOut = default; sOut.F = tOut; } // 11
    static void AssignInToOut<T>(out S<T> sOut, in T tIn)    { sOut = default; sOut.F = tIn; } // 12
 
    static void AssignValueToIn<T>(in S<T> sIn, T tValue) { sIn.F = tValue; } // 13
    static void AssignRefToIn<T>(in S<T> sIn, ref T tRef) { sIn.F = tRef; } // 14
    static void AssignOutToIn<T>(in S<T> sIn, out T tOut) { tOut = default; sIn.F = tOut; } // 15
    static void AssignInToIn<T>(in S<T> sIn, in T tIn)    { sIn.F = tIn; } // 16
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (9,59): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignValueToValue<T>(S<T> s, T tValue) { s.F = tValue; } // 1
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(9, 59),
                // (10,59): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignRefToValue<T>(S<T> s, ref T tRef) { s.F = tRef; } // 2
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(10, 59),
                // (11,75): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignOutToValue<T>(S<T> s, out T tOut) { tOut = default; s.F = tOut; } // 3
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(11, 75),
                // (12,59): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignInToValue<T>(S<T> s, in T tIn)    { s.F = tIn; } // 4
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(12, 59),
                // (14,64): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignValueToRef<T>(ref S<T> sRef, T tValue) { sRef.F = tValue; } // 5
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sRef.F").WithArguments("field", "F").WithLocation(14, 64),
                // (15,64): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignRefToRef<T>(ref S<T> sRef, ref T tRef) { sRef.F = tRef; } // 6
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sRef.F").WithArguments("field", "F").WithLocation(15, 64),
                // (16,80): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignOutToRef<T>(ref S<T> sRef, out T tOut) { tOut = default; sRef.F = tOut; } // 7
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sRef.F").WithArguments("field", "F").WithLocation(16, 80),
                // (17,64): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignInToRef<T>(ref S<T> sRef, in T tIn)    { sRef.F = tIn; } // 8
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sRef.F").WithArguments("field", "F").WithLocation(17, 64),
                // (19,80): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignValueToOut<T>(out S<T> sOut, T tValue) { sOut = default; sOut.F = tValue; } // 9
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sOut.F").WithArguments("field", "F").WithLocation(19, 80),
                // (20,80): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignRefToOut<T>(out S<T> sOut, ref T tRef) { sOut = default; sOut.F = tRef; } // 10
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sOut.F").WithArguments("field", "F").WithLocation(20, 80),
                // (21,96): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignOutToOut<T>(out S<T> sOut, out T tOut) { sOut = default; tOut = default; sOut.F = tOut; } // 11
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sOut.F").WithArguments("field", "F").WithLocation(21, 96),
                // (22,80): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignInToOut<T>(out S<T> sOut, in T tIn)    { sOut = default; sOut.F = tIn; } // 12
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sOut.F").WithArguments("field", "F").WithLocation(22, 80),
                // (24,61): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignValueToIn<T>(in S<T> sIn, T tValue) { sIn.F = tValue; } // 13
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sIn.F").WithArguments("field", "F").WithLocation(24, 61),
                // (25,61): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignRefToIn<T>(in S<T> sIn, ref T tRef) { sIn.F = tRef; } // 14
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sIn.F").WithArguments("field", "F").WithLocation(25, 61),
                // (26,77): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignOutToIn<T>(in S<T> sIn, out T tOut) { tOut = default; sIn.F = tOut; } // 15
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sIn.F").WithArguments("field", "F").WithLocation(26, 77),
                // (27,61): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignInToIn<T>(in S<T> sIn, in T tIn)    { sIn.F = tIn; } // 16
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sIn.F").WithArguments("field", "F").WithLocation(27, 61));
        }
 
        [Fact]
        public void AssignValueTo_ReadonlyRefField()
        {
            var source =
@"using System;
 
ref struct S<T>
{
    public readonly ref T F;
    public S(ref T t) { F = ref t; }
}
 
class Program
{
    static void AssignValueToValue<T>(S<T> s, T tValue) { s.F = tValue; }
    static void AssignRefToValue<T>(S<T> s, ref T tRef) { s.F = tRef; }
    static void AssignOutToValue<T>(S<T> s, out T tOut) { tOut = default; s.F = tOut; }
    static void AssignInToValue<T>(S<T> s, in T tIn)    { s.F = tIn; }
 
    static void AssignValueToRef<T>(ref S<T> sRef, T tValue) { sRef.F = tValue; }
    static void AssignRefToRef<T>(ref S<T> sRef, ref T tRef) { sRef.F = tRef; }
    static void AssignOutToRef<T>(ref S<T> sRef, out T tOut) { tOut = default; sRef.F = tOut; }
    static void AssignInToRef<T>(ref S<T> sRef, in T tIn)    { sRef.F = tIn; }
 
    static void AssignValueToOut<T>(out S<T> sOut, S<T> sInit, T tValue) { sOut = sInit; sOut.F = tValue; }
    static void AssignRefToOut<T>(out S<T> sOut, S<T> sInit, ref T tRef) { sOut = sInit; sOut.F = tRef; }
    static void AssignOutToOut<T>(out S<T> sOut, S<T> sInit, out T tOut) { sOut = sInit; tOut = default; sOut.F = tOut; }
    static void AssignInToOut<T>(out S<T> sOut, S<T> sInit, in T tIn)    { sOut = sInit; sOut.F = tIn; }
 
    static void AssignValueToIn<T>(in S<T> sIn, T tValue) { sIn.F = tValue; }
    static void AssignRefToIn<T>(in S<T> sIn, ref T tRef) { sIn.F = tRef; }
    static void AssignOutToIn<T>(in S<T> sIn, out T tOut) { tOut = default; sIn.F = tOut; }
    static void AssignInToIn<T>(in S<T> sIn, in T tIn)    { sIn.F = tIn; }
 
    static void Main()
    {
        int x, y;
        scoped S<int> s;
 
        x = 1; y = 2;
        s = new S<int>(ref x);
        AssignValueToValue(s, y);
        Console.WriteLine(s.F);
        x = 1; y = 2;
        s = new S<int>(ref x);
        AssignRefToValue(s, ref y);
        Console.WriteLine(s.F);
        x = 1; y = 2;
        s = new S<int>(ref x);
        AssignOutToValue(s, out y);
        Console.WriteLine(s.F);
        x = 1; y = 2;
        s = new S<int>(ref x);
        AssignInToValue(s, y);
        Console.WriteLine(s.F);
 
        x = 3; y = 4;
        s = new S<int>(ref x);
        AssignValueToRef(ref s, y);
        Console.WriteLine(s.F);
        x = 3; y = 4;
        s = new S<int>(ref x);
        AssignRefToRef(ref s, ref y);
        Console.WriteLine(s.F);
        x = 3; y = 4;
        s = new S<int>(ref x);
        AssignOutToRef(ref s, out y);
        Console.WriteLine(s.F);
        x = 3; y = 4;
        s = new S<int>(ref x);
        AssignInToRef(ref s, y);
        Console.WriteLine(s.F);
 
        x = 5; y = 6;
        s = new S<int>(ref x);
        AssignValueToOut(out s, new S<int>(ref x), y);
        Console.WriteLine(s.F);
        x = 5; y = 6;
        s = new S<int>(ref x);
        AssignRefToOut(out s, new S<int>(ref x), ref y);
        Console.WriteLine(s.F);
        x = 5; y = 6;
        s = new S<int>(ref x);
        AssignOutToOut(out s, new S<int>(ref x), out y);
        Console.WriteLine(s.F);
        x = 5; y = 6;
        s = new S<int>(ref x);
        AssignInToOut(out s, new S<int>(ref x), y);
        Console.WriteLine(s.F);
 
        x = 7; y = 8;
        s = new S<int>(ref x);
        AssignValueToIn(s, y);
        Console.WriteLine(s.F);
        x = 7; y = 8;
        s = new S<int>(ref x);
        AssignRefToIn(s, ref y);
        Console.WriteLine(s.F);
        x = 7; y = 8;
        s = new S<int>(ref x);
        AssignOutToIn(s, out y);
        Console.WriteLine(s.F);
        x = 7; y = 8;
        s = new S<int>(ref x);
        AssignInToIn(s, y);
        Console.WriteLine(s.F);
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput(
@"2
2
0
2
4
4
0
4
6
6
0
6
8
8
0
8"));
            verifier.VerifyILMultiple(
                "Program.AssignValueToValue<T>",
@"{
  // Code size       13 (0xd)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.F""
  IL_0006:  ldarg.1
  IL_0007:  stobj      ""T""
  IL_000c:  ret
}",
                "Program.AssignRefToValue<T>",
@"{
  // Code size       18 (0x12)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.F""
  IL_0006:  ldarg.1
  IL_0007:  ldobj      ""T""
  IL_000c:  stobj      ""T""
  IL_0011:  ret
}",
                "Program.AssignOutToValue<T>",
@"{
  // Code size       25 (0x19)
  .maxstack  2
  IL_0000:  ldarg.1
  IL_0001:  initobj    ""T""
  IL_0007:  ldarg.0
  IL_0008:  ldfld      ""ref T S<T>.F""
  IL_000d:  ldarg.1
  IL_000e:  ldobj      ""T""
  IL_0013:  stobj      ""T""
  IL_0018:  ret
}",
                "Program.AssignInToValue<T>",
@"{
  // Code size       18 (0x12)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.F""
  IL_0006:  ldarg.1
  IL_0007:  ldobj      ""T""
  IL_000c:  stobj      ""T""
  IL_0011:  ret
}",
                "Program.AssignValueToRef<T>",
@"{
  // Code size       13 (0xd)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.F""
  IL_0006:  ldarg.1
  IL_0007:  stobj      ""T""
  IL_000c:  ret
}",
                "Program.AssignRefToRef<T>",
@"{
  // Code size       18 (0x12)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.F""
  IL_0006:  ldarg.1
  IL_0007:  ldobj      ""T""
  IL_000c:  stobj      ""T""
  IL_0011:  ret
}",
                "Program.AssignOutToRef<T>",
@"{
  // Code size       25 (0x19)
  .maxstack  2
  IL_0000:  ldarg.1
  IL_0001:  initobj    ""T""
  IL_0007:  ldarg.0
  IL_0008:  ldfld      ""ref T S<T>.F""
  IL_000d:  ldarg.1
  IL_000e:  ldobj      ""T""
  IL_0013:  stobj      ""T""
  IL_0018:  ret
}",
                "Program.AssignInToRef<T>",
@"{
  // Code size       18 (0x12)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.F""
  IL_0006:  ldarg.1
  IL_0007:  ldobj      ""T""
  IL_000c:  stobj      ""T""
  IL_0011:  ret
}",
                "Program.AssignValueToOut<T>",
@"{
  // Code size       20 (0x14)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  stobj      ""S<T>""
  IL_0007:  ldarg.0
  IL_0008:  ldfld      ""ref T S<T>.F""
  IL_000d:  ldarg.2
  IL_000e:  stobj      ""T""
  IL_0013:  ret
}",
                "Program.AssignRefToOut<T>",
@"{
  // Code size       25 (0x19)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  stobj      ""S<T>""
  IL_0007:  ldarg.0
  IL_0008:  ldfld      ""ref T S<T>.F""
  IL_000d:  ldarg.2
  IL_000e:  ldobj      ""T""
  IL_0013:  stobj      ""T""
  IL_0018:  ret
}",
                "Program.AssignOutToOut<T>",
@"{
  // Code size       32 (0x20)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  stobj      ""S<T>""
  IL_0007:  ldarg.2
  IL_0008:  initobj    ""T""
  IL_000e:  ldarg.0
  IL_000f:  ldfld      ""ref T S<T>.F""
  IL_0014:  ldarg.2
  IL_0015:  ldobj      ""T""
  IL_001a:  stobj      ""T""
  IL_001f:  ret
}",
                "Program.AssignInToOut<T>",
@"{
  // Code size       25 (0x19)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  stobj      ""S<T>""
  IL_0007:  ldarg.0
  IL_0008:  ldfld      ""ref T S<T>.F""
  IL_000d:  ldarg.2
  IL_000e:  ldobj      ""T""
  IL_0013:  stobj      ""T""
  IL_0018:  ret
}",
                "Program.AssignValueToIn<T>",
@"{
  // Code size       13 (0xd)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.F""
  IL_0006:  ldarg.1
  IL_0007:  stobj      ""T""
  IL_000c:  ret
}",
                "Program.AssignRefToIn<T>",
@"{
  // Code size       18 (0x12)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.F""
  IL_0006:  ldarg.1
  IL_0007:  ldobj      ""T""
  IL_000c:  stobj      ""T""
  IL_0011:  ret
}",
                "Program.AssignOutToIn<T>",
@"{
  // Code size       25 (0x19)
  .maxstack  2
  IL_0000:  ldarg.1
  IL_0001:  initobj    ""T""
  IL_0007:  ldarg.0
  IL_0008:  ldfld      ""ref T S<T>.F""
  IL_000d:  ldarg.1
  IL_000e:  ldobj      ""T""
  IL_0013:  stobj      ""T""
  IL_0018:  ret
}",
                "Program.AssignInToIn<T>",
@"{
  // Code size       18 (0x12)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.F""
  IL_0006:  ldarg.1
  IL_0007:  ldobj      ""T""
  IL_000c:  stobj      ""T""
  IL_0011:  ret
}");
        }
 
        [Fact]
        public void AssignValueTo_ReadonlyRefReadonlyField()
        {
            var source =
@"ref struct S<T>
{
    public readonly ref readonly T F;
    public S(ref T t) { F = ref t; }
}
 
class Program
{
    static void AssignValueToValue<T>(S<T> s, T tValue) { s.F = tValue; } // 1
    static void AssignRefToValue<T>(S<T> s, ref T tRef) { s.F = tRef; } // 2
    static void AssignOutToValue<T>(S<T> s, out T tOut) { tOut = default; s.F = tOut; } // 3
    static void AssignInToValue<T>(S<T> s, in T tIn)    { s.F = tIn; } // 4
 
    static void AssignValueToRef<T>(ref S<T> sRef, T tValue) { sRef.F = tValue; } // 5
    static void AssignRefToRef<T>(ref S<T> sRef, ref T tRef) { sRef.F = tRef; } // 6
    static void AssignOutToRef<T>(ref S<T> sRef, out T tOut) { tOut = default; sRef.F = tOut; } // 7
    static void AssignInToRef<T>(ref S<T> sRef, in T tIn)    { sRef.F = tIn; } // 8
 
    static void AssignValueToOut<T>(out S<T> sOut, T tValue) { sOut = default; sOut.F = tValue; } // 9
    static void AssignRefToOut<T>(out S<T> sOut, ref T tRef) { sOut = default; sOut.F = tRef; } // 10
    static void AssignOutToOut<T>(out S<T> sOut, out T tOut) { sOut = default; tOut = default; sOut.F = tOut; } // 11
    static void AssignInToOut<T>(out S<T> sOut, in T tIn)    { sOut = default; sOut.F = tIn; } // 12
 
    static void AssignValueToIn<T>(in S<T> sIn, T tValue) { sIn.F = tValue; } // 13
    static void AssignRefToIn<T>(in S<T> sIn, ref T tRef) { sIn.F = tRef; } // 14
    static void AssignOutToIn<T>(in S<T> sIn, out T tOut) { tOut = default; sIn.F = tOut; } // 15
    static void AssignInToIn<T>(in S<T> sIn, in T tIn)    { sIn.F = tIn; } // 16
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (9,59): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignValueToValue<T>(S<T> s, T tValue) { s.F = tValue; } // 1
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(9, 59),
                // (10,59): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignRefToValue<T>(S<T> s, ref T tRef) { s.F = tRef; } // 2
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(10, 59),
                // (11,75): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignOutToValue<T>(S<T> s, out T tOut) { tOut = default; s.F = tOut; } // 3
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(11, 75),
                // (12,59): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignInToValue<T>(S<T> s, in T tIn)    { s.F = tIn; } // 4
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(12, 59),
                // (14,64): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignValueToRef<T>(ref S<T> sRef, T tValue) { sRef.F = tValue; } // 5
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sRef.F").WithArguments("field", "F").WithLocation(14, 64),
                // (15,64): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignRefToRef<T>(ref S<T> sRef, ref T tRef) { sRef.F = tRef; } // 6
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sRef.F").WithArguments("field", "F").WithLocation(15, 64),
                // (16,80): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignOutToRef<T>(ref S<T> sRef, out T tOut) { tOut = default; sRef.F = tOut; } // 7
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sRef.F").WithArguments("field", "F").WithLocation(16, 80),
                // (17,64): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignInToRef<T>(ref S<T> sRef, in T tIn)    { sRef.F = tIn; } // 8
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sRef.F").WithArguments("field", "F").WithLocation(17, 64),
                // (19,80): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignValueToOut<T>(out S<T> sOut, T tValue) { sOut = default; sOut.F = tValue; } // 9
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sOut.F").WithArguments("field", "F").WithLocation(19, 80),
                // (20,80): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignRefToOut<T>(out S<T> sOut, ref T tRef) { sOut = default; sOut.F = tRef; } // 10
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sOut.F").WithArguments("field", "F").WithLocation(20, 80),
                // (21,96): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignOutToOut<T>(out S<T> sOut, out T tOut) { sOut = default; tOut = default; sOut.F = tOut; } // 11
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sOut.F").WithArguments("field", "F").WithLocation(21, 96),
                // (22,80): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignInToOut<T>(out S<T> sOut, in T tIn)    { sOut = default; sOut.F = tIn; } // 12
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sOut.F").WithArguments("field", "F").WithLocation(22, 80),
                // (24,61): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignValueToIn<T>(in S<T> sIn, T tValue) { sIn.F = tValue; } // 13
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sIn.F").WithArguments("field", "F").WithLocation(24, 61),
                // (25,61): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignRefToIn<T>(in S<T> sIn, ref T tRef) { sIn.F = tRef; } // 14
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sIn.F").WithArguments("field", "F").WithLocation(25, 61),
                // (26,77): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignOutToIn<T>(in S<T> sIn, out T tOut) { tOut = default; sIn.F = tOut; } // 15
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sIn.F").WithArguments("field", "F").WithLocation(26, 77),
                // (27,61): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignInToIn<T>(in S<T> sIn, in T tIn)    { sIn.F = tIn; } // 16
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "sIn.F").WithArguments("field", "F").WithLocation(27, 61));
        }
 
        [Fact]
        public void AssignRefTo_RefField()
        {
            var source =
@"ref struct S<T>
{
    public ref T F;
    public S(ref T t) { F = ref t; }
}
 
class Program
{
    static void AssignValueToValue<T>(S<T> s, T tValue) { s.F = ref tValue; } // 1
    static void AssignRefToValue<T>(S<T> s, ref T tRef) { s.F = ref tRef; } // 2
    static void AssignOutToValue<T>(S<T> s, out T tOut) { tOut = default; s.F = ref tOut; } // 3
    static void AssignInToValue<T>(S<T> s, in T tIn)    { s.F = ref tIn; } // 4
 
    static void AssignValueToRef<T>(ref S<T> sRef, T tValue) { sRef.F = ref tValue; } // 5
    static void AssignRefToRef<T>(ref S<T> sRef, ref T tRef) { sRef.F = ref tRef; } // 6
    static void AssignOutToRef<T>(ref S<T> sRef, out T tOut) { tOut = default; sRef.F = ref tOut; } // 7
    static void AssignInToRef<T>(ref S<T> sRef, in T tIn)    { sRef.F = ref tIn; } // 8
 
    static void AssignValueToOut<T>(out S<T> sOut, T tValue) { sOut = default; sOut.F = ref tValue; } // 9
    static void AssignRefToOut<T>(out S<T> sOut, ref T tRef) { sOut = default; sOut.F = ref tRef; }
    static void AssignOutToOut<T>(out S<T> sOut, out T tOut) { sOut = default; tOut = default; sOut.F = ref tOut; } // 10
    static void AssignInToOut<T>(out S<T> sOut, in T tIn)    { sOut = default; sOut.F = ref tIn; } // 11
 
    static void AssignValueToIn<T>(in S<T> sIn, T tValue) { sIn.F = ref tValue; } // 12
    static void AssignRefToIn<T>(in S<T> sIn, ref T tRef) { sIn.F = ref tRef; } // 13
    static void AssignOutToIn<T>(in S<T> sIn, out T tOut) { tOut = default; sIn.F = ref tOut; } // 14
    static void AssignInToIn<T>(in S<T> sIn, in T tIn)    { sIn.F = ref tIn; } // 15
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (9,59): error CS8374: Cannot ref-assign 'tValue' to 'F' because 'tValue' has a narrower escape scope than 'F'.
                //     static void AssignValueToValue<T>(S<T> s, T tValue) { s.F = ref tValue; } // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s.F = ref tValue").WithArguments("F", "tValue").WithLocation(9, 59),
                // (10,59): error CS9079: Cannot ref-assign 'tRef' to 'F' because 'tRef' can only escape the current method through a return statement.
                //     static void AssignRefToValue<T>(S<T> s, ref T tRef) { s.F = ref tRef; } // 2
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "s.F = ref tRef").WithArguments("F", "tRef").WithLocation(10, 59),
                // (11,75): error CS8374: Cannot ref-assign 'tOut' to 'F' because 'tOut' has a narrower escape scope than 'F'.
                //     static void AssignOutToValue<T>(S<T> s, out T tOut) { tOut = default; s.F = ref tOut; } // 3
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s.F = ref tOut").WithArguments("F", "tOut").WithLocation(11, 75),
                // (12,69): error CS8331: Cannot assign to variable 'tIn' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignInToValue<T>(S<T> s, in T tIn)    { s.F = ref tIn; } // 4
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "tIn").WithArguments("variable", "tIn").WithLocation(12, 69),
                // (14,64): error CS8374: Cannot ref-assign 'tValue' to 'F' because 'tValue' has a narrower escape scope than 'F'.
                //     static void AssignValueToRef<T>(ref S<T> sRef, T tValue) { sRef.F = ref tValue; } // 5
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "sRef.F = ref tValue").WithArguments("F", "tValue").WithLocation(14, 64),
                // (15,64): error CS9079: Cannot ref-assign 'tRef' to 'F' because 'tRef' can only escape the current method through a return statement.
                //     static void AssignRefToRef<T>(ref S<T> sRef, ref T tRef) { sRef.F = ref tRef; } // 6
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "sRef.F = ref tRef").WithArguments("F", "tRef").WithLocation(15, 64),
                // (16,80): error CS8374: Cannot ref-assign 'tOut' to 'F' because 'tOut' has a narrower escape scope than 'F'.
                //     static void AssignOutToRef<T>(ref S<T> sRef, out T tOut) { tOut = default; sRef.F = ref tOut; } // 7
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "sRef.F = ref tOut").WithArguments("F", "tOut").WithLocation(16, 80),
                // (17,77): error CS8331: Cannot assign to variable 'tIn' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignInToRef<T>(ref S<T> sRef, in T tIn)    { sRef.F = ref tIn; } // 8
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "tIn").WithArguments("variable", "tIn").WithLocation(17, 77),
                // (19,80): error CS8374: Cannot ref-assign 'tValue' to 'F' because 'tValue' has a narrower escape scope than 'F'.
                //     static void AssignValueToOut<T>(out S<T> sOut, T tValue) { sOut = default; sOut.F = ref tValue; } // 9
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "sOut.F = ref tValue").WithArguments("F", "tValue").WithLocation(19, 80),
                // (21,96): error CS8374: Cannot ref-assign 'tOut' to 'F' because 'tOut' has a narrower escape scope than 'F'.
                //     static void AssignOutToOut<T>(out S<T> sOut, out T tOut) { sOut = default; tOut = default; sOut.F = ref tOut; } // 10
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "sOut.F = ref tOut").WithArguments("F", "tOut").WithLocation(21, 96),
                // (22,93): error CS8331: Cannot assign to variable 'tIn' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignInToOut<T>(out S<T> sOut, in T tIn)    { sOut = default; sOut.F = ref tIn; } // 11
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "tIn").WithArguments("variable", "tIn").WithLocation(22, 93),
                // (24,61): error CS8332: Cannot assign to a member of variable 'sIn' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignValueToIn<T>(in S<T> sIn, T tValue) { sIn.F = ref tValue; } // 12
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "sIn.F").WithArguments("variable", "sIn").WithLocation(24, 61),
                // (25,61): error CS8332: Cannot assign to a member of variable 'sIn' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignRefToIn<T>(in S<T> sIn, ref T tRef) { sIn.F = ref tRef; } // 13
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "sIn.F").WithArguments("variable", "sIn").WithLocation(25, 61),
                // (26,77): error CS8332: Cannot assign to a member of variable 'sIn' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignOutToIn<T>(in S<T> sIn, out T tOut) { tOut = default; sIn.F = ref tOut; } // 14
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "sIn.F").WithArguments("variable", "sIn").WithLocation(26, 77),
                // (27,61): error CS8332: Cannot assign to a member of variable 'sIn' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignInToIn<T>(in S<T> sIn, in T tIn)    { sIn.F = ref tIn; } // 15
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "sIn.F").WithArguments("variable", "sIn").WithLocation(27, 61));
 
            // Valid cases from above.
            source =
@"using System;
 
ref struct S<T>
{
    public ref T F;
    public S(ref T t) { F = ref t; }
}
 
class Program
{
    static void AssignRefToOut<T>(out S<T> sOut, ref T tRef) { sOut = default; sOut.F = ref tRef; }
 
    static void Main()
    {
        int x, y;
        scoped S<int> s;
 
        x = 5; y = 6;
        s = new S<int>(ref x);
        AssignRefToOut(out s, ref y);
        Console.WriteLine(s.F);
    }
}";
            comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput(
@"6"));
 
            verifier.VerifyILMultiple(
                "Program.AssignRefToOut<T>",
@"{
  // Code size       15 (0xf)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  initobj    ""S<T>""
  IL_0007:  ldarg.0
  IL_0008:  ldarg.1
  IL_0009:  stfld      ""ref T S<T>.F""
  IL_000e:  ret
}");
        }
 
        [Fact]
        public void AssignRefTo_RefReadonlyField()
        {
            var source =
@"ref struct S<T>
{
    public ref readonly T F;
    public S(ref T t) { F = ref t; }
}
 
class Program
{
    static void AssignValueToValue<T>(S<T> s, T tValue) { s.F = ref tValue; } // 1
    static void AssignRefToValue<T>(S<T> s, ref T tRef) { s.F = ref tRef; }
    static void AssignOutToValue<T>(S<T> s, out T tOut) { tOut = default; s.F = ref tOut; } // 2
    static void AssignInToValue<T>(S<T> s, in T tIn)    { s.F = ref tIn; }
 
    static void AssignValueToRef<T>(ref S<T> sRef, T tValue) { sRef.F = ref tValue; } // 3
    static void AssignRefToRef<T>(ref S<T> sRef, ref T tRef) { sRef.F = ref tRef; }
    static void AssignOutToRef<T>(ref S<T> sRef, out T tOut) { tOut = default; sRef.F = ref tOut; } // 4
    static void AssignInToRef<T>(ref S<T> sRef, in T tIn)    { sRef.F = ref tIn; }
 
    static void AssignValueToOut<T>(out S<T> sOut, T tValue) { sOut = default; sOut.F = ref tValue; } // 5
    static void AssignRefToOut<T>(out S<T> sOut, ref T tRef) { sOut = default; sOut.F = ref tRef; }
    static void AssignOutToOut<T>(out S<T> sOut, out T tOut) { sOut = default; tOut = default; sOut.F = ref tOut; } // 6
    static void AssignInToOut<T>(out S<T> sOut, in T tIn)    { sOut = default; sOut.F = ref tIn; }
 
    static void AssignValueToIn<T>(in S<T> sIn, T tValue) { sIn.F = ref tValue; } // 7
    static void AssignRefToIn<T>(in S<T> sIn, ref T tRef) { sIn.F = ref tRef; } // 8
    static void AssignOutToIn<T>(in S<T> sIn, out T tOut) { tOut = default; sIn.F = ref tOut; } // 9
    static void AssignInToIn<T>(in S<T> sIn, in T tIn)    { sIn.F = ref tIn; } // 10
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (9,59): error CS8374: Cannot ref-assign 'tValue' to 'F' because 'tValue' has a narrower escape scope than 'F'.
                //     static void AssignValueToValue<T>(S<T> s, T tValue) { s.F = ref tValue; } // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s.F = ref tValue").WithArguments("F", "tValue").WithLocation(9, 59),
                // (10,59): error CS9079: Cannot ref-assign 'tRef' to 'F' because 'tRef' can only escape the current method through a return statement.
                //     static void AssignRefToValue<T>(S<T> s, ref T tRef) { s.F = ref tRef; }
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "s.F = ref tRef").WithArguments("F", "tRef").WithLocation(10, 59),
                // (11,75): error CS8374: Cannot ref-assign 'tOut' to 'F' because 'tOut' has a narrower escape scope than 'F'.
                //     static void AssignOutToValue<T>(S<T> s, out T tOut) { tOut = default; s.F = ref tOut; } // 2
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s.F = ref tOut").WithArguments("F", "tOut").WithLocation(11, 75),
                // (12,59): error CS9079: Cannot ref-assign 'tIn' to 'F' because 'tIn' can only escape the current method through a return statement.
                //     static void AssignInToValue<T>(S<T> s, in T tIn)    { s.F = ref tIn; }
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "s.F = ref tIn").WithArguments("F", "tIn").WithLocation(12, 59),
                // (14,64): error CS8374: Cannot ref-assign 'tValue' to 'F' because 'tValue' has a narrower escape scope than 'F'.
                //     static void AssignValueToRef<T>(ref S<T> sRef, T tValue) { sRef.F = ref tValue; } // 3
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "sRef.F = ref tValue").WithArguments("F", "tValue").WithLocation(14, 64),
                // (15,64): error CS9079: Cannot ref-assign 'tRef' to 'F' because 'tRef' can only escape the current method through a return statement.
                //     static void AssignRefToRef<T>(ref S<T> sRef, ref T tRef) { sRef.F = ref tRef; }
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "sRef.F = ref tRef").WithArguments("F", "tRef").WithLocation(15, 64),
                // (16,80): error CS8374: Cannot ref-assign 'tOut' to 'F' because 'tOut' has a narrower escape scope than 'F'.
                //     static void AssignOutToRef<T>(ref S<T> sRef, out T tOut) { tOut = default; sRef.F = ref tOut; } // 4
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "sRef.F = ref tOut").WithArguments("F", "tOut").WithLocation(16, 80),
                // (17,64): error CS9079: Cannot ref-assign 'tIn' to 'F' because 'tIn' can only escape the current method through a return statement.
                //     static void AssignInToRef<T>(ref S<T> sRef, in T tIn)    { sRef.F = ref tIn; }
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "sRef.F = ref tIn").WithArguments("F", "tIn").WithLocation(17, 64),
                // (19,80): error CS8374: Cannot ref-assign 'tValue' to 'F' because 'tValue' has a narrower escape scope than 'F'.
                //     static void AssignValueToOut<T>(out S<T> sOut, T tValue) { sOut = default; sOut.F = ref tValue; } // 5
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "sOut.F = ref tValue").WithArguments("F", "tValue").WithLocation(19, 80),
                // (21,96): error CS8374: Cannot ref-assign 'tOut' to 'F' because 'tOut' has a narrower escape scope than 'F'.
                //     static void AssignOutToOut<T>(out S<T> sOut, out T tOut) { sOut = default; tOut = default; sOut.F = ref tOut; } // 6
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "sOut.F = ref tOut").WithArguments("F", "tOut").WithLocation(21, 96),
                // (24,61): error CS8332: Cannot assign to a member of variable 'sIn' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignValueToIn<T>(in S<T> sIn, T tValue) { sIn.F = ref tValue; } // 7
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "sIn.F").WithArguments("variable", "sIn").WithLocation(24, 61),
                // (25,61): error CS8332: Cannot assign to a member of variable 'sIn' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignRefToIn<T>(in S<T> sIn, ref T tRef) { sIn.F = ref tRef; } // 8
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "sIn.F").WithArguments("variable", "sIn").WithLocation(25, 61),
                // (26,77): error CS8332: Cannot assign to a member of variable 'sIn' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignOutToIn<T>(in S<T> sIn, out T tOut) { tOut = default; sIn.F = ref tOut; } // 9
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "sIn.F").WithArguments("variable", "sIn").WithLocation(26, 77),
                // (27,61): error CS8332: Cannot assign to a member of variable 'sIn' or use it as the right hand side of a ref assignment because it is a readonly variable
                //     static void AssignInToIn<T>(in S<T> sIn, in T tIn)    { sIn.F = ref tIn; } // 10
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "sIn.F").WithArguments("variable", "sIn").WithLocation(27, 61));
 
            // Valid cases from above.
            source =
@"using System;
 
ref struct S<T>
{
    public ref readonly T F;
    public S(ref T t) { F = ref t; }
}
 
class Program
{
    static void AssignRefToOut<T>(out S<T> sOut, ref T tRef) { sOut = default; sOut.F = ref tRef; }
    static void AssignInToOut<T>(out S<T> sOut, in T tIn)    { sOut = default; sOut.F = ref tIn; }
 
    static void Main()
    {
        int x, y;
        scoped S<int> s;
 
        x = 5; y = 6;
        s = new S<int>(ref x);
        AssignRefToOut(out s, ref y);
        Console.WriteLine(s.F);
        x = 5; y = 6;
        s = new S<int>(ref x);
        AssignInToOut(out s, y);
        Console.WriteLine(s.F);
    }
}";
            comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput(
@"6
6"));
            verifier.VerifyILMultiple(
                "Program.AssignRefToOut<T>",
@"{
  // Code size       15 (0xf)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  initobj    ""S<T>""
  IL_0007:  ldarg.0
  IL_0008:  ldarg.1
  IL_0009:  stfld      ""ref readonly T S<T>.F""
  IL_000e:  ret
}",
                "Program.AssignInToOut<T>",
@"{
  // Code size       15 (0xf)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  initobj    ""S<T>""
  IL_0007:  ldarg.0
  IL_0008:  ldarg.1
  IL_0009:  stfld      ""ref readonly T S<T>.F""
  IL_000e:  ret
}");
        }
 
        [Fact]
        public void AssignRefTo_ReadonlyRefField()
        {
            var source =
@"ref struct S<T>
{
    public readonly ref T F;
    public S(ref T t) { F = ref t; }
}
 
class Program
{
    static void AssignValueToValue<T>(S<T> s, T tValue) { s.F = ref tValue; } // 1
    static void AssignRefToValue<T>(S<T> s, ref T tRef) { s.F = ref tRef; } // 2
    static void AssignOutToValue<T>(S<T> s, out T tOut) { tOut = default; s.F = ref tOut; } // 3
    static void AssignInToValue<T>(S<T> s, in T tIn)    { s.F = ref tIn; } // 4
 
    static void AssignValueToRef<T>(ref S<T> sRef, T tValue) { sRef.F = ref tValue; } // 5
    static void AssignRefToRef<T>(ref S<T> sRef, ref T tRef) { sRef.F = ref tRef; } // 6
    static void AssignOutToRef<T>(ref S<T> sRef, out T tOut) { tOut = default; sRef.F = ref tOut; } // 7
    static void AssignInToRef<T>(ref S<T> sRef, in T tIn)    { sRef.F = ref tIn; } // 8
 
    static void AssignValueToOut<T>(out S<T> sOut, T tValue) { sOut = default; sOut.F = ref tValue; } // 9
    static void AssignRefToOut<T>(out S<T> sOut, ref T tRef) { sOut = default; sOut.F = ref tRef; } // 10
    static void AssignOutToOut<T>(out S<T> sOut, out T tOut) { sOut = default; tOut = default; sOut.F = ref tOut; } // 11
    static void AssignInToOut<T>(out S<T> sOut, in T tIn)    { sOut = default; sOut.F = ref tIn; } // 12
 
    static void AssignValueToIn<T>(in S<T> sIn, T tValue) { sIn.F = ref tValue; } // 13
    static void AssignRefToIn<T>(in S<T> sIn, ref T tRef) { sIn.F = ref tRef; } // 14
    static void AssignOutToIn<T>(in S<T> sIn, out T tOut) { tOut = default; sIn.F = ref tOut; } // 15
    static void AssignInToIn<T>(in S<T> sIn, in T tIn)    { sIn.F = ref tIn; } // 16
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (9,59): 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)
                //     static void AssignValueToValue<T>(S<T> s, T tValue) { s.F = ref tValue; } // 1
                Diagnostic(ErrorCode.ERR_AssgReadonly, "s.F").WithLocation(9, 59),
                // (10,59): 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)
                //     static void AssignRefToValue<T>(S<T> s, ref T tRef) { s.F = ref tRef; } // 2
                Diagnostic(ErrorCode.ERR_AssgReadonly, "s.F").WithLocation(10, 59),
                // (11,75): 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)
                //     static void AssignOutToValue<T>(S<T> s, out T tOut) { tOut = default; s.F = ref tOut; } // 3
                Diagnostic(ErrorCode.ERR_AssgReadonly, "s.F").WithLocation(11, 75),
                // (12,59): 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)
                //     static void AssignInToValue<T>(S<T> s, in T tIn)    { s.F = ref tIn; } // 4
                Diagnostic(ErrorCode.ERR_AssgReadonly, "s.F").WithLocation(12, 59),
                // (14,64): 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)
                //     static void AssignValueToRef<T>(ref S<T> sRef, T tValue) { sRef.F = ref tValue; } // 5
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sRef.F").WithLocation(14, 64),
                // (15,64): 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)
                //     static void AssignRefToRef<T>(ref S<T> sRef, ref T tRef) { sRef.F = ref tRef; } // 6
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sRef.F").WithLocation(15, 64),
                // (16,80): 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)
                //     static void AssignOutToRef<T>(ref S<T> sRef, out T tOut) { tOut = default; sRef.F = ref tOut; } // 7
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sRef.F").WithLocation(16, 80),
                // (17,64): 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)
                //     static void AssignInToRef<T>(ref S<T> sRef, in T tIn)    { sRef.F = ref tIn; } // 8
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sRef.F").WithLocation(17, 64),
                // (19,80): 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)
                //     static void AssignValueToOut<T>(out S<T> sOut, T tValue) { sOut = default; sOut.F = ref tValue; } // 9
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sOut.F").WithLocation(19, 80),
                // (20,80): 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)
                //     static void AssignRefToOut<T>(out S<T> sOut, ref T tRef) { sOut = default; sOut.F = ref tRef; } // 10
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sOut.F").WithLocation(20, 80),
                // (21,96): 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)
                //     static void AssignOutToOut<T>(out S<T> sOut, out T tOut) { sOut = default; tOut = default; sOut.F = ref tOut; } // 11
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sOut.F").WithLocation(21, 96),
                // (22,80): 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)
                //     static void AssignInToOut<T>(out S<T> sOut, in T tIn)    { sOut = default; sOut.F = ref tIn; } // 12
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sOut.F").WithLocation(22, 80),
                // (24,61): 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)
                //     static void AssignValueToIn<T>(in S<T> sIn, T tValue) { sIn.F = ref tValue; } // 13
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sIn.F").WithLocation(24, 61),
                // (25,61): 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)
                //     static void AssignRefToIn<T>(in S<T> sIn, ref T tRef) { sIn.F = ref tRef; } // 14
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sIn.F").WithLocation(25, 61),
                // (26,77): 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)
                //     static void AssignOutToIn<T>(in S<T> sIn, out T tOut) { tOut = default; sIn.F = ref tOut; } // 15
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sIn.F").WithLocation(26, 77),
                // (27,61): 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)
                //     static void AssignInToIn<T>(in S<T> sIn, in T tIn)    { sIn.F = ref tIn; } // 16
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sIn.F").WithLocation(27, 61));
        }
 
        [Fact]
        public void AssignRefTo_ReadonlyRefReadonlyField()
        {
            var source =
@"ref struct S<T>
{
    public readonly ref readonly T F;
    public S(ref T t) { F = ref t; }
}
 
class Program
{
    static void AssignValueToValue<T>(S<T> s, T tValue) { s.F = ref tValue; } // 1
    static void AssignRefToValue<T>(S<T> s, ref T tRef) { s.F = ref tRef; } // 2
    static void AssignOutToValue<T>(S<T> s, out T tOut) { tOut = default; s.F = ref tOut; } // 3
    static void AssignInToValue<T>(S<T> s, in T tIn)    { s.F = ref tIn; } // 4
 
    static void AssignValueToRef<T>(ref S<T> sRef, T tValue) { sRef.F = ref tValue; } // 5
    static void AssignRefToRef<T>(ref S<T> sRef, ref T tRef) { sRef.F = ref tRef; } // 6
    static void AssignOutToRef<T>(ref S<T> sRef, out T tOut) { tOut = default; sRef.F = ref tOut; } // 7
    static void AssignInToRef<T>(ref S<T> sRef, in T tIn)    { sRef.F = ref tIn; } // 8
 
    static void AssignValueToOut<T>(out S<T> sOut, T tValue) { sOut = default; sOut.F = ref tValue; } // 9
    static void AssignRefToOut<T>(out S<T> sOut, ref T tRef) { sOut = default; sOut.F = ref tRef; } // 10
    static void AssignOutToOut<T>(out S<T> sOut, out T tOut) { sOut = default; tOut = default; sOut.F = ref tOut; } // 11
    static void AssignInToOut<T>(out S<T> sOut, in T tIn)    { sOut = default; sOut.F = ref tIn; } // 12
 
    static void AssignValueToIn<T>(in S<T> sIn, T tValue) { sIn.F = ref tValue; } // 13
    static void AssignRefToIn<T>(in S<T> sIn, ref T tRef) { sIn.F = ref tRef; } // 14
    static void AssignOutToIn<T>(in S<T> sIn, out T tOut) { tOut = default; sIn.F = ref tOut; } // 15
    static void AssignInToIn<T>(in S<T> sIn, in T tIn)    { sIn.F = ref tIn; } // 16
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (9,59): 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)
                //     static void AssignValueToValue<T>(S<T> s, T tValue) { s.F = ref tValue; } // 1
                Diagnostic(ErrorCode.ERR_AssgReadonly, "s.F").WithLocation(9, 59),
                // (10,59): 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)
                //     static void AssignRefToValue<T>(S<T> s, ref T tRef) { s.F = ref tRef; } // 2
                Diagnostic(ErrorCode.ERR_AssgReadonly, "s.F").WithLocation(10, 59),
                // (11,75): 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)
                //     static void AssignOutToValue<T>(S<T> s, out T tOut) { tOut = default; s.F = ref tOut; } // 3
                Diagnostic(ErrorCode.ERR_AssgReadonly, "s.F").WithLocation(11, 75),
                // (12,59): 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)
                //     static void AssignInToValue<T>(S<T> s, in T tIn)    { s.F = ref tIn; } // 4
                Diagnostic(ErrorCode.ERR_AssgReadonly, "s.F").WithLocation(12, 59),
                // (14,64): 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)
                //     static void AssignValueToRef<T>(ref S<T> sRef, T tValue) { sRef.F = ref tValue; } // 5
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sRef.F").WithLocation(14, 64),
                // (15,64): 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)
                //     static void AssignRefToRef<T>(ref S<T> sRef, ref T tRef) { sRef.F = ref tRef; } // 6
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sRef.F").WithLocation(15, 64),
                // (16,80): 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)
                //     static void AssignOutToRef<T>(ref S<T> sRef, out T tOut) { tOut = default; sRef.F = ref tOut; } // 7
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sRef.F").WithLocation(16, 80),
                // (17,64): 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)
                //     static void AssignInToRef<T>(ref S<T> sRef, in T tIn)    { sRef.F = ref tIn; } // 8
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sRef.F").WithLocation(17, 64),
                // (19,80): 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)
                //     static void AssignValueToOut<T>(out S<T> sOut, T tValue) { sOut = default; sOut.F = ref tValue; } // 9
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sOut.F").WithLocation(19, 80),
                // (20,80): 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)
                //     static void AssignRefToOut<T>(out S<T> sOut, ref T tRef) { sOut = default; sOut.F = ref tRef; } // 10
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sOut.F").WithLocation(20, 80),
                // (21,96): 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)
                //     static void AssignOutToOut<T>(out S<T> sOut, out T tOut) { sOut = default; tOut = default; sOut.F = ref tOut; } // 11
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sOut.F").WithLocation(21, 96),
                // (22,80): 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)
                //     static void AssignInToOut<T>(out S<T> sOut, in T tIn)    { sOut = default; sOut.F = ref tIn; } // 12
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sOut.F").WithLocation(22, 80),
                // (24,61): 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)
                //     static void AssignValueToIn<T>(in S<T> sIn, T tValue) { sIn.F = ref tValue; } // 13
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sIn.F").WithLocation(24, 61),
                // (25,61): 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)
                //     static void AssignRefToIn<T>(in S<T> sIn, ref T tRef) { sIn.F = ref tRef; } // 14
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sIn.F").WithLocation(25, 61),
                // (26,77): 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)
                //     static void AssignOutToIn<T>(in S<T> sIn, out T tOut) { tOut = default; sIn.F = ref tOut; } // 15
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sIn.F").WithLocation(26, 77),
                // (27,61): 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)
                //     static void AssignInToIn<T>(in S<T> sIn, in T tIn)    { sIn.F = ref tIn; } // 16
                Diagnostic(ErrorCode.ERR_AssgReadonly, "sIn.F").WithLocation(27, 61));
        }
 
        [Fact]
        public void AssignOutParameterFrom_RefField()
        {
            var source =
@"#pragma warning disable 649
ref struct S<T>
{
    public ref T Ref;
    public ref readonly T RefReadonly;
    public readonly ref T ReadonlyRef;
    public readonly ref readonly T ReadonlyRefReadonly;
}
 
class Program
{
    static void FromValueRef<T>(S<T> s, out T t)                 { t = s.Ref; }
    static void FromValueRefReadonly<T>(S<T> s, out T t)         { t = s.RefReadonly; }
    static void FromValueReadonlyRef<T>(S<T> s, out T t)         { t = s.ReadonlyRef; }
    static void FromValueReadonlyRefReadonly<T>(S<T> s, out T t) { t = s.ReadonlyRefReadonly; }
 
    static void FromRefRef<T>(ref S<T> s, out T t)                 { t = s.Ref; }
    static void FromRefRefReadonly<T>(ref S<T> s, out T t)         { t = s.RefReadonly; }
    static void FromRefReadonlyRef<T>(ref S<T> s, out T t)         { t = s.ReadonlyRef; }
    static void FromRefReadonlyRefReadonly<T>(ref S<T> s, out T t) { t = s.ReadonlyRefReadonly; }
 
    static void FromOutRef<T>(out S<T> s, out T t)                 { s = default; t = s.Ref; }
    static void FromOutRefReadonly<T>(out S<T> s, out T t)         { s = default; t = s.RefReadonly; }
    static void FromOutReadonlyRef<T>(out S<T> s, out T t)         { s = default; t = s.ReadonlyRef; }
    static void FromOutReadonlyRefReadonly<T>(out S<T> s, out T t) { s = default; t = s.ReadonlyRefReadonly; }
 
    static void FromInRef<T>(in S<T> s, out T t)                 { t = s.Ref; }
    static void FromInRefReadonly<T>(in S<T> s, out T t)         { t = s.RefReadonly; }
    static void FromInReadonlyRef<T>(in S<T> s, out T t)         { t = s.ReadonlyRef; }
    static void FromInReadonlyRefReadonly<T>(in S<T> s, out T t) { t = s.ReadonlyRefReadonly; }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void AssignRefLocalFrom_RefField()
        {
            var source =
@"ref struct S<T>
{
    public ref T Ref;
    public ref readonly T RefReadonly;
    public readonly ref T ReadonlyRef;
    public readonly ref readonly T ReadonlyRefReadonly;
}
 
class Program
{
    static void FromValueRef<T>(S<T> s)                 { ref T t = ref s.Ref; }
    static void FromValueRefReadonly<T>(S<T> s)         { ref T t = ref s.RefReadonly; } // 1
    static void FromValueReadonlyRef<T>(S<T> s)         { ref T t = ref s.ReadonlyRef; }
    static void FromValueReadonlyRefReadonly<T>(S<T> s) { ref T t = ref s.ReadonlyRefReadonly; } // 2
 
    static void FromRefRef<T>(ref S<T> s)                 { ref T t = ref s.Ref; }
    static void FromRefRefReadonly<T>(ref S<T> s)         { ref T t = ref s.RefReadonly; } // 3
    static void FromRefReadonlyRef<T>(ref S<T> s)         { ref T t = ref s.ReadonlyRef; }
    static void FromRefReadonlyRefReadonly<T>(ref S<T> s) { ref T t = ref s.ReadonlyRefReadonly; } // 4
 
    static void FromOutRef<T>(out S<T> s)                 { s = default; ref T t = ref s.Ref; }
    static void FromOutRefReadonly<T>(out S<T> s)         { s = default; ref T t = ref s.RefReadonly; } // 5
    static void FromOutReadonlyRef<T>(out S<T> s)         { s = default; ref T t = ref s.ReadonlyRef; }
    static void FromOutReadonlyRefReadonly<T>(out S<T> s) { s = default; ref T t = ref s.ReadonlyRefReadonly; } // 6
 
    static void FromInRef<T>(in S<T> s)                 { ref T t = ref s.Ref; }
    static void FromInRefReadonly<T>(in S<T> s)         { ref T t = ref s.RefReadonly; } // 7
    static void FromInReadonlyRef<T>(in S<T> s)         { ref T t = ref s.ReadonlyRef; }
    static void FromInReadonlyRefReadonly<T>(in S<T> s) { ref T t = ref s.ReadonlyRefReadonly; } // 8
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (12,73): error CS8329: Cannot use field 'RefReadonly' as a ref or out value because it is a readonly variable
                //     static void FromValueRefReadonly<T>(S<T> s)         { ref T t = ref s.RefReadonly; } // 1
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.RefReadonly").WithArguments("field", "RefReadonly").WithLocation(12, 73),
                // (14,73): error CS8329: Cannot use field 'ReadonlyRefReadonly' as a ref or out value because it is a readonly variable
                //     static void FromValueReadonlyRefReadonly<T>(S<T> s) { ref T t = ref s.ReadonlyRefReadonly; } // 2
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.ReadonlyRefReadonly").WithArguments("field", "ReadonlyRefReadonly").WithLocation(14, 73),
                // (17,75): error CS8329: Cannot use field 'RefReadonly' as a ref or out value because it is a readonly variable
                //     static void FromRefRefReadonly<T>(ref S<T> s)         { ref T t = ref s.RefReadonly; } // 3
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.RefReadonly").WithArguments("field", "RefReadonly").WithLocation(17, 75),
                // (19,75): error CS8329: Cannot use field 'ReadonlyRefReadonly' as a ref or out value because it is a readonly variable
                //     static void FromRefReadonlyRefReadonly<T>(ref S<T> s) { ref T t = ref s.ReadonlyRefReadonly; } // 4
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.ReadonlyRefReadonly").WithArguments("field", "ReadonlyRefReadonly").WithLocation(19, 75),
                // (22,88): error CS8329: Cannot use field 'RefReadonly' as a ref or out value because it is a readonly variable
                //     static void FromOutRefReadonly<T>(out S<T> s)         { s = default; ref T t = ref s.RefReadonly; } // 5
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.RefReadonly").WithArguments("field", "RefReadonly").WithLocation(22, 88),
                // (24,88): error CS8329: Cannot use field 'ReadonlyRefReadonly' as a ref or out value because it is a readonly variable
                //     static void FromOutReadonlyRefReadonly<T>(out S<T> s) { s = default; ref T t = ref s.ReadonlyRefReadonly; } // 6
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.ReadonlyRefReadonly").WithArguments("field", "ReadonlyRefReadonly").WithLocation(24, 88),
                // (27,73): error CS8329: Cannot use field 'RefReadonly' as a ref or out value because it is a readonly variable
                //     static void FromInRefReadonly<T>(in S<T> s)         { ref T t = ref s.RefReadonly; } // 7
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.RefReadonly").WithArguments("field", "RefReadonly").WithLocation(27, 73),
                // (29,73): error CS8329: Cannot use field 'ReadonlyRefReadonly' as a ref or out value because it is a readonly variable
                //     static void FromInReadonlyRefReadonly<T>(in S<T> s) { ref T t = ref s.ReadonlyRefReadonly; } // 8
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.ReadonlyRefReadonly").WithArguments("field", "ReadonlyRefReadonly").WithLocation(29, 73));
        }
 
        [Fact]
        public void AssignRefReadonlyLocalFrom_RefField()
        {
            var source =
@"ref struct S<T>
{
    public ref T Ref;
    public ref readonly T RefReadonly;
    public readonly ref T ReadonlyRef;
    public readonly ref readonly T ReadonlyRefReadonly;
}
 
class Program
{
    static void FromValueRef<T>(S<T> s)                 { ref readonly T t = ref s.Ref; }
    static void FromValueRefReadonly<T>(S<T> s)         { ref readonly T t = ref s.RefReadonly; }
    static void FromValueReadonlyRef<T>(S<T> s)         { ref readonly T t = ref s.ReadonlyRef; }
    static void FromValueReadonlyRefReadonly<T>(S<T> s) { ref readonly T t = ref s.ReadonlyRefReadonly; }
 
    static void FromRefRef<T>(ref S<T> s)                 { ref readonly T t = ref s.Ref; }
    static void FromRefRefReadonly<T>(ref S<T> s)         { ref readonly T t = ref s.RefReadonly; }
    static void FromRefReadonlyRef<T>(ref S<T> s)         { ref readonly T t = ref s.ReadonlyRef; }
    static void FromRefReadonlyRefReadonly<T>(ref S<T> s) { ref readonly T t = ref s.ReadonlyRefReadonly; }
 
    static void FromOutRef<T>(out S<T> s)                 { s = default; ref readonly T t = ref s.Ref; }
    static void FromOutRefReadonly<T>(out S<T> s)         { s = default; ref readonly T t = ref s.RefReadonly; }
    static void FromOutReadonlyRef<T>(out S<T> s)         { s = default; ref readonly T t = ref s.ReadonlyRef; }
    static void FromOutReadonlyRefReadonly<T>(out S<T> s) { s = default; ref readonly T t = ref s.ReadonlyRefReadonly; }
 
    static void FromInRef<T>(in S<T> s)                 { ref readonly T t = ref s.Ref; }
    static void FromInRefReadonly<T>(in S<T> s)         { ref readonly T t = ref s.RefReadonly; }
    static void FromInReadonlyRef<T>(in S<T> s)         { ref readonly T t = ref s.ReadonlyRef; }
    static void FromInReadonlyRefReadonly<T>(in S<T> s) { ref readonly T t = ref s.ReadonlyRefReadonly; }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void RefReturn()
        {
            var source =
@"class Program
{
    static ref T F1<T>(T t) => ref t; // 1
    static ref T F2<T>(ref T t) => ref t;
    static ref T F3<T>(out T t) { t = default; return ref t; } // 2
    static ref T F4<T>(in T t) => ref t; // 3
    static ref readonly T F5<T>(T t) => ref t; // 4
    static ref readonly T F6<T>(ref T t) => ref t;
    static ref readonly T F7<T>(out T t) { t = default; return ref t; } // 5
    static ref readonly T F8<T>(in T t) => ref t;
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (3,36): error CS8166: Cannot return a parameter by reference 't' because it is not a ref parameter
                //     static ref T F1<T>(T t) => ref t; // 1
                Diagnostic(ErrorCode.ERR_RefReturnParameter, "t").WithArguments("t").WithLocation(3, 36),
                // (5,59): error CS9075: Cannot return a parameter by reference 't' because it is scoped to the current method
                //     static ref T F3<T>(out T t) { t = default; return ref t; } // 2
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "t").WithArguments("t").WithLocation(5, 59),
                // (6,39): error CS8333: Cannot return variable 't' by writable reference because it is a readonly variable
                //     static ref T F4<T>(in T t) => ref t; // 3
                Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "t").WithArguments("variable", "t").WithLocation(6, 39),
                // (7,45): error CS8166: Cannot return a parameter by reference 't' because it is not a ref parameter
                //     static ref readonly T F5<T>(T t) => ref t; // 4
                Diagnostic(ErrorCode.ERR_RefReturnParameter, "t").WithArguments("t").WithLocation(7, 45),
                // (9,68): error CS9075: Cannot return a parameter by reference 't' because it is scoped to the current method
                //     static ref readonly T F7<T>(out T t) { t = default; return ref t; } // 5
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "t").WithArguments("t").WithLocation(9, 68));
        }
 
        [Fact]
        public void RefReturn_Ref()
        {
            var source =
@"ref struct S<T>
{
    public ref T F;
    public ref T F1() => ref F;
    public ref readonly T F2() => ref F;
}
class Program
{
    static ref T F3<T>(S<T> s) => ref s.F;
    static ref T F4<T>(ref S<T> s) => ref s.F;
    static ref T F5<T>(out S<T> s) { s = default; return ref s.F; }
    static ref T F6<T>(in S<T> s) => ref s.F;
    static ref readonly T F7<T>(S<T> s) => ref s.F;
    static ref readonly T F8<T>(ref S<T> s) => ref s.F;
    static ref readonly T F9<T>(out S<T> s) { s = default; return ref s.F; }
    static ref readonly T F10<T>(in S<T> s) => ref s.F;
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void RefReturn_RefReadonly()
        {
            var source =
@"ref struct S<T>
{
    public ref readonly T F;
    public ref T F1() => ref F;
    public ref readonly T F2() => ref F;
}
class Program
{
    static ref T F3<T>(S<T> s) => ref s.F;
    static ref T F4<T>(ref S<T> s) => ref s.F;
    static ref T F5<T>(out S<T> s) { s = default; return ref s.F; }
    static ref T F6<T>(in S<T> s) => ref s.F;
    static ref readonly T F7<T>(S<T> s) => ref s.F;
    static ref readonly T F8<T>(ref S<T> s) => ref s.F;
    static ref readonly T F9<T>(out S<T> s) { s = default; return ref s.F; }
    static ref readonly T F10<T>(in S<T> s) => ref s.F;
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (4,30): error CS8333: Cannot return field 'F' by writable reference because it is a readonly variable
                //     public ref T F1() => ref F;
                Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "F").WithArguments("field", "F").WithLocation(4, 30),
                // (9,39): error CS8333: Cannot return field 'F' by writable reference because it is a readonly variable
                //     static ref T F3<T>(S<T> s) => ref s.F;
                Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(9, 39),
                // (10,43): error CS8333: Cannot return field 'F' by writable reference because it is a readonly variable
                //     static ref T F4<T>(ref S<T> s) => ref s.F;
                Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(10, 43),
                // (11,62): error CS8333: Cannot return field 'F' by writable reference because it is a readonly variable
                //     static ref T F5<T>(out S<T> s) { s = default; return ref s.F; }
                Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(11, 62),
                // (12,42): error CS8333: Cannot return field 'F' by writable reference because it is a readonly variable
                //     static ref T F6<T>(in S<T> s) => ref s.F;
                Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(12, 42));
        }
 
        [Fact]
        public void RefReturn_ReadonlyRef()
        {
            var source =
@"ref struct S<T>
{
    public readonly ref T F;
    public ref T F1() => ref F;
    public ref readonly T F2() => ref F;
}
class Program
{
    static ref T F3<T>(S<T> s) => ref s.F;
    static ref T F4<T>(ref S<T> s) => ref s.F;
    static ref T F5<T>(out S<T> s) { s = default; return ref s.F; }
    static ref T F6<T>(in S<T> s) => ref s.F;
    static ref readonly T F7<T>(S<T> s) => ref s.F;
    static ref readonly T F8<T>(ref S<T> s) => ref s.F;
    static ref readonly T F9<T>(out S<T> s) { s = default; return ref s.F; }
    static ref readonly T F10<T>(in S<T> s) => ref s.F;
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void RefReturn_ReadonlyRefReadonly()
        {
            var source =
@"ref struct S<T>
{
    public readonly ref readonly T F;
    public ref T F1() => ref F;
    public ref readonly T F2() => ref F;
}
class Program
{
    static ref T F3<T>(S<T> s) => ref s.F;
    static ref T F4<T>(ref S<T> s) => ref s.F;
    static ref T F5<T>(out S<T> s) { s = default; return ref s.F; }
    static ref T F6<T>(in S<T> s) => ref s.F;
    static ref readonly T F7<T>(S<T> s) => ref s.F;
    static ref readonly T F8<T>(ref S<T> s) => ref s.F;
    static ref readonly T F9<T>(out S<T> s) { s = default; return ref s.F; }
    static ref readonly T F10<T>(in S<T> s) => ref s.F;
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (4,30): error CS8333: Cannot return field 'F' by writable reference because it is a readonly variable
                //     public ref T F1() => ref F;
                Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "F").WithArguments("field", "F").WithLocation(4, 30),
                // (9,39): error CS8333: Cannot return field 'F' by writable reference because it is a readonly variable
                //     static ref T F3<T>(S<T> s) => ref s.F;
                Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(9, 39),
                // (10,43): error CS8333: Cannot return field 'F' by writable reference because it is a readonly variable
                //     static ref T F4<T>(ref S<T> s) => ref s.F;
                Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(10, 43),
                // (11,62): error CS8333: Cannot return field 'F' by writable reference because it is a readonly variable
                //     static ref T F5<T>(out S<T> s) { s = default; return ref s.F; }
                Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(11, 62),
                // (12,42): error CS8333: Cannot return field 'F' by writable reference because it is a readonly variable
                //     static ref T F6<T>(in S<T> s) => ref s.F;
                Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(12, 42));
        }
 
        [Fact]
        public void RefParameter_InstanceMethod_Ref()
        {
            var source =
@"ref struct S<T>
{
    public ref T F;
    public S(ref T t)
    {
        F = ref t;
        M1(F);
        M2(ref F);
        M3(out F);
        M4(F);
        M4(in F);
    }
    object P
    {
        init
        {
            M1(F);
            M2(ref F);
            M3(out F);
            M4(F);
            M4(in F);
        }
    }
    void M()
    {
        M1(F);
        M2(ref F);
        M3(out F);
        M4(F);
        M4(in F);
    }
    static void M1(T t) { }
    static void M2(ref T t) { }
    static void M3(out T t) { t = default; }
    static void M4(in T t) { }
}";
            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void RefParameter_InstanceMethod_RefReadonly()
        {
            var source =
@"ref struct S<T>
{
    public ref readonly T F;
    public S(ref T t)
    {
        F = ref t;
        M1(F);
        M2(ref F); // 1
        M3(out F); // 2
        M4(F);
        M4(in F);
    }
    object P
    {
        init
        {
            M1(F);
            M2(ref F); // 3
            M3(out F); // 4
            M4(F);
            M4(in F);
        }
    }
    void M()
    {
        M1(F);
        M2(ref F); // 5
        M3(out F); // 6
        M4(F);
        M4(in F);
    }
    static void M1(T t) { }
    static void M2(ref T t) { }
    static void M3(out T t) { t = default; }
    static void M4(in T t) { }
}";
            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (8,16): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //         M2(ref F); // 1
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "F").WithArguments("field", "F").WithLocation(8, 16),
                // (9,16): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //         M3(out F); // 2
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "F").WithArguments("field", "F").WithLocation(9, 16),
                // (18,20): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //             M2(ref F); // 3
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "F").WithArguments("field", "F").WithLocation(18, 20),
                // (19,20): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //             M3(out F); // 4
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "F").WithArguments("field", "F").WithLocation(19, 20),
                // (27,16): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //         M2(ref F); // 5
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "F").WithArguments("field", "F").WithLocation(27, 16),
                // (28,16): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //         M3(out F); // 6
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "F").WithArguments("field", "F").WithLocation(28, 16));
        }
 
        [Fact]
        public void RefParameter_InstanceMethod_ReadonlyRef()
        {
            var source =
@"ref struct S<T>
{
    public readonly ref T F;
    public S(ref T t)
    {
        F = ref t;
        M1(F);
        M2(ref F);
        M3(out F);
        M4(F);
        M4(in F);
    }
    object P
    {
        init
        {
            M1(F);
            M2(ref F);
            M3(out F);
            M4(F);
            M4(in F);
        }
    }
    void M()
    {
        M1(F);
        M2(ref F);
        M3(out F);
        M4(F);
        M4(in F);
    }
    static void M1(T t) { }
    static void M2(ref T t) { }
    static void M3(out T t) { t = default; }
    static void M4(in T t) { }
}";
            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void RefParameter_InstanceMethod_ReadonlyRefReadonly()
        {
            var source =
@"ref struct S<T>
{
    public readonly ref readonly T F;
    public S(ref T t)
    {
        F = ref t;
        M1(F);
        M2(ref F); // 1
        M3(out F); // 2
        M4(F);
        M4(in F);
    }
    object P
    {
        init
        {
            M1(F);
            M2(ref F); // 3
            M3(out F); // 4
            M4(F);
            M4(in F);
        }
    }
    void M()
    {
        M1(F);
        M2(ref F); // 5
        M3(out F); // 6
        M4(F);
        M4(in F);
    }
    static void M1(T t) { }
    static void M2(ref T t) { }
    static void M3(out T t) { t = default; }
    static void M4(in T t) { }
}";
            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (8,16): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //         M2(ref F); // 1
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "F").WithArguments("field", "F").WithLocation(8, 16),
                // (9,16): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //         M3(out F); // 2
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "F").WithArguments("field", "F").WithLocation(9, 16),
                // (18,20): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //             M2(ref F); // 3
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "F").WithArguments("field", "F").WithLocation(18, 20),
                // (19,20): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //             M3(out F); // 4
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "F").WithArguments("field", "F").WithLocation(19, 20),
                // (27,16): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //         M2(ref F); // 5
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "F").WithArguments("field", "F").WithLocation(27, 16),
                // (28,16): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //         M3(out F); // 6
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "F").WithArguments("field", "F").WithLocation(28, 16));
        }
 
        [Fact]
        public void RefParameter_Ref()
        {
            var source =
@"ref struct S<T>
{
    public ref T F;
}
 
class Program
{
    static void M1<T>(T t) { }
    static void M2<T>(ref T t) { }
    static void M3<T>(out T t) { t = default; }
    static void M4<T>(in T t) { }
 
    static void FromValue1<T>(S<T> s)  { M1(s.F); }
    static void FromValue2<T>(S<T> s)  { M2(ref s.F); }
    static void FromValue3<T>(S<T> s)  { M3(out s.F); }
    static void FromValue4A<T>(S<T> s) { M4(in s.F); }
    static void FromValue4B<T>(S<T> s) { M4(s.F); }
 
    static void FromRef1<T>(ref S<T> s)  { M1(s.F); }
    static void FromRef2<T>(ref S<T> s)  { M2(ref s.F); }
    static void FromRef3<T>(ref S<T> s)  { M3(out s.F); }
    static void FromRef4A<T>(ref S<T> s) { M4(in s.F); }
    static void FromRef4B<T>(ref S<T> s) { M4(s.F); }
 
    static void FromOut1<T>(out S<T> s)  { s = default; M1(s.F); }
    static void FromOut2<T>(out S<T> s)  { s = default; M2(ref s.F); }
    static void FromOut3<T>(out S<T> s)  { s = default; M3(out s.F); }
    static void FromOut4A<T>(out S<T> s) { s = default; M4(in s.F); }
    static void FromOut4B<T>(out S<T> s) { s = default; M4(s.F); }
 
    static void FromIn1<T>(in S<T> s)  { M1(s.F); }
    static void FromIn2<T>(in S<T> s)  { M2(ref s.F); }
    static void FromIn3<T>(in S<T> s)  { M3(out s.F); }
    static void FromIn4A<T>(in S<T> s) { M4(in s.F); }
    static void FromIn4B<T>(in S<T> s) { M4(s.F); }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void RefParameter_RefReadonly()
        {
            var source =
@"ref struct S<T>
{
    public ref readonly T F;
}
 
class Program
{
    static void M1<T>(T t) { }
    static void M2<T>(ref T t) { }
    static void M3<T>(out T t) { t = default; }
    static void M4<T>(in T t) { }
 
    static void FromValue1<T>(S<T> s)  { M1(s.F); }
    static void FromValue2<T>(S<T> s)  { M2(ref s.F); } // 1
    static void FromValue3<T>(S<T> s)  { M3(out s.F); } // 2
    static void FromValue4A<T>(S<T> s) { M4(in s.F); }
    static void FromValue4B<T>(S<T> s) { M4(s.F); }
 
    static void FromRef1<T>(ref S<T> s)  { M1(s.F); }
    static void FromRef2<T>(ref S<T> s)  { M2(ref s.F); } // 3
    static void FromRef3<T>(ref S<T> s)  { M3(out s.F); } // 4
    static void FromRef4A<T>(ref S<T> s) { M4(in s.F); }
    static void FromRef4B<T>(ref S<T> s) { M4(s.F); }
 
    static void FromOut1<T>(out S<T> s)  { s = default; M1(s.F); }
    static void FromOut2<T>(out S<T> s)  { s = default; M2(ref s.F); } // 5
    static void FromOut3<T>(out S<T> s)  { s = default; M3(out s.F); } // 6
    static void FromOut4A<T>(out S<T> s) { s = default; M4(in s.F); }
    static void FromOut4B<T>(out S<T> s) { s = default; M4(s.F); }
 
    static void FromIn1<T>(in S<T> s)  { M1(s.F); }
    static void FromIn2<T>(in S<T> s)  { M2(ref s.F); } // 7
    static void FromIn3<T>(in S<T> s)  { M3(out s.F); } // 8
    static void FromIn4A<T>(in S<T> s) { M4(in s.F); }
    static void FromIn4B<T>(in S<T> s) { M4(s.F); }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (14,49): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //     static void FromValue2<T>(S<T> s)  { M2(ref s.F); } // 1
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(14, 49),
                // (15,49): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //     static void FromValue3<T>(S<T> s)  { M3(out s.F); } // 2
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(15, 49),
                // (20,51): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //     static void FromRef2<T>(ref S<T> s)  { M2(ref s.F); } // 3
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(20, 51),
                // (21,51): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //     static void FromRef3<T>(ref S<T> s)  { M3(out s.F); } // 4
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(21, 51),
                // (26,64): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //     static void FromOut2<T>(out S<T> s)  { s = default; M2(ref s.F); } // 5
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(26, 64),
                // (27,64): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //     static void FromOut3<T>(out S<T> s)  { s = default; M3(out s.F); } // 6
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(27, 64),
                // (32,49): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //     static void FromIn2<T>(in S<T> s)  { M2(ref s.F); } // 7
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(32, 49),
                // (33,49): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //     static void FromIn3<T>(in S<T> s)  { M3(out s.F); } // 8
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(33, 49));
        }
 
        [Fact]
        public void RefParameter_ReadonlyRef()
        {
            var source =
@"ref struct S<T>
{
    public readonly ref T F;
}
 
class Program
{
    static void M1<T>(T t) { }
    static void M2<T>(ref T t) { }
    static void M3<T>(out T t) { t = default; }
    static void M4<T>(in T t) { }
 
    static void FromValue1<T>(S<T> s)  { M1(s.F); }
    static void FromValue2<T>(S<T> s)  { M2(ref s.F); }
    static void FromValue3<T>(S<T> s)  { M3(out s.F); }
    static void FromValue4A<T>(S<T> s) { M4(in s.F); }
    static void FromValue4B<T>(S<T> s) { M4(s.F); }
 
    static void FromRef1<T>(ref S<T> s)  { M1(s.F); }
    static void FromRef2<T>(ref S<T> s)  { M2(ref s.F); }
    static void FromRef3<T>(ref S<T> s)  { M3(out s.F); }
    static void FromRef4A<T>(ref S<T> s) { M4(in s.F); }
    static void FromRef4B<T>(ref S<T> s) { M4(s.F); }
 
    static void FromOut1<T>(out S<T> s)  { s = default; M1(s.F); }
    static void FromOut2<T>(out S<T> s)  { s = default; M2(ref s.F); }
    static void FromOut3<T>(out S<T> s)  { s = default; M3(out s.F); }
    static void FromOut4A<T>(out S<T> s) { s = default; M4(in s.F); }
    static void FromOut4B<T>(out S<T> s) { s = default; M4(s.F); }
 
    static void FromIn1<T>(in S<T> s)  { M1(s.F); }
    static void FromIn2<T>(in S<T> s)  { M2(ref s.F); }
    static void FromIn3<T>(in S<T> s)  { M3(out s.F); }
    static void FromIn4A<T>(in S<T> s) { M4(in s.F); }
    static void FromIn4B<T>(in S<T> s) { M4(s.F); }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void RefParameter_ReadonlyRefReadonly()
        {
            var source =
@"ref struct S<T>
{
    public readonly ref readonly T F;
}
 
class Program
{
    static void M1<T>(T t) { }
    static void M2<T>(ref T t) { }
    static void M3<T>(out T t) { t = default; }
    static void M4<T>(in T t) { }
 
    static void FromValue1<T>(S<T> s)  { M1(s.F); }
    static void FromValue2<T>(S<T> s)  { M2(ref s.F); } // 1
    static void FromValue3<T>(S<T> s)  { M3(out s.F); } // 2
    static void FromValue4A<T>(S<T> s) { M4(in s.F); }
    static void FromValue4B<T>(S<T> s) { M4(s.F); }
 
    static void FromRef1<T>(ref S<T> s)  { M1(s.F); }
    static void FromRef2<T>(ref S<T> s)  { M2(ref s.F); } // 3
    static void FromRef3<T>(ref S<T> s)  { M3(out s.F); } // 4
    static void FromRef4A<T>(ref S<T> s) { M4(in s.F); }
    static void FromRef4B<T>(ref S<T> s) { M4(s.F); }
 
    static void FromOut1<T>(out S<T> s)  { s = default; M1(s.F); }
    static void FromOut2<T>(out S<T> s)  { s = default; M2(ref s.F); } // 5
    static void FromOut3<T>(out S<T> s)  { s = default; M3(out s.F); } // 6
    static void FromOut4A<T>(out S<T> s) { s = default; M4(in s.F); }
    static void FromOut4B<T>(out S<T> s) { s = default; M4(s.F); }
 
    static void FromIn1<T>(in S<T> s)  { M1(s.F); }
    static void FromIn2<T>(in S<T> s)  { M2(ref s.F); } // 7
    static void FromIn3<T>(in S<T> s)  { M3(out s.F); } // 8
    static void FromIn4A<T>(in S<T> s) { M4(in s.F); }
    static void FromIn4B<T>(in S<T> s) { M4(s.F); }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (14,49): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //     static void FromValue2<T>(S<T> s)  { M2(ref s.F); } // 1
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(14, 49),
                // (15,49): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //     static void FromValue3<T>(S<T> s)  { M3(out s.F); } // 2
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(15, 49),
                // (20,51): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //     static void FromRef2<T>(ref S<T> s)  { M2(ref s.F); } // 3
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(20, 51),
                // (21,51): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //     static void FromRef3<T>(ref S<T> s)  { M3(out s.F); } // 4
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(21, 51),
                // (26,64): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //     static void FromOut2<T>(out S<T> s)  { s = default; M2(ref s.F); } // 5
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(26, 64),
                // (27,64): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //     static void FromOut3<T>(out S<T> s)  { s = default; M3(out s.F); } // 6
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(27, 64),
                // (32,49): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //     static void FromIn2<T>(in S<T> s)  { M2(ref s.F); } // 7
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(32, 49),
                // (33,49): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
                //     static void FromIn3<T>(in S<T> s)  { M3(out s.F); } // 8
                Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(33, 49));
        }
 
        [Fact]
        public void RefParameter_ReadonlyRefReadonly_PEVerifyCompat()
        {
            var source =
@"#pragma warning disable 649
ref struct S<T>
{
    public readonly ref readonly T F;
}
 
class Program
{
    static void M1<T>(T t) { }
    static void M4<T>(in T t) { }
 
    static void FromValue1<T>(S<T> s)  { M1(s.F); }
    static void FromValue4A<T>(S<T> s) { M4(in s.F); }
    static void FromValue4B<T>(S<T> s) { M4(s.F); }
 
    static void FromRef1<T>(ref S<T> s)  { M1(s.F); }
    static void FromRef4A<T>(ref S<T> s) { M4(in s.F); }
    static void FromRef4B<T>(ref S<T> s) { M4(s.F); }
 
    static void FromOut1<T>(out S<T> s)  { s = default; M1(s.F); }
    static void FromOut4A<T>(out S<T> s) { s = default; M4(in s.F); }
    static void FromOut4B<T>(out S<T> s) { s = default; M4(s.F); }
 
    static void FromIn1<T>(in S<T> s)  { M1(s.F); }
    static void FromIn4A<T>(in S<T> s) { M4(in s.F); }
    static void FromIn4B<T>(in S<T> s) { M4(s.F); }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.RegularPreview.WithFeature("peverify-compat"), targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void InitobjField()
        {
            var source =
@"using System;
struct S<T>
{
    public T F;
}
ref struct R<T>
{
    public ref S<T> S;
}
class Program
{
    static void Main()
    {
        var s = new S<int>();
        scoped var r = new R<int>();
        r.S = ref s;
        NewField(ref r);
        r.S.F = 42;
        Console.WriteLine(s.F);
        Console.WriteLine(r.S.F);
    }
    static void NewField<T>(ref R<T> r)
    {
        r.S = new S<T>();
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput(
@"42
42
"));
            verifier.VerifyIL("Program.NewField<T>",
@"{
  // Code size       13 (0xd)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref S<T> R<T>.S""
  IL_0006:  initobj    ""S<T>""
  IL_000c:  ret
}");
        }
 
        [Fact]
        public void ReadWriteField()
        {
            var source =
@"using System;
ref struct S<T>
{
    public ref T F;
    public S(ref T t) { F = ref t; }
}
class Program
{
    static void Main()
    {
        int x = 1;
        scoped var s = new S<int>();
        s.F = ref x;
        Write(s, 42);
        Console.WriteLine(Read(s));
        Console.WriteLine(x);
    }
    static int Read(S<int> s)
    {
        return s.F;
    }
    static void Write(S<int> s, int value)
    {
        s.F = value;
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput(
@"42
42
"));
            verifier.VerifyIL("S<T>..ctor(ref T)",
@"{
  // Code size        8 (0x8)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  stfld      ""ref T S<T>.F""
  IL_0007:  ret
}");
            verifier.VerifyIL("Program.Read",
@"{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref int S<int>.F""
  IL_0006:  ldind.i4
  IL_0007:  ret
}");
            verifier.VerifyIL("Program.Write",
@"{
  // Code size        9 (0x9)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref int S<int>.F""
  IL_0006:  ldarg.1
  IL_0007:  stind.i4
  IL_0008:  ret
}");
        }
 
        [Fact]
        public void ReadWriteNestedField()
        {
            var source =
@"using System;
using System.Diagnostics.CodeAnalysis;
ref struct R1<T>
{
    public ref T F;
    public R1(ref T t) { F = ref t; }
}
ref struct R2<T>
{
    public ref R1<T> R1;
    public R2(ref R1<T> r1) { R1 = ref r1; }
}
class Program
{
    static void Main()
    {
        int i = 0;
        var r1 = new R1<int>(ref i);
        var r2 = new R2<int>(ref r1);
        r2.R1.F = 42;
        Console.WriteLine(Read(r2));
        Console.WriteLine(ReadIn(r2));
        Console.WriteLine(i);
    }
    static T Read<T>(R2<T> r2)
    {
        return r2.R1.F;
    }
    static T ReadIn<T>(in R2<T> r2In)
    {
        return r2In.R1.F;
    }
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (10,12): error CS9050: A ref field cannot refer to a ref struct.
                //     public ref R1<T> R1;
                Diagnostic(ErrorCode.ERR_RefFieldCannotReferToRefStruct, "ref R1<T>").WithLocation(10, 12));
        }
 
        [Fact]
        public void ReadWriteFieldWithTemp()
        {
            var source =
@"ref struct S<T>
{
    public ref T F;
    private int _other;
    public S(int other) : this() { _other = other; }
}
class Program
{
    static T ReadWrite1<T>(ref T t)
    {
        return new S<T>().F = ref t;
    }
    static T ReadWrite2<T>(ref T t)
    {
        return new S<T>(1).F = ref t;
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (11,16): error CS0131: The left-hand side of an assignment must be a variable, property or indexer
                //         return new S<T>().F = ref t;
                Diagnostic(ErrorCode.ERR_AssgLvalueExpected, "new S<T>().F").WithLocation(11, 16),
                // (15,16): error CS0131: The left-hand side of an assignment must be a variable, property or indexer
                //         return new S<T>(1).F = ref t;
                Diagnostic(ErrorCode.ERR_AssgLvalueExpected, "new S<T>(1).F").WithLocation(15, 16));
        }
 
        [WorkItem(62122, "https://github.com/dotnet/roslyn/issues/62122")]
        [Fact]
        public void ReadAndDiscard()
        {
            var source =
@"using System;
ref struct S<T>
{
    public ref T F;
    public S(ref T t) { F = ref t; }
}
class Program
{
    static void Main()
    {
        int i = 1;
        Try(1, () => ReadAndDiscard1(ref i));
        Try(2, () => ReadAndDiscardNoArg<int>());
        Try(3, () => ReadAndDiscard2(new S<int>(ref i)));
        Try(4, () => ReadAndDiscard2(new S<int>()));
 
        void Try(int i, Action a)
        {
            try
            {
                a();
                Console.WriteLine(i);
            }
            catch (NullReferenceException)
            {
                Console.WriteLine(""NullReferenceException"");
            }
        }
    }
    static void ReadAndDiscard1<T>(ref T t)
    {
        _ = new S<T>(ref t).F;
    }
    static void ReadAndDiscardNoArg<T>()
    {
        _ = new S<T>().F;
    }
    static void ReadAndDiscard2<T>(in S<T> s)
    {
        _ = s.F;
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput(
@"1
NullReferenceException
3
NullReferenceException
"));
            verifier.VerifyIL("Program.ReadAndDiscard1<T>", """
{
  // Code size       18 (0x12)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  newobj     "S<T>..ctor(ref T)"
  IL_0006:  ldfld      "ref T S<T>.F"
  IL_000b:  ldobj      "T"
  IL_0010:  pop
  IL_0011:  ret
}
""");
            verifier.VerifyIL("Program.ReadAndDiscardNoArg<T>", """
{
  // Code size       21 (0x15)
  .maxstack  1
  .locals init (S<T> V_0)
  IL_0000:  ldloca.s   V_0
  IL_0002:  initobj    "S<T>"
  IL_0008:  ldloc.0
  IL_0009:  ldfld      "ref T S<T>.F"
  IL_000e:  ldobj      "T"
  IL_0013:  pop
  IL_0014:  ret
}
""");
            verifier.VerifyIL("Program.ReadAndDiscard2<T>", """
{
  // Code size       13 (0xd)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  ldfld      "ref T S<T>.F"
  IL_0006:  ldobj      "T"
  IL_000b:  pop
  IL_000c:  ret
}
""");
        }
 
        [Fact]
        public void RefReturn_ByValueArg()
        {
            var source =
@"using System;
ref struct S<T>
{
    public ref T F;
    public S(ref T t) { F = ref t; }
}
class Program
{
    static void Main()
    {
        int i = 1;
        var s = new S<int>(ref i);
        RefReturn(s) = 2;
        i = RefReadonlyReturn(s);
        Console.WriteLine(i);
    }
    static ref T RefReturn<T>(S<T> s) => ref s.F;
    static ref readonly T RefReadonlyReturn<T>(S<T> s) => ref s.F;
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("2"));
            var expectedIL =
@"{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  ldfld      ""ref T S<T>.F""
  IL_0007:  ret
}";
            verifier.VerifyIL("Program.RefReturn<T>", expectedIL);
            verifier.VerifyIL("Program.RefReadonlyReturn<T>", expectedIL);
        }
 
        [Fact]
        public void RefReturn_RefArg()
        {
            var source =
@"using System;
ref struct S<T>
{
    public ref T F;
    public S(ref T t) { F = ref t; }
}
class Program
{
    static void Main()
    {
        int i = 1;
        var s = new S<int>(ref i);
        RefReturn(ref s) = 2;
        i = RefReadonlyReturn(ref s);
        Console.WriteLine(i);
    }
    static ref T RefReturn<T>(ref S<T> s) => ref s.F;
    static ref readonly T RefReadonlyReturn<T>(ref S<T> s) => ref s.F;
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("2"));
            var expectedIL =
@"{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.F""
  IL_0006:  ret
}";
            verifier.VerifyIL("Program.RefReturn<T>", expectedIL);
            verifier.VerifyIL("Program.RefReadonlyReturn<T>", expectedIL);
        }
 
        [Fact]
        public void RefReturn_InArg()
        {
            var source =
@"using System;
ref struct S<T>
{
    public ref T F;
    public S(ref T t) { F = ref t; }
}
class Program
{
    static void Main()
    {
        int i = 1;
        var s = new S<int>(ref i);
        RefReturn(s) = 2;
        i = RefReadonlyReturn(s);
        Console.WriteLine(i);
    }
    static ref T RefReturn<T>(in S<T> s) => ref s.F;
    static ref readonly T RefReadonlyReturn<T>(in S<T> s) => ref s.F;
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("2"));
            var expectedIL =
@"{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.F""
  IL_0006:  ret
}";
            verifier.VerifyIL("Program.RefReturn<T>", expectedIL);
            verifier.VerifyIL("Program.RefReadonlyReturn<T>", expectedIL);
        }
 
        [Fact]
        public void RefReturn_OutArg()
        {
            var source =
@"using System;
ref struct S<T>
{
    public ref T F;
    public S(ref T t) { F = ref t; }
}
class Program
{
    static void Main()
    {
        int i = 1;
        scoped S<int> s;
        RefReturn(out s, ref i) = 2;
        i = RefReadonlyReturn(out s, ref i);
        Console.WriteLine(i);
    }
    static ref T RefReturn<T>(out S<T> s, ref T t)
    {
        s = new S<T>(ref t);
        return ref s.F;
    }
    static ref readonly T RefReadonlyReturn<T>(out S<T> s, ref T t)
    {
        s = new S<T>(ref t);
        return ref s.F;
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("2"));
            var expectedIL =
@"{
  // Code size       19 (0x13)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  newobj     ""S<T>..ctor(ref T)""
  IL_0007:  stobj      ""S<T>""
  IL_000c:  ldarg.0
  IL_000d:  ldfld      ""ref T S<T>.F""
  IL_0012:  ret
}";
            verifier.VerifyIL("Program.RefReturn<T>", expectedIL);
            verifier.VerifyIL("Program.RefReadonlyReturn<T>", expectedIL);
        }
 
        [Fact]
        public void CompoundOperations_01()
        {
            var source =
@"using System;
ref struct S<T>
{
    public ref T F;
    public S(ref T t) { F = ref t; }
}
class Program
{
    static void Main()
    {
        int x = 42;
        scoped var s = new S<int>(ref x);
        Increment(s);
        Console.WriteLine(s.F);
        Console.WriteLine(x);
        Subtract(s, 10);
        Console.WriteLine(s.F);
        Console.WriteLine(x);
    }
    static void Increment(S<int> s)
    {
        s.F++;
    }
    static void Subtract(S<int> s, int offset)
    {
        s.F -= offset;
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput(
@"43
43
33
33
"));
            verifier.VerifyIL("Program.Increment",
@"{
  // Code size       13 (0xd)
  .maxstack  3
  IL_0000:  ldarga.s   V_0
  IL_0002:  ldfld      ""ref int S<int>.F""
  IL_0007:  dup
  IL_0008:  ldind.i4
  IL_0009:  ldc.i4.1
  IL_000a:  add
  IL_000b:  stind.i4
  IL_000c:  ret
}");
            verifier.VerifyIL("Program.Subtract",
@"{
  // Code size       13 (0xd)
  .maxstack  3
  IL_0000:  ldarga.s   V_0
  IL_0002:  ldfld      ""ref int S<int>.F""
  IL_0007:  dup
  IL_0008:  ldind.i4
  IL_0009:  ldarg.1
  IL_000a:  sub
  IL_000b:  stind.i4
  IL_000c:  ret
}");
        }
 
        [Theory]
        [InlineData("ref")]
        [InlineData("readonly ref")]
        public void CompoundOperations_02(string refKind)
        {
            var source =
$@"using System;
ref struct S
{{
    public {refKind} int F;
    public S(ref int i) {{ F = ref i; }}
    public void Increment()
    {{
        F++;
    }}
    public void Subtract(int offset)
    {{
        F -= offset;
    }}
}}
class Program
{{
    static void Main()
    {{
        int x = 42;
        scoped var s = new S(ref x);
        s.Increment();
        Console.WriteLine(s.F);
        Console.WriteLine(x);
        s.Subtract(10);
        Console.WriteLine(s.F);
        Console.WriteLine(x);
    }}
}}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput(
@"43
43
33
33
"));
            verifier.VerifyIL("S.Increment",
@"{
  // Code size       17 (0x11)
  .maxstack  3
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref int S.F""
  IL_0006:  ldarg.0
  IL_0007:  ldfld      ""ref int S.F""
  IL_000c:  ldind.i4
  IL_000d:  ldc.i4.1
  IL_000e:  add
  IL_000f:  stind.i4
  IL_0010:  ret
}");
            verifier.VerifyIL("S.Subtract",
@"{
  // Code size       17 (0x11)
  .maxstack  3
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref int S.F""
  IL_0006:  ldarg.0
  IL_0007:  ldfld      ""ref int S.F""
  IL_000c:  ldind.i4
  IL_000d:  ldarg.1
  IL_000e:  sub
  IL_000f:  stind.i4
  IL_0010:  ret
}");
        }
 
        [Fact]
        public void ConditionalOperator()
        {
            var source =
@"using System;
ref struct S<T>
{
    public ref T F;
    public S(ref T t) { F = ref t; }
}
class Program
{
    static void Main()
    {
        int x = 1;
        int y = 2;
        var sx = new S<int>(ref x);
        var sy = new S<int>(ref y);
        Console.WriteLine(ConditionalOperator(true, sx, sy));
        Console.WriteLine(ConditionalOperator(false, sx, sy));
        ConditionalOperatorRef(true, ref sx, ref sy) = 3;
        ConditionalOperatorRef(false, ref sx, ref sy) = 4;
        Console.WriteLine(x);
        Console.WriteLine(y);
    }
    static T ConditionalOperator<T>(bool b, S<T> sx, S<T> sy)
    {
        return b ? sx.F : sy.F;
    }
    static ref T ConditionalOperatorRef<T>(bool b, ref S<T> sx, ref S<T> sy)
    {
        return ref b ? ref sx.F : ref sy.F;
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput(
@"1
2
3
4
"));
            verifier.VerifyIL("Program.ConditionalOperator<T>",
@"{
  // Code size       27 (0x1b)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  brtrue.s   IL_000f
  IL_0003:  ldarg.2
  IL_0004:  ldfld      ""ref T S<T>.F""
  IL_0009:  ldobj      ""T""
  IL_000e:  ret
  IL_000f:  ldarg.1
  IL_0010:  ldfld      ""ref T S<T>.F""
  IL_0015:  ldobj      ""T""
  IL_001a:  ret
}");
            verifier.VerifyIL("Program.ConditionalOperatorRef<T>",
@"{
  // Code size       17 (0x11)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  brtrue.s   IL_000a
  IL_0003:  ldarg.2
  IL_0004:  ldfld      ""ref T S<T>.F""
  IL_0009:  ret
  IL_000a:  ldarg.1
  IL_000b:  ldfld      ""ref T S<T>.F""
  IL_0010:  ret
}");
        }
 
        [Fact]
        public void ConditionalAccess()
        {
            var source =
@"using System;
ref struct S<T>
{
    public ref T F;
    public S(ref T t) { F = ref t; }
}
class Program
{
    static void Main()
    {
        object o = 1;
        int i = 2;
        var s1 = new S<object>(ref o);
        var s2 = new S<int>(ref i);
        Console.WriteLine(ConditionalAccess(s1));
        Console.WriteLine(ConditionalAccess(s2));
    }
    static string ConditionalAccess<T>(S<T> s)
    {
        return s.F?.ToString();
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput(
@"1
2
"));
            verifier.VerifyIL("Program.ConditionalAccess<T>",
@"{
  // Code size       54 (0x36)
  .maxstack  2
  .locals init (T V_0)
  IL_0000:  ldarga.s   V_0
  IL_0002:  ldfld      ""ref T S<T>.F""
  IL_0007:  ldloca.s   V_0
  IL_0009:  initobj    ""T""
  IL_000f:  ldloc.0
  IL_0010:  box        ""T""
  IL_0015:  brtrue.s   IL_002a
  IL_0017:  ldobj      ""T""
  IL_001c:  stloc.0
  IL_001d:  ldloca.s   V_0
  IL_001f:  ldloc.0
  IL_0020:  box        ""T""
  IL_0025:  brtrue.s   IL_002a
  IL_0027:  pop
  IL_0028:  ldnull
  IL_0029:  ret
  IL_002a:  constrained. ""T""
  IL_0030:  callvirt   ""string object.ToString()""
  IL_0035:  ret
}");
        }
 
        [Fact]
        public void Deconstruct()
        {
            var source =
@"using System;
class Pair<T, U>
{
    public readonly T First;
    public readonly U Second;
    public Pair(T first, U second)
    {
        First = first;
        Second = second;
    }
    public void Deconstruct(out T first, out U second)
    {
        first = First;
        second = Second;
    }
}
ref struct S<T>
{
    public ref T F;
    public S(ref T t) { F = ref t; }
}
class Program
{
    static void Main()
    {
        int i = 0;
        string s = null;
        var s1 = new S<int>(ref i);
        var s2 = new S<string>(ref s);
        Deconstruct(new Pair<int, string>(1, ""Hello world""), s1, s2);
        Console.WriteLine((i, s));
    }
    static void Deconstruct<T, U>(Pair<T, U> pair, S<T> s1, S<U> s2)
    {
        (s1.F, s2.F) = pair;
    }
}";
            var references = TargetFrameworkUtil.GetReferences(TargetFramework.Standard, additionalReferences: null);
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput(@"(1, Hello world)"));
            verifier.VerifyIL("Program.Deconstruct<T, U>",
@"{
  // Code size       39 (0x27)
  .maxstack  4
  .locals init (T& V_0,
                T V_1,
                U V_2)
  IL_0000:  ldarga.s   V_1
  IL_0002:  ldfld      ""ref T S<T>.F""
  IL_0007:  stloc.0
  IL_0008:  ldarga.s   V_2
  IL_000a:  ldfld      ""ref U S<U>.F""
  IL_000f:  ldarg.0
  IL_0010:  ldloca.s   V_1
  IL_0012:  ldloca.s   V_2
  IL_0014:  callvirt   ""void Pair<T, U>.Deconstruct(out T, out U)""
  IL_0019:  ldloc.0
  IL_001a:  ldloc.1
  IL_001b:  stobj      ""T""
  IL_0020:  ldloc.2
  IL_0021:  stobj      ""U""
  IL_0026:  ret
}");
        }
 
        [WorkItem(64448, "https://github.com/dotnet/roslyn/issues/64448")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Deconstruct_01(LanguageVersion languageVersion)
        {
            var source =
@"ref struct R1
{
    public R1(ref int i) { }
    public void Deconstruct(out int x, out int y) => throw null;
}
readonly ref struct R2
{
    public R2(ref int i) { }
    public void Deconstruct(out int x, out int y) => throw null;
}
class Program
{
    static void F1()
    {
        int i = 1;
        var r = new R1(ref i);
        int x1, y1;
        (x1, y1) = r;
        r.Deconstruct(out x1, out y1);
    }
    static void F2()
    {
        int i = 2;
        var r = new R2(ref i);
        int x2, y2;
        (x2, y2) = r;
        r.Deconstruct(out x2, out y2);
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics();
        }
 
        [WorkItem(64448, "https://github.com/dotnet/roslyn/issues/64448")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Deconstruct_02A(LanguageVersion languageVersion)
        {
            var source =
@"using System;
static class Program
{
    static void Main()
    {
        Span<int> s = stackalloc int[10];
        int x, y;
        (x, y) = s;
        s.Deconstruct(out x, out y);
    }
    static void Deconstruct(this Span<int> s, out int x, out int y) => throw null;
}";
            var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics();
        }
 
        [WorkItem(64448, "https://github.com/dotnet/roslyn/issues/64448")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Deconstruct_02B(LanguageVersion languageVersion)
        {
            var source =
@"using System;
static class Program
{
    static void Main()
    {
        ReadOnlySpan<int> s = stackalloc int[10];
        int x, y;
        (x, y) = s;
        s.Deconstruct(out x, out y);
    }
    static void Deconstruct(this ReadOnlySpan<int> s, out int x, out int y) => throw null;
}";
            var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics();
        }
 
        [WorkItem(64448, "https://github.com/dotnet/roslyn/issues/64448")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Deconstruct_03A(LanguageVersion languageVersion)
        {
            var source =
@"using System;
static class Program
{
    static void F1()
    {
        Span<int> s = stackalloc int[10];
        int x1;
        Span<byte> y1;
        (x1, y1) = s; // 1
        s.Deconstruct(out x1, out y1); // 2
    }
    static void F2()
    {
        Span<int> s = stackalloc int[10];
        int x2;
        Span<byte> y2 = stackalloc byte[1];
        (x2, y2) = s;
        s.Deconstruct(out x2, out y2);
    }
    static void Deconstruct(this Span<int> s, out int x, out Span<byte> y) => throw null;
}";
            var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics(
                // (9,9): error CS8352: Cannot use variable '(x1, y1) = s' in this context because it may expose referenced variables outside of their declaration scope
                //         (x1, y1) = s; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "(x1, y1) = s").WithArguments("(x1, y1) = s").WithLocation(9, 9),
                // (9,20): error CS8350: This combination of arguments to 'Program.Deconstruct(Span<int>, out int, out Span<byte>)' is disallowed because it may expose variables referenced by parameter 's' outside of their declaration scope
                //         (x1, y1) = s; // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, "s").WithArguments("Program.Deconstruct(System.Span<int>, out int, out System.Span<byte>)", "s").WithLocation(9, 20),
                // (10,9): error CS8352: Cannot use variable 's' in this context because it may expose referenced variables outside of their declaration scope
                //         s.Deconstruct(out x1, out y1); // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s").WithArguments("s").WithLocation(10, 9),
                // (10,9): error CS8350: This combination of arguments to 'Program.Deconstruct(Span<int>, out int, out Span<byte>)' is disallowed because it may expose variables referenced by parameter 's' outside of their declaration scope
                //         s.Deconstruct(out x1, out y1); // 2
                Diagnostic(ErrorCode.ERR_CallArgMixing, "s.Deconstruct(out x1, out y1)").WithArguments("Program.Deconstruct(System.Span<int>, out int, out System.Span<byte>)", "s").WithLocation(10, 9));
        }
 
        [WorkItem(64448, "https://github.com/dotnet/roslyn/issues/64448")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Deconstruct_03B(LanguageVersion languageVersion)
        {
            var source =
@"using System;
static class Program
{
    static void F1()
    {
        ReadOnlySpan<int> s = stackalloc int[10];
        int x1;
        ReadOnlySpan<byte> y1;
        (x1, y1) = s; // 1
        s.Deconstruct(out x1, out y1); // 2
    }
    static void F2()
    {
        ReadOnlySpan<int> s = stackalloc int[10];
        int x2;
        ReadOnlySpan<byte> y2 = stackalloc byte[1];
        (x2, y2) = s;
        s.Deconstruct(out x2, out y2);
    }
    static void Deconstruct(this ReadOnlySpan<int> s, out int x, out ReadOnlySpan<byte> y) => throw null;
}";
            var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics(
                // (9,9): error CS8352: Cannot use variable '(x1, y1) = s' in this context because it may expose referenced variables outside of their declaration scope
                //         (x1, y1) = s; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "(x1, y1) = s").WithArguments("(x1, y1) = s").WithLocation(9, 9),
                // (9,20): error CS8350: This combination of arguments to 'Program.Deconstruct(ReadOnlySpan<int>, out int, out ReadOnlySpan<byte>)' is disallowed because it may expose variables referenced by parameter 's' outside of their declaration scope
                //         (x1, y1) = s; // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, "s").WithArguments("Program.Deconstruct(System.ReadOnlySpan<int>, out int, out System.ReadOnlySpan<byte>)", "s").WithLocation(9, 20),
                // (10,9): error CS8352: Cannot use variable 's' in this context because it may expose referenced variables outside of their declaration scope
                //         s.Deconstruct(out x1, out y1); // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s").WithArguments("s").WithLocation(10, 9),
                // (10,9): error CS8350: This combination of arguments to 'Program.Deconstruct(ReadOnlySpan<int>, out int, out ReadOnlySpan<byte>)' is disallowed because it may expose variables referenced by parameter 's' outside of their declaration scope
                //         s.Deconstruct(out x1, out y1); // 2
                Diagnostic(ErrorCode.ERR_CallArgMixing, "s.Deconstruct(out x1, out y1)").WithArguments("Program.Deconstruct(System.ReadOnlySpan<int>, out int, out System.ReadOnlySpan<byte>)", "s").WithLocation(10, 9));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Deconstruct_04(LanguageVersion languageVersion)
        {
            var source =
@"using System;
ref struct R1
{
    public void Deconstruct(out R2 x, out R2 y) => throw null;
}
ref struct R2
{
    public R2(Span<byte> s) { }
}
static class Program
{
    static void Main()
    {
        Span<int> s = stackalloc int[10];
        R2 x = new R2(stackalloc byte[1]);
        R2 y = new R2(stackalloc byte[1]);
        R2 z1 = new R2(stackalloc byte[1]);
        (x, (y, z1)) = s;
        R2 z2 = default;
        (x, (y, z2)) = s; // 1
        (z2, (y, z1)) = s; // 2
    }
    static void Deconstruct(this Span<int> s, out R2 x, out R1 y) => throw null;
}";
            var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics(
                // (20,9): error CS8352: Cannot use variable '(x, (y, z2)) = s' in this context because it may expose referenced variables outside of their declaration scope
                //         (x, (y, z2)) = s; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "(x, (y, z2)) = s").WithArguments("(x, (y, z2)) = s").WithLocation(20, 9),
                // (20,24): error CS8350: This combination of arguments to 'R1.Deconstruct(out R2, out R2)' is disallowed because it may expose variables referenced by parameter 'this' outside of their declaration scope
                //         (x, (y, z2)) = s; // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, "s").WithArguments("R1.Deconstruct(out R2, out R2)", "this").WithLocation(20, 24),
                // (21,9): error CS8352: Cannot use variable '(z2, (y, z1)) = s' in this context because it may expose referenced variables outside of their declaration scope
                //         (z2, (y, z1)) = s; // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "(z2, (y, z1)) = s").WithArguments("(z2, (y, z1)) = s").WithLocation(21, 9),
                // (21,25): error CS8350: This combination of arguments to 'Program.Deconstruct(Span<int>, out R2, out R1)' is disallowed because it may expose variables referenced by parameter 's' outside of their declaration scope
                //         (z2, (y, z1)) = s; // 2
                Diagnostic(ErrorCode.ERR_CallArgMixing, "s").WithArguments("Program.Deconstruct(System.Span<int>, out R2, out R1)", "s").WithLocation(21, 25));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Deconstruct_05(LanguageVersion languageVersion)
        {
            var source =
@"ref struct R
{
}
static class Program
{
    static void F(ref R r)
    {
        (r, r) = r;
        r.Deconstruct(out r, out r);
    }
    static void Deconstruct(this R r, out R x, out R y) => throw null;
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics();
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Deconstruct_06(LanguageVersion languageVersion)
        {
            var source =
@"using System;
static class Program
{
    static void F()
    {
        Span<int> s = stackalloc int[10];
        (s, s) = s;
        s.Deconstruct(out s, out s);
    }
    static void Deconstruct(this Span<int> s, out Span<int> x, out Span<int> y) => throw null;
}";
            var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics();
        }
 
        [WorkItem(64448, "https://github.com/dotnet/roslyn/issues/64448")]
        [Fact]
        public void Deconstruct_07()
        {
            var source =
@"ref struct R1
{
    public R1(ref int i) { }
    public void Deconstruct(out int x, out R2 y) => throw null;
}
ref struct R2
{
}
class Program
{
    static void F1()
    {
        int i = 1;
        var r = new R1(ref i);
        int x;
        scoped R2 y;
        (x, y) = r;
        r.Deconstruct(out x, out y);
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Deconstruct_08(LanguageVersion languageVersion)
        {
            var source =
@"using System;
static class Program
{
    static void Main()
    {
        Span<int> x = stackalloc int[10];
        Span<int> y = default;
        (x, y) = (y, x);
    }
}";
            var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics(
                // (8,19): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (x, y) = (y, x);
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "y").WithArguments("System.Span<int>").WithLocation(8, 19),
                // (8,22): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (x, y) = (y, x);
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "x").WithArguments("System.Span<int>").WithLocation(8, 22));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Deconstruct_09(LanguageVersion languageVersion)
        {
            var source =
@"ref struct R1
{
    public R1(ref int i) { }
    public void Deconstruct(out int x, out R2 y) => throw null;
}
ref struct R2
{
}
class Program
{
    static R2 F1()
    {
        int i = 1;
        var r = new R1(ref i);
        var (x1, y1) = r;
        return y1; // 1
    }
    static R2 F2()
    {
        int i = 2;
        var r = new R1(ref i);
        r.Deconstruct(out var x2, out var y2);
        return y2; // 2
    }
    static R2 F3(ref int i)
    {
        var r = new R1(ref i);
        var (x3, y3) = r;
        return y3;
    }
    static R2 F4(ref int i)
    {
        var r = new R1(ref i);
        r.Deconstruct(out var x4, out var y4);
        return y4;
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            if (languageVersion == LanguageVersion.CSharp10)
            {
                comp.VerifyEmitDiagnostics();
            }
            else
            {
                comp.VerifyEmitDiagnostics(
                    // (16,16): error CS8352: Cannot use variable 'y1' in this context because it may expose referenced variables outside of their declaration scope
                    //         return y1; // 1
                    Diagnostic(ErrorCode.ERR_EscapeVariable, "y1").WithArguments("y1").WithLocation(16, 16),
                    // (23,16): error CS8352: Cannot use variable 'y2' in this context because it may expose referenced variables outside of their declaration scope
                    //         return y2; // 2
                    Diagnostic(ErrorCode.ERR_EscapeVariable, "y2").WithArguments("y2").WithLocation(23, 16));
            }
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Deconstruct_10(LanguageVersion languageVersion)
        {
            var source =
@"using System;
static class Program
{
    static Span<byte> F1()
    {
        Span<int> s = stackalloc int[10];
        var (x1, y1) = s;
        return y1; // 1
    }
    static Span<byte> F2()
    {
        Span<int> s = stackalloc int[10];
        s.Deconstruct(out var x2, out var y2);
        return y2; // 2
    }
    static Span<byte> F3()
    {
        Span<int> s = default;
        var (x3, y3) = s;
        return y3;
    }
    static Span<byte> F4()
    {
        Span<int> s = default;
        s.Deconstruct(out var x4, out var y4);
        return y4;
    }
    static void Deconstruct(this Span<int> s, out int x, out Span<byte> y) => throw null;
}";
            var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics(
                // (8,16): error CS8352: Cannot use variable 'y1' in this context because it may expose referenced variables outside of their declaration scope
                //         return y1; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y1").WithArguments("y1").WithLocation(8, 16),
                // (14,16): error CS8352: Cannot use variable 'y2' in this context because it may expose referenced variables outside of their declaration scope
                //         return y2; // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y2").WithArguments("y2").WithLocation(14, 16));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Deconstruct_11(LanguageVersion languageVersion)
        {
            var source =
@"using System;
ref struct R
{
}
ref struct Enumerable
{
    public Enumerable(Span<int> s) { }
    public Enumerator GetEnumerator() => default;
}
ref struct Enumerator
{
    public bool MoveNext() => false;
    public Span<int> Current => default;
}
static class Program
{
    static R F1()
    {
        var e = new Enumerable(stackalloc int[10]);
        foreach (var (x1, y1) in e)
            return y1; // 1
        return default;
    }
    static R F2(ref int i)
    {
        var e = new Enumerable(default);
        foreach (var (x2, y2) in e)
            return y2;
        return default;
    }
    static void Deconstruct(this Span<int> s, out R x, out R y) => throw null;
}";
            var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics(
                // (21,20): error CS8352: Cannot use variable 'y1' in this context because it may expose referenced variables outside of their declaration scope
                //             return y1; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y1").WithArguments("y1").WithLocation(21, 20));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Deconstruct_12(LanguageVersion languageVersion)
        {
            var source =
@"using System;
ref struct R
{
}
static class Program
{
    static R F1()
    {
        Span<int> span = stackalloc int[10];
        R x1, y1;
        (x1, y1) = span; // 1
        return y1;
    }
    static R F2()
    {
        Span<int> span = stackalloc int[10];
        var (x2, y2) = span;
        return y2; // 2
    }
    static R F3()
    {
        Span<int> span = stackalloc int[10];
        (var x3, var y3) = span;
        return y3; // 3
    }
    static R F4()
    {
        Span<int> span = stackalloc int[10];
        (R x4, R y4) = span;
        return y4; // 4
    }
    static R F5()
    {
        Span<int> span = default;
        var (x5, y5) = span;
        return y5;
    }
    static void Deconstruct(this Span<int> s, out R x, out R y) => throw null;
}";
            var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics(
                // (11,9): error CS8352: Cannot use variable '(x1, y1) = span' in this context because it may expose referenced variables outside of their declaration scope
                //         (x1, y1) = span; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "(x1, y1) = span").WithArguments("(x1, y1) = span").WithLocation(11, 9),
                // (11,20): error CS8350: This combination of arguments to 'Program.Deconstruct(Span<int>, out R, out R)' is disallowed because it may expose variables referenced by parameter 's' outside of their declaration scope
                //         (x1, y1) = span; // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, "span").WithArguments("Program.Deconstruct(System.Span<int>, out R, out R)", "s").WithLocation(11, 20),
                // (18,16): error CS8352: Cannot use variable 'y2' in this context because it may expose referenced variables outside of their declaration scope
                //         return y2; // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y2").WithArguments("y2").WithLocation(18, 16),
                // (24,16): error CS8352: Cannot use variable 'y3' in this context because it may expose referenced variables outside of their declaration scope
                //         return y3; // 3
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y3").WithArguments("y3").WithLocation(24, 16),
                // (30,16): error CS8352: Cannot use variable 'y4' in this context because it may expose referenced variables outside of their declaration scope
                //         return y4; // 4
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y4").WithArguments("y4").WithLocation(30, 16));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Deconstruct_13(LanguageVersion languageVersion)
        {
            var source =
@"using System;
ref struct R
{
}
static class Program
{
    static void F()
    {
        Span<int> span = stackalloc int[10];
        var (x1, y1) = span;
        span.Deconstruct(out var x2, out var y2);
    }
    static void Deconstruct(this Span<int> s, out R x, out R y) => throw null;
}";
            var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void InParamReorder()
        {
            var source =
@"using System;
using System.Diagnostics.CodeAnalysis;
ref struct S<T>
{
    public ref T F;
    public S(ref T t) { F = ref t; }
}
class Program
{
    static void Main()
    {
        int x = 1;
        int y = 2;
        var sx = new S<int>(ref x);
        var sy = new S<int>(ref y);
        Reorder(sx, sy);
    }
    static ref S<T> Get<T>(ref S<T> s)
    {
        return ref s;
    }
    static void Reorder<T>(scoped S<T> sx, scoped S<T> sy)
    {
        M(y: in Get(ref sy).F, x: in Get(ref sx).F);
    }
    static void M<T>(in T x, in T y)
    {
        Console.WriteLine(x);
        Console.WriteLine(y);
    }
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput(
@"1
2
"));
            verifier.VerifyIL("Program.Reorder<T>",
@"{
  // Code size       32 (0x20)
  .maxstack  2
  .locals init (T& V_0)
  IL_0000:  ldarga.s   V_1
  IL_0002:  call       ""ref S<T> Program.Get<T>(ref S<T>)""
  IL_0007:  ldfld      ""ref T S<T>.F""
  IL_000c:  stloc.0
  IL_000d:  ldarga.s   V_0
  IL_000f:  call       ""ref S<T> Program.Get<T>(ref S<T>)""
  IL_0014:  ldfld      ""ref T S<T>.F""
  IL_0019:  ldloc.0
  IL_001a:  call       ""void Program.M<T>(in T, in T)""
  IL_001f:  ret
}");
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void ReturnRefToByValueParameter_01(LanguageVersion languageVersion)
        {
            var source =
@"
using System.Diagnostics.CodeAnalysis;
ref struct S<T>
{
}
class Program
{
    static ref S<T> F1<T>([UnscopedRef] ref S<T> x1)
    {
        return ref x1;
    }
    static ref S<T> F2<T>(S<T> x2)
    {
        ref var y2 = ref F1(ref x2);
        return ref y2; // 1
    }
}";
 
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            if (languageVersion == LanguageVersion.CSharp10)
            {
                comp.VerifyEmitDiagnostics(
                    // (8,28): error CS9063: UnscopedRefAttribute cannot be applied to this parameter because it is unscoped by default.
                    //     static ref S<T> F1<T>([UnscopedRef] ref S<T> x1)
                    Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedTarget, "UnscopedRef").WithLocation(8, 28),
                    // (15,20): error CS8157: Cannot return 'y2' by reference because it was initialized to a value that cannot be returned by reference
                    //         return ref y2; // 1
                    Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "y2").WithArguments("y2").WithLocation(15, 20));
            }
            else
            {
                comp.VerifyEmitDiagnostics(
                    // (15,20): error CS8157: Cannot return 'y2' by reference because it was initialized to a value that cannot be returned by reference
                    //         return ref y2; // 1
                    Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "y2").WithArguments("y2").WithLocation(15, 20));
            }
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void ReturnRefToByValueParameter_02(LanguageVersion languageVersion)
        {
            var source =
@"
ref struct S<T>
{
}
class Program
{
    static ref S<T> F1<T>(ref S<T> x1, ref S<T> y1)
    {
        return ref x1;
    }
    static void F2<T>(S<T> x2, S<T> y2)
    {
        var z1 = F1(ref x2, ref y2);
    }
}";
 
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics();
        }
 
        [WorkItem(62098, "https://github.com/dotnet/roslyn/issues/62098")]
        [Fact]
        public void RefToContainingType()
        {
            var source =
@"
using System.Diagnostics.CodeAnalysis;
ref struct R<T>
{
    public ref R<T> Next;
}
class Program
{
    static void F<T>(ref R<T> r)
    {
        r.Next = ref r;
    }
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }, targetFramework: TargetFramework.Net70);
            // https://github.com/dotnet/roslyn/issues/62098: Allow ref field of the containing type.
            comp.VerifyEmitDiagnostics(
                // (5,12): error CS9050: A ref field cannot refer to a ref struct.
                //     public ref R<T> Next;
                Diagnostic(ErrorCode.ERR_RefFieldCannotReferToRefStruct, "ref R<T>").WithLocation(5, 12),
                // (5,21): error CS0523: Struct member 'R<T>.Next' of type 'R<T>' causes a cycle in the struct layout
                //     public ref R<T> Next;
                Diagnostic(ErrorCode.ERR_StructLayoutCycle, "Next").WithArguments("R<T>.Next", "R<T>").WithLocation(5, 21),
                // (11,9): error CS9079: Cannot ref-assign 'r' to 'Next' because 'r' can only escape the current method through a return statement.
                //         r.Next = ref r;
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "r.Next = ref r").WithArguments("Next", "r").WithLocation(11, 9));
        }
 
        /// <summary>
        /// Ref auto-properties are not supported.
        /// </summary>
        [Fact]
        public void RefAutoProperty_01()
        {
            var source =
@"using System;
ref struct S<T>
{
    public ref T P0 { get; }
    public ref T P1 { get; set; }
    public ref T P2 { get; init; }
    public S(ref T t)
    {
        P0 = ref t;
        P1 = ref t;
        P2 = ref t;
    }
}
class Program
{
    static void Main()
    {
        int x = 0;
        var s = new S<int>(ref x);
        s.P0 = 0;
        s.P1 = 1;
        s.P2 = 2;
        s.P0 = ref x;
        s.P1 = ref x;
        s.P2 = ref x;
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (4,18): error CS8145: Auto-implemented properties cannot return by reference
                //     public ref T P0 { get; }
                Diagnostic(ErrorCode.ERR_AutoPropertyCannotBeRefReturning, "P0").WithLocation(4, 18),
                // (5,18): error CS8145: Auto-implemented properties cannot return by reference
                //     public ref T P1 { get; set; }
                Diagnostic(ErrorCode.ERR_AutoPropertyCannotBeRefReturning, "P1").WithLocation(5, 18),
                // (5,28): error CS8147: Properties which return by reference cannot have set accessors
                //     public ref T P1 { get; set; }
                Diagnostic(ErrorCode.ERR_RefPropertyCannotHaveSetAccessor, "set").WithLocation(5, 28),
                // (6,18): error CS8145: Auto-implemented properties cannot return by reference
                //     public ref T P2 { get; init; }
                Diagnostic(ErrorCode.ERR_AutoPropertyCannotBeRefReturning, "P2").WithLocation(6, 18),
                // (6,28): error CS0518: Predefined type 'System.Runtime.CompilerServices.IsExternalInit' is not defined or imported
                //     public ref T P2 { get; init; }
                Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "init").WithArguments("System.Runtime.CompilerServices.IsExternalInit").WithLocation(6, 28),
                // (6,28): error CS8147: Properties which return by reference cannot have set accessors
                //     public ref T P2 { get; init; }
                Diagnostic(ErrorCode.ERR_RefPropertyCannotHaveSetAccessor, "init").WithLocation(6, 28),
                // (9,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         P0 = ref t;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "P0").WithLocation(9, 9),
                // (10,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         P1 = ref t;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "P1").WithLocation(10, 9),
                // (11,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         P2 = ref t;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "P2").WithLocation(11, 9),
                // (23,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         s.P0 = ref x;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "s.P0").WithLocation(23, 9),
                // (24,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         s.P1 = ref x;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "s.P1").WithLocation(24, 9),
                // (25,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         s.P2 = ref x;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "s.P2").WithLocation(25, 9));
        }
 
        /// <summary>
        /// Ref auto-properties are not supported.
        /// </summary>
        [Fact]
        public void RefAutoProperty_02()
        {
            var source =
@"using System;
ref struct S<T>
{
    public ref readonly T P0 { get; }
    public ref readonly T P1 { get; set; }
    public ref readonly T P2 { get; init; }
    public S(ref T t)
    {
        P0 = ref t;
        P1 = ref t;
        P2 = ref t;
    }
}
class Program
{
    static void Main()
    {
        int x = 0;
        var s = new S<int>(ref x);
        s.P0 = ref x;
        s.P1 = ref x;
        s.P2 = ref x;
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (4,27): error CS8145: Auto-implemented properties cannot return by reference
                //     public ref readonly T P0 { get; }
                Diagnostic(ErrorCode.ERR_AutoPropertyCannotBeRefReturning, "P0").WithLocation(4, 27),
                // (5,27): error CS8145: Auto-implemented properties cannot return by reference
                //     public ref readonly T P1 { get; set; }
                Diagnostic(ErrorCode.ERR_AutoPropertyCannotBeRefReturning, "P1").WithLocation(5, 27),
                // (5,37): error CS8147: Properties which return by reference cannot have set accessors
                //     public ref readonly T P1 { get; set; }
                Diagnostic(ErrorCode.ERR_RefPropertyCannotHaveSetAccessor, "set").WithLocation(5, 37),
                // (6,27): error CS8145: Auto-implemented properties cannot return by reference
                //     public ref readonly T P2 { get; init; }
                Diagnostic(ErrorCode.ERR_AutoPropertyCannotBeRefReturning, "P2").WithLocation(6, 27),
                // (6,37): error CS0518: Predefined type 'System.Runtime.CompilerServices.IsExternalInit' is not defined or imported
                //     public ref readonly T P2 { get; init; }
                Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "init").WithArguments("System.Runtime.CompilerServices.IsExternalInit").WithLocation(6, 37),
                // (6,37): error CS8147: Properties which return by reference cannot have set accessors
                //     public ref readonly T P2 { get; init; }
                Diagnostic(ErrorCode.ERR_RefPropertyCannotHaveSetAccessor, "init").WithLocation(6, 37),
                // (9,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         P0 = ref t;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "P0").WithLocation(9, 9),
                // (10,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         P1 = ref t;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "P1").WithLocation(10, 9),
                // (11,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         P2 = ref t;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "P2").WithLocation(11, 9),
                // (20,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         s.P0 = ref x;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "s.P0").WithLocation(20, 9),
                // (21,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         s.P1 = ref x;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "s.P1").WithLocation(21, 9),
                // (22,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         s.P2 = ref x;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "s.P2").WithLocation(22, 9));
        }
 
        [Fact]
        [WorkItem(60807, "https://github.com/dotnet/roslyn/issues/60807")]
        public void RefAndOut_PropertiesAndIndexers_As_ValuesAndParameters()
        {
            var source =
@"
var c = new C();
var r = new R();
//expressions
ref int n = ref c.N;  //CS0206
ref var l = ref c[0]; //CS0206
ref var l2 = ref r[0];//OK
_ = M(ref c.N);       //CS0206
_ = M(ref r.N);       //OK
_ = M(ref c[0]);      //CS0206
_ = M(ref r[0]);      //OK
_ = M2(out c.N);      //CS0206
_ = M2(out r.N);      //OK
_ = M2(out c[0]);     //CS0206
_ = M2(out r[0]);     //OK
//definitions
static string M(ref int number) { return """"; }
static string M2(out int number) { number = 42; return """"; }
class C
{
    public int N { get; set; }
    private int[] arr = new int[100];
    public int this[int i] => arr[i];
}
ref struct R
{
    public R(){}
    private ref int n;
    public ref int N => ref n;
    private static int[] s_arr = new int[1];
    private ref int[] arr = ref s_arr;
    public ref int this[int i] => ref arr[i];
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (5,17): error CS0206: A non ref-returning property or indexer may not be used as an out or ref value
                // ref int n = ref c.N;  //CS0206
                Diagnostic(ErrorCode.ERR_RefProperty, "c.N").WithLocation(5, 17),
                // (6,17): error CS0206: A non ref-returning property or indexer may not be used as an out or ref value
                // ref var l = ref c[0]; //CS0206
                Diagnostic(ErrorCode.ERR_RefProperty, "c[0]").WithLocation(6, 17),
                // (8,11): error CS0206: A non ref-returning property or indexer may not be used as an out or ref value
                // _ = M(ref c.N);       //CS0206
                Diagnostic(ErrorCode.ERR_RefProperty, "c.N").WithLocation(8, 11),
                // (10,11): error CS0206: A non ref-returning property or indexer may not be used as an out or ref value
                // _ = M(ref c[0]);      //CS0206
                Diagnostic(ErrorCode.ERR_RefProperty, "c[0]").WithLocation(10, 11),
                // (12,12): error CS0206: A non ref-returning property or indexer may not be used as an out or ref value
                // _ = M2(out c.N);      //CS0206
                Diagnostic(ErrorCode.ERR_RefProperty, "c.N").WithLocation(12, 12),
                // (14,12): error CS0206: A non ref-returning property or indexer may not be used as an out or ref value
                // _ = M2(out c[0]);     //CS0206
                Diagnostic(ErrorCode.ERR_RefProperty, "c[0]").WithLocation(14, 12)
            );
        }
 
        [Fact]
        public void RefAccessor_Value()
        {
            var source =
@"using System;
ref struct S<T>
{
    internal T t;
    internal ref T F() => ref t;
}
class Program
{
    static void Main()
    {
        var s = new S<int>();
        s.t = 1;
        s.F() = 2;
        Console.WriteLine(s.F());
        Console.WriteLine(s.t);
        s.t = 3;
        Console.WriteLine(s.F());
        Console.WriteLine(s.t);
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (5,31): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //     internal ref T F() => ref t;
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "t").WithLocation(5, 31));
        }
 
        [Fact]
        public void RefAccessor_Ref()
        {
            var source =
@"using System;
ref struct S<T>
{
    internal ref T t;
    internal ref T F() => ref t;
    internal S(ref T t) { this.t = ref t; }
}
class Program
{
    static void Main()
    {
        int i = 0;
        var s = new S<int>(ref i);
        s.t = 1;
        s.F() = 2;
        Console.WriteLine(s.F());
        Console.WriteLine(s.t);
        s.t = 3;
        Console.WriteLine(s.F());
        Console.WriteLine(s.t);
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput(
@"2
2
3
3
"));
            verifier.VerifyIL("S<T>.F",
@"{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""ref T S<T>.t""
  IL_0006:  ret
}");
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Span_01(LanguageVersion languageVersion)
        {
            var source =
@"using System;
class Program
{
    static ref int F1()
    {
        Span<int> s1 = stackalloc int[10];
        return ref s1[1]; // 1
    }
    static ref int F2()
    {
        Span<int> s2 = new int[10];
        return ref s2[1];
    }
}";
            var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics(
                // (7,20): error CS8352: Cannot use variable 's1' in this context because it may expose referenced variables outside of their declaration scope
                //         return ref s1[1]; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s1").WithArguments("s1").WithLocation(7, 20));
        }
 
        // A version of above with an explicit definition of Span<T>.
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Span_02(LanguageVersion languageVersion)
        {
            var sourceA =
@"namespace System
{
    public ref struct Span<T>
    {
        unsafe public Span(void* ptr, int length) { }
        public ref T this[int index] => throw null;
        public static implicit operator Span<T>(T[] a) => throw null;
    }
}";
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular10, options: TestOptions.UnsafeReleaseDll);
            var refA = comp.EmitToImageReference();
 
            var sourceB =
@"using System;
class Program
{
    static ref int F1()
    {
        Span<int> s1 = stackalloc int[10];
        return ref s1[1]; // 1
    }
    static ref int F2()
    {
        Span<int> s2 = new int[10];
        return ref s2[1];
    }
}";
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics(
                // (7,20): error CS8352: Cannot use variable 's1' in this context because it may expose referenced variables outside of their declaration scope
                //         return ref s1[1]; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s1").WithArguments("s1").WithLocation(7, 20));
        }
 
        [Fact, WorkItem(63104, "https://github.com/dotnet/roslyn/issues/63104")]
        public void RefFieldsConsideredManaged()
        {
            var source = @"
unsafe
{
    StructWithRefField* p = stackalloc StructWithRefField[10]; // 1, 2
    C.M<StructWithRefField>(); // 3
}
 
public ref struct StructWithRefField
{
    public ref byte RefField;
}
 
class C
{
    public static void M<T>() where T : unmanaged { }
}";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugExe, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (4,5): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('StructWithRefField')
                //     StructWithRefField* p = stackalloc StructWithRefField[10]; // 1, 2
                Diagnostic(ErrorCode.WRN_ManagedAddr, "StructWithRefField*").WithArguments("StructWithRefField").WithLocation(4, 5),
                // (4,40): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('StructWithRefField')
                //     StructWithRefField* p = stackalloc StructWithRefField[10]; // 1, 2
                Diagnostic(ErrorCode.ERR_ManagedAddr, "StructWithRefField").WithArguments("StructWithRefField").WithLocation(4, 40),
                // (5,7): error CS0306: The type 'StructWithRefField' may not be used as a type argument
                //     C.M<StructWithRefField>(); // 3
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "M<StructWithRefField>").WithArguments("StructWithRefField").WithLocation(5, 7)
                );
 
            Assert.True(comp.GetTypeByMetadataName("StructWithRefField").IsManagedTypeNoUseSiteDiagnostics);
        }
 
        [Fact, WorkItem(63104, "https://github.com/dotnet/roslyn/issues/63104")]
        public void RefFieldsConsideredManaged_Generic()
        {
            var source = @"
unsafe
{
    StructWithIndirectRefField* p = stackalloc StructWithIndirectRefField[10]; // 1, 2
    C.M<StructWithIndirectRefField>(); // 3
}
 
ref struct StructWithIndirectRefField
{
    public StructWithRefField<int> Field;
}
ref struct StructWithRefField<T>
{
    public ref T RefField;
}
 
class C
{
    public static void M<T>() where T : unmanaged { }
}";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugExe, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (4,5): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('StructWithIndirectRefField')
                //     StructWithIndirectRefField* p = stackalloc StructWithIndirectRefField[10]; // 1, 2
                Diagnostic(ErrorCode.WRN_ManagedAddr, "StructWithIndirectRefField*").WithArguments("StructWithIndirectRefField").WithLocation(4, 5),
                // (4,48): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('StructWithIndirectRefField')
                //     StructWithIndirectRefField* p = stackalloc StructWithIndirectRefField[10]; // 1, 2
                Diagnostic(ErrorCode.ERR_ManagedAddr, "StructWithIndirectRefField").WithArguments("StructWithIndirectRefField").WithLocation(4, 48),
                // (5,7): error CS0306: The type 'StructWithIndirectRefField' may not be used as a type argument
                //     C.M<StructWithIndirectRefField>(); // 3
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "M<StructWithIndirectRefField>").WithArguments("StructWithIndirectRefField").WithLocation(5, 7),
                // (10,36): warning CS0649: Field 'StructWithIndirectRefField.Field' is never assigned to, and will always have its default value
                //     public StructWithRefField<int> Field;
                Diagnostic(ErrorCode.WRN_UnassignedInternalField, "Field").WithArguments("StructWithIndirectRefField.Field", "").WithLocation(10, 36),
                // (14,18): warning CS0649: Field 'StructWithRefField<T>.RefField' is never assigned to, and will always have its default value
                //     public ref T RefField;
                Diagnostic(ErrorCode.WRN_UnassignedInternalField, "RefField").WithArguments("StructWithRefField<T>.RefField", "").WithLocation(14, 18)
                );
 
            Assert.True(comp.GetTypeByMetadataName("StructWithIndirectRefField").IsManagedTypeNoUseSiteDiagnostics);
        }
 
        [Fact, WorkItem(63104, "https://github.com/dotnet/roslyn/issues/63104")]
        public void RefFieldsConsideredManaged_Indirect()
        {
            var source = @"
unsafe
{
    StructWithIndirectRefField* p = stackalloc StructWithIndirectRefField[10]; // 1, 2
}
 
public ref struct StructWithIndirectRefField
{
    public StructWithRefField Field;
}
 
public ref struct StructWithRefField
{
    public ref byte RefField;
}";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugExe, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (4,5): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('StructWithIndirectRefField')
                //     StructWithIndirectRefField* p = stackalloc StructWithIndirectRefField[10]; // 1, 2
                Diagnostic(ErrorCode.WRN_ManagedAddr, "StructWithIndirectRefField*").WithArguments("StructWithIndirectRefField").WithLocation(4, 5),
                // (4,48): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('StructWithIndirectRefField')
                //     StructWithIndirectRefField* p = stackalloc StructWithIndirectRefField[10]; // 1, 2
                Diagnostic(ErrorCode.ERR_ManagedAddr, "StructWithIndirectRefField").WithArguments("StructWithIndirectRefField").WithLocation(4, 48)
                );
 
            Assert.True(comp.GetTypeByMetadataName("StructWithIndirectRefField").IsManagedTypeNoUseSiteDiagnostics);
        }
 
        [WorkItem(62618, "https://github.com/dotnet/roslyn/issues/62618")]
        [Theory]
        [CombinatorialData]
        public void RefAssignValueScopeMismatch_01A(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersion,
            bool useUnsafe)
        {
            string unsafeModifier = useUnsafe ? "unsafe" : "";
            var source =
$@"using System;
class Program
{{
    static void Main()
    {{
        Span<int> s = new[] {{ 1 }};
        M(ref s);
    }}
    {unsafeModifier} static void M(ref Span<int> s)
    {{
        Span<int> local = stackalloc int[] {{ 1 }};
        ref Span<int> rL = ref local;
        rL = ref s; // 1
        rL = local;
    }}
}}";
            var comp = CreateCompilationWithSpanAndMemoryExtensions(source,
                parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
                options: (useUnsafe ? TestOptions.UnsafeReleaseExe : null));
            if (useUnsafe)
            {
                comp.VerifyEmitDiagnostics(
                    // (13,9): warning CS9097: This ref-assigns 's' to 'rL' but 's' has a wider value escape scope than 'rL' allowing assignment through 'rL' of values with narrower escapes scopes than 's'.
                    //         rL = ref s; // 1
                    Diagnostic(ErrorCode.WRN_RefAssignValEscapeWider, "rL = ref s").WithArguments("rL", "s").WithLocation(13, 9));
            }
            else
            {
                comp.VerifyEmitDiagnostics(
                    // (13,9): error CS9096: Cannot ref-assign 's' to 'rL' because 's' has a wider value escape scope than 'rL' allowing assignment through 'rL' of values with narrower escapes scopes than 's'.
                    //         rL = ref s; // 1
                    Diagnostic(ErrorCode.ERR_RefAssignValEscapeWider, "rL = ref s").WithArguments("rL", "s").WithLocation(13, 9));
            }
        }
 
        [WorkItem(62618, "https://github.com/dotnet/roslyn/issues/62618")]
        [Theory]
        [CombinatorialData]
        public void RefAssignValueScopeMismatch_01B(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersion,
            bool useUnsafe)
        {
            string unsafeModifier = useUnsafe ? "unsafe" : "";
            var source =
$@"using System;
class Program
{{
    static void Main()
    {{
        Span<int> s = new[] {{ 1 }};
        M(ref s);
    }}
    {unsafeModifier} static void M(ref Span<int> s)
    {{
        Span<int> local = stackalloc int[] {{ 1 }};
        ref readonly Span<int> rL = ref local;
        rL = ref s; // 1
        rL = local; // 2
    }}
}}";
            var comp = CreateCompilationWithSpanAndMemoryExtensions(source,
                parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
                options: (useUnsafe ? TestOptions.UnsafeReleaseExe : null));
            if (useUnsafe)
            {
                comp.VerifyEmitDiagnostics(
                    // (13,9): warning CS9097: This ref-assigns 's' to 'rL' but 's' has a wider value escape scope than 'rL' allowing assignment through 'rL' of values with narrower escapes scopes than 's'.
                    //         rL = ref s; // 1
                    Diagnostic(ErrorCode.WRN_RefAssignValEscapeWider, "rL = ref s").WithArguments("rL", "s").WithLocation(13, 9),
                    // (14,9): error CS0131: The left-hand side of an assignment must be a variable, property or indexer
                    //         rL = local; // 2
                    Diagnostic(ErrorCode.ERR_AssgLvalueExpected, "rL").WithLocation(14, 9));
            }
            else
            {
                comp.VerifyEmitDiagnostics(
                    // (13,9): error CS9096: Cannot ref-assign 's' to 'rL' because 's' has a wider value escape scope than 'rL' allowing assignment through 'rL' of values with narrower escapes scopes than 's'.
                    //         rL = ref s; // 1
                    Diagnostic(ErrorCode.ERR_RefAssignValEscapeWider, "rL = ref s").WithArguments("rL", "s").WithLocation(13, 9),
                    // (14,9): error CS0131: The left-hand side of an assignment must be a variable, property or indexer
                    //         rL = local; // 2
                    Diagnostic(ErrorCode.ERR_AssgLvalueExpected, "rL").WithLocation(14, 9));
            }
        }
 
        [WorkItem(62618, "https://github.com/dotnet/roslyn/issues/62618")]
        [Theory]
        [CombinatorialData]
        public void RefAssignValueScopeMismatch_02(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersion,
            bool useUnsafe)
        {
            string unsafeModifier = useUnsafe ? "unsafe" : "";
            var source =
$@"ref struct R
{{
    public R(ref int i) {{ }}
}}
class Program
{{
    static void Main()
    {{
        R r = default;
        M(ref r);
    }}
    {unsafeModifier} static void M(ref R r1)
    {{
        int i = 0;
        R local = new R(ref i);
        ref R r2 = ref local;
        r2 = ref r1; // 1
        r2 = local;
    }}
}}";
            var comp = CreateCompilation(source,
                parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
                options: (useUnsafe ? TestOptions.UnsafeReleaseExe : null));
            if (languageVersion == LanguageVersion.CSharp10)
            {
                comp.VerifyEmitDiagnostics();
            }
            else if (useUnsafe)
            {
                comp.VerifyEmitDiagnostics(
                    // (17,9): warning CS9097: This ref-assigns 'r1' to 'r2' but 'r1' has a wider value escape scope than 'r2' allowing assignment through 'r2' of values with narrower escapes scopes than 'r1'.
                    //         r2 = ref r1; // 1
                    Diagnostic(ErrorCode.WRN_RefAssignValEscapeWider, "r2 = ref r1").WithArguments("r2", "r1").WithLocation(17, 9));
            }
            else
            {
                comp.VerifyEmitDiagnostics(
                    // (17,9): error CS9096: Cannot ref-assign 'r1' to 'r2' because 'r1' has a wider value escape scope than 'r2' allowing assignment through 'r2' of values with narrower escapes scopes than 'r1'.
                    //         r2 = ref r1; // 1
                    Diagnostic(ErrorCode.ERR_RefAssignValEscapeWider, "r2 = ref r1").WithArguments("r2", "r1").WithLocation(17, 9));
            }
        }
 
        [WorkItem(62618, "https://github.com/dotnet/roslyn/issues/62618")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefAssignValueScopeMismatch_03(LanguageVersion languageVersion)
        {
            var source =
@"ref struct R1
{
    public R2 F;
}
ref struct R2
{
    public R2(ref int i) { }
}
class Program
{
    static void Main()
    {
        R1 r = default;
        M(ref r);
    }
    static void M(ref R1 r1)
    {
        int i = 0;
        R2 local = new R2(ref i);
        ref R2 r2 = ref local;
        r2 = ref r1.F; // 1
        r2 = local;
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            if (languageVersion == LanguageVersion.CSharp10)
            {
                comp.VerifyEmitDiagnostics();
            }
            else
            {
                comp.VerifyEmitDiagnostics(
                    // (21,9): error CS9096: Cannot ref-assign 'r1.F' to 'r2' because 'r1.F' has a wider value escape scope than 'r2' allowing assignment through 'r2' of values with narrower escapes scopes than 'r1.F'.
                    //         r2 = ref r1.F; // 1
                    Diagnostic(ErrorCode.ERR_RefAssignValEscapeWider, "r2 = ref r1.F").WithArguments("r2", "r1.F").WithLocation(21, 9));
            }
        }
 
        [WorkItem(62618, "https://github.com/dotnet/roslyn/issues/62618")]
        [Fact]
        public void RefAssignValueScopeMismatch_04()
        {
            var source =
@"using System;
class Program
{
    static Span<int> F()
    {
        Span<int> s1 = default;
        {
            scoped ref Span<int> r1 = ref s1;
            Span<int> s2 = stackalloc int[1];
            ref Span<int> r2 = ref s2;
            r2 = ref r1; // 1
            r2 = s2;
        }
        return s1;
    }
}";
            var comp = CreateCompilationWithSpanAndMemoryExtensions(source);
            comp.VerifyEmitDiagnostics(
                // (11,13): error CS9096: Cannot ref-assign 'r1' to 'r2' because 'r1' has a wider value escape scope than 'r2' allowing assignment through 'r2' of values with narrower escapes scopes than 'r1'.
                //             r2 = ref r1; // 1
                Diagnostic(ErrorCode.ERR_RefAssignValEscapeWider, "r2 = ref r1").WithArguments("r2", "r1").WithLocation(11, 13));
        }
 
        [WorkItem(62618, "https://github.com/dotnet/roslyn/issues/62618")]
        [Fact]
        public void RefAssignValueScopeMismatch_05()
        {
            var source =
@"ref struct S
{
    public S(ref int i) { }
}
class Program
{
    static S F()
    {
        S s1 = default;
        scoped ref S r1 = ref s1;
        int i = 0;
        S s2 = new S(ref i);
        ref S r2 = ref s2;
        r2 = ref r1; // 1
        r2 = s2;
        return s1;
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (14,9): error CS9096: Cannot ref-assign 'r1' to 'r2' because 'r1' has a wider value escape scope than 'r2' allowing assignment through 'r2' of values with narrower escapes scopes than 'r1'.
                //         r2 = ref r1; // 1
                Diagnostic(ErrorCode.ERR_RefAssignValEscapeWider, "r2 = ref r1").WithArguments("r2", "r1").WithLocation(14, 9));
        }
 
        [Theory]
        [CombinatorialData]
        public void RefAssignValueScopeMismatch_06(bool useUnsafe)
        {
            string unsafeModifier = useUnsafe ? "unsafe" : "";
            var source =
$@"ref struct S
{{
    public S(ref int i) {{ }}
}}
class Program
{{
    {unsafeModifier} static S F()
    {{
        S s1 = default;
        scoped ref S r1 = ref s1;
        scoped S s2 = default;
        ref S r2 = ref s2;
        r1 = ref r2; // 1
        r2 = s2;
        return s1;
    }}
}}";
            var comp = CreateCompilation(source,
                options: (useUnsafe ? TestOptions.UnsafeReleaseDll : null));
            if (useUnsafe)
            {
                comp.VerifyEmitDiagnostics(
                    // (13,18): warning CS9080: Use of variable 'r2' in this context may expose referenced variables outside of their declaration scope
                    //         r1 = ref r2; // 1
                    Diagnostic(ErrorCode.WRN_EscapeVariable, "r2").WithArguments("r2").WithLocation(13, 18));
            }
            else
            {
                comp.VerifyEmitDiagnostics(
                    // (13,18): error CS8352: Cannot use variable 'r2' in this context because it may expose referenced variables outside of their declaration scope
                    //         r1 = ref r2;
                    Diagnostic(ErrorCode.ERR_EscapeVariable, "r2").WithArguments("r2").WithLocation(13, 18));
            }
        }
 
        // Breaking change in C#11: Cannot return an 'out' parameter by reference.
        [Fact]
        public void BreakingChange_ReturnOutByRef()
        {
            var source =
@"class Program
{
    static ref T ReturnOutParamByRef<T>(out T t)
    {
        t = default;
        return ref t;
    }
}";
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics();
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (6,20): error CS9075: Cannot return a parameter by reference 't' because it is scoped to the current method
                //         return ref t;
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "t").WithArguments("t").WithLocation(6, 20));
        }
 
        [Theory]
        [CombinatorialData]
        public void InstanceMethodCannotCaptureRefByRef(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionA,
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionB,
            bool useCompilationReference)
        {
            var sourceA =
@"public ref struct R<T>
{
    public void MayCaptureArg(ref T t) { }
}";
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionA));
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class Program
{
    static R<int> Use(R<int> r)
    {
        int i = 42;
        r.MayCaptureArg(ref i);
        return r;
    }
}";
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionB));
            comp.VerifyEmitDiagnostics();
        }
 
        [Theory]
        [CombinatorialData]
        public void RefStructInstanceMethodMayCaptureRef(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionA,
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionB,
            bool useCompilationReference)
        {
            var sourceA =
@"public ref struct R<T>
{
    public void MayCaptureArg(ref T t) { }
    public static R<int> Create(ref int i) => default;
}";
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionA));
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class Program
{
    static void Use()
    {
        int x = 1;
        int y = 2;
        R<int>.Create(ref x).MayCaptureArg(ref y);
    }
}";
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionB));
            comp.VerifyEmitDiagnostics();
        }
 
        // Breaking change in C#11: The rvalue from a method invocation that
        // returns a ref struct is safe-to-escape from ... the ref-safe-to-escape of all ref arguments.
        [Theory]
        [CombinatorialData]
        public void BreakingChange_RefStructReturnFromRefArguments_01(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionA,
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionB,
            bool useCompilationReference)
        {
            var sourceA =
@"public ref struct R { }
public class A
{
    public static R MayCaptureArg(ref int i) => new R();
    public static R MayCaptureDefaultArg(in int i = 0) => new R();
}";
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionA));
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class B : A
{
    static R Create()
    {
        int i = 0;
        return MayCaptureArg(ref i);
    }
    static R CreateDefault()
    {
        return MayCaptureDefaultArg();
    }
}";
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionB));
            if (languageVersionA == LanguageVersion.CSharp10)
            {
                comp.VerifyEmitDiagnostics();
            }
            else
            {
                comp.VerifyEmitDiagnostics(
                    // (6,16): error CS8347: Cannot use a result of 'A.MayCaptureArg(ref int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                    //         return MayCaptureArg(ref i);
                    Diagnostic(ErrorCode.ERR_EscapeCall, "MayCaptureArg(ref i)").WithArguments("A.MayCaptureArg(ref int)", "i").WithLocation(6, 16),
                    // (6,34): error CS8168: Cannot return local 'i' by reference because it is not a ref local
                    //         return MayCaptureArg(ref i);
                    Diagnostic(ErrorCode.ERR_RefReturnLocal, "i").WithArguments("i").WithLocation(6, 34),
                    // (10,16): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                    //         return MayCaptureDefaultArg();
                    Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "MayCaptureDefaultArg()").WithLocation(10, 16),
                    // (10,16): error CS8347: Cannot use a result of 'A.MayCaptureDefaultArg(in int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                    //         return MayCaptureDefaultArg();
                    Diagnostic(ErrorCode.ERR_EscapeCall, "MayCaptureDefaultArg()").WithArguments("A.MayCaptureDefaultArg(in int)", "i").WithLocation(10, 16));
            }
        }
 
        // Another version of the breaking change above, this time
        // with ref structs passed by reference as constructor this.
        [WorkItem(62940, "https://github.com/dotnet/roslyn/issues/62940")]
        [Theory]
        [CombinatorialData]
        public void BreakingChange_RefStructReturnFromRefArguments_02(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionA,
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionB,
            bool useCompilationReference)
        {
            var sourceA =
@"public ref struct R1
{
    public R1(ref object o) { }
}
public readonly ref struct R2
{
    public R2(in object o) { }
}";
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionA));
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class Program
{
    static R1 F1()
    {
        var o = new object();
        return new R1(ref o);
    }
    static R2 F2()
    {
        return new R2(new object());
    }
}";
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionB));
            if (languageVersionA == LanguageVersion.CSharp10)
            {
                comp.VerifyEmitDiagnostics();
            }
            else
            {
                comp.VerifyEmitDiagnostics(
                    // (6,16): error CS8347: Cannot use a result of 'R1.R1(ref object)' in this context because it may expose variables referenced by parameter 'o' outside of their declaration scope
                    //         return new R1(ref o);
                    Diagnostic(ErrorCode.ERR_EscapeCall, "new R1(ref o)").WithArguments("R1.R1(ref object)", "o").WithLocation(6, 16),
                    // (6,27): error CS8168: Cannot return local 'o' by reference because it is not a ref local
                    //         return new R1(ref o);
                    Diagnostic(ErrorCode.ERR_RefReturnLocal, "o").WithArguments("o").WithLocation(6, 27),
                    // (10,16): error CS8347: Cannot use a result of 'R2.R2(in object)' in this context because it may expose variables referenced by parameter 'o' outside of their declaration scope
                    //         return new R2(new object());
                    Diagnostic(ErrorCode.ERR_EscapeCall, "new R2(new object())").WithArguments("R2.R2(in object)", "o").WithLocation(10, 16),
                    // (10,23): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                    //         return new R2(new object());
                    Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "new object()").WithLocation(10, 23));
            }
        }
 
        // Another version of the breaking change above, this time
        // with a function pointer type.
        [Theory]
        [CombinatorialData]
        public void BreakingChange_RefStructReturnFromRefArguments_03(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionA,
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionB,
            bool useCompilationReference)
        {
            var sourceA =
@"public ref struct R { }
unsafe public class A
{
    private static R _MayCaptureArg(ref int i) => new R();
    public static delegate*<ref int, R> MayCaptureArg = &_MayCaptureArg;
}";
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionA), options: TestOptions.UnsafeReleaseDll);
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class B : A
{
    unsafe static R Create()
    {
        int i = 0;
        return MayCaptureArg(ref i);
    }
}";
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionB), options: TestOptions.UnsafeReleaseDll);
            if (languageVersionA == LanguageVersion.CSharp10)
            {
                comp.VerifyEmitDiagnostics();
            }
            else
            {
                comp.VerifyEmitDiagnostics(
                    // (6,34): warning CS9091: This returns local 'i' by reference but it is not a ref local
                    //         return MayCaptureArg(ref i);
                    Diagnostic(ErrorCode.WRN_RefReturnLocal, "i").WithArguments("i").WithLocation(6, 34));
            }
        }
 
        // Breaking change in C#11: A ref to ref struct argument is considered
        // an unscoped reference when passed to an __arglist.
        [Theory]
        [CombinatorialData]
        public void BreakingChange_RefToRefStructInArglist(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionA,
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionB,
            bool useCompilationReference)
        {
            var sourceA =
@"public ref struct R { }
public class A
{
    public static void MayCaptureRef(__arglist) { }
}";
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionA));
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class B : A
{
    static void Main()
    {
        var r = new R();
        MayCaptureRef(__arglist(ref r)); // error: may expose variables outside of their declaration scope
    }
}";
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionB));
            comp.VerifyEmitDiagnostics();
        }
 
        [Theory]
        [CombinatorialData]
        public void ParameterScope_01(bool useCompilationReference)
        {
            var sourceA =
@"public ref struct R
{
    public R(ref int i) { }
}
public static class A
{
    public static void F1(R x1, scoped R y1) { }
    public static void F2(ref R x2, scoped ref R y2) { }
    public static void F3(in R x3, scoped in R y3) { }
    public static void F4(out R x4, scoped out R y4) { x4 = default; y4 = default; }
}";
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (7,33): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     public static void F1(R x1, scoped R y1) { }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(7, 33),
                // (8,37): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     public static void F2(ref R x2, scoped ref R y2) { }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(8, 37),
                // (9,36): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     public static void F3(in R x3, scoped in R y3) { }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(9, 36),
                // (10,37): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     public static void F4(out R x4, scoped out R y4) { x4 = default; y4 = default; }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(10, 37));
 
            verify(comp, useUpdatedEscapeRules: false);
 
            comp = CreateCompilation(sourceA);
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"static class B
{
    static void F(ref R x)
    {
        int i = 0;
        R y = new R(ref i);
        A.F2(ref x, ref y);
    }
}";
            comp = CreateCompilation(sourceB, references: new[] { refA });
            comp.VerifyEmitDiagnostics(
                // (7,9): error CS8350: This combination of arguments to 'A.F2(ref R, scoped ref R)' is disallowed because it may expose variables referenced by parameter 'y2' outside of their declaration scope
                //         A.F2(ref x, ref y);
                Diagnostic(ErrorCode.ERR_CallArgMixing, "A.F2(ref x, ref y)").WithArguments("A.F2(ref R, scoped ref R)", "y2").WithLocation(7, 9),
                // (7,25): error CS8352: Cannot use variable 'y' in this context because it may expose referenced variables outside of their declaration scope
                //         A.F2(ref x, ref y);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y").WithArguments("y").WithLocation(7, 25));
 
            verify(comp, useUpdatedEscapeRules: true);
 
            static void verify(CSharpCompilation comp, bool useUpdatedEscapeRules)
            {
                var parameters = comp.GetMember<MethodSymbol>("A.F1").Parameters;
                VerifyParameterSymbol(parameters[0], "R x1", RefKind.None, ScopedKind.None);
                VerifyParameterSymbol(parameters[1], "scoped R y1", RefKind.None, ScopedKind.ScopedValue);
 
                parameters = comp.GetMember<MethodSymbol>("A.F2").Parameters;
                VerifyParameterSymbol(parameters[0], "ref R x2", RefKind.Ref, ScopedKind.None);
                VerifyParameterSymbol(parameters[1], "scoped ref R y2", RefKind.Ref, ScopedKind.ScopedRef);
 
                parameters = comp.GetMember<MethodSymbol>("A.F3").Parameters;
                VerifyParameterSymbol(parameters[0], "in R x3", RefKind.In, ScopedKind.None);
                VerifyParameterSymbol(parameters[1], "scoped in R y3", RefKind.In, ScopedKind.ScopedRef);
 
                parameters = comp.GetMember<MethodSymbol>("A.F4").Parameters;
                VerifyParameterSymbol(parameters[0], "out R x4", RefKind.Out, useUpdatedEscapeRules ? ScopedKind.ScopedRef : ScopedKind.None);
                VerifyParameterSymbol(parameters[1], "out R y4", RefKind.Out, ScopedKind.ScopedRef);
            }
        }
 
        [Fact]
        public void ParameterScope_02()
        {
            var source =
@"ref struct A<T>
{
    A(scoped ref T t) { }
    T this[scoped in object o] => default;
    public static implicit operator B<T>(scoped in A<T> a) => default;
}
struct B<T>
{
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (3,7): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     A(scoped ref T t) { }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(3, 7),
                // (4,12): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     T this[scoped in object o] => default;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(4, 12),
                // (5,42): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     public static implicit operator B<T>(scoped in A<T> a) => default;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(5, 42));
            verify(comp);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                VerifyParameterSymbol(comp.GetMember<NamedTypeSymbol>("A").Constructors.Single(c => !c.IsImplicitlyDeclared).Parameters[0], "scoped ref T t", RefKind.Ref, ScopedKind.ScopedRef);
                VerifyParameterSymbol(comp.GetMember<PropertySymbol>("A.this[]").GetMethod.Parameters[0], "scoped in System.Object o", RefKind.In, ScopedKind.ScopedRef);
            }
        }
 
        [Fact]
        public void ParameterScope_03()
        {
            var source =
@"ref struct R { }
class Program
{
    static void Main()
    {
#pragma warning disable 8321
        static void L1(R x1, scoped R y1) { }
        static void L2(ref int x2, scoped ref int y2) { }
        static void L3(in int x3, scoped in int y3) { }
        static void L4(out int x4, scoped out int y4) { x4 = 0; y4 = 0; }
        static void L5(ref R x5, scoped ref R y5) { }
        static void L6(in R x6, scoped in R y6) { }
        static void L7(out R x7, scoped out R y7) { x7 = default; y7 = default; }
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (7,30): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         static void L1(R x1, scoped R y1) { }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(7, 30),
                // (8,36): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         static void L2(ref int x2, scoped ref int y2) { }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(8, 36),
                // (9,35): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         static void L3(in int x3, scoped in int y3) { }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(9, 35),
                // (10,36): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         static void L4(out int x4, scoped out int y4) { x4 = 0; y4 = 0; }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(10, 36),
                // (11,34): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         static void L5(ref R x5, scoped ref R y5) { }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(11, 34),
                // (12,33): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         static void L6(in R x6, scoped in R y6) { }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(12, 33),
                // (13,34): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         static void L7(out R x7, scoped out R y7) { x7 = default; y7 = default; }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(13, 34));
            verify(comp, useUpdatedEscapeRules: false);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
            verify(comp, useUpdatedEscapeRules: true);
 
            static void verify(CSharpCompilation comp, bool useUpdatedEscapeRules)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<LocalFunctionStatementSyntax>().ToArray();
                var localFunctions = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalFunctionSymbol>()).ToArray();
 
                VerifyParameterSymbol(localFunctions[0].Parameters[0], "R x1", RefKind.None, ScopedKind.None);
                VerifyParameterSymbol(localFunctions[0].Parameters[1], "scoped R y1", RefKind.None, ScopedKind.ScopedValue);
                VerifyParameterSymbol(localFunctions[1].Parameters[0], "ref System.Int32 x2", RefKind.Ref, ScopedKind.None);
                VerifyParameterSymbol(localFunctions[1].Parameters[1], "scoped ref System.Int32 y2", RefKind.Ref, ScopedKind.ScopedRef);
                VerifyParameterSymbol(localFunctions[2].Parameters[0], "in System.Int32 x3", RefKind.In, ScopedKind.None);
                VerifyParameterSymbol(localFunctions[2].Parameters[1], "scoped in System.Int32 y3", RefKind.In, ScopedKind.ScopedRef);
                VerifyParameterSymbol(localFunctions[3].Parameters[0], "out System.Int32 x4", RefKind.Out, useUpdatedEscapeRules ? ScopedKind.ScopedRef : ScopedKind.None);
                VerifyParameterSymbol(localFunctions[3].Parameters[1], "out System.Int32 y4", RefKind.Out, ScopedKind.ScopedRef);
                VerifyParameterSymbol(localFunctions[4].Parameters[0], "ref R x5", RefKind.Ref, ScopedKind.None);
                VerifyParameterSymbol(localFunctions[4].Parameters[1], "scoped ref R y5", RefKind.Ref, ScopedKind.ScopedRef);
                VerifyParameterSymbol(localFunctions[5].Parameters[0], "in R x6", RefKind.In, ScopedKind.None);
                VerifyParameterSymbol(localFunctions[5].Parameters[1], "scoped in R y6", RefKind.In, ScopedKind.ScopedRef);
                VerifyParameterSymbol(localFunctions[6].Parameters[0], "out R x7", RefKind.Out, useUpdatedEscapeRules ? ScopedKind.ScopedRef : ScopedKind.None);
                VerifyParameterSymbol(localFunctions[6].Parameters[1], "out R y7", RefKind.Out, ScopedKind.ScopedRef);
            }
        }
 
        [Fact]
        public void ParameterScope_04()
        {
            var source =
@"ref struct R { }
class Program
{
    static void Main()
    {
        var f1 = (R x1, scoped R y1) => { };
        var f2 = (ref int x2, scoped ref int y2) => { };
        var f3 = (in int x3, scoped in int y3) => { };
        var f4 = (out int x4, scoped out int y4, [System.Diagnostics.CodeAnalysis.UnscopedRefAttribute] out int z4) => { x4 = 0; y4 = 0; z4 = 0; };
        var f5 = (ref R x5, scoped ref R y5) => { };
        var f6 = (in R x6, scoped in R y6) => { };
        var f7 = (out R x7, scoped out R y7) => { x7 = default; y7 = default; };
    }
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (6,25): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         var f1 = (R x1, scoped R y1) => { };
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(6, 25),
                // (7,31): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         var f2 = (ref int x2, scoped ref int y2) => { };
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(7, 31),
                // (8,30): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         var f3 = (in int x3, scoped in int y3) => { };
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(8, 30),
                // (9,31): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         var f4 = (out int x4, scoped out int y4, [System.Diagnostics.CodeAnalysis.UnscopedRefAttribute] out int z4) => { x4 = 0; y4 = 0; z4 = 0; };
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(9, 31),
                // (9,51): error CS9063: UnscopedRefAttribute cannot be applied to this item because it is unscoped by default.
                //         var f4 = (out int x4, scoped out int y4, [System.Diagnostics.CodeAnalysis.UnscopedRefAttribute] out int z4) => { x4 = 0; y4 = 0; z4 = 0; };
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedTarget, "System.Diagnostics.CodeAnalysis.UnscopedRefAttribute").WithLocation(9, 51),
                // (10,29): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         var f5 = (ref R x5, scoped ref R y5) => { };
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(10, 29),
                // (11,28): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         var f6 = (in R x6, scoped in R y6) => { };
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(11, 28),
                // (12,29): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         var f7 = (out R x7, scoped out R y7) => { x7 = default; y7 = default; };
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(12, 29));
            verify(comp, useUpdatedEscapeRules: false);
 
            comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyEmitDiagnostics();
            verify(comp, useUpdatedEscapeRules: true);
 
            static void verify(CSharpCompilation comp, bool useUpdatedEscapeRules)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var delegateTypesAndLambdas = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Select(d => getDelegateTypeAndLambda(model, d)).ToArray();
 
                verifyParameter(delegateTypesAndLambdas[0], 0, "R", "x1", RefKind.None, ScopedKind.None, false);
                verifyParameter(delegateTypesAndLambdas[0], 1, "scoped R", "y1", RefKind.None, ScopedKind.ScopedValue, false);
                verifyParameter(delegateTypesAndLambdas[1], 0, "ref System.Int32", "x2", RefKind.Ref, ScopedKind.None, false);
                verifyParameter(delegateTypesAndLambdas[1], 1, "scoped ref System.Int32", "y2", RefKind.Ref, ScopedKind.ScopedRef, false);
                verifyParameter(delegateTypesAndLambdas[2], 0, "in System.Int32", "x3", RefKind.In, ScopedKind.None, false);
                verifyParameter(delegateTypesAndLambdas[2], 1, "scoped in System.Int32", "y3", RefKind.In, ScopedKind.ScopedRef, false);
                verifyParameter(delegateTypesAndLambdas[3], 0, "out System.Int32", "x4", RefKind.Out, useUpdatedEscapeRules ? ScopedKind.ScopedRef : ScopedKind.None, false);
                verifyParameter(delegateTypesAndLambdas[3], 1, "out System.Int32", "y4", RefKind.Out, ScopedKind.ScopedRef, false);
                verifyParameter(delegateTypesAndLambdas[3], 2, "out System.Int32", "z4", RefKind.Out, ScopedKind.None, true);
                verifyParameter(delegateTypesAndLambdas[4], 0, "ref R", "x5", RefKind.Ref, ScopedKind.None, false);
                verifyParameter(delegateTypesAndLambdas[4], 1, "scoped ref R", "y5", RefKind.Ref, ScopedKind.ScopedRef, false);
                verifyParameter(delegateTypesAndLambdas[5], 0, "in R", "x6", RefKind.In, ScopedKind.None, false);
                verifyParameter(delegateTypesAndLambdas[5], 1, "scoped in R", "y6", RefKind.In, ScopedKind.ScopedRef, false);
                verifyParameter(delegateTypesAndLambdas[6], 0, "out R", "x7", RefKind.Out, useUpdatedEscapeRules ? ScopedKind.ScopedRef : ScopedKind.None, false);
                verifyParameter(delegateTypesAndLambdas[6], 1, "out R", "y7", RefKind.Out, ScopedKind.ScopedRef, false);
            }
 
            static void verifyParameter((NamedTypeSymbol, LambdaSymbol) delegateTypeAndLambda, int parameterIndex, string expectedDisplayType, string expectedDisplayName, RefKind expectedRefKind, ScopedKind expectedScope, bool expectedHasUnscopedRefAttribute)
            {
                var (delegateType, lambda) = delegateTypeAndLambda;
                VerifyParameterSymbol(delegateType.DelegateInvokeMethod.Parameters[parameterIndex], $"{expectedDisplayType} arg{parameterIndex + 1}", expectedRefKind, expectedScope, expectedHasUnscopedRefAttribute);
                VerifyParameterSymbol(lambda.Parameters[parameterIndex], $"{expectedDisplayType} {expectedDisplayName}", expectedRefKind, expectedScope, expectedHasUnscopedRefAttribute);
            }
 
            static (NamedTypeSymbol, LambdaSymbol) getDelegateTypeAndLambda(SemanticModel model, VariableDeclaratorSyntax decl)
            {
                var delegateType = (NamedTypeSymbol)model.GetDeclaredSymbol(decl).GetSymbol<LocalSymbol>().Type;
                var value = decl.DescendantNodes().OfType<ParenthesizedLambdaExpressionSyntax>().Single();
                var lambda = model.GetSymbolInfo(value).Symbol.GetSymbol<LambdaSymbol>();
                return (delegateType, lambda);
            }
        }
 
        [Fact]
        public void ParameterScope_05()
        {
            var source =
@"ref struct R { }
delegate void D1(scoped R r1);
delegate void D2(scoped ref R r2);
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (2,18): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                // delegate void D1(scoped R r1);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(2, 18),
                // (3,18): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                // delegate void D2(scoped ref R r2);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(3, 18));
            verify(comp, useUpdatedEscapeRules: false);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
            verify(comp, useUpdatedEscapeRules: true);
 
            static void verify(CSharpCompilation comp, bool useUpdatedEscapeRules)
            {
                VerifyParameterSymbol(comp.GetMember<NamedTypeSymbol>("D1").DelegateInvokeMethod.Parameters[0], "scoped R r1", RefKind.None, ScopedKind.ScopedValue);
                VerifyParameterSymbol(comp.GetMember<NamedTypeSymbol>("D2").DelegateInvokeMethod.Parameters[0], "scoped ref R r2", RefKind.Ref, ScopedKind.ScopedRef);
            }
        }
 
        [Fact]
        public void ParameterScope_06()
        {
            var source =
@"ref struct R { }
class Program
{
    static void F1(scoped R r1) { }
    static void F2(scoped ref R x, scoped ref int y) { }
    static ref R F3(ref R r) => throw null;
    static unsafe void Main()
    {
        delegate*<scoped R, void> f1 = &F1;
        delegate*<scoped ref R, scoped ref int, void> f2 = &F2;
        delegate*<ref R, ref R> f3 = &F3;
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10, options: TestOptions.UnsafeReleaseExe);
            comp.VerifyEmitDiagnostics(
                // (4,20): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     static void F1(scoped R r1) { }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(4, 20),
                // (5,20): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     static void F2(scoped ref R x, scoped ref int y) { }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(5, 20),
                // (5,36): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     static void F2(scoped ref R x, scoped ref int y) { }
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(5, 36),
                // (9,19): error CS8755: 'scoped' cannot be used as a modifier on a function pointer parameter.
                //         delegate*<scoped R, void> f1 = &F1;
                Diagnostic(ErrorCode.ERR_BadFuncPointerParamModifier, "scoped").WithArguments("scoped").WithLocation(9, 19),
                // (10,19): error CS8755: 'scoped' cannot be used as a modifier on a function pointer parameter.
                //         delegate*<scoped ref R, scoped ref int, void> f2 = &F2;
                Diagnostic(ErrorCode.ERR_BadFuncPointerParamModifier, "scoped").WithArguments("scoped").WithLocation(10, 19),
                // (10,33): error CS8755: 'scoped' cannot be used as a modifier on a function pointer parameter.
                //         delegate*<scoped ref R, scoped ref int, void> f2 = &F2;
                Diagnostic(ErrorCode.ERR_BadFuncPointerParamModifier, "scoped").WithArguments("scoped").WithLocation(10, 33)
                );
            verify(comp, useUpdatedEscapeRules: false);
 
            comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseExe);
            comp.VerifyEmitDiagnostics(
                // (9,19): error CS8755: 'scoped' cannot be used as a modifier on a function pointer parameter.
                //         delegate*<scoped R, void> f1 = &F1;
                Diagnostic(ErrorCode.ERR_BadFuncPointerParamModifier, "scoped").WithArguments("scoped").WithLocation(9, 19),
                // (10,19): error CS8755: 'scoped' cannot be used as a modifier on a function pointer parameter.
                //         delegate*<scoped ref R, scoped ref int, void> f2 = &F2;
                Diagnostic(ErrorCode.ERR_BadFuncPointerParamModifier, "scoped").WithArguments("scoped").WithLocation(10, 19),
                // (10,33): error CS8755: 'scoped' cannot be used as a modifier on a function pointer parameter.
                //         delegate*<scoped ref R, scoped ref int, void> f2 = &F2;
                Diagnostic(ErrorCode.ERR_BadFuncPointerParamModifier, "scoped").WithArguments("scoped").WithLocation(10, 33)
                );
            verify(comp, useUpdatedEscapeRules: true);
 
            static void verify(CSharpCompilation comp, bool useUpdatedEscapeRules)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
                var methods = decls.Select(d => ((FunctionPointerTypeSymbol)model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>().Type).Signature).ToArray();
 
                VerifyParameterSymbol(methods[0].Parameters[0], "R", RefKind.None, ScopedKind.None);
                VerifyParameterSymbol(methods[1].Parameters[0], "ref R", RefKind.Ref, ScopedKind.None);
                VerifyParameterSymbol(methods[1].Parameters[1], "ref System.Int32", RefKind.Ref, ScopedKind.None);
                VerifyParameterSymbol(methods[2].Parameters[0], "ref R", RefKind.Ref, ScopedKind.None);
            }
        }
 
        [Fact]
        public void ParameterScope_07()
        {
            var source =
@"ref struct R { }
class Program
{
    static void F0(scoped R r) { }
    static void F3(scoped ref R r) { }
    static void F6(scoped in R r) { }
    static void F9(scoped out R r) { r = default; }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
 
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F0").Parameters[0], "scoped R r", RefKind.None, ScopedKind.ScopedValue);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F3").Parameters[0], "scoped ref R r", RefKind.Ref, ScopedKind.ScopedRef);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F6").Parameters[0], "scoped in R r", RefKind.In, ScopedKind.ScopedRef);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F9").Parameters[0], "out R r", RefKind.Out, ScopedKind.ScopedRef);
        }
 
        [Fact]
        public void ParameterScope_08()
        {
            var source =
@"ref struct R { }
class Program
{
    static void Main()
    {
        var f1 = (scoped scoped R r) => { };
        var f2 = (ref scoped scoped R r) => { };
        var f3 = (scoped scoped ref R r) => { };
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (6,19): error CS0103: The name 'scoped' does not exist in the current context
                //         var f1 = (scoped scoped R r) => { };
                Diagnostic(ErrorCode.ERR_NameNotInContext, "scoped").WithArguments("scoped").WithLocation(6, 19),
                // (6,26): error CS1026: ) expected
                //         var f1 = (scoped scoped R r) => { };
                Diagnostic(ErrorCode.ERR_CloseParenExpected, "scoped").WithLocation(6, 26),
                // (6,26): error CS1002: ; expected
                //         var f1 = (scoped scoped R r) => { };
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "scoped").WithLocation(6, 26),
                // (6,35): warning CS0168: The variable 'r' is declared but never used
                //         var f1 = (scoped scoped R r) => { };
                Diagnostic(ErrorCode.WRN_UnreferencedVar, "r").WithArguments("r").WithLocation(6, 35),
                // (6,36): error CS1002: ; expected
                //         var f1 = (scoped scoped R r) => { };
                Diagnostic(ErrorCode.ERR_SemicolonExpected, ")").WithLocation(6, 36),
                // (6,36): error CS1513: } expected
                //         var f1 = (scoped scoped R r) => { };
                Diagnostic(ErrorCode.ERR_RbraceExpected, ")").WithLocation(6, 36),
                // (7,19): error CS1525: Invalid expression term 'ref'
                //         var f2 = (ref scoped scoped R r) => { };
                Diagnostic(ErrorCode.ERR_InvalidExprTerm, "ref scoped").WithArguments("ref").WithLocation(7, 19),
                // (7,19): error CS1073: Unexpected token 'ref'
                //         var f2 = (ref scoped scoped R r) => { };
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(7, 19),
                // (7,30): error CS1026: ) expected
                //         var f2 = (ref scoped scoped R r) => { };
                Diagnostic(ErrorCode.ERR_CloseParenExpected, "scoped").WithLocation(7, 30),
                // (7,30): error CS1002: ; expected
                //         var f2 = (ref scoped scoped R r) => { };
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "scoped").WithLocation(7, 30),
                // (7,39): error CS0128: A local variable or function named 'r' is already defined in this scope
                //         var f2 = (ref scoped scoped R r) => { };
                Diagnostic(ErrorCode.ERR_LocalDuplicate, "r").WithArguments("r").WithLocation(7, 39),
                // (7,39): warning CS0168: The variable 'r' is declared but never used
                //         var f2 = (ref scoped scoped R r) => { };
                Diagnostic(ErrorCode.WRN_UnreferencedVar, "r").WithArguments("r").WithLocation(7, 39),
                // (7,40): error CS1002: ; expected
                //         var f2 = (ref scoped scoped R r) => { };
                Diagnostic(ErrorCode.ERR_SemicolonExpected, ")").WithLocation(7, 40),
                // (7,40): error CS1513: } expected
                //         var f2 = (ref scoped scoped R r) => { };
                Diagnostic(ErrorCode.ERR_RbraceExpected, ")").WithLocation(7, 40),
                // (8,19): error CS0103: The name 'scoped' does not exist in the current context
                //         var f3 = (scoped scoped ref R r) => { };
                Diagnostic(ErrorCode.ERR_NameNotInContext, "scoped").WithArguments("scoped").WithLocation(8, 19),
                // (8,26): error CS1026: ) expected
                //         var f3 = (scoped scoped ref R r) => { };
                Diagnostic(ErrorCode.ERR_CloseParenExpected, "scoped").WithLocation(8, 26),
                // (8,26): error CS1002: ; expected
                //         var f3 = (scoped scoped ref R r) => { };
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "scoped").WithLocation(8, 26),
                // (8,39): error CS0128: A local variable or function named 'r' is already defined in this scope
                //         var f3 = (scoped scoped ref R r) => { };
                Diagnostic(ErrorCode.ERR_LocalDuplicate, "r").WithArguments("r").WithLocation(8, 39),
                // (8,39): error CS8174: A declaration of a by-reference variable must have an initializer
                //         var f3 = (scoped scoped ref R r) => { };
                Diagnostic(ErrorCode.ERR_ByReferenceVariableMustBeInitialized, "r").WithLocation(8, 39),
                // (8,39): warning CS0168: The variable 'r' is declared but never used
                //         var f3 = (scoped scoped ref R r) => { };
                Diagnostic(ErrorCode.WRN_UnreferencedVar, "r").WithArguments("r").WithLocation(8, 39),
                // (8,40): error CS1002: ; expected
                //         var f3 = (scoped scoped ref R r) => { };
                Diagnostic(ErrorCode.ERR_SemicolonExpected, ")").WithLocation(8, 40),
                // (8,40): error CS1513: } expected
                //         var f3 = (scoped scoped ref R r) => { };
                Diagnostic(ErrorCode.ERR_RbraceExpected, ")").WithLocation(8, 40)
                );
        }
 
        [Fact]
        public void ParameterScope_09()
        {
            var source =
@"ref struct @scoped { }
class Program
{
    static void F0(scoped s) { }
    static void F1(scoped scoped s) { }
    static void F2(ref scoped s) { }
    static void F4(scoped ref scoped s) { }
    static void F5(in scoped s) { }
    static void F7(scoped in scoped s) { }
    static void F8(out scoped s) { s = default; }
    static void FA(scoped out scoped s) { s = default; }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
 
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F0").Parameters[0], "scoped s", RefKind.None, ScopedKind.None);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F1").Parameters[0], "scoped scoped s", RefKind.None, ScopedKind.ScopedValue);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F2").Parameters[0], "ref scoped s", RefKind.Ref, ScopedKind.None);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F4").Parameters[0], "scoped ref scoped s", RefKind.Ref, ScopedKind.ScopedRef);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F5").Parameters[0], "in scoped s", RefKind.In, ScopedKind.None);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F7").Parameters[0], "scoped in scoped s", RefKind.In, ScopedKind.ScopedRef);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F8").Parameters[0], "out scoped s", RefKind.Out, ScopedKind.ScopedRef);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.FA").Parameters[0], "out scoped s", RefKind.Out, ScopedKind.ScopedRef);
        }
 
        [WorkItem(62080, "https://github.com/dotnet/roslyn/issues/62080")]
        [Fact]
        public void ParameterScope_11()
        {
            var source =
@"ref struct R { }
delegate R D1(R r);
delegate R D2(scoped R r);
class Program
{
    static void Main()
    {
        D1 d1 = r1 => r1;
        D2 d2 = r2 => r2;
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (9,17): error CS8986: The 'scoped' modifier of parameter 'r2' doesn't match target 'D2'.
                //         D2 d2 = r2 => r2;
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "r2 => r2").WithArguments("r2", "D2").WithLocation(9, 17));
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var lambdas = tree.GetRoot().DescendantNodes().OfType<SimpleLambdaExpressionSyntax>().Select(e => model.GetSymbolInfo(e).Symbol.GetSymbol<LambdaSymbol>()).ToArray();
 
            VerifyParameterSymbol(lambdas[0].Parameters[0], "R r1", RefKind.None, ScopedKind.None);
            VerifyParameterSymbol(lambdas[1].Parameters[0], "R r2", RefKind.None, ScopedKind.None);
        }
 
        [Fact]
        public void ParameterScope_12()
        {
            var source0 =
@".assembly extern mscorlib { .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89) }
.assembly '<<GeneratedFileName>>' { }
.module '<<GeneratedFileName>>.dll'
.custom instance void System.Runtime.CompilerServices.RefSafetyRulesAttribute::.ctor(int32) = { int32(11) }
.class private System.Runtime.CompilerServices.RefSafetyRulesAttribute extends [mscorlib]System.Attribute
{
  .method public hidebysig specialname rtspecialname instance void .ctor(int32 version) cil managed { ret }
  .field public int32 Version
}
.class private System.Runtime.CompilerServices.ScopedRefAttribute extends [mscorlib]System.Attribute
{
  .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret }
}
.class public A
{
  .method public static void F1([out] int32& i)
  {
    .param [1]
    .custom instance void System.Runtime.CompilerServices.ScopedRefAttribute::.ctor() = ( 01 00 00 00 ) // ScopedRefAttribute()
    ldnull
    throw
  }
}
";
            var ref0 = CompileIL(source0, prependDefaultHeader: false);
 
            var source1 =
@"class Program
{
    static void Main()
    {
        int i;
        A.F1(out i);
    }
}";
            var comp = CreateCompilation(source1, references: new[] { ref0 });
            comp.VerifyDiagnostics();
 
            VerifyParameterSymbol(comp.GetMember<PEMethodSymbol>("A.F1").Parameters[0], "out System.Int32 i", RefKind.Out, ScopedKind.ScopedRef);
        }
 
        [WorkItem(62691, "https://github.com/dotnet/roslyn/issues/62691")]
        [CombinatorialData]
        [Theory]
        public void RefToRefStructParameter_01(bool useCompilationReference)
        {
            var sourceA =
@"public ref struct R { }
public class A
{
    public static void F(R a, ref R b, in R c, out R d) { d = default; }
}";
            var comp = CreateCompilation(sourceA);
            comp.VerifyDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class B
{
    static void Main()
    {
        R a = new R();
        R b = new R();
        R c = new R();
        scoped R d;
        A.F(a, ref b, in c, out d);
    }
}";
            comp = CreateCompilation(sourceB, references: new[] { refA });
            comp.VerifyEmitDiagnostics();
 
            var parameters = comp.GetMember<MethodSymbol>("A.F").Parameters;
            VerifyParameterSymbol(parameters[0], "R a", RefKind.None, ScopedKind.None);
            VerifyParameterSymbol(parameters[1], "ref R b", RefKind.Ref, ScopedKind.None);
            VerifyParameterSymbol(parameters[2], "in R c", RefKind.In, ScopedKind.None);
            VerifyParameterSymbol(parameters[3], "out R d", RefKind.Out, ScopedKind.ScopedRef);
        }
 
        [WorkItem(62691, "https://github.com/dotnet/roslyn/issues/62691")]
        [Fact]
        public void RefToRefStructParameter_02()
        {
            var source =
@"ref struct R
{
    public ref int F;
    public R(ref int i) { F = ref i; }
}
class Program
{
    static ref R F1()
    {
        int i = 42;
        var r1 = new R(ref i);
        return ref ReturnRef(ref r1);
    }
    static ref R F2(ref int i)
    {
        var r2 = new R(ref i);
        return ref ReturnRef(ref r2);
    }
    
    // NB: there is actually no valid implementation here except to throw.
    // With this signature, we will never be able to return any ref struct by reference.
    static ref R ReturnRef(scoped ref R r) => throw null;
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
 
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.ReturnRef").Parameters[0], "scoped ref R r", RefKind.Ref, ScopedKind.ScopedRef);
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void ThisScope(LanguageVersion languageVersion)
        {
            var source =
@"class C
{
    public C() { }
    void F1() { }
}
struct S1
{
    public S1() { }
    void F1() { }
    readonly void F2() { }
}
ref struct R1
{
    public R1() { }
    void F1() { }
    readonly void F2() { }
}
readonly struct S2
{
    public S2() { }
    void F1() { }
    readonly void F2() { }
}
readonly ref struct R2
{
    public R2() { }
    void F1() { }
    readonly void F2() { }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics();
 
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("C..ctor").ThisParameter, "C this", RefKind.None, ScopedKind.None);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("C.F1").ThisParameter, "C this", RefKind.None, ScopedKind.None);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("S1..ctor").ThisParameter, "out S1 this", RefKind.Out, ScopedKind.ScopedRef);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("S1.F1").ThisParameter, "ref S1 this", RefKind.Ref, ScopedKind.ScopedRef);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("S1.F2").ThisParameter, "in S1 this", RefKind.In, ScopedKind.ScopedRef);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("R1..ctor").ThisParameter, "out R1 this", RefKind.Out, ScopedKind.ScopedRef);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("R1.F1").ThisParameter, "ref R1 this", RefKind.Ref, ScopedKind.ScopedRef);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("R1.F2").ThisParameter, "in R1 this", RefKind.In, ScopedKind.ScopedRef);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("S2..ctor").ThisParameter, "out S2 this", RefKind.Out, ScopedKind.ScopedRef);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("S2.F1").ThisParameter, "in S2 this", RefKind.In, ScopedKind.ScopedRef);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("S2.F2").ThisParameter, "in S2 this", RefKind.In, ScopedKind.ScopedRef);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("R2..ctor").ThisParameter, "out R2 this", RefKind.Out, ScopedKind.ScopedRef);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("R2.F1").ThisParameter, "in R2 this", RefKind.In, ScopedKind.ScopedRef);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("R2.F2").ThisParameter, "in R2 this", RefKind.In, ScopedKind.ScopedRef);
 
            var type = comp.GetMember<NamedTypeSymbol>("S1");
            var thisParameter = new ThisParameterSymbol(forMethod: null, type); // "this" parameter for property for instance.
            VerifyParameterSymbol(thisParameter, "ref S1 this", RefKind.Ref, ScopedKind.ScopedRef);
 
            bool useUpdatedEscapeRules = languageVersion == LanguageVersion.CSharp11;
            Assert.Equal(useUpdatedEscapeRules, thisParameter.UseUpdatedEscapeRules);
 
            // https://github.com/dotnet/roslyn/issues/62780: Test additional cases with [UnscopedRef].
        }
 
        [Fact]
        public void ExtensionThisScope()
        {
            var source =
@"ref struct R<T> { }
static class Extensions
{
    static void F0(this R<object> r) { }
    static void F1(this scoped R<object> r) { }
    static void F2<T>(scoped this R<T> r) { }
    static void F3<T>(this scoped ref T t) where T : struct { }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (6,23): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
                //     static void F2<T>(scoped this R<T> r) { }
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(6, 23),
                // (6,30): error CS1001: Identifier expected
                //     static void F2<T>(scoped this R<T> r) { }
                Diagnostic(ErrorCode.ERR_IdentifierExpected, "this").WithLocation(6, 30),
                // (6,30): error CS1003: Syntax error, ',' expected
                //     static void F2<T>(scoped this R<T> r) { }
                Diagnostic(ErrorCode.ERR_SyntaxError, "this").WithArguments(",").WithLocation(6, 30),
                // (6,30): error CS1100: Method 'F2' has a parameter modifier 'this' which is not on the first parameter
                //     static void F2<T>(scoped this R<T> r) { }
                Diagnostic(ErrorCode.ERR_BadThisParam, "this").WithArguments("F2").WithLocation(6, 30)
                );
 
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Extensions.F0").Parameters[0], "R<System.Object> r", RefKind.None, ScopedKind.None);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Extensions.F1").Parameters[0], "scoped R<System.Object> r", RefKind.None, ScopedKind.ScopedValue);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Extensions.F2").Parameters[0], "scoped", RefKind.None, ScopedKind.None);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Extensions.F3").Parameters[0], "scoped ref T t", RefKind.Ref, ScopedKind.ScopedRef);
        }
 
        [Fact]
        public void ParamsScope()
        {
            var source =
@"class Program
{
 
    static void F2(params scoped object[] args) { }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (4,20): error CS8986: The 'scoped' modifier can be used for refs and ref struct values only.
                //     static void F2(params scoped object[] args) { }
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "params scoped object[] args").WithLocation(4, 20));
 
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F2").Parameters[0], "scoped params System.Object[] args", RefKind.None, ScopedKind.ScopedValue);
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void ReturnTypeScope(LanguageVersion langVersion)
        {
            var source =
@"ref struct R { }
class Program
{
    static scoped R F1<T>() => throw null;
    static scoped ref R F2<T>() => throw null;
    static void Main()
    {
#pragma warning disable 8321
        static scoped R L1<T>() => throw null;
        static scoped ref readonly R L2<T>() => throw null;
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
            comp.VerifyDiagnostics(
                // (4,21): error CS0106: The modifier 'scoped' is not valid for this item
                //     static scoped R F1<T>() => throw null;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "F1").WithArguments("scoped").WithLocation(4, 21),
                // (5,25): error CS0106: The modifier 'scoped' is not valid for this item
                //     static scoped ref R F2<T>() => throw null;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "F2").WithArguments("scoped").WithLocation(5, 25),
                // (9,16): error CS0106: The modifier 'scoped' is not valid for this item
                //         static scoped R L1<T>() => throw null;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "scoped").WithArguments("scoped").WithLocation(9, 16),
                // (10,16): error CS0106: The modifier 'scoped' is not valid for this item
                //         static scoped ref readonly R L2<T>() => throw null;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "scoped").WithArguments("scoped").WithLocation(10, 16));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DelegateReturnTypeScope(LanguageVersion langVersion)
        {
            var source =
@"ref struct R { }
delegate ref scoped R D();
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
            comp.VerifyEmitDiagnostics(
                // (2,14): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
                // delegate ref scoped R D();
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(2, 14),
                // (2,21): error CS0101: The namespace '<global namespace>' already contains a definition for 'R'
                // delegate ref scoped R D();
                Diagnostic(ErrorCode.ERR_DuplicateNameInNS, "R").WithArguments("R", "<global namespace>").WithLocation(2, 21),
                // (2,23): error CS1003: Syntax error, '(' expected
                // delegate ref scoped R D();
                Diagnostic(ErrorCode.ERR_SyntaxError, "D").WithArguments("(").WithLocation(2, 23),
                // (2,23): error CS0246: The type or namespace name 'D' could not be found (are you missing a using directive or an assembly reference?)
                // delegate ref scoped R D();
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "D").WithArguments("D").WithLocation(2, 23),
                // (2,24): error CS1001: Identifier expected
                // delegate ref scoped R D();
                Diagnostic(ErrorCode.ERR_IdentifierExpected, "(").WithLocation(2, 24),
                // (2,24): error CS1003: Syntax error, ',' expected
                // delegate ref scoped R D();
                Diagnostic(ErrorCode.ERR_SyntaxError, "(").WithArguments(",").WithLocation(2, 24),
                // (2,25): error CS8124: Tuple must contain at least two elements.
                // delegate ref scoped R D();
                Diagnostic(ErrorCode.ERR_TupleTooFewElements, ")").WithLocation(2, 25),
                // (2,26): error CS1001: Identifier expected
                // delegate ref scoped R D();
                Diagnostic(ErrorCode.ERR_IdentifierExpected, ";").WithLocation(2, 26),
                // (2,26): error CS1026: ) expected
                // delegate ref scoped R D();
                Diagnostic(ErrorCode.ERR_CloseParenExpected, ";").WithLocation(2, 26)
                );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void TypeScopeModifier_01(LanguageVersion langVersion)
        {
            var source =
@"scoped struct A { }
scoped ref struct B { }
scoped readonly ref struct C { }
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
            comp.VerifyDiagnostics(
                // (1,1): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
                // scoped struct A { }
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(1, 1),
                // (1,8): error CS1001: Identifier expected
                // scoped struct A { }
                Diagnostic(ErrorCode.ERR_IdentifierExpected, "struct").WithLocation(1, 8),
                // (1,8): error CS1002: ; expected
                // scoped struct A { }
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "struct").WithLocation(1, 8),
                // (2,12): error CS1031: Type expected
                // scoped ref struct B { }
                Diagnostic(ErrorCode.ERR_TypeExpected, "struct").WithLocation(2, 12),
                // (3,8): error CS1585: Member modifier 'readonly' must precede the member type and name
                // scoped readonly ref struct C { }
                Diagnostic(ErrorCode.ERR_BadModifierLocation, "readonly").WithArguments("readonly").WithLocation(3, 8)
                );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void TypeScopeModifier_02(LanguageVersion langVersion)
        {
            var source =
@"scoped record A { }
scoped readonly record struct B;
readonly scoped record struct C();
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
            comp.VerifyDiagnostics(
                // (1,8): error CS0118: 'record' is a variable but is used like a type
                // scoped record A { }
                Diagnostic(ErrorCode.ERR_BadSKknown, "record").WithArguments("record", "variable", "type").WithLocation(1, 8),
                // (1,15): error CS0116: A namespace cannot directly contain members such as fields, methods or statements
                // scoped record A { }
                Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "A").WithLocation(1, 15),
                // (1,15): error CS0106: The modifier 'scoped' is not valid for this item
                // scoped record A { }
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "A").WithArguments("scoped").WithLocation(1, 15),
                // (1,15): error CS0548: '<invalid-global-code>.A': property or indexer must have at least one accessor
                // scoped record A { }
                Diagnostic(ErrorCode.ERR_PropertyWithNoAccessors, "A").WithArguments("<invalid-global-code>.A").WithLocation(1, 15),
                // (2,8): error CS1585: Member modifier 'readonly' must precede the member type and name
                // scoped readonly record struct B;
                Diagnostic(ErrorCode.ERR_BadModifierLocation, "readonly").WithArguments("readonly").WithLocation(2, 8),
                // (3,1): error CS8803: Top-level statements must precede namespace and type declarations.
                // readonly scoped record struct C();
                Diagnostic(ErrorCode.ERR_TopLevelStatementAfterNamespaceOrType, "readonly scoped record ").WithLocation(3, 1),
                // (3,1): error CS0106: The modifier 'readonly' is not valid for this item
                // readonly scoped record struct C();
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "readonly").WithArguments("readonly").WithLocation(3, 1),
                // (3,10): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
                // readonly scoped record struct C();
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(3, 10),
                // (3,17): warning CS0168: The variable 'record' is declared but never used
                // readonly scoped record struct C();
                Diagnostic(ErrorCode.WRN_UnreferencedVar, "record").WithArguments("record").WithLocation(3, 17),
                // (3,24): error CS1002: ; expected
                // readonly scoped record struct C();
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "struct").WithLocation(3, 24),
                // (3,32): error CS8652: The feature 'primary constructors' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
                // readonly scoped record struct C();
                Diagnostic(ErrorCode.ERR_FeatureInPreview, "()").WithArguments("primary constructors").WithLocation(3, 32)
                );
        }
 
        [Fact]
        public void FieldTypeScope_01()
        {
            var source =
@"#pragma warning disable 169
ref struct R1 { }
ref struct R2
{
    scoped R1 F1;
    scoped ref int F3;
}";
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (5,15): error CS0106: The modifier 'scoped' is not valid for this item
                //     scoped R1 F1;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "F1").WithArguments("scoped").WithLocation(5, 15),
                // (6,12): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     scoped ref int F3;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "ref int").WithArguments("ref fields", "11.0").WithLocation(6, 12),
                // (6,20): error CS0106: The modifier 'scoped' is not valid for this item
                //     scoped ref int F3;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "F3").WithArguments("scoped").WithLocation(6, 20));
 
            comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (5,15): error CS0106: The modifier 'scoped' is not valid for this item
                //     scoped R1 F1;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "F1").WithArguments("scoped").WithLocation(5, 15),
                // (6,20): error CS0106: The modifier 'scoped' is not valid for this item
                //     scoped ref int F3;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "F3").WithArguments("scoped").WithLocation(6, 20));
        }
 
        [Fact]
        public void FieldTypeScope_02()
        {
            var source =
@"#pragma warning disable 169
ref struct R1 { }
ref struct R2
{
    scoped private R1 F1;
    scoped private ref int F3;
}";
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (5,12): error CS1585: Member modifier 'private' must precede the member type and name
                //     scoped private R1 F1;
                Diagnostic(ErrorCode.ERR_BadModifierLocation, "private").WithArguments("private").WithLocation(5, 12),
                // (6,12): error CS1585: Member modifier 'private' must precede the member type and name
                //     scoped private ref int F3;
                Diagnostic(ErrorCode.ERR_BadModifierLocation, "private").WithArguments("private").WithLocation(6, 12),
                // (6,20): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     scoped private ref int F3;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "ref int").WithArguments("ref fields", "11.0").WithLocation(6, 20));
 
            comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (5,12): error CS1585: Member modifier 'private' must precede the member type and name
                //     scoped private R1 F1;
                Diagnostic(ErrorCode.ERR_BadModifierLocation, "private").WithArguments("private").WithLocation(5, 12),
                // (6,12): error CS1585: Member modifier 'private' must precede the member type and name
                //     scoped private ref int F3;
                Diagnostic(ErrorCode.ERR_BadModifierLocation, "private").WithArguments("private").WithLocation(6, 12));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void PropertyTypeScope(LanguageVersion langVersion)
        {
            var source =
@"ref struct R1 { }
ref struct R2
{
    scoped R1 P1 { get; }
    scoped R1 P2 { get; init; }
    scoped R1 P3 { set { } }
    scoped ref int P5 => throw null;
}";
            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
            comp.VerifyDiagnostics(
                // (4,15): error CS0106: The modifier 'scoped' is not valid for this item
                //     scoped R1 P1 { get; }
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("scoped").WithLocation(4, 15),
                // (5,15): error CS0106: The modifier 'scoped' is not valid for this item
                //     scoped R1 P2 { get; init; }
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "P2").WithArguments("scoped").WithLocation(5, 15),
                // (6,15): error CS0106: The modifier 'scoped' is not valid for this item
                //     scoped R1 P3 { set { } }
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "P3").WithArguments("scoped").WithLocation(6, 15),
                // (7,20): error CS0106: The modifier 'scoped' is not valid for this item
                //     scoped ref int P5 => throw null;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "P5").WithArguments("scoped").WithLocation(7, 20));
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                verifyValueParameter(comp.GetMember<PropertySymbol>("R2.P2"), "R1 value", RefKind.None, ScopedKind.None);
                verifyValueParameter(comp.GetMember<PropertySymbol>("R2.P3"), "R1 value", RefKind.None, ScopedKind.None);
            }
 
            static void verifyValueParameter(PropertySymbol property, string expectedDisplayString, RefKind expectedRefKind, ScopedKind expectedScope)
            {
                Assert.Equal(expectedRefKind, property.RefKind);
                VerifyParameterSymbol(property.SetMethod.Parameters[0], expectedDisplayString, expectedRefKind, expectedScope);
            }
        }
 
        [Fact]
        public void SubstitutedParameter()
        {
            var source =
@"ref struct R<T> { }
class A<T>
{
    public static void F(scoped R<T> x, scoped in T y) { }
}
class B : A<int>
{
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
 
            var method = (MethodSymbol)comp.GetMember<NamedTypeSymbol>("B").BaseTypeNoUseSiteDiagnostics.GetMember("F");
            VerifyParameterSymbol(method.Parameters[0], "scoped R<System.Int32> x", RefKind.None, ScopedKind.ScopedValue);
            VerifyParameterSymbol(method.Parameters[1], "scoped in System.Int32 y", RefKind.In, ScopedKind.ScopedRef);
        }
 
        [Fact]
        public void RetargetingParameter()
        {
            var sourceA =
@"public ref struct R { }
public class A
{
    public static void F(scoped R x, scoped in int y) { }
}
";
            var comp = CreateCompilation(sourceA, targetFramework: TargetFramework.Mscorlib40);
            var refA = comp.ToMetadataReference();
 
            var sourceB =
@"class B
{
    static void Main()
    {
        A.F(default, 0);
    }
}";
            comp = CreateCompilation(sourceB, new[] { refA }, targetFramework: TargetFramework.Mscorlib45);
            comp.VerifyEmitDiagnostics();
            CompileAndVerify(comp);
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var expr = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single().Expression;
            var method = model.GetSymbolInfo(expr).Symbol.GetSymbol<RetargetingMethodSymbol>();
 
            VerifyParameterSymbol(method.Parameters[0], "scoped R x", RefKind.None, ScopedKind.ScopedValue);
            VerifyParameterSymbol(method.Parameters[1], "scoped in System.Int32 y", RefKind.In, ScopedKind.ScopedRef);
        }
 
        private static readonly SymbolDisplayFormat displayFormatWithScoped = SymbolDisplayFormat.TestFormat.
            AddParameterOptions(SymbolDisplayParameterOptions.IncludeModifiers).
            AddLocalOptions(SymbolDisplayLocalOptions.IncludeModifiers);
 
        private static void VerifyParameterSymbol(ParameterSymbol parameter, string expectedDisplayString, RefKind expectedRefKind, ScopedKind expectedScope, bool expectedHasUnscopedRefAttribute = false)
        {
            Assert.Equal(expectedDisplayString, parameter.ToDisplayString(displayFormatWithScoped));
            Assert.Equal(expectedRefKind, parameter.RefKind);
            Assert.Equal(expectedScope, parameter.EffectiveScope);
            Assert.Equal(expectedHasUnscopedRefAttribute, parameter.HasUnscopedRefAttribute);
 
            var attribute = parameter.GetAttributes().FirstOrDefault(a => a.GetTargetAttributeSignatureIndex(parameter, AttributeDescription.ScopedRefAttribute) != -1);
            Assert.Null(attribute);
 
            VerifyParameterSymbol(parameter.GetPublicSymbol(), expectedDisplayString, expectedRefKind, expectedScope);
        }
 
        private static void VerifyParameterSymbol(IParameterSymbol parameter, string expectedDisplayString, RefKind expectedRefKind, ScopedKind expectedScope)
        {
            Assert.Equal(expectedRefKind, parameter.RefKind);
            Assert.Equal(expectedScope, parameter.ScopedKind);
            Assert.Equal(expectedDisplayString, parameter.ToDisplayString(displayFormatWithScoped));
        }
 
        [Fact]
        public void LocalScope_01()
        {
            var source =
@"#pragma warning disable 219
ref struct R { }
class Program
{
    static void F(ref R r)
    {
        scoped R r1 = default;
        scoped ref R r2 = ref r;
        scoped ref readonly R r5 = ref r;
        scoped var r11 = (R)default;
        scoped ref var r21 = ref r;
        scoped ref readonly var r51 = ref r;
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (7,9): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         scoped R r1 = default;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(7, 9),
                // (8,9): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         scoped ref R r2 = ref r;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(8, 9),
                // (9,9): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         scoped ref readonly R r5 = ref r;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(9, 9),
                // (10,9): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         scoped var r11 = (R)default;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(10, 9),
                // (11,9): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         scoped ref var r21 = ref r;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(11, 9),
                // (12,9): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         scoped ref readonly var r51 = ref r;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(12, 9)
                );
            verify(comp);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                VerifyLocalSymbol(locals[0], "scoped R r1", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[1], "scoped ref R r2", RefKind.Ref, ScopedKind.ScopedRef);
                VerifyLocalSymbol(locals[2], "scoped ref readonly R r5", RefKind.RefReadOnly, ScopedKind.ScopedRef);
                VerifyLocalSymbol(locals[3], "scoped R r11", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[4], "scoped ref R r21", RefKind.Ref, ScopedKind.ScopedRef);
                VerifyLocalSymbol(locals[5], "scoped ref readonly R r51", RefKind.RefReadOnly, ScopedKind.ScopedRef);
 
                foreach (var decl in decls)
                {
                    var type = ((VariableDeclarationSyntax)decl.Parent).Type;
 
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type));
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type.SkipScoped(out _)));
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type.SkipScoped(out _).SkipRef()));
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("R", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("R", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
            }
        }
 
        [Fact]
        public void LocalScope_01_Script()
        {
            var source =
@"#pragma warning disable 219
scoped R r1 = default;
scoped var r11 = (R)default;
 
ref struct R { }
";
 
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script);
            comp.VerifyEmitDiagnostics(
                // (2,1): error CS8345: Field or auto-implemented property cannot be of type 'R' unless it is an instance member of a ref struct.
                // scoped R r1 = default;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "scoped R").WithArguments("R").WithLocation(2, 1),
                // (2,10): error CS0106: The modifier 'scoped' is not valid for this item
                // scoped R r1 = default;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "r1").WithArguments("scoped").WithLocation(2, 10),
                // (3,1): error CS8345: Field or auto-implemented property cannot be of type 'R' unless it is an instance member of a ref struct.
                // scoped var r11 = (R)default;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "scoped var").WithArguments("R").WithLocation(3, 1),
                // (3,12): error CS0106: The modifier 'scoped' is not valid for this item
                // scoped var r11 = (R)default;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "r11").WithArguments("scoped").WithLocation(3, 12)
                );
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
 
                Assert.Equal(2, decls.Length);
 
                foreach (var decl in decls)
                {
                    var f = model.GetDeclaredSymbol(decl).GetSymbol<FieldSymbol>();
 
                    Assert.Equal(RefKind.None, f.RefKind);
                    Assert.Equal("Script.R", f.Type.ToTestDisplayString());
 
                    var type = ((VariableDeclarationSyntax)decl.Parent).Type;
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("Script.R", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("Script.R", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
            }
        }
 
        [Fact]
        public void LocalScope_01_For()
        {
            var source =
@"#pragma warning disable 219
ref struct R { }
class Program
{
    static void F(ref R r)
    {
        for (scoped R r1 = default;;) break;
        for (scoped ref R r2 = ref r;;) break;
        for (scoped ref readonly R r5 = ref r;;) break;
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (7,14): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         for (scoped R r1 = default;;) break;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(7, 14),
                // (8,14): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         for (scoped ref R r2 = ref r;;) break;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(8, 14),
                // (9,14): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         for (scoped ref readonly R r5 = ref r;;) break;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(9, 14));
            verify(comp);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                VerifyLocalSymbol(locals[0], "scoped R r1", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[1], "scoped ref R r2", RefKind.Ref, ScopedKind.ScopedRef);
                VerifyLocalSymbol(locals[2], "scoped ref readonly R r5", RefKind.RefReadOnly, ScopedKind.ScopedRef);
 
                foreach (var decl in decls)
                {
                    var type = ((VariableDeclarationSyntax)decl.Parent).Type;
 
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type));
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type.SkipScoped(out _)));
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type.SkipScoped(out _).SkipRef()));
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("R", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("R", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
            }
        }
 
        [Fact]
        public void LocalScope_01_Deconstruction()
        {
            var source =
@"#pragma warning disable 219
ref struct R { }
class Program
{
    static void F(RR r)
    {
        (scoped R r1, var a) = r;
        (scoped ref R r2, var b) = r;
        (scoped ref readonly R r5, var c) = r;
        (scoped R _, var d) = r;
        (scoped var _, var e) = r;
        (scoped ref R _, var f) = r;
        (scoped ref var _, var g) = r;
        (scoped ref readonly R _, var h) = r;
        (scoped ref readonly var _, var i) = r;
        (scoped var r11, var j) = r;
        (scoped ref var r21, var k) = r;
        (scoped ref readonly var r51, var l) = r;
    }
}
 
class RR
{
    public void Deconstruct(out R x, out int y) => throw null;
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (7,10): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         (scoped R r1, var a) = r;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(7, 10),
                // (8,10): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         (scoped ref R r2, var b) = r;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(8, 10),
                // (8,17): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         (scoped ref R r2, var b) = r;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(8, 17),
                // (9,10): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         (scoped ref readonly R r5, var c) = r;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(9, 10),
                // (9,17): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         (scoped ref readonly R r5, var c) = r;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(9, 17),
                // (10,10): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         (scoped R _, var d) = r;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(10, 10),
                // (11,10): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         (scoped var _, var e) = r;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(11, 10),
                // (12,10): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         (scoped ref R _, var f) = r;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(12, 10),
                // (12,17): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         (scoped ref R _, var f) = r;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(12, 17),
                // (13,10): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         (scoped ref var _, var g) = r;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(13, 10),
                // (13,17): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         (scoped ref var _, var g) = r;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(13, 17),
                // (14,10): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         (scoped ref readonly R _, var h) = r;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(14, 10),
                // (14,17): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         (scoped ref readonly R _, var h) = r;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(14, 17),
                // (15,10): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         (scoped ref readonly var _, var i) = r;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(15, 10),
                // (15,17): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         (scoped ref readonly var _, var i) = r;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(15, 17),
                // (16,10): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         (scoped var r11, var j) = r;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(16, 10),
                // (17,10): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         (scoped ref var r21, var k) = r;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(17, 10),
                // (17,17): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         (scoped ref var r21, var k) = r;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(17, 17),
                // (18,10): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         (scoped ref readonly var r51, var l) = r;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(18, 10),
                // (18,17): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         (scoped ref readonly var r51, var l) = r;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(18, 17)
                );
 
            verify(comp);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (8,17): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         (scoped ref R r2, var b) = r;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(8, 17),
                // (9,17): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         (scoped ref readonly R r5, var c) = r;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(9, 17),
                // (10,10): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         (scoped R _, var d) = r;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(10, 10),
                // (11,10): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         (scoped var _, var e) = r;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(11, 10),
                // (12,10): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         (scoped ref R _, var f) = r;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(12, 10),
                // (12,17): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         (scoped ref R _, var f) = r;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(12, 17),
                // (13,10): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         (scoped ref var _, var g) = r;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(13, 10),
                // (13,17): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         (scoped ref var _, var g) = r;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(13, 17),
                // (14,10): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         (scoped ref readonly R _, var h) = r;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(14, 10),
                // (14,17): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         (scoped ref readonly R _, var h) = r;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(14, 17),
                // (15,10): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         (scoped ref readonly var _, var i) = r;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(15, 10),
                // (15,17): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         (scoped ref readonly var _, var i) = r;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(15, 17),
                // (17,17): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         (scoped ref var r21, var k) = r;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(17, 17),
                // (18,17): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         (scoped ref readonly var r51, var l) = r;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(18, 17)
                );
 
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<DeclarationExpressionSyntax>().
                    Where(d => d.Type is ScopedTypeSyntax && d.Designation is SingleVariableDesignationSyntax).
                    Select(d => d.Designation).ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                Assert.Equal(6, locals.Length);
 
                VerifyLocalSymbol(locals[0], "scoped R r1", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[1], "scoped R r2", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[2], "scoped R r5", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[3], "scoped R r11", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[4], "scoped R r21", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[5], "scoped R r51", RefKind.None, ScopedKind.ScopedValue);
 
                foreach (var decl in decls)
                {
                    var type = ((DeclarationExpressionSyntax)decl.Parent).Type;
 
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type));
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type.SkipScoped(out _)));
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type.SkipScoped(out _).SkipRef()));
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("R", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("R", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
 
                var discard = tree.GetRoot().DescendantNodes().OfType<DiscardDesignationSyntax>().ToArray();
                Assert.Equal(6, discard.Length);
 
                foreach (var decl in discard)
                {
                    Assert.Null(model.GetDeclaredSymbol(decl));
                    Assert.Null(model.GetSymbolInfo(decl).Symbol);
                    Assert.Null(model.GetTypeInfo(decl).Type);
 
                    var type = ((DeclarationExpressionSyntax)decl.Parent).Type;
 
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type));
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type.SkipScoped(out _)));
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type.SkipScoped(out _).SkipRef()));
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("R", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("R", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
            }
        }
 
        [Fact]
        public void LocalScope_01_Deconstruction_Script()
        {
            var source =
@"#pragma warning disable 219
RR r = new RR();
(scoped R r1, var a) = r;
(scoped ref R r2, var b) = r;
(scoped ref readonly R r5, var c) = r;
(scoped R _, var d) = r;
(scoped var _, var e) = r;
(scoped ref R _, var f) = r;
(scoped ref var _, var g) = r;
(scoped ref readonly R _, var h) = r;
(scoped ref readonly var _, var i) = r;
(scoped var r11, var j) = r;
(scoped ref var r21, var k) = r;
(scoped ref readonly var r51, var l) = r;
 
ref struct R { }
 
class RR
{
    public void Deconstruct(out R x, out int y) => throw null;
}
";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script);
            comp.VerifyEmitDiagnostics(
                // (3,2): error CS8345: Field or auto-implemented property cannot be of type 'R' unless it is an instance member of a ref struct.
                // (scoped R r1, var a) = r;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "scoped R").WithArguments("R").WithLocation(3, 2),
                // (3,2): error CS1073: Unexpected token 'scoped'
                // (scoped R r1, var a) = r;
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "scoped").WithArguments("scoped").WithLocation(3, 2),
                // (4,2): error CS8345: Field or auto-implemented property cannot be of type 'R' unless it is an instance member of a ref struct.
                // (scoped ref R r2, var b) = r;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "scoped ref R").WithArguments("R").WithLocation(4, 2),
                // (4,2): error CS1073: Unexpected token 'scoped'
                // (scoped ref R r2, var b) = r;
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "scoped").WithArguments("scoped").WithLocation(4, 2),
                // (4,9): error CS1073: Unexpected token 'ref'
                // (scoped ref R r2, var b) = r;
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(4, 9),
                // (5,2): error CS8345: Field or auto-implemented property cannot be of type 'R' unless it is an instance member of a ref struct.
                // (scoped ref readonly R r5, var c) = r;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "scoped ref readonly R").WithArguments("R").WithLocation(5, 2),
                // (5,2): error CS1073: Unexpected token 'scoped'
                // (scoped ref readonly R r5, var c) = r;
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "scoped").WithArguments("scoped").WithLocation(5, 2),
                // (5,9): error CS1073: Unexpected token 'ref'
                // (scoped ref readonly R r5, var c) = r;
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(5, 9),
                // (6,2): error CS9061: The 'scoped' modifier cannot be used with discard.
                // (scoped R _, var d) = r;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(6, 2),
                // (7,2): error CS9061: The 'scoped' modifier cannot be used with discard.
                // (scoped var _, var e) = r;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(7, 2),
                // (8,2): error CS9061: The 'scoped' modifier cannot be used with discard.
                // (scoped ref R _, var f) = r;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(8, 2),
                // (8,9): error CS9072: A deconstruction variable cannot be declared as a ref local
                // (scoped ref R _, var f) = r;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(8, 9),
                // (9,2): error CS9061: The 'scoped' modifier cannot be used with discard.
                // (scoped ref var _, var g) = r;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(9, 2),
                // (9,9): error CS9072: A deconstruction variable cannot be declared as a ref local
                // (scoped ref var _, var g) = r;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(9, 9),
                // (10,2): error CS9061: The 'scoped' modifier cannot be used with discard.
                // (scoped ref readonly R _, var h) = r;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(10, 2),
                // (10,9): error CS9072: A deconstruction variable cannot be declared as a ref local
                // (scoped ref readonly R _, var h) = r;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(10, 9),
                // (11,2): error CS9061: The 'scoped' modifier cannot be used with discard.
                // (scoped ref readonly var _, var i) = r;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(11, 2),
                // (11,9): error CS9072: A deconstruction variable cannot be declared as a ref local
                // (scoped ref readonly var _, var i) = r;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(11, 9),
                // (12,2): error CS8345: Field or auto-implemented property cannot be of type 'R' unless it is an instance member of a ref struct.
                // (scoped var r11, var j) = r;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "scoped var").WithArguments("R").WithLocation(12, 2),
                // (12,2): error CS1073: Unexpected token 'scoped'
                // (scoped var r11, var j) = r;
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "scoped").WithArguments("scoped").WithLocation(12, 2),
                // (13,2): error CS8345: Field or auto-implemented property cannot be of type 'R' unless it is an instance member of a ref struct.
                // (scoped ref var r21, var k) = r;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "scoped ref var").WithArguments("R").WithLocation(13, 2),
                // (13,2): error CS1073: Unexpected token 'scoped'
                // (scoped ref var r21, var k) = r;
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "scoped").WithArguments("scoped").WithLocation(13, 2),
                // (13,9): error CS1073: Unexpected token 'ref'
                // (scoped ref var r21, var k) = r;
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(13, 9),
                // (14,2): error CS8345: Field or auto-implemented property cannot be of type 'R' unless it is an instance member of a ref struct.
                // (scoped ref readonly var r51, var l) = r;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "scoped ref readonly var").WithArguments("R").WithLocation(14, 2),
                // (14,2): error CS1073: Unexpected token 'scoped'
                // (scoped ref readonly var r51, var l) = r;
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "scoped").WithArguments("scoped").WithLocation(14, 2),
                // (14,9): error CS1073: Unexpected token 'ref'
                // (scoped ref readonly var r51, var l) = r;
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(14, 9)
                );
 
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<DeclarationExpressionSyntax>().
                    Where(d => d.Type is ScopedTypeSyntax && d.Designation is SingleVariableDesignationSyntax).
                    Select(d => d.Designation).ToArray();
 
                Assert.Equal(6, decls.Length);
 
                foreach (var decl in decls)
                {
                    var f = model.GetDeclaredSymbol(decl).GetSymbol<FieldSymbol>();
 
                    Assert.Equal(RefKind.None, f.RefKind);
                    Assert.Equal("Script.R", f.Type.ToTestDisplayString());
 
                    var type = ((DeclarationExpressionSyntax)decl.Parent).Type;
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("Script.R", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("Script.R", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
 
                var discard = tree.GetRoot().DescendantNodes().OfType<DiscardDesignationSyntax>().ToArray();
                Assert.Equal(6, discard.Length);
 
                foreach (var decl in discard)
                {
                    Assert.Null(model.GetDeclaredSymbol(decl));
                    Assert.Null(model.GetSymbolInfo(decl).Symbol);
                    Assert.Null(model.GetTypeInfo(decl).Type);
 
                    var type = ((DeclarationExpressionSyntax)decl.Parent).Type;
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("Script.R", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("Script.R", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
            }
        }
 
        [Fact]
        public void LocalScope_01_OutVar()
        {
            var source =
@"#pragma warning disable 219
ref struct R { }
class Program
{
    static void F(ref R r)
    {
        M1(out scoped R r1);
        M1(out scoped ref R r2);
        M1(out scoped ref readonly R r5);
        M1(out scoped R _);
        M1(out scoped var _);
        M1(out scoped ref R _);
        M1(out scoped ref var _);
        M1(out scoped ref readonly R _);
        M1(out scoped ref readonly var _);
        M1(out scoped var r11);
        M1(out scoped ref var r21);
        M1(out scoped ref readonly var r51);
 
        M1(out scoped _);
        M1(out scoped scoped _);
    }
 
    static void M1(out R r) => throw null;
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (7,16): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         M1(out scoped R r1);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(7, 16),
                // (8,16): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         M1(out scoped ref R r2);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(8, 16),
                // (8,23): error CS8388: An out variable cannot be declared as a ref local
                //         M1(out scoped ref R r2);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref R").WithLocation(8, 23),
                // (9,16): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         M1(out scoped ref readonly R r5);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(9, 16),
                // (9,23): error CS8388: An out variable cannot be declared as a ref local
                //         M1(out scoped ref readonly R r5);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref readonly R").WithLocation(9, 23),
                // (10,16): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         M1(out scoped R _);
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(10, 16),
                // (11,16): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         M1(out scoped var _);
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(11, 16),
                // (12,16): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         M1(out scoped ref R _);
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(12, 16),
                // (12,23): error CS8388: An out variable cannot be declared as a ref local
                //         M1(out scoped ref R _);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref R").WithLocation(12, 23),
                // (13,16): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         M1(out scoped ref var _);
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(13, 16),
                // (13,23): error CS8388: An out variable cannot be declared as a ref local
                //         M1(out scoped ref var _);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref var").WithLocation(13, 23),
                // (14,16): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         M1(out scoped ref readonly R _);
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(14, 16),
                // (14,23): error CS8388: An out variable cannot be declared as a ref local
                //         M1(out scoped ref readonly R _);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref readonly R").WithLocation(14, 23),
                // (15,16): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         M1(out scoped ref readonly var _);
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(15, 16),
                // (15,23): error CS8388: An out variable cannot be declared as a ref local
                //         M1(out scoped ref readonly var _);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref readonly var").WithLocation(15, 23),
                // (16,16): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         M1(out scoped var r11);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(16, 16),
                // (17,16): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         M1(out scoped ref var r21);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(17, 16),
                // (17,23): error CS8388: An out variable cannot be declared as a ref local
                //         M1(out scoped ref var r21);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref var").WithLocation(17, 23),
                // (18,16): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         M1(out scoped ref readonly var r51);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(18, 16),
                // (18,23): error CS8388: An out variable cannot be declared as a ref local
                //         M1(out scoped ref readonly var r51);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref readonly var").WithLocation(18, 23),
                // (20,16): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
                //         M1(out scoped _);
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(20, 16),
                // (21,16): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         M1(out scoped scoped _);
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(21, 16),
                // (21,23): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
                //         M1(out scoped scoped _);
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(21, 23)
                );
 
            verify(comp);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (8,23): error CS8388: An out variable cannot be declared as a ref local
                //         M1(out scoped ref R r2);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref R").WithLocation(8, 23),
                // (9,23): error CS8388: An out variable cannot be declared as a ref local
                //         M1(out scoped ref readonly R r5);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref readonly R").WithLocation(9, 23),
                // (10,16): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         M1(out scoped R _);
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(10, 16),
                // (11,16): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         M1(out scoped var _);
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(11, 16),
                // (12,16): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         M1(out scoped ref R _);
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(12, 16),
                // (12,23): error CS8388: An out variable cannot be declared as a ref local
                //         M1(out scoped ref R _);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref R").WithLocation(12, 23),
                // (13,16): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         M1(out scoped ref var _);
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(13, 16),
                // (13,23): error CS8388: An out variable cannot be declared as a ref local
                //         M1(out scoped ref var _);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref var").WithLocation(13, 23),
                // (14,16): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         M1(out scoped ref readonly R _);
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(14, 16),
                // (14,23): error CS8388: An out variable cannot be declared as a ref local
                //         M1(out scoped ref readonly R _);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref readonly R").WithLocation(14, 23),
                // (15,16): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         M1(out scoped ref readonly var _);
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(15, 16),
                // (15,23): error CS8388: An out variable cannot be declared as a ref local
                //         M1(out scoped ref readonly var _);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref readonly var").WithLocation(15, 23),
                // (17,23): error CS8388: An out variable cannot be declared as a ref local
                //         M1(out scoped ref var r21);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref var").WithLocation(17, 23),
                // (18,23): error CS8388: An out variable cannot be declared as a ref local
                //         M1(out scoped ref readonly var r51);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref readonly var").WithLocation(18, 23),
                // (20,16): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
                //         M1(out scoped _);
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(20, 16),
                // (21,16): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         M1(out scoped scoped _);
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(21, 16),
                // (21,23): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
                //         M1(out scoped scoped _);
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(21, 23)
                );
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<SingleVariableDesignationSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                Assert.Equal(6, locals.Length);
 
                VerifyLocalSymbol(locals[0], "scoped R r1", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[1], "scoped R r2", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[2], "scoped R r5", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[3], "scoped R r11", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[4], "scoped R r21", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[5], "scoped R r51", RefKind.None, ScopedKind.ScopedValue);
 
                foreach (var decl in decls)
                {
                    var type = ((DeclarationExpressionSyntax)decl.Parent).Type;
 
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type));
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type.SkipScoped(out _)));
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type.SkipScoped(out _).SkipRef()));
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("R", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("R", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
 
                var discard = tree.GetRoot().DescendantNodes().OfType<DiscardDesignationSyntax>().ToArray();
                Assert.Equal(8, discard.Length);
 
                for (int i = 0; i < 6; i++)
                {
                    var decl = discard[i];
 
                    Assert.Null(model.GetDeclaredSymbol(decl));
                    Assert.Null(model.GetSymbolInfo(decl).Symbol);
                    Assert.Null(model.GetTypeInfo(decl).Type);
 
                    var type = ((DeclarationExpressionSyntax)decl.Parent).Type;
 
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type));
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type.SkipScoped(out _)));
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type.SkipScoped(out _).SkipRef()));
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("R", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("R", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
            }
        }
 
        [Fact]
        public void LocalScope_01_OutVar_Script()
        {
            var source =
@"#pragma warning disable 219
 
M1(out scoped R r1);
M1(out scoped ref R r2);
M1(out scoped ref readonly R r5);
M1(out scoped R _);
M1(out scoped var _);
M1(out scoped ref R _);
M1(out scoped ref var _);
M1(out scoped ref readonly R _);
M1(out scoped ref readonly var _);
M1(out scoped var r11);
M1(out scoped ref var r21);
M1(out scoped ref readonly var r51);
 
static void M1(out R r) => throw null;
 
ref struct R { }
";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script);
            comp.VerifyEmitDiagnostics(
                // (3,8): error CS8345: Field or auto-implemented property cannot be of type 'R' unless it is an instance member of a ref struct.
                // M1(out scoped R r1);
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "scoped R").WithArguments("R").WithLocation(3, 8),
                // (3,8): error CS1073: Unexpected token 'scoped'
                // M1(out scoped R r1);
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "scoped").WithArguments("scoped").WithLocation(3, 8),
                // (4,8): error CS8345: Field or auto-implemented property cannot be of type 'R' unless it is an instance member of a ref struct.
                // M1(out scoped ref R r2);
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "scoped ref R").WithArguments("R").WithLocation(4, 8),
                // (4,8): error CS1073: Unexpected token 'scoped'
                // M1(out scoped ref R r2);
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "scoped").WithArguments("scoped").WithLocation(4, 8),
                // (4,15): error CS1073: Unexpected token 'ref'
                // M1(out scoped ref R r2);
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(4, 15),
                // (5,8): error CS8345: Field or auto-implemented property cannot be of type 'R' unless it is an instance member of a ref struct.
                // M1(out scoped ref readonly R r5);
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "scoped ref readonly R").WithArguments("R").WithLocation(5, 8),
                // (5,8): error CS1073: Unexpected token 'scoped'
                // M1(out scoped ref readonly R r5);
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "scoped").WithArguments("scoped").WithLocation(5, 8),
                // (5,15): error CS1073: Unexpected token 'ref'
                // M1(out scoped ref readonly R r5);
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(5, 15),
                // (6,8): error CS9061: The 'scoped' modifier cannot be used with discard.
                // M1(out scoped R _);
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(6, 8),
                // (7,8): error CS9061: The 'scoped' modifier cannot be used with discard.
                // M1(out scoped var _);
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(7, 8),
                // (8,8): error CS9061: The 'scoped' modifier cannot be used with discard.
                // M1(out scoped ref R _);
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(8, 8),
                // (8,15): error CS8388: An out variable cannot be declared as a ref local
                // M1(out scoped ref R _);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref R").WithLocation(8, 15),
                // (9,8): error CS9061: The 'scoped' modifier cannot be used with discard.
                // M1(out scoped ref var _);
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(9, 8),
                // (9,15): error CS8388: An out variable cannot be declared as a ref local
                // M1(out scoped ref var _);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref var").WithLocation(9, 15),
                // (10,8): error CS9061: The 'scoped' modifier cannot be used with discard.
                // M1(out scoped ref readonly R _);
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(10, 8),
                // (10,15): error CS8388: An out variable cannot be declared as a ref local
                // M1(out scoped ref readonly R _);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref readonly R").WithLocation(10, 15),
                // (11,8): error CS9061: The 'scoped' modifier cannot be used with discard.
                // M1(out scoped ref readonly var _);
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(11, 8),
                // (11,15): error CS8388: An out variable cannot be declared as a ref local
                // M1(out scoped ref readonly var _);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref readonly var").WithLocation(11, 15),
                // (12,8): error CS8345: Field or auto-implemented property cannot be of type 'R' unless it is an instance member of a ref struct.
                // M1(out scoped var r11);
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "scoped var").WithArguments("R").WithLocation(12, 8),
                // (12,8): error CS1073: Unexpected token 'scoped'
                // M1(out scoped var r11);
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "scoped").WithArguments("scoped").WithLocation(12, 8),
                // (13,8): error CS8345: Field or auto-implemented property cannot be of type 'R' unless it is an instance member of a ref struct.
                // M1(out scoped ref var r21);
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "scoped ref var").WithArguments("R").WithLocation(13, 8),
                // (13,8): error CS1073: Unexpected token 'scoped'
                // M1(out scoped ref var r21);
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "scoped").WithArguments("scoped").WithLocation(13, 8),
                // (13,15): error CS1073: Unexpected token 'ref'
                // M1(out scoped ref var r21);
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(13, 15),
                // (14,8): error CS8345: Field or auto-implemented property cannot be of type 'R' unless it is an instance member of a ref struct.
                // M1(out scoped ref readonly var r51);
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "scoped ref readonly var").WithArguments("R").WithLocation(14, 8),
                // (14,8): error CS1073: Unexpected token 'scoped'
                // M1(out scoped ref readonly var r51);
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "scoped").WithArguments("scoped").WithLocation(14, 8),
                // (14,15): error CS1073: Unexpected token 'ref'
                // M1(out scoped ref readonly var r51);
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(14, 15)
                );
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<SingleVariableDesignationSyntax>().ToArray();
 
                Assert.Equal(6, decls.Length);
 
                foreach (var decl in decls)
                {
                    var f = model.GetDeclaredSymbol(decl).GetSymbol<FieldSymbol>();
 
                    Assert.Equal(RefKind.None, f.RefKind);
                    Assert.Equal("Script.R", f.Type.ToTestDisplayString());
 
                    var type = ((DeclarationExpressionSyntax)decl.Parent).Type;
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("Script.R", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("Script.R", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
 
                var discard = tree.GetRoot().DescendantNodes().OfType<DiscardDesignationSyntax>().ToArray();
                Assert.Equal(6, discard.Length);
 
                foreach (var decl in discard)
                {
                    Assert.Null(model.GetDeclaredSymbol(decl));
                    Assert.Null(model.GetSymbolInfo(decl).Symbol);
                    Assert.Null(model.GetTypeInfo(decl).Type);
 
                    var type = ((DeclarationExpressionSyntax)decl.Parent).Type;
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("Script.R", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("Script.R", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
            }
        }
 
        [Fact]
        public void LocalScope_02()
        {
            var source =
@"ref struct R { }
class Program
{
    static void Main()
    {
        scoped scoped R x = default;
        scoped scoped ref R z = ref x;
    }
}";
            var comp = CreateCompilation(source);
            // Duplicate scoped modifiers result are parse errors rather than binding errors.
            comp.VerifyDiagnostics(
                // (6,16): error CS0118: 'scoped' is a variable but is used like a type
                //         scoped scoped R x = default;
                Diagnostic(ErrorCode.ERR_BadSKknown, "scoped").WithArguments("scoped", "variable", "type").WithLocation(6, 16),
                // (6,23): warning CS0168: The variable 'R' is declared but never used
                //         scoped scoped R x = default;
                Diagnostic(ErrorCode.WRN_UnreferencedVar, "R").WithArguments("R").WithLocation(6, 23),
                // (6,25): error CS1002: ; expected
                //         scoped scoped R x = default;
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "x").WithLocation(6, 25),
                // (6,25): error CS0103: The name 'x' does not exist in the current context
                //         scoped scoped R x = default;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "x").WithArguments("x").WithLocation(6, 25),
                // (7,9): error CS0118: 'scoped' is a variable but is used like a type
                //         scoped scoped ref R z = ref x;
                Diagnostic(ErrorCode.ERR_BadSKknown, "scoped").WithArguments("scoped", "variable", "type").WithLocation(7, 9),
                // (7,16): warning CS0168: The variable 'scoped' is declared but never used
                //         scoped scoped ref R z = ref x;
                Diagnostic(ErrorCode.WRN_UnreferencedVar, "scoped").WithArguments("scoped").WithLocation(7, 16),
                // (7,23): error CS1002: ; expected
                //         scoped scoped ref R z = ref x;
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "ref").WithLocation(7, 23),
                // (7,37): error CS0103: The name 'x' does not exist in the current context
                //         scoped scoped ref R z = ref x;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "x").WithArguments("x").WithLocation(7, 37)
                );
        }
 
        [Fact]
        public void LocalScope_03()
        {
            var source =
@"scoped scoped R x = default;
scoped scoped ref R z = ref x;
ref struct R { }
";
            var comp = CreateCompilation(source);
            // Duplicate scoped modifiers result are parse errors rather than binding errors.
            comp.VerifyDiagnostics(
                // (1,8): error CS0118: 'scoped' is a variable but is used like a type
                // scoped scoped R x = default;
                Diagnostic(ErrorCode.ERR_BadSKknown, "scoped").WithArguments("scoped", "variable", "type").WithLocation(1, 8),
                // (1,15): warning CS0168: The variable 'R' is declared but never used
                // scoped scoped R x = default;
                Diagnostic(ErrorCode.WRN_UnreferencedVar, "R").WithArguments("R").WithLocation(1, 15),
                // (1,17): error CS1003: Syntax error, ',' expected
                // scoped scoped R x = default;
                Diagnostic(ErrorCode.ERR_SyntaxError, "x").WithArguments(",").WithLocation(1, 17),
                // (2,1): error CS0118: 'scoped' is a variable but is used like a type
                // scoped scoped ref R z = ref x;
                Diagnostic(ErrorCode.ERR_BadSKknown, "scoped").WithArguments("scoped", "variable", "type").WithLocation(2, 1),
                // (2,8): warning CS0168: The variable 'scoped' is declared but never used
                // scoped scoped ref R z = ref x;
                Diagnostic(ErrorCode.WRN_UnreferencedVar, "scoped").WithArguments("scoped").WithLocation(2, 8),
                // (2,15): error CS1003: Syntax error, ',' expected
                // scoped scoped ref R z = ref x;
                Diagnostic(ErrorCode.ERR_SyntaxError, "ref").WithArguments(",").WithLocation(2, 15));
        }
 
        [Fact]
        public void LocalScope_04()
        {
            var source =
@"scoped s1 = default;
ref scoped s2 = ref s1; // 1
ref @scoped s3 = ref s1;
scoped scoped s4 = default; // 2
scoped ref scoped s5 = ref s1; // 3
scoped ref @scoped s6 = ref s1; // 4
ref struct @scoped { } // 5
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (4,1): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                // scoped scoped s4 = default; // 2
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(4, 1),
                // (4,15): warning CS0219: The variable 's4' is assigned but its value is never used
                // scoped scoped s4 = default; // 2
                Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "s4").WithArguments("s4").WithLocation(4, 15),
                // (5,1): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                // scoped ref scoped s5 = ref s1; // 3
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(5, 1),
                // (6,1): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                // scoped ref @scoped s6 = ref s1; // 4
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(6, 1)
                );
            verify(comp);
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (4,15): warning CS0219: The variable 's4' is assigned but its value is never used
                // scoped scoped s4 = default; // 2
                Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "s4").WithArguments("s4").WithLocation(4, 15)
                );
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                VerifyLocalSymbol(locals[0], "scoped s1", RefKind.None, ScopedKind.None);
                VerifyLocalSymbol(locals[1], "ref scoped s2", RefKind.Ref, ScopedKind.None);
                VerifyLocalSymbol(locals[2], "ref scoped s3", RefKind.Ref, ScopedKind.None);
                VerifyLocalSymbol(locals[3], "scoped scoped s4", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[4], "scoped ref scoped s5", RefKind.Ref, ScopedKind.ScopedRef);
                VerifyLocalSymbol(locals[5], "scoped ref scoped s6", RefKind.Ref, ScopedKind.ScopedRef);
            }
        }
 
        [Fact]
        public void LocalScope_04_For()
        {
            var source =
@"for (scoped s1 = default;;) {
    for (ref scoped s2 = ref s1;;) {break;} // 1
    for (ref @scoped s3 = ref s1;;) {break;}
    for (scoped scoped s4 = default;;) {break;} // 2
    for (scoped ref scoped s5 = ref s1;;) {break;} // 3
    for (scoped ref @scoped s6 = ref s1;;) {break;} // 4
}
 
ref struct @scoped { } // 5
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (4,10): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     for (scoped scoped s4 = default;;) {break;} // 2
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(4, 10),
                // (4,24): warning CS0219: The variable 's4' is assigned but its value is never used
                //     for (scoped scoped s4 = default;;) {break;} // 2
                Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "s4").WithArguments("s4").WithLocation(4, 24),
                // (5,10): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     for (scoped ref scoped s5 = ref s1;;) {break;} // 3
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(5, 10),
                // (6,10): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     for (scoped ref @scoped s6 = ref s1;;) {break;} // 4
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(6, 10)
                );
            verify(comp);
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (4,24): warning CS0219: The variable 's4' is assigned but its value is never used
                //     for (scoped scoped s4 = default;;) {break;} // 2
                Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "s4").WithArguments("s4").WithLocation(4, 24)
                );
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                VerifyLocalSymbol(locals[0], "scoped s1", RefKind.None, ScopedKind.None);
                VerifyLocalSymbol(locals[1], "ref scoped s2", RefKind.Ref, ScopedKind.None);
                VerifyLocalSymbol(locals[2], "ref scoped s3", RefKind.Ref, ScopedKind.None);
                VerifyLocalSymbol(locals[3], "scoped scoped s4", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[4], "scoped ref scoped s5", RefKind.Ref, ScopedKind.ScopedRef);
                VerifyLocalSymbol(locals[5], "scoped ref scoped s6", RefKind.Ref, ScopedKind.ScopedRef);
            }
        }
 
        [Fact]
        public void LocalScope_04_Deconstruction()
        {
            var source =
@"
var r = new RR();
(scoped s1, var a) = r;
(@scoped s3, var b) = r;
(scoped scoped s4, var c) = r;
(scoped @scoped s6, var d) = r;
 
(scoped _, var e) = r;
(scoped scoped _, var f) = r;
 
ref struct @scoped { }
 
class RR
{
    public void Deconstruct(out @scoped x, out int y) => throw null;
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (5,2): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                // (scoped scoped s4, var c) = r;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(5, 2),
                // (6,2): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                // (scoped @scoped s6, var d) = r;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(6, 2),
                // (9,2): error CS9061: The 'scoped' modifier cannot be used with discard.
                // (scoped scoped _, var f) = r;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(9, 2)
                );
            verify(comp);
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (9,2): error CS9061: The 'scoped' modifier cannot be used with discard.
                // (scoped scoped _, var f) = r;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(9, 2)
                );
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<SingleVariableDesignationSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                VerifyLocalSymbol(locals[0], "scoped s1", RefKind.None, ScopedKind.None);
                VerifyLocalSymbol(locals[2], "scoped s3", RefKind.None, ScopedKind.None);
                VerifyLocalSymbol(locals[4], "scoped scoped s4", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[6], "scoped scoped s6", RefKind.None, ScopedKind.ScopedValue);
            }
        }
 
        [Fact]
        public void LocalScope_04_OutVar()
        {
            var source =
@"
M(out scoped s1);
M(out @scoped s3);
M(out scoped scoped s4);
M(out scoped @scoped s6);
 
void M(out scoped x) => throw null;
 
ref struct @scoped { }
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (4,7): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                // M(out scoped scoped s4);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(4, 7),
                // (5,7): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                // M(out scoped @scoped s6);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(5, 7)
                );
            verify(comp);
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<SingleVariableDesignationSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                Assert.Equal(4, locals.Length);
 
                VerifyLocalSymbol(locals[0], "scoped s1", RefKind.None, ScopedKind.None);
                VerifyLocalSymbol(locals[1], "scoped s3", RefKind.None, ScopedKind.None);
                VerifyLocalSymbol(locals[2], "scoped scoped s4", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[3], "scoped scoped s6", RefKind.None, ScopedKind.ScopedValue);
            }
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void LocalScope_05(LanguageVersion langVersion)
        {
            var source =
@"bool scoped;
scoped = true;
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
            comp.VerifyDiagnostics(
                // (1,6): warning CS0219: The variable 'scoped' is assigned but its value is never used
                // bool scoped;
                Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "scoped").WithArguments("scoped").WithLocation(1, 6));
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
            var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
            VerifyLocalSymbol(locals[0], "System.Boolean scoped", RefKind.None, ScopedKind.None);
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void LocalScope_05_For(LanguageVersion langVersion)
        {
            var source =
@"for (bool scoped;;) {
for (scoped = true;;) {break;}
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
            comp.VerifyDiagnostics(
                // (1,11): warning CS0219: The variable 'scoped' is assigned but its value is never used
                // for (bool scoped;;) {
                Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "scoped").WithArguments("scoped").WithLocation(1, 11)
                );
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
            var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
            VerifyLocalSymbol(locals[0], "System.Boolean scoped", RefKind.None, ScopedKind.None);
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void LocalScope_05_Deconstruction(LanguageVersion langVersion)
        {
            var source =
@"
(bool scoped, var x) = (true, 0);
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
            comp.VerifyDiagnostics();
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var decls = tree.GetRoot().DescendantNodes().OfType<SingleVariableDesignationSyntax>().ToArray();
            var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
            VerifyLocalSymbol(locals[0], "System.Boolean scoped", RefKind.None, ScopedKind.None);
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void LocalScope_05_OutVar(LanguageVersion langVersion)
        {
            var source =
@"
M(out bool scoped);
 
void M(out bool x) => throw null;
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
            comp.VerifyDiagnostics();
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var decls = tree.GetRoot().DescendantNodes().OfType<SingleVariableDesignationSyntax>().ToArray();
            var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
            VerifyLocalSymbol(locals[0], "System.Boolean scoped", RefKind.None, ScopedKind.None);
        }
 
        [Fact]
        public void LocalScope_06()
        {
            var source =
@"ref struct R<T> { }
class Program
{
    static void M(R<int> r0)
    {
        scoped var r1 = new R<int>();
        scoped ref var r3 = ref r0;
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (6,20): warning CS0219: The variable 'r1' is assigned but its value is never used
                //         scoped var r1 = new R<int>();
                Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "r1").WithArguments("r1").WithLocation(6, 20)
                );
 
            verifyModel(comp);
 
            comp = CreateCompilation(source, parseOptions: TestOptions.RegularDefault.WithFeature("run-nullable-analysis", "never"));
            verifyModel(comp);
 
            static void verifyModel(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                foreach (SourceLocalSymbol local in locals)
                {
                    Assert.True(local.IsVar);
                    Assert.Equal("R<System.Int32>", local.Type.ToTestDisplayString());
                }
 
                VerifyLocalSymbol(locals[0], "scoped R<System.Int32> r1", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[1], "scoped ref R<System.Int32> r3", RefKind.Ref, ScopedKind.ScopedRef);
 
                foreach (var decl in decls)
                {
                    var type = ((VariableDeclarationSyntax)decl.Parent).Type;
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("R<System.Int32>", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("R<System.Int32>", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
            }
        }
 
        [Fact]
        public void LocalScope_06_For()
        {
            var source =
@"ref struct R<T> { }
class Program
{
    static void M(R<int> r0)
    {
        for (scoped var r1 = new R<int>();;) break;
        for (scoped ref var r3 = ref r0;;) break;
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (6,25): warning CS0219: The variable 'r1' is assigned but its value is never used
                //         for (scoped var r1 = new R<int>();;) break;
                Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "r1").WithArguments("r1").WithLocation(6, 25)
                );
 
            verifyModel(comp);
 
            comp = CreateCompilation(source, parseOptions: TestOptions.RegularDefault.WithFeature("run-nullable-analysis", "never"));
            verifyModel(comp);
 
            static void verifyModel(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                foreach (SourceLocalSymbol local in locals)
                {
                    Assert.True(local.IsVar);
                    Assert.Equal("R<System.Int32>", local.Type.ToTestDisplayString());
                }
 
                VerifyLocalSymbol(locals[0], "scoped R<System.Int32> r1", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[1], "scoped ref R<System.Int32> r3", RefKind.Ref, ScopedKind.ScopedRef);
 
                foreach (var decl in decls)
                {
                    var type = ((VariableDeclarationSyntax)decl.Parent).Type;
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("R<System.Int32>", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("R<System.Int32>", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
            }
        }
 
        [Fact]
        public void LocalScope_06_Deconstruction()
        {
            var source =
@"ref struct R<T> { }
class Program
{
    static void M(R<int> r0)
    {
        (scoped var r1, var a) = new RR(new R<int>());
        (scoped ref var r3, var b) = new RR(ref r0);
 
        scoped R<int> r4;
        int c;
        (r4, c) = new RR(ref r0);
    }
}
 
ref struct RR
{
    public RR(R<int> x){}
    public RR(ref R<int> x){}
    public void Deconstruct(out R<int> x, out int y) => throw null;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,17): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         (scoped ref var r3, var b) = new RR(ref r0);
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(7, 17)
                );
 
            verifyModel(comp);
 
            comp = CreateCompilation(source, parseOptions: TestOptions.RegularDefault.WithFeature("run-nullable-analysis", "never"));
            verifyModel(comp);
 
            static void verifyModel(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<SingleVariableDesignationSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<SourceLocalSymbol>()).ToArray();
 
                for (int i = 0; i < 3; i += 2)
                {
                    Assert.True(locals[i].IsVar);
                    Assert.Equal("R<System.Int32>", locals[i].Type.ToTestDisplayString());
                }
 
                VerifyLocalSymbol(locals[0], "scoped R<System.Int32> r1", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[2], "scoped R<System.Int32> r3", RefKind.None, ScopedKind.ScopedValue);
 
                for (int i = 0; i < 3; i += 2)
                {
                    var decl = decls[i];
                    var type = ((DeclarationExpressionSyntax)decl.Parent).Type;
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("R<System.Int32>", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("R<System.Int32>", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
            }
        }
 
        [Fact]
        public void LocalScope_06_OutVar()
        {
            var source =
@"ref struct R<T> { }
class Program
{
    static void M(R<int> r0)
    {
        M1(out scoped var r1, new R<int>());
        M2(out scoped ref var r3, ref r0);
 
        scoped R<int> r4;
        M2(out r4, ref r0);
    }
 
    static void M1(out R<int> y, R<int> x) => throw null;
    static void M2(out R<int> y, ref R<int> x) => throw null;
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,23): error CS8388: An out variable cannot be declared as a ref local
                //         M2(out scoped ref var r3, ref r0);
                Diagnostic(ErrorCode.ERR_OutVariableCannotBeByRef, "ref var").WithLocation(7, 23)
                );
 
            verifyModel(comp);
 
            comp = CreateCompilation(source, parseOptions: TestOptions.RegularDefault.WithFeature("run-nullable-analysis", "never"));
            verifyModel(comp);
 
            static void verifyModel(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<SingleVariableDesignationSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                foreach (SourceLocalSymbol local in locals)
                {
                    Assert.True(local.IsVar);
                    Assert.Equal("R<System.Int32>", local.Type.ToTestDisplayString());
                }
 
                VerifyLocalSymbol(locals[0], "scoped R<System.Int32> r1", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[1], "scoped R<System.Int32> r3", RefKind.None, ScopedKind.ScopedValue);
 
                foreach (var decl in decls)
                {
                    var type = ((DeclarationExpressionSyntax)decl.Parent).Type;
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("R<System.Int32>", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("R<System.Int32>", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
            }
        }
 
        [Fact]
        public void LocalScope_07()
        {
            var source =
@"
class Program
{
    static void Test(ref int x)
    {
        ref int a = ref x;
        scoped extern ref int b = ref x;
    }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,9): error CS0103: The name 'scoped' does not exist in the current context
                //         scoped extern ref int b = ref x;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "scoped").WithArguments("scoped").WithLocation(7, 9),
                // (7,16): error CS1002: ; expected
                //         scoped extern ref int b = ref x;
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "extern").WithLocation(7, 16),
                // (7,16): error CS0106: The modifier 'extern' is not valid for this item
                //         scoped extern ref int b = ref x;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "extern").WithArguments("extern").WithLocation(7, 16)
                );
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
            var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
            Assert.Equal(2, locals.Length);
            VerifyLocalSymbol(locals[0], "ref System.Int32 a", RefKind.Ref, ScopedKind.None);
            VerifyLocalSymbol(locals[1], "ref System.Int32 b", RefKind.Ref, ScopedKind.None);
        }
 
        [Fact]
        public void LocalScope_08()
        {
            var source =
@"
class Program
{
    static void Test(ref int x)
    {
        scoped ref int[M(out var b)] a;
        b++;
    }
 
    static int M(out int x) => throw null;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (6,23): error CS0270: Array size cannot be specified in a variable declaration (try initializing with a 'new' expression)
                //         scoped ref int[M(out var b)] a;
                Diagnostic(ErrorCode.ERR_ArraySizeInDeclaration, "[M(out var b)]").WithLocation(6, 23),
                // (6,38): error CS8174: A declaration of a by-reference variable must have an initializer
                //         scoped ref int[M(out var b)] a;
                Diagnostic(ErrorCode.ERR_ByReferenceVariableMustBeInitialized, "a").WithLocation(6, 38),
                // (6,38): warning CS0168: The variable 'a' is declared but never used
                //         scoped ref int[M(out var b)] a;
                Diagnostic(ErrorCode.WRN_UnreferencedVar, "a").WithArguments("a").WithLocation(6, 38),
                // (7,9): error CS0165: Use of unassigned local variable 'b'
                //         b++;
                Diagnostic(ErrorCode.ERR_UseDefViolation, "b").WithArguments("b").WithLocation(7, 9)
                );
        }
 
        [Fact]
        public void LocalScope_08_For()
        {
            var source =
@"
class Program
{
    static void Test(ref int x)
    {
        for (scoped ref int[M(out var b)] a;;) {
            b++;
        }
    }
 
    static int M(out int x) => throw null;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (6,28): error CS0270: Array size cannot be specified in a variable declaration (try initializing with a 'new' expression)
                //         for (scoped ref int[M(out var b)] a;;) {
                Diagnostic(ErrorCode.ERR_ArraySizeInDeclaration, "[M(out var b)]").WithLocation(6, 28),
                // (6,43): error CS8174: A declaration of a by-reference variable must have an initializer
                //         for (scoped ref int[M(out var b)] a;;) {
                Diagnostic(ErrorCode.ERR_ByReferenceVariableMustBeInitialized, "a").WithLocation(6, 43),
                // (6,43): warning CS0168: The variable 'a' is declared but never used
                //         for (scoped ref int[M(out var b)] a;;) {
                Diagnostic(ErrorCode.WRN_UnreferencedVar, "a").WithArguments("a").WithLocation(6, 43),
                // (7,13): error CS0165: Use of unassigned local variable 'b'
                //             b++;
                Diagnostic(ErrorCode.ERR_UseDefViolation, "b").WithArguments("b").WithLocation(7, 13)
                );
        }
 
        [WorkItem(64009, "https://github.com/dotnet/roslyn/issues/64009")]
        [Fact]
        public void LocalScope_09()
        {
            var source =
@"{
    scoped s1 = default;
    scoped ref @scoped s2 = ref s1;
}
ref struct @scoped { }
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [WorkItem(64009, "https://github.com/dotnet/roslyn/issues/64009")]
        [Fact]
        public void LocalScope_09_For_01()
        {
            var source =
@"for (scoped s1 = default;;) {
    scoped ref @scoped s2 = ref s1;
}
ref struct @scoped { }
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [WorkItem(64009, "https://github.com/dotnet/roslyn/issues/64009")]
        [Fact]
        public void LocalScope_09_For_02()
        {
            var source =
@"scoped s1 = default;
for (scoped ref @scoped s2 = ref s1;;) break;
 
ref struct @scoped { }
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void LocalScope_10()
        {
            var source =
@"{
    int i = 0;
    S s1 = new S(ref i);
    scoped S s2 = s1;
}
ref struct S
{
    public S(ref int i) { }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void LocalScope_10_For_01()
        {
            var source =
@"int i = 0;
S s1 = new S(ref i);
for (scoped S s2 = s1;;) break;
 
ref struct S
{
    public S(ref int i) { }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void LocalScope_10_For_02()
        {
            var source =
@"int i = 0;
for (S s1 = new S(ref i);;) {
    scoped S s2 = s1;
    break;
}
ref struct S
{
    public S(ref int i) { }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void LocalScope_10_Deconstruction()
        {
            var source =
@"{
    int i = 0;
    S s1 = new S(ref i);
    (scoped S s2, var a) = s1;
    scoped S s3;
    int b;
    (s3, b) = s1;
}
ref struct S
{
    public S(ref int i) { }
 
    public void Deconstruct(out S x, out int y) => throw null; 
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void LocalScope_10_OutVar()
        {
            var source =
@"{
    int i = 0;
    S s1 = new S(ref i);
    s1.M(out scoped S s2);
    scoped S s3;
    s1.M(out s3);
}
ref struct S
{
    public S(ref int i) { }
 
    public void M(out S x) => throw null;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void LocalScope_11()
        {
            var source =
@"class Program
{
    static void Main()
    {
        S s0 = default;
        scoped ref S r0 = ref s0;
        {
            scoped ref S r1 = ref s0;
            r0 = ref r1; // 1
        }
        {
            scoped ref S r2 = ref r0;
            r0 = ref r2; // 2
        }
        {
            ref S r3 = ref s0;
            r0 = ref r3;
        }
        {
            ref S r4 = ref r0;
            r0 = ref r4;
        }
    }
}
ref struct S { }
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (9,13): error CS8374: Cannot ref-assign 'r1' to 'r0' because 'r1' has a narrower escape scope than 'r0'.
                //             r0 = ref r1; // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r0 = ref r1").WithArguments("r0", "r1").WithLocation(9, 13),
                // (13,13): error CS8374: Cannot ref-assign 'r2' to 'r0' because 'r2' has a narrower escape scope than 'r0'.
                //             r0 = ref r2; // 2
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r0 = ref r2").WithArguments("r0", "r2").WithLocation(13, 13));
        }
 
        [Fact]
        public void LocalScope_11_For_01()
        {
            var source =
@"class Program
{
    static void Main()
    {
        S s0 = default;
        scoped ref S r0 = ref s0;
        for (scoped ref S r1 = ref s0;;) {
            r0 = ref r1; // 1
            break;
        }
        for (scoped ref S r2 = ref r0;;) {
            r0 = ref r2; // 2
            break;
        }
        for (ref S r3 = ref s0;;) {
            r0 = ref r3;
            break;
        }
        for (ref S r4 = ref r0;;) {
            r0 = ref r4;
            break;
        }
    }
}
ref struct S { }
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (8,13): error CS8374: Cannot ref-assign 'r1' to 'r0' because 'r1' has a narrower escape scope than 'r0'.
                //             r0 = ref r1; // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r0 = ref r1").WithArguments("r0", "r1").WithLocation(8, 13),
                // (12,13): error CS8374: Cannot ref-assign 'r2' to 'r0' because 'r2' has a narrower escape scope than 'r0'.
                //             r0 = ref r2; // 2
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r0 = ref r2").WithArguments("r0", "r2").WithLocation(12, 13));
        }
 
        [Fact]
        public void LocalScope_11_For_02()
        {
            var source =
@"class Program
{
    static void Main()
    {
        S s0 = default;
        for (scoped ref S r0 = ref s0;;)
        {
            scoped ref S r1 = ref s0;
            r0 = ref r1; // 1
 
            scoped ref S r2 = ref r0;
            r0 = ref r2; // 2
 
            ref S r3 = ref s0;
            r0 = ref r3;
 
            ref S r4 = ref r0;
            r0 = ref r4;
 
            break;
        }
    }
}
ref struct S { }
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (9,13): error CS8374: Cannot ref-assign 'r1' to 'r0' because 'r1' has a narrower escape scope than 'r0'.
                //             r0 = ref r1; // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r0 = ref r1").WithArguments("r0", "r1").WithLocation(9, 13),
                // (12,13): error CS8374: Cannot ref-assign 'r2' to 'r0' because 'r2' has a narrower escape scope than 'r0'.
                //             r0 = ref r2; // 2
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r0 = ref r2").WithArguments("r0", "r2").WithLocation(12, 13)
                );
        }
 
        [Fact]
        public void LocalScope_12()
        {
            var source =
@"class Program
{
    static void Main()
    {
        int i0 = 0;
        S s0 = new S(ref i0);
        {
            int i1 = 1;
            S s1 = new S(ref i1);
            s0 = s1; // 1
        }
        {
            scoped S s2 = s0;
            s0 = s2; // 2
        }
        {
            S s3 = s0;
            s0 = s3;
        }
    }
}
ref struct S
{
    public S(ref int i) { }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (10,18): error CS8352: Cannot use variable 's1' in this context because it may expose referenced variables outside of their declaration scope
                //             s0 = s1; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s1").WithArguments("s1").WithLocation(10, 18),
                // (14,18): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                //             s0 = s2; // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(14, 18));
        }
 
        [Fact]
        public void LocalScope_12_For_01()
        {
            var source =
@"class Program
{
    static void Main()
    {
        int i0 = 0;
        S s0 = new S(ref i0);
        {
            int i1 = 1;
            for (S s1 = new S(ref i1);;) {
                s0 = s1; // 1
                break;
            }
        }
        for (scoped S s2 = s0;;) {
            s0 = s2; // 2
            break;
        }
        for (S s3 = s0;;) {
            s0 = s3;
            break;
        }
    }
}
ref struct S
{
    public S(ref int i) { }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (10,22): error CS8352: Cannot use variable 's1' in this context because it may expose referenced variables outside of their declaration scope
                //                 s0 = s1; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s1").WithArguments("s1").WithLocation(10, 22),
                // (15,18): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                //             s0 = s2; // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(15, 18)
                );
        }
 
        [Fact]
        public void LocalScope_12_For_02()
        {
            var source =
@"class Program
{
    static void Main()
    {
        int i0 = 0;
        for (S s0 = new S(ref i0);;)
        {
            int i1 = 1;
            S s1 = new S(ref i1);
            s0 = s1; // 1
 
            scoped S s2 = s0;
            s0 = s2; // 2
 
            S s3 = s0;
            s0 = s3;
 
            break;
        }
    }
}
ref struct S
{
    public S(ref int i) { }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (10,18): error CS8352: Cannot use variable 's1' in this context because it may expose referenced variables outside of their declaration scope
                //             s0 = s1; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s1").WithArguments("s1").WithLocation(10, 18),
                // (13,18): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                //             s0 = s2; // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(13, 18)
                );
        }
 
        [Fact]
        public void LocalScope_12_Deconstruct()
        {
            var source =
@"class Program
{
    static void Main()
    {
        int i0 = 0;
        S s0 = new S(ref i0);
        {
            int i1 = 1;
            (S s1, var a) = new S(ref i1);
            s0 = s1;
        }
        {
            (scoped S s2, var b) = s0;
            s0 = s2;
        }
        {
            (S s3, var c) = s0;
            s0 = s3;
        }
        {
            int i1 = 1;
            S s11;
            int d;
            (s11, d) = new S(ref i1);
            s0 = s11;
        }
        {
            scoped S s21;
            int e;
            (s21, e) = s0;
            s0 = s21;
        }
        {
            S s31;
            int f;
            (s31, f) = s0;
            s0 = s31;
        }
    }
}
ref struct S
{
    public S(ref int i) { }
    public void Deconstruct(out S x, out int y) => throw null;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (10,18): error CS8352: Cannot use variable 's1' in this context because it may expose referenced variables outside of their declaration scope
                //             s0 = s1;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s1").WithArguments("s1").WithLocation(10, 18),
                // (14,18): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                //             s0 = s2;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(14, 18),
                // (24,13): error CS8352: Cannot use variable '(s11, d) = new S(ref i1)' in this context because it may expose referenced variables outside of their declaration scope
                //             (s11, d) = new S(ref i1);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "(s11, d) = new S(ref i1)").WithArguments("(s11, d) = new S(ref i1)").WithLocation(24, 13),
                // (24,24): error CS8350: This combination of arguments to 'S.Deconstruct(out S, out int)' is disallowed because it may expose variables referenced by parameter 'this' outside of their declaration scope
                //             (s11, d) = new S(ref i1);
                Diagnostic(ErrorCode.ERR_CallArgMixing, "new S(ref i1)").WithArguments("S.Deconstruct(out S, out int)", "this").WithLocation(24, 24),
                // (31,18): error CS8352: Cannot use variable 's21' in this context because it may expose referenced variables outside of their declaration scope
                //             s0 = s21;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s21").WithArguments("s21").WithLocation(31, 18),
                // (36,13): error CS8352: Cannot use variable '(s31, f) = s0' in this context because it may expose referenced variables outside of their declaration scope
                //             (s31, f) = s0;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "(s31, f) = s0").WithArguments("(s31, f) = s0").WithLocation(36, 13),
                // (36,24): error CS8350: This combination of arguments to 'S.Deconstruct(out S, out int)' is disallowed because it may expose variables referenced by parameter 'this' outside of their declaration scope
                //             (s31, f) = s0;
                Diagnostic(ErrorCode.ERR_CallArgMixing, "s0").WithArguments("S.Deconstruct(out S, out int)", "this").WithLocation(36, 24)
                );
        }
 
        [Fact]
        public void LocalScope_12_OutVar()
        {
            var source =
@"class Program
{
    static void Main()
    {
        int i0 = 0;
        S s0 = new S(ref i0);
        {
            int i1 = 1;
            (new S(ref i1)).M(out S s1);
            s0 = s1;
        }
        {
            s0.M(out scoped S s2);
            s0 = s2;
        }
        {
            s0.M(out S s3);
            s0 = s3;
        }
        {
            scoped S s21;
            s0.M(out s21);
            s0 = s21;
        }
 
        {
            int i1 = 1;
            (new S(ref i1)).M(out scoped S s4);
            s0 = s4;
        }
        {
            int i1 = 1;
            (new S(ref i1)).M(out var s5);
            s0 = s5;
        }
        {
            int i1 = 1;
            (new S(ref i1)).M(out scoped var s7);
            s0 = s7;
        }
    }
}
ref struct S
{
    public S(ref int i) { }
    public void M(out S x) => throw null;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (10,18): error CS8352: Cannot use variable 's1' in this context because it may expose referenced variables outside of their declaration scope
                //             s0 = s1;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s1").WithArguments("s1").WithLocation(10, 18),
                // (14,18): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                //             s0 = s2;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(14, 18),
                // (23,18): error CS8352: Cannot use variable 's21' in this context because it may expose referenced variables outside of their declaration scope
                //             s0 = s21;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s21").WithArguments("s21").WithLocation(23, 18),
                // (29,18): error CS8352: Cannot use variable 's4' in this context because it may expose referenced variables outside of their declaration scope
                //             s0 = s4;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s4").WithArguments("s4").WithLocation(29, 18),
                // (34,18): error CS8352: Cannot use variable 's5' in this context because it may expose referenced variables outside of their declaration scope
                //             s0 = s5;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s5").WithArguments("s5").WithLocation(34, 18),
                // (39,18): error CS8352: Cannot use variable 's7' in this context because it may expose referenced variables outside of their declaration scope
                //             s0 = s7;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s7").WithArguments("s7").WithLocation(39, 18)
                );
        }
 
        [Fact]
        public void LocalScope_13()
        {
            var source =
@"#pragma warning disable 219
ref struct R { }
class Program
{
    static void F(ref R r)
    {
        scoped ref R r2 = ref r, r5 = ref r;
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (7,9): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         scoped ref R r2 = ref r, r5 = ref r;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(7, 9)
                );
 
            verify(comp, useUpdatedEscapeRules: false);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
            verify(comp, useUpdatedEscapeRules: true);
 
            static void verify(CSharpCompilation comp, bool useUpdatedEscapeRules)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                VerifyLocalSymbol(locals[0], "scoped ref R r2", RefKind.Ref, ScopedKind.ScopedRef);
                VerifyLocalSymbol(locals[1], "scoped ref R r5", RefKind.Ref, ScopedKind.ScopedRef);
 
                var type = ((VariableDeclarationSyntax)decls[0].Parent).Type;
                Assert.Null(model.GetTypeInfo(type).Type);
                Assert.Equal("R", model.GetSymbolInfo(type.SkipScoped(out _).SkipRef()).Symbol.ToTestDisplayString());
            }
        }
 
        [Fact]
        public void LocalScope_13_For()
        {
            var source =
@"#pragma warning disable 219
ref struct R { }
class Program
{
    static void F(ref R r)
    {
        for (scoped ref R r2 = ref r, r5 = ref r;;) break;
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (7,14): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         for (scoped ref R r2 = ref r, r5 = ref r;;) break;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(7, 14)
                );
 
            verify(comp, useUpdatedEscapeRules: false);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
            verify(comp, useUpdatedEscapeRules: true);
 
            static void verify(CSharpCompilation comp, bool useUpdatedEscapeRules)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                VerifyLocalSymbol(locals[0], "scoped ref R r2", RefKind.Ref, ScopedKind.ScopedRef);
                VerifyLocalSymbol(locals[1], "scoped ref R r5", RefKind.Ref, ScopedKind.ScopedRef);
 
                var type = ((VariableDeclarationSyntax)decls[0].Parent).Type;
                Assert.Null(model.GetTypeInfo(type).Type);
                Assert.Equal("R", model.GetSymbolInfo(type.SkipScoped(out _).SkipRef()).Symbol.ToTestDisplayString());
            }
        }
 
        [Fact]
        public void ScopedRefAndRefStructOnly_06_For()
        {
            var source =
@"#pragma warning disable CS0219 // The variable is assigned but its value is never used
struct S<T> { }
class Program
{
    static void Main()
    {
        for (scoped var y1 = new S<int>();;) break;
        var y2 = new S<int>();
        for (scoped ref var y3 = ref y2;;) break;
        for (scoped S<int> y4 = new S<int>(), y5 = new S<int>();;) break;
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,21): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         for (scoped var y1 = new S<int>();;) break; // 2
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "var").WithLocation(7, 21),
                // (10,21): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         for (scoped S<int> y4 = new S<int>(), y5 = new S<int>();;) break;
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "S<int>").WithLocation(10, 21),
                // (10,21): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         for (scoped S<int> y4 = new S<int>(), y5 = new S<int>();;) break;
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "S<int>").WithLocation(10, 21)
                );
        }
 
        [Fact]
        public void ScopedRefAndRefStructOnly_06_Deconstruct()
        {
            var source =
@"#pragma warning disable CS0219 // The variable is assigned but its value is never used
struct S<T> { }
class Program
{
    static void Main()
    {
        (scoped var y1, var a) = (new S<int>(), 0);
        (var y2, var b) = (new S<int>(), 1);
        (scoped S<int> y3, var c) = (new S<int>(), 0);
        (S<int> y4, var d) = (new S<int>(), 1);
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,17): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         (scoped var y1, var a) = (new S<int>(), 0);
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "var").WithLocation(7, 17),
                // (9,17): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         (scoped S<int> y3, var c) = (new S<int>(), 0);
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "S<int>").WithLocation(9, 17)
                );
        }
 
        [Fact]
        public void ScopedRefAndRefStructOnly_06_OutVar()
        {
            var source =
@"#pragma warning disable CS0219 // The variable is assigned but its value is never used
struct S<T> { }
class Program
{
    static void Main()
    {
        M(out scoped var y1);
        M(out var y2);
        M(out scoped S<int> y3);
        M(out S<int> y4);
    }
 
    static void M(out S<int> x) => throw null;
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,22): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         M(out scoped var y1);
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "var").WithLocation(7, 22),
                // (9,22): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         M(out scoped S<int> y3);
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "S<int>").WithLocation(9, 22)
                );
        }
 
        [Fact]
        public void LocalScopeAndInitializer_01()
        {
            var source =
@"ref struct R { }
class Program
{
    static void Values(R r1, scoped R r2)
    {
        R r11 = r1;
        R r12 = r2;
        scoped R r21 = r1;
        scoped R r22 = r2;
    }
    static void Refs(ref R r1, scoped ref R r2)
    {
        ref R r31 = ref r1;
        ref R r32 = ref r2;
        scoped ref R r41 = ref r1;
        scoped ref R r42 = ref r2;
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
            var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
            VerifyLocalSymbol(locals[0], "R r11", RefKind.None, ScopedKind.None);
            VerifyLocalSymbol(locals[1], "R r12", RefKind.None, ScopedKind.None);
            VerifyLocalSymbol(locals[2], "scoped R r21", RefKind.None, ScopedKind.ScopedValue);
            VerifyLocalSymbol(locals[3], "scoped R r22", RefKind.None, ScopedKind.ScopedValue);
 
            VerifyLocalSymbol(locals[4], "ref R r31", RefKind.Ref, ScopedKind.None);
            VerifyLocalSymbol(locals[5], "ref R r32", RefKind.Ref, ScopedKind.None);
            VerifyLocalSymbol(locals[6], "scoped ref R r41", RefKind.Ref, ScopedKind.ScopedRef);
            VerifyLocalSymbol(locals[7], "scoped ref R r42", RefKind.Ref, ScopedKind.ScopedRef);
        }
 
        [Fact]
        public void LocalScope_01_Foreach_01()
        {
            var source =
@"#pragma warning disable 219
ref struct R { }
class Program
{
    static void F(ref R r)
    {
        foreach (scoped R r1 in new Enumerable1()) break;
        foreach (scoped ref R r2 in new Enumerable2(ref r)) break;
        foreach (scoped ref readonly R r5 in new Enumerable2(ref r)) break;
    }
}
 
class Enumerable1
{
    public Enumerator1 GetEnumerator() => default;
}
 
class Enumerator1
{
    public R Current => default;
    public bool MoveNext() => false;
}
 
class Enumerable2
{
    public Enumerable2(ref R x) {}
    public Enumerator2 GetEnumerator() => default;
}
 
class Enumerator2
{
    public ref R Current => throw null;
    public bool MoveNext() => false;
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (7,18): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         foreach (scoped R r1 in new Enumerable1()) break;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(7, 18),
                // (8,18): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         foreach (scoped ref R r2 in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(8, 18),
                // (9,18): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         foreach (scoped ref readonly R r5 in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(9, 18)
                );
 
            verify(comp);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<ForEachStatementSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                VerifyLocalSymbol(locals[0], "scoped R r1", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[1], "scoped ref R r2", RefKind.Ref, ScopedKind.ScopedRef);
                VerifyLocalSymbol(locals[2], "scoped ref readonly R r5", RefKind.RefReadOnly, ScopedKind.ScopedRef);
 
                foreach (var decl in decls)
                {
                    var type = decl.Type;
 
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type));
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type.SkipScoped(out _)));
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type.SkipScoped(out _).SkipRef()));
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("R", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("R", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
            }
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void LocalScope_01_Foreach_02(LanguageVersion languageVersion)
        {
            var source =
@"#pragma warning disable 219
ref struct R { }
class Program
{
    static void F(ref R r)
    {
        foreach (var _ in new Enumerable1()) break;
        foreach (R _ in new Enumerable1()) break;
        foreach (ref var _ in new Enumerable2(ref r)) break;
        foreach (ref readonly var _ in new Enumerable2(ref r)) break;
        foreach (ref R _ in new Enumerable2(ref r)) break;
    }
}
 
class Enumerable1
{
    public Enumerator1 GetEnumerator() => default;
}
 
class Enumerator1
{
    public R Current => default;
    public bool MoveNext() => false;
}
 
class Enumerable2
{
    public Enumerable2(ref R x) {}
    public Enumerator2 GetEnumerator() => default;
}
 
class Enumerator2
{
    public ref R Current => throw null;
    public bool MoveNext() => false;
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void LocalScope_01_Foreach_Deconstruction_01()
        {
            var source =
@"#pragma warning disable 219
 
class Program
{
    static void F(ref R r)
    {
        foreach ((scoped R r1, scoped var _) in new Enumerable1()) break;
        foreach ((scoped ref R r2, scoped ref var _) in new Enumerable2(ref r)) break;
        foreach ((scoped ref readonly R r5, scoped ref readonly var _) in new Enumerable2(ref r)) break;
 
        foreach ((scoped var r11, scoped R _) in new Enumerable1()) break;
        foreach ((scoped ref var r21, scoped ref R _) in new Enumerable2(ref r)) break;
        foreach ((scoped ref readonly var r51, scoped ref readonly R _) in new Enumerable2(ref r)) break;
    }
}
 
ref struct R 
{
    public void Deconstruct(out R x, out R y) => throw null;
}
 
class Enumerable1
{
    public Enumerator1 GetEnumerator() => default;
}
 
class Enumerator1
{
    public R Current => default;
    public bool MoveNext() => false;
}
 
class Enumerable2
{
    public Enumerable2(ref R x) {}
    public Enumerator2 GetEnumerator() => default;
}
 
class Enumerator2
{
    public ref R Current => throw null;
    public bool MoveNext() => false;
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (7,19): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         foreach ((scoped R r1, scoped var _) in new Enumerable1()) break;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(7, 19),
                // (7,32): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         foreach ((scoped R r1, scoped var _) in new Enumerable1()) break;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(7, 32),
                // (8,19): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         foreach ((scoped ref R r2, scoped ref var _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(8, 19),
                // (8,26): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((scoped ref R r2, scoped ref var _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(8, 26),
                // (8,36): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         foreach ((scoped ref R r2, scoped ref var _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(8, 36),
                // (8,43): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((scoped ref R r2, scoped ref var _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(8, 43),
                // (9,19): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         foreach ((scoped ref readonly R r5, scoped ref readonly var _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(9, 19),
                // (9,26): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((scoped ref readonly R r5, scoped ref readonly var _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(9, 26),
                // (9,45): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         foreach ((scoped ref readonly R r5, scoped ref readonly var _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(9, 45),
                // (9,52): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((scoped ref readonly R r5, scoped ref readonly var _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(9, 52),
                // (11,19): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         foreach ((scoped var r11, scoped R _) in new Enumerable1()) break;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(11, 19),
                // (11,35): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         foreach ((scoped var r11, scoped R _) in new Enumerable1()) break;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(11, 35),
                // (12,19): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         foreach ((scoped ref var r21, scoped ref R _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(12, 19),
                // (12,26): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((scoped ref var r21, scoped ref R _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(12, 26),
                // (12,39): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         foreach ((scoped ref var r21, scoped ref R _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(12, 39),
                // (12,46): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((scoped ref var r21, scoped ref R _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(12, 46),
                // (13,19): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         foreach ((scoped ref readonly var r51, scoped ref readonly R _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(13, 19),
                // (13,26): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((scoped ref readonly var r51, scoped ref readonly R _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(13, 26),
                // (13,48): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         foreach ((scoped ref readonly var r51, scoped ref readonly R _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(13, 48),
                // (13,55): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((scoped ref readonly var r51, scoped ref readonly R _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(13, 55)
                );
            verify(comp);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (7,32): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         foreach ((scoped R r1, scoped var _) in new Enumerable1()) break;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(7, 32),
                // (8,26): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((scoped ref R r2, scoped ref var _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(8, 26),
                // (8,36): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         foreach ((scoped ref R r2, scoped ref var _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(8, 36),
                // (8,43): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((scoped ref R r2, scoped ref var _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(8, 43),
                // (9,26): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((scoped ref readonly R r5, scoped ref readonly var _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(9, 26),
                // (9,45): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         foreach ((scoped ref readonly R r5, scoped ref readonly var _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(9, 45),
                // (9,52): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((scoped ref readonly R r5, scoped ref readonly var _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(9, 52),
                // (11,35): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         foreach ((scoped var r11, scoped R _) in new Enumerable1()) break;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(11, 35),
                // (12,26): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((scoped ref var r21, scoped ref R _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(12, 26),
                // (12,39): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         foreach ((scoped ref var r21, scoped ref R _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(12, 39),
                // (12,46): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((scoped ref var r21, scoped ref R _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(12, 46),
                // (13,26): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((scoped ref readonly var r51, scoped ref readonly R _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(13, 26),
                // (13,48): error CS9061: The 'scoped' modifier cannot be used with discard.
                //         foreach ((scoped ref readonly var r51, scoped ref readonly R _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_ScopedDiscard, "scoped").WithLocation(13, 48),
                // (13,55): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((scoped ref readonly var r51, scoped ref readonly R _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(13, 55)
                );
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<SingleVariableDesignationSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                VerifyLocalSymbol(locals[0], "scoped R r1", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[1], "scoped R r2", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[2], "scoped R r5", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[3], "scoped R r11", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[4], "scoped R r21", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[5], "scoped R r51", RefKind.None, ScopedKind.ScopedValue);
 
                foreach (var decl in decls)
                {
                    var type = ((DeclarationExpressionSyntax)decl.Parent).Type;
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("R", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("R", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
 
                var discard = tree.GetRoot().DescendantNodes().OfType<DiscardDesignationSyntax>().ToArray();
                Assert.Equal(6, discard.Length);
 
                foreach (var decl in discard)
                {
                    Assert.Null(model.GetDeclaredSymbol(decl));
                    Assert.Null(model.GetSymbolInfo(decl).Symbol);
                    Assert.Null(model.GetTypeInfo(decl).Type);
 
                    var type = ((DeclarationExpressionSyntax)decl.Parent).Type;
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("R", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("R", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
            }
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void LocalScope_01_Foreach_Deconstruction_02(LanguageVersion languageVersion)
        {
            var source =
@"#pragma warning disable 219
 
class Program
{
    static void F0(ref R r)
    {
        foreach ((R r0, _) in new Enumerable1()) break;
 
        foreach ((R r1, var _) in new Enumerable1()) break;
        foreach ((ref R r2, ref var _) in new Enumerable2(ref r)) break;
        foreach ((ref readonly R r5, ref readonly var _) in new Enumerable2(ref r)) break;
 
        foreach ((var r11, R _) in new Enumerable1()) break;
        foreach ((ref var r21, ref R _) in new Enumerable2(ref r)) break;
        foreach ((ref readonly var r51, ref readonly R _) in new Enumerable2(ref r)) break;
    }
 
    static void F1()
    {
        var e1 = new Enumerable1().GetEnumerator();
        e1.MoveNext();
        e1.Current.Deconstruct(out R r0, out _);
        e1.Current.Deconstruct(out R r1, out var _);
        e1.Current.Deconstruct(out var r11, out R _);
    }
}
 
ref struct R 
{
    public void Deconstruct(out R x, out R y) => throw null;
}
 
class Enumerable1
{
    public Enumerator1 GetEnumerator() => default;
}
 
class Enumerator1
{
    public R Current => default;
    public bool MoveNext() => false;
}
 
class Enumerable2
{
    public Enumerable2(ref R x) {}
    public Enumerator2 GetEnumerator() => default;
}
 
class Enumerator2
{
    public ref R Current => throw null;
    public bool MoveNext() => false;
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics(
                // (10,19): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((ref R r2, ref var _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(10, 19),
                // (10,29): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((ref R r2, ref var _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(10, 29),
                // (11,19): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((ref readonly R r5, ref readonly var _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(11, 19),
                // (11,38): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((ref readonly R r5, ref readonly var _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(11, 38),
                // (14,19): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((ref var r21, ref R _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(14, 19),
                // (14,32): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((ref var r21, ref R _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(14, 32),
                // (15,19): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((ref readonly var r51, ref readonly R _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(15, 19),
                // (15,41): error CS9072: A deconstruction variable cannot be declared as a ref local
                //         foreach ((ref readonly var r51, ref readonly R _) in new Enumerable2(ref r)) break;
                Diagnostic(ErrorCode.ERR_DeconstructVariableCannotBeByRef, "ref").WithLocation(15, 41));
        }
 
        [Fact]
        public void LocalScope_04_Foreach()
        {
            var source =
@"foreach (scoped s1 in new Enumerable1()) {
    foreach (ref scoped s2 in new Enumerable2()) {break;} // 1
    foreach (ref @scoped s3 in new Enumerable2()) {break;}
    foreach (scoped scoped s4 in new Enumerable1()) {break;} // 2
    foreach (scoped ref scoped s5 in new Enumerable2()) {break;} // 3
    foreach (scoped ref @scoped s6 in new Enumerable2()) {break;} // 4
}
 
ref struct @scoped { } // 5
 
class Enumerable1
{
    public Enumerator1 GetEnumerator() => default;
}
 
class Enumerator1
{
    public @scoped Current => default;
    public bool MoveNext() => false;
}
 
class Enumerable2
{
    public Enumerator2 GetEnumerator() => default;
}
 
class Enumerator2
{
    public ref @scoped Current => throw null;
    public bool MoveNext() => false;
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (4,14): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     foreach (scoped scoped s4 in new Enumerable1()) {break;} // 2
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(4, 14),
                // (5,14): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     foreach (scoped ref scoped s5 in new Enumerable2()) {break;} // 3
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(5, 14),
                // (6,14): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     foreach (scoped ref @scoped s6 in new Enumerable2()) {break;} // 4
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(6, 14)
                );
            verify(comp);
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<ForEachStatementSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                VerifyLocalSymbol(locals[0], "scoped s1", RefKind.None, ScopedKind.None);
                VerifyLocalSymbol(locals[1], "ref scoped s2", RefKind.Ref, ScopedKind.None);
                VerifyLocalSymbol(locals[2], "ref scoped s3", RefKind.Ref, ScopedKind.None);
                VerifyLocalSymbol(locals[3], "scoped scoped s4", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[4], "scoped ref scoped s5", RefKind.Ref, ScopedKind.ScopedRef);
                VerifyLocalSymbol(locals[5], "scoped ref scoped s6", RefKind.Ref, ScopedKind.ScopedRef);
            }
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void LocalScope_05_Foreach(LanguageVersion langVersion)
        {
            var source =
@"foreach (bool scoped in new bool[] {}) {
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
            comp.VerifyDiagnostics();
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var decls = tree.GetRoot().DescendantNodes().OfType<ForEachStatementSyntax>().ToArray();
            var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
            VerifyLocalSymbol(locals[0], "System.Boolean scoped", RefKind.None, ScopedKind.None);
        }
 
        [Fact]
        public void LocalScope_06_Foreach()
        {
            var source =
@"ref struct R<T> { }
class Program
{
    static void M(R<int> r0)
    {
        foreach (scoped var r1 in new Enumerable1<int>()) break;
        foreach (scoped ref var r3 in new Enumerable2<int>(ref r0)) break;
    }
}
 
class Enumerable1<T>
{
    public Enumerator1<T> GetEnumerator() => default;
}
 
class Enumerator1<T>
{
    public R<T> Current => default;
    public bool MoveNext() => false;
}
 
class Enumerable2<T>
{
    public Enumerable2(ref R<T> x) {}
    public Enumerator2<T> GetEnumerator() => default;
}
 
class Enumerator2<T>
{
    public ref R<T> Current => throw null;
    public bool MoveNext() => false;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
 
            verifyModel(comp);
 
            comp = CreateCompilation(source, parseOptions: TestOptions.RegularDefault.WithFeature("run-nullable-analysis", "never"));
            verifyModel(comp);
 
            static void verifyModel(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<ForEachStatementSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                foreach (SourceLocalSymbol local in locals)
                {
                    Assert.True(local.IsVar);
                    Assert.Equal("R<System.Int32>", local.Type.ToTestDisplayString());
                }
 
                VerifyLocalSymbol(locals[0], "scoped R<System.Int32> r1", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[1], "scoped ref R<System.Int32> r3", RefKind.Ref, ScopedKind.ScopedRef);
 
                foreach (var decl in decls)
                {
                    var type = decl.Type;
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("R<System.Int32>", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("R<System.Int32>", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
            }
        }
 
        [Fact]
        public void LocalScope_09_Foreach_01()
        {
            var source =
@"foreach (scoped s1 in new Enumerable1()) {
    scoped ref @scoped s2 = ref s1;
}
ref struct @scoped { }
 
class Enumerable1
{
    public Enumerator1 GetEnumerator() => default;
}
 
class Enumerator1
{
    public @scoped Current => default;
    public bool MoveNext() => false;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (2,33): error CS1657: Cannot use 's1' as a ref or out value because it is a 'foreach iteration variable'
                //     scoped ref @scoped s2 = ref s1;
                Diagnostic(ErrorCode.ERR_RefReadonlyLocalCause, "s1").WithArguments("s1", "foreach iteration variable").WithLocation(2, 33)
                );
        }
 
        [Fact]
        public void LocalScope_09_Foreach_02()
        {
            var source =
@"scoped s1 = default;
foreach (scoped ref @scoped s2 in Enumerable1.Create(ref s1)) break;
 
ref struct @scoped { }
 
class Enumerable1
{
    public static Enumerable1 Create(ref @scoped p) => default;
    public Enumerator1 GetEnumerator() => default;
}
 
class Enumerator1
{
    public ref @scoped Current => throw null;
    public bool MoveNext() => false;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void LocalScope_10_Foreach_01()
        {
            var source =
@"int i = 0;
S s1 = new S(ref i);
foreach (scoped S s2 in Enumerable1.Create(s1)) break;
 
ref struct S
{
    public S(ref int i) { }
}
 
class Enumerable1
{
    public static Enumerable1 Create(S p) => default;
    public Enumerator1 GetEnumerator() => default;
}
 
class Enumerator1
{
    public S Current => throw null;
    public bool MoveNext() => false;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Theory]
        [InlineData("class")]
        [InlineData("ref struct")]
        public void LocalScope_10_Foreach_02(string kind)
        {
            var source =
@"int i = 0;
foreach (S s1 in Enumerable1.Create(ref i)) {
    scoped S s2 = s1;
    break;
}
ref struct S
{
    public S(ref int i) { }
}
 
" + kind + @" Enumerable1
{
    public static Enumerable1 Create(ref int p) => default;
    public Enumerator1 GetEnumerator() => default;
}
 
class Enumerator1
{
    public S Current => throw null;
    public bool MoveNext() => false;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void LocalScope_11_Foreach_01()
        {
            var source =
@"class Program
{
    static void Main()
    {
        S s0 = default;
        scoped ref S r0 = ref s0;
        foreach (scoped ref S r1 in ClassEnumerable.Create(ref s0)) {
            r0 = ref r1; // 1
            break;
        }
        foreach (scoped ref S r2 in ClassEnumerable.Create(ref s0)) {
            r0 = ref r2; // 2
            break;
        }
        foreach (ref S r3 in ClassEnumerable.Create(ref s0)) {
            r0 = ref r3;
            break;
        }
        foreach (ref S r4 in ClassEnumerable.Create(ref s0)) {
            r0 = ref r4;
            break;
        }
        foreach (scoped ref S r5 in RefStructEnumerable.Create(ref s0)) {
            r0 = ref r5; // 3
            break;
        }
        foreach (ref S r6 in RefStructEnumerable.Create(ref s0)) {
            r0 = ref r6; // 4
            break;
        }
    }
}
ref struct S { }
 
class ClassEnumerable
{
    public static ClassEnumerable Create(ref S p) => default;
    public ClassEnumerator GetEnumerator() => default;
}
 
ref struct RefStructEnumerable
{
    public static RefStructEnumerable Create(ref S p) => default;
    public ClassEnumerator GetEnumerator() => default;
}
 
class ClassEnumerator
{
    public ref S Current => throw null;
    public bool MoveNext() => false;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (8,13): error CS8374: Cannot ref-assign 'r1' to 'r0' because 'r1' has a narrower escape scope than 'r0'.
                //             r0 = ref r1; // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r0 = ref r1").WithArguments("r0", "r1").WithLocation(8, 13),
                // (12,13): error CS8374: Cannot ref-assign 'r2' to 'r0' because 'r2' has a narrower escape scope than 'r0'.
                //             r0 = ref r2; // 2
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r0 = ref r2").WithArguments("r0", "r2").WithLocation(12, 13),
                // (24,13): error CS8374: Cannot ref-assign 'r5' to 'r0' because 'r5' has a narrower escape scope than 'r0'.
                //             r0 = ref r5; // 3
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r0 = ref r5").WithArguments("r0", "r5").WithLocation(24, 13),
                // (28,22): error CS8352: Cannot use variable 'r6' in this context because it may expose referenced variables outside of their declaration scope
                //             r0 = ref r6; // 4
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r6").WithArguments("r6").WithLocation(28, 22));
        }
 
        [Theory]
        [InlineData("class")]
        [InlineData("ref struct")]
        public void LocalScope_11_Foreach_02(string kind)
        {
            var source =
@"class Program
{
    static void Main()
    {
        S s0 = default;
        foreach (scoped ref S r0 in Enumerable1.Create(ref s0))
        {
            scoped ref S r1 = ref s0;
            r0 = ref r1;
 
            scoped ref S r2 = ref r0;
            r0 = ref r2;
 
            ref S r3 = ref s0;
            r0 = ref r3;
 
            ref S r4 = ref r0;
            r0 = ref r4;
 
            break;
        }
    }
}
ref struct S { }
 
" + kind + @" Enumerable1
{
    public static Enumerable1 Create(ref S p) => default;
    public Enumerator1 GetEnumerator() => default;
}
 
class Enumerator1
{
    public ref S Current => throw null;
    public bool MoveNext() => false;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (9,13): error CS1656: Cannot assign to 'r0' because it is a 'foreach iteration variable'
                //             r0 = ref r1;
                Diagnostic(ErrorCode.ERR_AssgReadonlyLocalCause, "r0").WithArguments("r0", "foreach iteration variable").WithLocation(9, 13),
                // (12,13): error CS1656: Cannot assign to 'r0' because it is a 'foreach iteration variable'
                //             r0 = ref r2;
                Diagnostic(ErrorCode.ERR_AssgReadonlyLocalCause, "r0").WithArguments("r0", "foreach iteration variable").WithLocation(12, 13),
                // (15,13): error CS1656: Cannot assign to 'r0' because it is a 'foreach iteration variable'
                //             r0 = ref r3;
                Diagnostic(ErrorCode.ERR_AssgReadonlyLocalCause, "r0").WithArguments("r0", "foreach iteration variable").WithLocation(15, 13),
                // (18,13): error CS1656: Cannot assign to 'r0' because it is a 'foreach iteration variable'
                //             r0 = ref r4;
                Diagnostic(ErrorCode.ERR_AssgReadonlyLocalCause, "r0").WithArguments("r0", "foreach iteration variable").WithLocation(18, 13)
                );
        }
 
        [Fact]
        [WorkItem(64218, "https://github.com/dotnet/roslyn/issues/64218")]
        public void LocalScope_12_Foreach_01()
        {
            var source =
@"class Program
{
    static void Main()
    {
        int i0 = 0;
        S s0 = new S(ref i0);
        {
            int i1 = 1;
            foreach (S s1 in Enumerable1.Create(ref i1)) {
                s0 = s1;
                break;
            }
        }
        foreach (scoped S s2 in Enumerable1.Create(s0)) {
            s0 = s2; // 1
            break;
        }
        foreach (S s3 in Enumerable1.Create(s0)) {
            s0 = s3;
            break;
        }
    }
}
ref struct S
{
    public S(ref int i) { }
}
 
class Enumerable1
{
    public static Enumerable1 Create(ref int p) => default;
    public static Enumerable1 Create(S p) => default;
    public Enumerator1 GetEnumerator() => default;
}
 
class Enumerator1
{
    public S Current => throw null;
    public bool MoveNext() => false;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (15,18): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                //             s0 = s2; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(15, 18)
                );
        }
 
        [Theory]
        [InlineData("class")]
        [InlineData("ref struct")]
        public void LocalScope_12_Foreach_02(string kind)
        {
            var source =
@"class Program
{
    static void Main()
    {
        int i0 = 0;
        foreach (S s0 in Enumerable1.Create(ref i0))
        {
            int i1 = 1;
            S s1 = new S(ref i1);
            s0 = s1;
 
            scoped S s2 = s0;
            s0 = s2;
 
            S s3 = s0;
            s0 = s3;
 
            break;
        }
    }
}
ref struct S
{
    public S(ref int i) { }
}
 
" + kind + @" Enumerable1
{
    public static Enumerable1 Create(ref int p) => default;
    public Enumerator1 GetEnumerator() => default;
}
 
class Enumerator1
{
    public S Current => throw null;
    public bool MoveNext() => false;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (10,13): error CS1656: Cannot assign to 's0' because it is a 'foreach iteration variable'
                //             s0 = s1;
                Diagnostic(ErrorCode.ERR_AssgReadonlyLocalCause, "s0").WithArguments("s0", "foreach iteration variable").WithLocation(10, 13),
                // (13,13): error CS1656: Cannot assign to 's0' because it is a 'foreach iteration variable'
                //             s0 = s2;
                Diagnostic(ErrorCode.ERR_AssgReadonlyLocalCause, "s0").WithArguments("s0", "foreach iteration variable").WithLocation(13, 13),
                // (16,13): error CS1656: Cannot assign to 's0' because it is a 'foreach iteration variable'
                //             s0 = s3;
                Diagnostic(ErrorCode.ERR_AssgReadonlyLocalCause, "s0").WithArguments("s0", "foreach iteration variable").WithLocation(16, 13)
                );
        }
 
        [Fact]
        [WorkItem(64218, "https://github.com/dotnet/roslyn/issues/64218")]
        public void LocalScope_12_Foreach_03()
        {
            var source =
@"class Program
{
    static void Main()
    {
        int i0 = 0;
        S s0 = new S(ref i0);
        {
            int i1 = 1;
            foreach (S s1 in Enumerable1.Create(ref i1)) {
                s0 = s1;
                break;
            }
        }
    }
}
ref struct S
{
    public S(ref int i) { }
}
ref struct Enumerable1
{
    public static Enumerable1 Create(ref int p) => default;
    public Enumerator1 GetEnumerator() => default;
}
ref struct Enumerator1
{
    public S Current => throw null;
    public bool MoveNext() => false;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (10,22): error CS8352: Cannot use variable 's1' in this context because it may expose referenced variables outside of their declaration scope
                //                 s0 = s1;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s1").WithArguments("s1").WithLocation(10, 22)
                );
        }
 
        [Fact]
        [WorkItem(64218, "https://github.com/dotnet/roslyn/issues/64218")]
        public void LocalScope_12_Foreach_04()
        {
            var source =
@"class Program
{
    static void Main()
    {
        int i0 = 0;
        S s0 = new S(ref i0);
        {
            int i1 = 1;
            foreach (S s1 in RefStructEnumerable.Create(ref i1)) {
                s0 = s1;
                break;
            }
        }
        {
            int i2 = 1;
            foreach (S s2 in ClassEnumerable.Create(ref i2)) {
                s0 = s2;
                break;
            }
        }
    }
}
ref struct S
{
    public S(ref int i) { }
}
ref struct RefStructEnumerable
{
    public static RefStructEnumerable Create(ref int p) => default;
    public ClassEnumerator GetEnumerator() => default;
}
class ClassEnumerable
{
    public static ClassEnumerable Create(ref int p) => default;
    public ClassEnumerator GetEnumerator() => default;
}
class ClassEnumerator
{
    public S Current => throw null;
    public bool MoveNext() => false;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (10,22): error CS8352: Cannot use variable 's1' in this context because it may expose referenced variables outside of their declaration scope
                //                 s0 = s1;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s1").WithArguments("s1").WithLocation(10, 22));
        }
 
        [Fact]
        public void ScopedRefAndRefStructOnly_06_Foreach()
        {
            var source =
@"
struct S<T> { }
class Program
{
    static void Main()
    {
        foreach (scoped var y1 in new Enumerable1<int>()) break;
        foreach (scoped ref var y3 in new Enumerable2<int>()) break;
        foreach (scoped S<int> y1 in new Enumerable1<int>()) break;
        foreach (scoped ref S<int> y3 in new Enumerable2<int>()) break;
    }
}
 
class Enumerable1<T>
{
    public Enumerator1<T> GetEnumerator() => default;
}
 
class Enumerator1<T>
{
    public S<T> Current => default;
    public bool MoveNext() => false;
}
 
class Enumerable2<T>
{
    public Enumerator2<T> GetEnumerator() => default;
}
 
class Enumerator2<T>
{
    public ref S<T> Current => throw null;
    public bool MoveNext() => false;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,25): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         foreach (scoped var y1 in new Enumerable1<int>()) break;
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "var").WithLocation(7, 25),
                // (9,25): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         foreach (scoped S<int> y1 in new Enumerable1<int>()) break;
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "S<int>").WithLocation(9, 25)
                );
        }
 
        [Fact]
        public void ScopedRefAndRefStructOnly_06_Foreach_Deconstruction()
        {
            var source =
@"
class Program
{
    static void Main()
    {
        foreach ((scoped var y1, scoped S<int> y2) in new Enumerable1<int>()) break;
    }
}
 
struct S<T>
{
    public void Deconstruct(out S<T> x, out S<T> y) => throw null;
}
 
class Enumerable1<T>
{
    public Enumerator1<T> GetEnumerator() => default;
}
 
class Enumerator1<T>
{
    public S<T> Current => default;
    public bool MoveNext() => false;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (6,26): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         foreach ((scoped var y1, scoped S<int> y2) in new Enumerable1<int>()) break;
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "var").WithLocation(6, 26),
                // (6,41): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         foreach ((scoped var y1, scoped S<int> y2) in new Enumerable1<int>()) break;
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "S<int>").WithLocation(6, 41)
                );
        }
 
        private static void VerifyLocalSymbol(LocalSymbol local, string expectedDisplayString, RefKind expectedRefKind, ScopedKind expectedScope)
        {
            Assert.Equal(expectedRefKind, local.RefKind);
            Assert.Equal(expectedScope, local.Scope);
            Assert.Equal(expectedDisplayString, local.ToDisplayString(displayFormatWithScoped));
 
            VerifyLocalSymbol(local.GetPublicSymbol(), expectedDisplayString, expectedRefKind, expectedScope);
        }
 
        private static void VerifyLocalSymbol(ILocalSymbol local, string expectedDisplayString, RefKind expectedRefKind, ScopedKind expectedScope)
        {
            Assert.Equal(expectedRefKind, local.RefKind);
            Assert.Equal(expectedScope, local.ScopedKind);
            Assert.Equal(expectedDisplayString, local.ToDisplayString(displayFormatWithScoped));
        }
 
        [ConditionalFact(typeof(WindowsDesktopOnly), Reason = ConditionalSkipReason.NoPiaNeedsDesktop)]
        public void ParameterScope_EmbeddedMethod()
        {
            var sourceA =
@"using System.Runtime.InteropServices;
[assembly: ImportedFromTypeLib(""_.dll"")]
[assembly: Guid(""DB204C34-AE89-49C6-9174-09F72E7F7F10"")]
[ComImport()]
[Guid(""933FEEE7-2728-4F87-A802-953F3CF1B1E9"")]
public interface I
{
    void M(scoped ref int i);
}
";
            var comp = CreateCompilation(sourceA);
            var refA = comp.EmitToImageReference(embedInteropTypes: true);
 
            var sourceB =
@"class C : I
{
    public void M(scoped ref int i) { }
}
class Program
{
    static void Main()
    {
    }
}";
            CompileAndVerify(sourceB, references: new[] { refA },
                symbolValidator: module =>
                {
                    var method = module.GlobalNamespace.GetMember<PEMethodSymbol>("I.M");
                    // Attribute is not included for the parameter from the embedded method.
                    VerifyParameterSymbol(method.Parameters[0], "ref System.Int32 i", RefKind.Ref, ScopedKind.None);
                });
        }
 
        [Fact]
        public void Conversions_01()
        {
            var source =
@"ref struct R { }
class Program
{
    static R Implicit1(scoped R r) => r;
    static R Implicit2(ref R r) => r;
    static R Implicit4(scoped ref R r) => r;
    static R Explicit1(scoped R r) => (R)r;
    static R Explicit2(ref R r) => (R)r;
    static R Explicit4(scoped ref R r) => (R)r;
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (4,39): error CS8352: Cannot use variable 'scoped R r' in this context because it may expose referenced variables outside of their declaration scope
                //     static R Implicit1(scoped R r) => r;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r").WithArguments("scoped R r").WithLocation(4, 39),
                // (7,39): error CS8352: Cannot use variable 'scoped R r' in this context because it may expose referenced variables outside of their declaration scope
                //     static R Explicit1(scoped R r) => (R)r;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "(R)r").WithArguments("scoped R r").WithLocation(7, 39));
        }
 
        [Fact]
        public void DelegateConversions_01()
        {
            var source =
@"ref struct R { }
delegate R D1(R x, R y);
delegate R D2(R x, scoped R y);
delegate ref R D3(ref R x, ref R y);
delegate ref R D5(ref R x, scoped ref R y);
class Program
{
    static void Implicit()
    {
        D1 d1 = (R x, scoped R y) => x;
        D2 d2 = (R x, R y) => x; // 1
        D3 d3 = (ref R x, scoped ref R y) => ref x;
        D5 d5 = (ref R x, ref R y) => ref x; // 2
    }
    static void Explicit()
    {
        var d1 = (D1)((R x, scoped R y) => x);
        var d2 = (D2)((R x, R y) => x); // 3
        var d3 = (D3)((ref R x, scoped ref R y) => ref x);
        var d5 = (D5)((ref R x, ref R y) => ref x); // 4
    }
    static void New()
    {
        var d1 = new D1((R x, scoped R y) => x);
        var d2 = new D2((R x, R y) => x); // 5
        var d3 = new D3((ref R x, scoped ref R y) => ref x);
        var d5 = new D5((ref R x, ref R y) => ref x); // 6
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (11,17): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'D2'.
                //         D2 d2 = (R x, R y) => x; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(R x, R y) => x").WithArguments("y", "D2").WithLocation(11, 17),
                // (13,17): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'D5'.
                //         D5 d5 = (ref R x, ref R y) => ref x; // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(ref R x, ref R y) => ref x").WithArguments("y", "D5").WithLocation(13, 17),
                // (18,18): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'D2'.
                //         var d2 = (D2)((R x, R y) => x); // 3
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(D2)((R x, R y) => x)").WithArguments("y", "D2").WithLocation(18, 18),
                // (20,18): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'D5'.
                //         var d5 = (D5)((ref R x, ref R y) => ref x); // 4
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(D5)((ref R x, ref R y) => ref x)").WithArguments("y", "D5").WithLocation(20, 18),
                // (25,25): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'D2'.
                //         var d2 = new D2((R x, R y) => x); // 5
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(R x, R y) => x").WithArguments("y", "D2").WithLocation(25, 25),
                // (27,25): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'D5'.
                //         var d5 = new D5((ref R x, ref R y) => ref x); // 6
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(ref R x, ref R y) => ref x").WithArguments("y", "D5").WithLocation(27, 25));
        }
 
        [Fact]
        public void DelegateConversions_02()
        {
            var source =
@"ref struct R { }
delegate R D1(R x, R y);
delegate R D2(R x, scoped R y);
delegate ref R D3(ref R x, ref R y);
delegate ref R D5(ref R x, scoped ref R y);
class Program
{
    static R M1(R x, R y) => x;
    static R M2(R x, scoped R y) => x;
    static ref R M3(ref R x, ref R y) => ref x;
    static ref R M5(ref R x, scoped ref R y) => ref x;
    static void Implicit()
    {
        D1 d1 = M2;
        D2 d2 = M1; // 1
        D3 d3 = M5;
        D5 d5 = M3; // 2
    }
    static void Explicit()
    {
        var d1 = (D1)M2;
        var d2 = (D2)M1; // 3
        var d3 = (D3)M5;
        var d5 = (D5)M3; // 4
    }
    static void New()
    {
        var d1 = new D1(M2);
        var d2 = new D2(M1); // 5
        var d3 = new D3(M5);
        var d5 = new D5(M3); // 6
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (15,17): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'D2'.
                //         D2 d2 = M1; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "M1").WithArguments("y", "D2").WithLocation(15, 17),
                // (17,17): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'D5'.
                //         D5 d5 = M3; // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "M3").WithArguments("y", "D5").WithLocation(17, 17),
                // (22,18): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'D2'.
                //         var d2 = (D2)M1; // 3
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(D2)M1").WithArguments("y", "D2").WithLocation(22, 18),
                // (24,18): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'D5'.
                //         var d5 = (D5)M3; // 4
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(D5)M3").WithArguments("y", "D5").WithLocation(24, 18),
                // (29,25): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'D2'.
                //         var d2 = new D2(M1); // 5
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "M1").WithArguments("y", "D2").WithLocation(29, 25),
                // (31,25): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'D5'.
                //         var d5 = new D5(M3); // 6
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "M3").WithArguments("y", "D5").WithLocation(31, 25));
        }
 
        [Fact]
        public void DelegateConversions_03()
        {
            var source =
@"delegate ref int D1(ref int x, ref int y);
delegate ref int D2(scoped ref int x, ref int y);
delegate D1 D1R();
delegate D2 D2R();
class Program
{
    static void Implicit()
    {
        D1R d1 = () => (scoped ref int x, ref int y) => ref y;
        D2R d2 = () => (ref int x, ref int y) => ref x; // 1
    }
    static void Explicit()
    {
        var d1 = (D1R)(() => (scoped ref int x, ref int y) => ref y);
        var d2 = (D2R)(() => (ref int x, ref int y) => ref x); // 2
    }
    static void New()
    {
        var d1 = new D1R(() => (scoped ref int x, ref int y) => ref y);
        var d2 = new D2R(() => (ref int x, ref int y) => ref x); // 3
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (10,24): error CS8986: The 'scoped' modifier of parameter 'x' doesn't match target 'D2'.
                //         D2R d2 = () => (ref int x, ref int y) => ref x; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(ref int x, ref int y) => ref x").WithArguments("x", "D2").WithLocation(10, 24),
                // (15,30): error CS8986: The 'scoped' modifier of parameter 'x' doesn't match target 'D2'.
                //         var d2 = (D2R)(() => (ref int x, ref int y) => ref x); // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(ref int x, ref int y) => ref x").WithArguments("x", "D2").WithLocation(15, 30),
                // (20,32): error CS8986: The 'scoped' modifier of parameter 'x' doesn't match target 'D2'.
                //         var d2 = new D2R(() => (ref int x, ref int y) => ref x); // 3
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(ref int x, ref int y) => ref x").WithArguments("x", "D2").WithLocation(20, 32));
        }
 
        [Fact]
        public void DelegateConversions_04()
        {
            var source =
@"delegate ref int D1(ref int x, ref int y);
delegate ref int D2(scoped ref int x, ref int y);
delegate D1 D1R();
delegate D2 D2R();
class Program
{
    static ref int M1(ref int x, ref int y) => ref x;
    static ref int M2(scoped ref int x, ref int y) => ref y;
    static void Implicit()
    {
        D1R d1 = () => M2;
        D2R d2 = () => M1; // 1
    }
    static void Explicit()
    {
        var d1 = (D1R)M2;
        var d2 = (D2R)M1; // 2
    }
    static void New()
    {
        var d1 = new D1R(M2);
        var d2 = new D2R(M1); // 3
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (12,24): error CS8986: The 'scoped' modifier of parameter 'x' doesn't match target 'D2'.
                //         D2R d2 = () => M1; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "M1").WithArguments("x", "D2").WithLocation(12, 24),
                // (16,18): error CS0123: No overload for 'M2' matches delegate 'D1R'
                //         var d1 = (D1R)M2;
                Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "(D1R)M2").WithArguments("M2", "D1R").WithLocation(16, 18),
                // (17,18): error CS0123: No overload for 'M1' matches delegate 'D2R'
                //         var d2 = (D2R)M1; // 2
                Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "(D2R)M1").WithArguments("M1", "D2R").WithLocation(17, 18),
                // (21,18): error CS0123: No overload for 'M2' matches delegate 'D1R'
                //         var d1 = new D1R(M2);
                Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "new D1R(M2)").WithArguments("M2", "D1R").WithLocation(21, 18),
                // (22,18): error CS0123: No overload for 'M1' matches delegate 'D2R'
                //         var d2 = new D2R(M1); // 3
                Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "new D2R(M1)").WithArguments("M1", "D2R").WithLocation(22, 18));
        }
 
        [Fact]
        public void DelegateConversions_05()
        {
            var source =
@"ref struct R { }
delegate R D1(R x, R y);
delegate R D2(R x, scoped R y);
delegate ref R D3(ref R x, ref R y);
delegate ref R D5(ref R x, scoped ref R y);
class Program
{
    static void Implicit()
    {
        D1 d1 = delegate(R x, scoped R y) { return x; };
        D2 d2 = delegate(R x, R y) { return x; }; // 1
        D3 d3 = delegate(ref R x, scoped ref R y) { return ref x; };
        D5 d5 = delegate(ref R x, ref R y) { return ref x; }; // 2
    }
    static void Explicit()
    {
        var d1 = (D1)(delegate(R x, scoped R y) { return x; });
        var d2 = (D2)(delegate(R x, R y) { return x; }); // 3
        var d3 = (D3)(delegate(ref R x, scoped ref R y) { return ref x; });
        var d5 = (D5)(delegate(ref R x, ref R y) { return ref x; }); // 4
    }
    static void New()
    {
        var d1 = new D1(delegate(R x, scoped R y) { return x; });
        var d2 = new D2(delegate(R x, R y) { return x; }); // 5
        var d3 = new D3(delegate(ref R x, scoped ref R y) { return ref x; });
        var d5 = new D5(delegate(ref R x, ref R y) { return ref x; }); // 6
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (11,17): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'D2'.
                //         D2 d2 = delegate(R x, R y) { return x; }; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "delegate(R x, R y) { return x; }").WithArguments("y", "D2").WithLocation(11, 17),
                // (13,17): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'D5'.
                //         D5 d5 = delegate(ref R x, ref R y) { return ref x; }; // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "delegate(ref R x, ref R y) { return ref x; }").WithArguments("y", "D5").WithLocation(13, 17),
                // (18,18): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'D2'.
                //         var d2 = (D2)(delegate(R x, R y) { return x; }); // 3
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(D2)(delegate(R x, R y) { return x; })").WithArguments("y", "D2").WithLocation(18, 18),
                // (20,18): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'D5'.
                //         var d5 = (D5)(delegate(ref R x, ref R y) { return ref x; }); // 4
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(D5)(delegate(ref R x, ref R y) { return ref x; })").WithArguments("y", "D5").WithLocation(20, 18),
                // (25,25): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'D2'.
                //         var d2 = new D2(delegate(R x, R y) { return x; }); // 5
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "delegate(R x, R y) { return x; }").WithArguments("y", "D2").WithLocation(25, 25),
                // (27,25): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'D5'.
                //         var d5 = new D5(delegate(ref R x, ref R y) { return ref x; }); // 6
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "delegate(ref R x, ref R y) { return ref x; }").WithArguments("y", "D5").WithLocation(27, 25));
        }
 
        [Fact]
        public void DelegateConversions_06()
        {
            var source =
@"using System.Linq.Expressions;
ref struct R { }
delegate R D1(R x, R y);
delegate R D2(R x, scoped R y);
delegate ref int D3(ref int x, ref int y);
delegate ref int D4(ref int x, scoped ref int y);
class Program
{
    static void Implicit()
    {
        Expression<D1> e1 = (R x, scoped R y) => x;
        Expression<D2> e2 = (R x, R y) => x; // 1
        Expression<D3> e3 = (ref int x, scoped ref int y) => ref x;
        Expression<D4> e4 = (ref int x, ref int y) => ref x; // 2
    }
    static void Explicit()
    {
        var e1 = (Expression<D1>)((R x, scoped R y) => x);
        var e2 = (Expression<D2>)((R x, R y) => x); // 3
        var e3 = (Expression<D3>)((ref int x, scoped ref int y) => ref x);
        var e4 = (Expression<D4>)((ref int x, ref int y) => ref x); // 4
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (11,32): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'R'.
                //         Expression<D1> e1 = (R x, scoped R y) => x;
                Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "x").WithArguments("R").WithLocation(11, 32),
                // (11,44): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'R'.
                //         Expression<D1> e1 = (R x, scoped R y) => x;
                Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "y").WithArguments("R").WithLocation(11, 44),
                // (11,50): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'R'.
                //         Expression<D1> e1 = (R x, scoped R y) => x;
                Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "x").WithArguments("R").WithLocation(11, 50),
                // (12,29): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'Expression<D2>'.
                //         Expression<D2> e2 = (R x, R y) => x; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(R x, R y) => x").WithArguments("y", "System.Linq.Expressions.Expression<D2>").WithLocation(12, 29),
                // (12,32): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'R'.
                //         Expression<D2> e2 = (R x, R y) => x; // 1
                Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "x").WithArguments("R").WithLocation(12, 32),
                // (12,37): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'R'.
                //         Expression<D2> e2 = (R x, R y) => x; // 1
                Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "y").WithArguments("R").WithLocation(12, 37),
                // (12,43): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'R'.
                //         Expression<D2> e2 = (R x, R y) => x; // 1
                Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "x").WithArguments("R").WithLocation(12, 43),
                // (13,29): error CS8155: Lambda expressions that return by reference cannot be converted to expression trees
                //         Expression<D3> e3 = (ref int x, scoped ref int y) => ref x;
                Diagnostic(ErrorCode.ERR_BadRefReturnExpressionTree, "(ref int x, scoped ref int y) => ref x").WithLocation(13, 29),
                // (13,38): error CS1951: An expression tree lambda may not contain a ref, in or out parameter
                //         Expression<D3> e3 = (ref int x, scoped ref int y) => ref x;
                Diagnostic(ErrorCode.ERR_ByRefParameterInExpressionTree, "x").WithLocation(13, 38),
                // (13,56): error CS1951: An expression tree lambda may not contain a ref, in or out parameter
                //         Expression<D3> e3 = (ref int x, scoped ref int y) => ref x;
                Diagnostic(ErrorCode.ERR_ByRefParameterInExpressionTree, "y").WithLocation(13, 56),
                // (14,29): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'Expression<D4>'.
                //         Expression<D4> e4 = (ref int x, ref int y) => ref x; // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(ref int x, ref int y) => ref x").WithArguments("y", "System.Linq.Expressions.Expression<D4>").WithLocation(14, 29),
                // (14,29): error CS8155: Lambda expressions that return by reference cannot be converted to expression trees
                //         Expression<D4> e4 = (ref int x, ref int y) => ref x; // 2
                Diagnostic(ErrorCode.ERR_BadRefReturnExpressionTree, "(ref int x, ref int y) => ref x").WithLocation(14, 29),
                // (14,38): error CS1951: An expression tree lambda may not contain a ref, in or out parameter
                //         Expression<D4> e4 = (ref int x, ref int y) => ref x; // 2
                Diagnostic(ErrorCode.ERR_ByRefParameterInExpressionTree, "x").WithLocation(14, 38),
                // (14,49): error CS1951: An expression tree lambda may not contain a ref, in or out parameter
                //         Expression<D4> e4 = (ref int x, ref int y) => ref x; // 2
                Diagnostic(ErrorCode.ERR_ByRefParameterInExpressionTree, "y").WithLocation(14, 49),
                // (18,38): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'R'.
                //         var e1 = (Expression<D1>)((R x, scoped R y) => x);
                Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "x").WithArguments("R").WithLocation(18, 38),
                // (18,50): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'R'.
                //         var e1 = (Expression<D1>)((R x, scoped R y) => x);
                Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "y").WithArguments("R").WithLocation(18, 50),
                // (18,56): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'R'.
                //         var e1 = (Expression<D1>)((R x, scoped R y) => x);
                Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "x").WithArguments("R").WithLocation(18, 56),
                // (19,18): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'Expression<D2>'.
                //         var e2 = (Expression<D2>)((R x, R y) => x); // 3
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(Expression<D2>)((R x, R y) => x)").WithArguments("y", "System.Linq.Expressions.Expression<D2>").WithLocation(19, 18),
                // (19,38): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'R'.
                //         var e2 = (Expression<D2>)((R x, R y) => x); // 3
                Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "x").WithArguments("R").WithLocation(19, 38),
                // (19,43): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'R'.
                //         var e2 = (Expression<D2>)((R x, R y) => x); // 3
                Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "y").WithArguments("R").WithLocation(19, 43),
                // (19,49): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'R'.
                //         var e2 = (Expression<D2>)((R x, R y) => x); // 3
                Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "x").WithArguments("R").WithLocation(19, 49),
                // (20,35): error CS8155: Lambda expressions that return by reference cannot be converted to expression trees
                //         var e3 = (Expression<D3>)((ref int x, scoped ref int y) => ref x);
                Diagnostic(ErrorCode.ERR_BadRefReturnExpressionTree, "(ref int x, scoped ref int y) => ref x").WithLocation(20, 35),
                // (20,44): error CS1951: An expression tree lambda may not contain a ref, in or out parameter
                //         var e3 = (Expression<D3>)((ref int x, scoped ref int y) => ref x);
                Diagnostic(ErrorCode.ERR_ByRefParameterInExpressionTree, "x").WithLocation(20, 44),
                // (20,62): error CS1951: An expression tree lambda may not contain a ref, in or out parameter
                //         var e3 = (Expression<D3>)((ref int x, scoped ref int y) => ref x);
                Diagnostic(ErrorCode.ERR_ByRefParameterInExpressionTree, "y").WithLocation(20, 62),
                // (21,18): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target 'Expression<D4>'.
                //         var e4 = (Expression<D4>)((ref int x, ref int y) => ref x); // 4
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(Expression<D4>)((ref int x, ref int y) => ref x)").WithArguments("y", "System.Linq.Expressions.Expression<D4>").WithLocation(21, 18),
                // (21,35): error CS8155: Lambda expressions that return by reference cannot be converted to expression trees
                //         var e4 = (Expression<D4>)((ref int x, ref int y) => ref x); // 4
                Diagnostic(ErrorCode.ERR_BadRefReturnExpressionTree, "(ref int x, ref int y) => ref x").WithLocation(21, 35),
                // (21,44): error CS1951: An expression tree lambda may not contain a ref, in or out parameter
                //         var e4 = (Expression<D4>)((ref int x, ref int y) => ref x); // 4
                Diagnostic(ErrorCode.ERR_ByRefParameterInExpressionTree, "x").WithLocation(21, 44),
                // (21,55): error CS1951: An expression tree lambda may not contain a ref, in or out parameter
                //         var e4 = (Expression<D4>)((ref int x, ref int y) => ref x); // 4
                Diagnostic(ErrorCode.ERR_ByRefParameterInExpressionTree, "y").WithLocation(21, 55));
        }
 
        [Fact]
        public void DelegateConversions_07()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
ref struct R<T> { }
delegate ref T D1<T>(scoped ref R<T> r);
delegate ref T D2<T>(ref R<T> r);
delegate ref T D3<T>(scoped in R<T> r);
delegate ref T D4<T>(in R<T> r);
delegate ref T D5<T>(out R<T> r);
delegate ref T D6<T>([UnscopedRef] out R<T> r);
class Program
{
    static void Implicit()
    {
        D1<int> d1 = (ref R<int> r) => ref F(); // 1
        D2<int> d2 = (scoped ref R<int> r) => ref F();
        D3<int> d3 = (in R<int> r) => ref F(); // 2
        D4<int> d4 = (scoped in R<int> r) => ref F();
        D5<int> d5 = ([UnscopedRef] out R<int> r) => { r = default; return ref F(); }; // 3
        D6<int> d6 = (out R<int> r) => { r = default; return ref F(); };
    }
    static void Explicit()
    {
        var d1 = (D1<int>)((ref R<int> r) => ref F()); // 4
        var d2 = (D2<int>)((scoped ref R<int> r) => ref F());
        var d3 = (D3<int>)((in R<int> r) => ref F()); // 5
        var d4 = (D4<int>)((scoped in R<int> r) => ref F());
        var d5 = (D5<int>)(([UnscopedRef] out R<int> r) => { r = default; return ref F(); }); // 6
        var d6 = (D6<int>)((out R<int> r) => { r = default; return ref F(); });
    }
    static void New()
    {
        var d1 = new D1<int>((ref R<int> r) => ref F()); // 7
        var d2 = new D2<int>((scoped ref R<int> r) => ref F());
        var d3 = new D3<int>((in R<int> r) => ref F()); // 8
        var d4 = new D4<int>((scoped in R<int> r) => ref F());
        var d5 = new D5<int>(([UnscopedRef] out R<int> r) => { r = default; return ref F(); }); // 9
        var d6 = new D6<int>((out R<int> r) => { r = default; return ref F(); });
    }
    static ref int F() => throw null;
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (13,22): error CS8986: The 'scoped' modifier of parameter 'r' doesn't match target 'D1<int>'.
                //         D1<int> d1 = (ref R<int> r) => ref F(); // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(ref R<int> r) => ref F()").WithArguments("r", "D1<int>").WithLocation(13, 22),
                // (15,22): error CS8986: The 'scoped' modifier of parameter 'r' doesn't match target 'D3<int>'.
                //         D3<int> d3 = (in R<int> r) => ref F(); // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(in R<int> r) => ref F()").WithArguments("r", "D3<int>").WithLocation(15, 22),
                // (17,22): error CS8986: The 'scoped' modifier of parameter 'r' doesn't match target 'D5<int>'.
                //         D5<int> d5 = ([UnscopedRef] out R<int> r) => { r = default; return ref F(); }; // 3
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "([UnscopedRef] out R<int> r) => { r = default; return ref F(); }").WithArguments("r", "D5<int>").WithLocation(17, 22),
                // (22,18): error CS8986: The 'scoped' modifier of parameter 'r' doesn't match target 'D1<int>'.
                //         var d1 = (D1<int>)((ref R<int> r) => ref F()); // 4
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(D1<int>)((ref R<int> r) => ref F())").WithArguments("r", "D1<int>").WithLocation(22, 18),
                // (24,18): error CS8986: The 'scoped' modifier of parameter 'r' doesn't match target 'D3<int>'.
                //         var d3 = (D3<int>)((in R<int> r) => ref F()); // 5
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(D3<int>)((in R<int> r) => ref F())").WithArguments("r", "D3<int>").WithLocation(24, 18),
                // (26,18): error CS8986: The 'scoped' modifier of parameter 'r' doesn't match target 'D5<int>'.
                //         var d5 = (D5<int>)(([UnscopedRef] out R<int> r) => { r = default; return ref F(); }); // 6
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(D5<int>)(([UnscopedRef] out R<int> r) => { r = default; return ref F(); })").WithArguments("r", "D5<int>").WithLocation(26, 18),
                // (31,30): error CS8986: The 'scoped' modifier of parameter 'r' doesn't match target 'D1<int>'.
                //         var d1 = new D1<int>((ref R<int> r) => ref F()); // 7
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(ref R<int> r) => ref F()").WithArguments("r", "D1<int>").WithLocation(31, 30),
                // (33,30): error CS8986: The 'scoped' modifier of parameter 'r' doesn't match target 'D3<int>'.
                //         var d3 = new D3<int>((in R<int> r) => ref F()); // 8
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(in R<int> r) => ref F()").WithArguments("r", "D3<int>").WithLocation(33, 30),
                // (35,30): error CS8986: The 'scoped' modifier of parameter 'r' doesn't match target 'D5<int>'.
                //         var d5 = new D5<int>(([UnscopedRef] out R<int> r) => { r = default; return ref F(); }); // 9
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "([UnscopedRef] out R<int> r) => { r = default; return ref F(); }").WithArguments("r", "D5<int>").WithLocation(35, 30));
        }
 
        [Theory]
        [InlineData("ref")]
        [InlineData("in ")]
        public void DelegateConversions_08(string refModifier)
        {
            var source =
$@"ref struct R<T> {{ }}
delegate void D0<T>(scoped {refModifier} T t);
delegate T D1<T>(scoped {refModifier} T t);
delegate ref T D2<T>(scoped {refModifier} T t);
delegate ref readonly T D3<T>(scoped {refModifier} T t);
delegate R<T> D4<T>(scoped {refModifier} T t);
class Program
{{
    static ref int F() => throw null;
    static void Main()
    {{
        D0<int> d0 = ({refModifier} int i) => {{ }};
        D1<int> d1 = ({refModifier} int i) => F();
        D2<int> d2 = ({refModifier} int i) => ref F(); // 1
        D3<int> d3 = ({refModifier} int i) => ref F(); // 2
        D4<int> d4 = ({refModifier} int i) => new R<int>(); // 3
    }}
}}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (14,22): error CS8986: The 'scoped' modifier of parameter 'i' doesn't match target 'D2<int>'.
                //         D2<int> d2 = (ref int i) => ref F(); // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, $"({refModifier} int i) => ref F()").WithArguments("i", "D2<int>").WithLocation(14, 22),
                // (15,22): error CS8986: The 'scoped' modifier of parameter 'i' doesn't match target 'D3<int>'.
                //         D3<int> d3 = (ref int i) => ref F(); // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, $"({refModifier} int i) => ref F()").WithArguments("i", "D3<int>").WithLocation(15, 22),
                // (16,22): error CS8986: The 'scoped' modifier of parameter 'i' doesn't match target 'D4<int>'.
                //         D4<int> d4 = (ref int i) => new R<int>(); // 3
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, $"({refModifier} int i) => new R<int>()").WithArguments("i", "D4<int>").WithLocation(16, 22));
        }
 
        [Theory]
        [InlineData("ref")]
        [InlineData("in ")]
        public void DelegateConversions_09(string refModifier)
        {
            var source =
$@"ref struct R<T> {{ }}
delegate void D0<T>(scoped {refModifier} T t, R<T> r);
delegate void D1<T>(scoped {refModifier} T t, ref R<T> r);
delegate void D2<T>(scoped {refModifier} T t, in R<T> r);
delegate void D3<T>(scoped {refModifier} T t, out R<T> r);
class Program
{{
    static ref int F() => throw null;
    static void Main()
    {{
        D0<int> d0 = ({refModifier} int i, R<int> r) => {{ }};
        D1<int> d1 = ({refModifier} int i, ref R<int> r) => {{ }}; // 1
        D2<int> d2 = ({refModifier} int i, in R<int> r) => {{ }};
        D3<int> d3 = ({refModifier} int i, out R<int> r) => {{ r = default; }}; // 2
    }}
}}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (12,22): error CS8986: The 'scoped' modifier of parameter 'i' doesn't match target 'D1<int>'.
                //         D1<int> d1 = (ref int i, ref R<int> r) => { }; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, $"({refModifier} int i, ref R<int> r) => {{ }}").WithArguments("i", "D1<int>").WithLocation(12, 22),
                // (14,22): error CS8986: The 'scoped' modifier of parameter 'i' doesn't match target 'D3<int>'.
                //         D3<int> d3 = (ref int i, out R<int> r) => { r = default; }; // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, $"({refModifier} int i, out R<int> r) => {{ r = default; }}").WithArguments("i", "D3<int>").WithLocation(14, 22));
        }
 
        [Fact]
        public void DelegateConversions_10()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
ref struct R<T> { }
delegate R<T> D0<T>();
delegate R<T> D1<T>(T t);
delegate R<T> D2<T>(scoped ref T t);
delegate R<T> D3<T>(scoped in T t);
delegate R<T> D4A<T>(scoped out T t);
delegate R<T> D4B<T>(out T t);
delegate R<T> D5<T>(scoped R<T> r);
class Program
{
    static void Main()
    {
        D0<int> d0 = () => new R<int>();
        D1<int> d1 = (int i) => new R<int>();
        D2<int> d2 = (ref int i) => new R<int>(); // 1
        D3<int> d3 = (in int i) => new R<int>(); // 2
        D4A<int> d4A = (out int i) => { i = 0; return new R<int>(); };
        D4B<int> d4B = ([UnscopedRef] out int i) => { i = 0; return new R<int>(); }; // 3
        D5<int> d5 = (R<int> r) => new R<int>(); // 4
    }
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (16,22): error CS8986: The 'scoped' modifier of parameter 'i' doesn't match target 'D2<int>'.
                //         D2<int> d2 = (ref int i) => new R<int>(); // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(ref int i) => new R<int>()").WithArguments("i", "D2<int>").WithLocation(16, 22),
                // (17,22): error CS8986: The 'scoped' modifier of parameter 'i' doesn't match target 'D3<int>'.
                //         D3<int> d3 = (in int i) => new R<int>(); // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(in int i) => new R<int>()").WithArguments("i", "D3<int>").WithLocation(17, 22),
                // (19,24): error CS8986: The 'scoped' modifier of parameter 'i' doesn't match target 'D4B<int>'.
                //         D4B<int> d4B = ([UnscopedRef] out int i) => { i = 0; return new R<int>(); }; // 3
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "([UnscopedRef] out int i) => { i = 0; return new R<int>(); }").WithArguments("i", "D4B<int>").WithLocation(19, 24),
                // (20,22): error CS8986: The 'scoped' modifier of parameter 'r' doesn't match target 'D5<int>'.
                //         D5<int> d5 = (R<int> r) => new R<int>(); // 4
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(R<int> r) => new R<int>()").WithArguments("r", "D5<int>").WithLocation(20, 22));
        }
 
        [Theory]
        [InlineData("ref         ")]
        [InlineData("ref readonly")]
        public void DelegateConversions_11(string refModifier)
        {
            var source =
$@"using System.Diagnostics.CodeAnalysis;
ref struct R<T> {{ }}
delegate {refModifier} T D0<T>();
delegate {refModifier} T D1<T>(T t);
delegate {refModifier} T D2<T>(scoped ref T t);
delegate {refModifier} T D3<T>(scoped in T t);
delegate {refModifier} T D4<T>(out T t);
delegate {refModifier} T D5<T>(scoped R<T> r);
class Program
{{
    static {refModifier} int F() => throw null;
    static void Main()
    {{
        D0<int> d0 = () => ref F();
        D1<int> d1 = (int i) => ref F();
        D2<int> d2 = (ref int i) => ref F(); // 1
        D3<int> d3 = (in int i) => ref F(); // 2
        D4<int> d4 = ([UnscopedRef] out int i) => {{ i = 0; return ref F(); }}; // 3
        D5<int> d5 = (R<int> r) => ref F(); // 4
    }}
}}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (16,22): error CS8986: The 'scoped' modifier of parameter 'i' doesn't match target 'D2<int>'.
                //         D2<int> d2 = (ref int i) => ref F(); // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(ref int i) => ref F()").WithArguments("i", "D2<int>").WithLocation(16, 22),
                // (17,22): error CS8986: The 'scoped' modifier of parameter 'i' doesn't match target 'D3<int>'.
                //         D3<int> d3 = (in int i) => ref F(); // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(in int i) => ref F()").WithArguments("i", "D3<int>").WithLocation(17, 22),
                // (18,22): error CS8986: The 'scoped' modifier of parameter 'i' doesn't match target 'D4<int>'.
                //         D4<int> d4 = ([UnscopedRef] out int i) => { i = 0; return ref F(); }; // 3
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "([UnscopedRef] out int i) => { i = 0; return ref F(); }").WithArguments("i", "D4<int>").WithLocation(18, 22),
                // (19,22): error CS8986: The 'scoped' modifier of parameter 'r' doesn't match target 'D5<int>'.
                //         D5<int> d5 = (R<int> r) => ref F(); // 4
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(R<int> r) => ref F()").WithArguments("r", "D5<int>").WithLocation(19, 22));
        }
 
        [Theory]
        [InlineData("ref         ")]
        [InlineData("ref readonly")]
        public void DelegateConversions_12(string refModifier)
        {
            var source =
$@"using System.Diagnostics.CodeAnalysis;
ref struct R<T> {{ }}
delegate {refModifier} T D0<T>();
delegate {refModifier} T D1<T>(T t);
delegate {refModifier} T D2<T>(ref T t);
delegate {refModifier} T D3<T>(in T t);
delegate {refModifier} T D4<T>(out T t);
delegate {refModifier} T D5<T>(R<T> r);
struct S1<T>
{{
    private {refModifier} T F() => throw null;
    public {refModifier} T F0() => ref F();
    public {refModifier} T F1(T t) => ref F();
    public {refModifier} T F2(ref T t) => ref F();
    public {refModifier} T F3(in T t) => ref F();
    public {refModifier} T F4(out T t) {{ t = default; return ref F(); }}
    public {refModifier} T F5(R<T> r) => ref F();
}}
struct S2<T>
{{
    private {refModifier} T F() => throw null;
    [UnscopedRef] public {refModifier} T F0() => ref F();
    [UnscopedRef] public {refModifier} T F1(T t) => ref F();
    [UnscopedRef] public {refModifier} T F2(ref T t) => ref F();
    [UnscopedRef] public {refModifier} T F3(in T t) => ref F();
    [UnscopedRef] public {refModifier} T F4(out T t) {{ t = default; return ref F(); }}
    [UnscopedRef] public {refModifier} T F5(R<T> r) => ref F();
}}
class Program
{{
    static void F1<T>(ref S1<T> s1)
    {{
        D0<T> d0 = s1.F0;
        D1<T> d1 = s1.F1;
        D2<T> d2 = s1.F2;
        D3<T> d3 = s1.F3;
        D4<T> d4 = s1.F4;
        D5<T> d5 = s1.F5;
    }}
    static void F2<T>(ref S2<T> s2)
    {{
        D0<T> d0 = s2.F0;
        D1<T> d1 = s2.F1;
        D2<T> d2 = s2.F2;
        D3<T> d3 = s2.F3;
        D4<T> d4 = s2.F4;
        D5<T> d5 = s2.F5;
    }}
}}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void DelegateConversions_Out()
        {
            var source =
@"ref struct R { }
delegate void D1(out int x, scoped out int y);
delegate void D2(out R x, scoped out R y);
class Program
{
    static void Implicit()
    {
        D1 d1 = (scoped out int x, out int y) => { x = 0; y = 0; };
        D2 d2 = (scoped out R x, out R y) => { x = default; y = default; };
    }
    static void Explicit()
    {
        var d1 = (D1)((scoped out int x, out int y) => { x = 0; y = 0; });
        var d2 = (D2)((scoped out R x, out R y) => { x = default; y = default; });
    }
    static void New()
    {
        var d1 = new D1((scoped out int x, out int y) => { x = 0; y = 0; });
        var d2 = new D2((scoped out R x, out R y) => { x = default; y = default; });
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void DelegateConversions_ImplicitlyTypedParameter()
        {
            var source = """
                delegate R D1(scoped R r);
 
                public ref struct R
                {
                    public ref int field;
                }
 
                class C
                {
                    void M()
                    {
                        D1 d1 = r => r; // 1
                        D1 d1_2 = (scoped R r) => r; // 2
                    }
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (12,17): error CS8986: The 'scoped' modifier of parameter 'r' doesn't match target 'D1'.
                //         D1 d1 = r => r; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "r => r").WithArguments("r", "D1").WithLocation(12, 17),
                // (13,35): error CS8352: Cannot use variable 'scoped R r' in this context because it may expose referenced variables outside of their declaration scope
                //         D1 d1_2 = (scoped R r) => r; // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r").WithArguments("scoped R r").WithLocation(13, 35)
                );
        }
 
        [Fact]
        public void DelegateConversions_ImplicitlyTypedParameter_OverloadResolution()
        {
            var source = """
                delegate R D1(scoped R r);
                delegate R D2(R r);
 
                public ref struct R
                {
                    public ref int field;
                }
 
                class C
                {
                    void M()
                    {
                        M2(r => r); // 1
                        M2((scoped R r) => r); // 2
                        M2(r => default); // 3
                    }
 
                    void M2(D1 d1) { }
                    void M2(D2 d2) { }
                }
                """;
 
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (13,9): error CS0121: The call is ambiguous between the following methods or properties: 'C.M2(D1)' and 'C.M2(D2)'
                //         M2(r => r); // 1
                Diagnostic(ErrorCode.ERR_AmbigCall, "M2").WithArguments("C.M2(D1)", "C.M2(D2)").WithLocation(13, 9),
                // (14,9): error CS0121: The call is ambiguous between the following methods or properties: 'C.M2(D1)' and 'C.M2(D2)'
                //         M2((scoped R r) => r); // 2
                Diagnostic(ErrorCode.ERR_AmbigCall, "M2").WithArguments("C.M2(D1)", "C.M2(D2)").WithLocation(14, 9),
                // (14,28): error CS8352: Cannot use variable 'scoped R' in this context because it may expose referenced variables outside of their declaration scope
                //         M2((scoped R r) => r); // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r").WithArguments("scoped R r").WithLocation(14, 28),
                // (15,9): error CS0121: The call is ambiguous between the following methods or properties: 'C.M2(D1)' and 'C.M2(D2)'
                //         M2(r => default); // 3
                Diagnostic(ErrorCode.ERR_AmbigCall, "M2").WithArguments("C.M2(D1)", "C.M2(D2)").WithLocation(15, 9)
                );
 
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);
            var invocations = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().ToArray();
 
            Assert.Equal("M2(r => r)", invocations[0].ToString());
            Assert.Null(model.GetSymbolInfo(invocations[0]).Symbol);
 
            Assert.Equal("M2((scoped R r) => r)", invocations[1].ToString());
            Assert.Null(model.GetSymbolInfo(invocations[1]).Symbol);
        }
 
        [Fact]
        public void DelegateConversions_ImplicitlyTypedParameter_ParameterlessAnonymousMethod_Ref()
        {
            var source = """
                delegate void D1(scoped R r1, scoped ref R r2);
 
                public ref struct R
                {
                    public ref int field;
                }
 
                class C
                {
                    void M()
                    {
                        D1 d1 = delegate { };
                    }
                }
                """;
 
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (12,17): error CS8986: The 'scoped' modifier of parameter '<p0>' doesn't match target 'D1'.
                //         D1 d1 = delegate { };
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "delegate { }").WithArguments("<p0>", "D1").WithLocation(12, 17),
                // (12,17): error CS8986: The 'scoped' modifier of parameter '<p1>' doesn't match target 'D1'.
                //         D1 d1 = delegate { };
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "delegate { }").WithArguments("<p1>", "D1").WithLocation(12, 17)
                );
 
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);
            var anonymousMethod = tree.GetRoot().DescendantNodes().OfType<AnonymousMethodExpressionSyntax>().Single();
 
            Assert.Equal("delegate { }", anonymousMethod.ToString());
            var method = model.GetSymbolInfo(anonymousMethod).Symbol;
            Assert.Equal("lambda expression", method.ToTestDisplayString());
            var parameters = method.GetParameters();
            Assert.Equal("R <p0>", parameters[0].ToTestDisplayString());
            Assert.Equal("ref R <p1>", parameters[1].ToTestDisplayString());
        }
 
        [Fact]
        public void DelegateConversions_ImplicitlyTypedParameter_ParameterlessAnonymousMethod_Out()
        {
            var source = """
                using System.Diagnostics.CodeAnalysis;
                delegate void D1([UnscopedRef] out R r3);
 
                public ref struct R
                {
                    public ref int field;
                }
 
                class C
                {
                    void M()
                    {
                        D1 d1 = delegate { };
                    }
                }
                """;
 
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (13,17): error CS1688: Cannot convert anonymous method block without a parameter list to delegate type 'D1' because it has one or more out parameters
                //         D1 d1 = delegate { };
                Diagnostic(ErrorCode.ERR_CantConvAnonMethNoParams, "delegate { }").WithArguments("D1").WithLocation(13, 17)
                );
 
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);
            var anonymousMethod = tree.GetRoot().DescendantNodes().OfType<AnonymousMethodExpressionSyntax>().Single();
 
            Assert.Equal("delegate { }", anonymousMethod.ToString());
            var method = model.GetSymbolInfo(anonymousMethod).Symbol;
            Assert.Equal("lambda expression", method.ToTestDisplayString());
            Assert.Empty(method.GetParameters());
        }
 
        [Fact]
        public void DelegateConversions_ImplicitlyTypedParameter_MissingParameters()
        {
            var source = """
                delegate R D1(scoped R r);
 
                public ref struct R
                {
                    public ref int field;
                }
 
                class C
                {
                    void M()
                    {
                        D1 d1 = () => new R();
                    }
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (12,17): error CS1593: Delegate 'D1' does not take 0 arguments
                //         D1 d1 = () => new R();
                Diagnostic(ErrorCode.ERR_BadDelArgCount, "() => new R()").WithArguments("D1", "0").WithLocation(12, 17)
                );
        }
 
        [Fact]
        public void DelegateConversions_ImplicitlyTypedParameter_ExtraParameters()
        {
            var source = """
                delegate R D1();
 
                public ref struct R
                {
                    public ref int field;
                }
 
                class C
                {
                    void M()
                    {
                        D1 d1 = r => r;
                        D1 d2 = (scoped R r) => r;
                    }
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (12,17): error CS1593: Delegate 'D1' does not take 1 arguments
                //         D1 d1 = r => r;
                Diagnostic(ErrorCode.ERR_BadDelArgCount, "r => r").WithArguments("D1", "1").WithLocation(12, 17),
                // (13,17): error CS1593: Delegate 'D1' does not take 1 arguments
                //         D1 d2 = (scoped R r) => r;
                Diagnostic(ErrorCode.ERR_BadDelArgCount, "(scoped R r) => r").WithArguments("D1", "1").WithLocation(13, 17)
                );
        }
 
        [Fact]
        public void DelegateConversions_ImplicitlyTypedParameter_NullableRewriteOfLambda()
        {
            var source = """
                #nullable enable
 
                delegate R<T> D<T>(scoped R<T> r, T t);
 
                public ref struct R<T>
                {
                    public ref int field;
                }
 
                class C
                {
                    static R<T> F<T>(D<T> f, T t) => throw null!;
 
                    static void M<U>(U? u) where U : class
                    {
                        F((r1, t1) => F((r2, t2) => r2, t1), u).ToString();
                    }
                }
                """;
 
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (16,25): error CS8986: The 'scoped' modifier of parameter 'r2' doesn't match target 'D<U>'.
                //         F((r1, t1) => F((r2, t2) => r2, t1), u).ToString();
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(r2, t2) => r2").WithArguments("r2", "D<U>").WithLocation(16, 25));
 
            var tree = comp.SyntaxTrees.Single();
            var model = comp.GetSemanticModel(tree);
            var lambdas = tree.GetRoot().DescendantNodes().OfType<ParenthesizedLambdaExpressionSyntax>().ToArray();
 
            Assert.Equal("(r1, t1) => F((r2, t2) => r2, t1)", lambdas[0].ToString());
            Assert.Equal("r1", lambdas[0].ParameterList.Parameters[0].Identifier.ToString());
            Assert.Equal("R<U> r1", model.GetDeclaredSymbol(lambdas[0].ParameterList.Parameters[0]).ToTestDisplayString());
 
            Assert.Equal("t1", lambdas[0].ParameterList.Parameters[1].Identifier.ToString());
            Assert.Equal("U t1", model.GetDeclaredSymbol(lambdas[0].ParameterList.Parameters[1]).ToTestDisplayString());
 
            Assert.Equal("(r2, t2) => r2", lambdas[1].ToString());
            Assert.Equal("r2", lambdas[1].ParameterList.Parameters[0].Identifier.ToString());
            Assert.Equal("R<U> r2", model.GetDeclaredSymbol(lambdas[1].ParameterList.Parameters[0]).ToTestDisplayString());
 
            Assert.Equal("t2", lambdas[1].ParameterList.Parameters[1].Identifier.ToString());
            Assert.Equal("U t2", model.GetDeclaredSymbol(lambdas[1].ParameterList.Parameters[1]).ToTestDisplayString());
        }
 
        [Fact]
        public void DelegateConversions_ImplicitlyTypedParameter_NestedLambdaReinference_NestedNotReinferred()
        {
            var source = @"
using System;
delegate R D<T>(scoped T t);
ref struct R { }
 
class C
{
    public static Action<T> Create<T>(T t, Action<T> a) => throw null!;
 
    public static void M(object? o)
    {
        var a = Create(o, o1 => {
            if (o1 == null) return;
            D<string> d = o2 => throw null!;
        });
    }
}";
 
            var comp = CreateCompilation(source, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (3,17): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                // delegate R D<T>(scoped T t);
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "scoped T t").WithLocation(3, 17)
                );
 
            var syntaxTree = comp.SyntaxTrees[0];
            var root = syntaxTree.GetRoot();
            var model = comp.GetSemanticModel(syntaxTree);
 
            var lambda = root.DescendantNodes().OfType<LambdaExpressionSyntax>().Last();
            Assert.Equal("o2 => throw null!", lambda.ToString());
            var lambdaSymbol = model.GetSymbolInfo(lambda).Symbol;
            Assert.Equal("System.String o2", lambdaSymbol.GetParameters()[0].ToTestDisplayString());
        }
 
        [Fact, WorkItem(64984, "https://github.com/dotnet/roslyn/issues/64984")]
        public void DelegateConversions_ImplicitlyTypedParameter_Conversion()
        {
            // The existence of conversions with incompatible `scoped` differences affects overload resolution
            // Tracked by https://github.com/dotnet/roslyn/issues/64984
            var source = """
                ref struct R { }
 
                delegate R D1(scoped R r);
                delegate R D2(R r);
 
                class Program
                {
                    static void Main()
                    {
                        D1 d1 = r1 => r1; // 1
                        M(r2 => r2); // 2
                        M(r3 => default); // 3
                        unsafe { M(r4 => r4); } // 4
                        M((R r5) => r5); // 5
 
                        D1 d1_2 = (scoped R r6) => default;
                        M((scoped R r7) => default); // 6
                        D1 d1_3 = (scoped R r8) => r8; // 7
                        M((scoped R r9) => r9); // 8
                    }
 
                    static void M(D1 d1) { }
                    static void M(D2 d2) { }
                }
                """;
 
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70, options: TestOptions.UnsafeDebugExe);
            comp.VerifyDiagnostics(
                // (10,17): error CS8986: The 'scoped' modifier of parameter 'r1' doesn't match target 'D1'.
                //         D1 d1 = r1 => r1; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "r1 => r1").WithArguments("r1", "D1").WithLocation(10, 17),
                // (11,9): error CS0121: The call is ambiguous between the following methods or properties: 'Program.M(D1)' and 'Program.M(D2)'
                //         M(r2 => r2); // 2
                Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("Program.M(D1)", "Program.M(D2)").WithLocation(11, 9),
                // (12,9): error CS0121: The call is ambiguous between the following methods or properties: 'Program.M(D1)' and 'Program.M(D2)'
                //         M(r3 => default); // 3
                Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("Program.M(D1)", "Program.M(D2)").WithLocation(12, 9),
                // (13,18): error CS0121: The call is ambiguous between the following methods or properties: 'Program.M(D1)' and 'Program.M(D2)'
                //         unsafe { M(r4 => r4); } // 4
                Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("Program.M(D1)", "Program.M(D2)").WithLocation(13, 18),
                // (14,9): error CS0121: The call is ambiguous between the following methods or properties: 'Program.M(D1)' and 'Program.M(D2)'
                //         M((R r5) => r5); // 5
                Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("Program.M(D1)", "Program.M(D2)").WithLocation(14, 9),
                // (17,9): error CS0121: The call is ambiguous between the following methods or properties: 'Program.M(D1)' and 'Program.M(D2)'
                //         M((scoped R r7) => default); // 6
                Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("Program.M(D1)", "Program.M(D2)").WithLocation(17, 9),
                // (18,36): error CS8352: Cannot use variable 'scoped R r8' in this context because it may expose referenced variables outside of their declaration scope
                //         D1 d1_3 = (scoped R r8) => r8; // 7
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r8").WithArguments("scoped R r8").WithLocation(18, 36),
                // (19,9): error CS0121: The call is ambiguous between the following methods or properties: 'Program.M(D1)' and 'Program.M(D2)'
                //         M((scoped R r9) => r9); // 8
                Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("Program.M(D1)", "Program.M(D2)").WithLocation(19, 9),
                // (19,28): error CS8352: Cannot use variable 'scoped R r9' in this context because it may expose referenced variables outside of their declaration scope
                //         M((scoped R r9) => r9); // 8
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r9").WithArguments("scoped R r9").WithLocation(19, 28)
                );
        }
 
        [Fact]
        public void DelegateConversions_13()
        {
            var source = """
                ref struct R { }
 
                delegate R D1(R r);
                delegate object D2(object o);
 
                class Program
                {
                    static void M(D1 d1) { }
                    static void M(D2 d2) { }
 
                    static R F(R r, ref int i) => r;
                    static object F(object o, ref int i) => o;
                
                    static void Main()
                    {
                        M(x =>
                            {
                                int i = 0;
                                return F(x, ref i);
                            });
                    }
                }
                """;
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (16,9): error CS0121: The call is ambiguous between the following methods or properties: 'Program.M(D1)' and 'Program.M(D2)'
                //         M(x =>
                Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("Program.M(D1)", "Program.M(D2)").WithLocation(16, 9));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DelegateConversions_14(LanguageVersion languageVersion)
        {
            var source = """
                using System;
 
                ref struct R { }
 
                delegate R D1(R r);
                delegate object D2(object o);
 
                class Program
                {
                    static void M(D1 d1) { }
                    static void M(D2 d2) { }
 
                    static void F(ref R x, ref Span<int> y) { }
                    static void F(ref object x, ref Span<int> y) { }
                
                    static void Main()
                    {
                        M(x =>
                            {
                                Span<int> y = stackalloc int[1];
                                F(ref x, ref y);
                                return x;
                            });
                    }
                }
                """;
            var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics(
                // (18,9): error CS0121: The call is ambiguous between the following methods or properties: 'Program.M(D1)' and 'Program.M(D2)'
                //         M(x =>
                Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("Program.M(D1)", "Program.M(D2)").WithLocation(18, 9));
        }
 
        [Fact]
        public void FunctionPointerConversions()
        {
            var source =
@"ref struct R { }
unsafe class Program
{
    static R F1(R x, scoped R y) => x;
    static R F2(R x, R y) => x;
    static ref readonly int F3(in int x, scoped in int y) => ref x;
    static ref readonly int F4(in int x, in int y) => ref x;
    static void Implicit()
    {
        delegate*<R, scoped R, R> d1 = &F2; // 1
        delegate*<R, R, R> d2 = &F1;
        delegate*<in int, scoped in int, ref readonly int> d3 = &F4; // 2
        delegate*<in int, in int, ref readonly int> d4 = &F3;
    }
    static void Explicit()
    {
        var d1 = (delegate*<R, scoped R, R>)&F2; // 3
        var d2 = (delegate*<R, R, R>)&F1;
        var d3 = (delegate*<in int, scoped in int, ref readonly int>)&F4; // 4
        var d4 = (delegate*<in int, in int, ref readonly int>)&F3;
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll);
            comp.VerifyDiagnostics(
                // (10,22): error CS8755: 'scoped' cannot be used as a modifier on a function pointer parameter.
                //         delegate*<R, scoped R, R> d1 = &F2; // 1
                Diagnostic(ErrorCode.ERR_BadFuncPointerParamModifier, "scoped").WithArguments("scoped").WithLocation(10, 22),
                // (12,27): error CS8755: 'scoped' cannot be used as a modifier on a function pointer parameter.
                //         delegate*<in int, scoped in int, ref readonly int> d3 = &F4; // 2
                Diagnostic(ErrorCode.ERR_BadFuncPointerParamModifier, "scoped").WithArguments("scoped").WithLocation(12, 27),
                // (17,32): error CS8755: 'scoped' cannot be used as a modifier on a function pointer parameter.
                //         var d1 = (delegate*<R, scoped R, R>)&F2; // 3
                Diagnostic(ErrorCode.ERR_BadFuncPointerParamModifier, "scoped").WithArguments("scoped").WithLocation(17, 32),
                // (19,37): error CS8755: 'scoped' cannot be used as a modifier on a function pointer parameter.
                //         var d3 = (delegate*<in int, scoped in int, ref readonly int>)&F4; // 4
                Diagnostic(ErrorCode.ERR_BadFuncPointerParamModifier, "scoped").WithArguments("scoped").WithLocation(19, 37));
        }
 
        [Fact]
        public void FunctionPointerConversions_Out()
        {
            var source =
@"unsafe class Program
{
    static void F(out int x, scoped out int y) { x = 0; y = 0; }
    static void Implicit()
    {
        delegate*<out int, out int, void> d = &F;
    }
    static void Explicit()
    {
        var d = (delegate*<out int, out int, void>)&F;
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void DuplicateMethodSignatures()
        {
            var source =
@"ref struct R<T> { }
class C<T>
{
    static void M1(R<T> r) { }
    void M2(scoped R<T> r) { }
    object this[R<T> r] => null;
    static void M1(scoped R<T> r) { } // 1
    void M2(R<T> r) { } // 2
    object this[scoped R<T> r] => null; // 3
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (7,17): error CS0111: Type 'C<T>' already defines a member called 'M1' with the same parameter types
                //     static void M1(scoped R<T> r) { } // 1
                Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "M1").WithArguments("M1", "C<T>").WithLocation(7, 17),
                // (8,10): error CS0111: Type 'C<T>' already defines a member called 'M2' with the same parameter types
                //     void M2(R<T> r) { } // 2
                Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "M2").WithArguments("M2", "C<T>").WithLocation(8, 10),
                // (9,12): error CS0111: Type 'C<T>' already defines a member called 'this' with the same parameter types
                //     object this[scoped R<T> r] => null; // 3
                Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "this").WithArguments("this", "C<T>").WithLocation(9, 12));
        }
 
        [Fact]
        public void Overloads()
        {
            var source =
@"ref struct R<T> { }
class C
{
    static void M1(R<int> r) { }
    static void M2(scoped R<int> r) { }
    static void M3(ref R<int> r) { }
    static void M4(scoped ref R<int> r) { }
    static void M5(scoped ref R<int> r) { }
    static void M1(scoped R<int> r) { } // 2
    static void M2(R<int> r) { } // 3
    static void M3(scoped ref R<int> r) { } // 4
    static void M4(scoped ref R<int> r) { } // 5
    static void M5(ref R<int> r) { } // 6
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (9,17): error CS0111: Type 'C' already defines a member called 'M1' with the same parameter types
                //     static void M1(scoped R<int> r) { } // 2
                Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "M1").WithArguments("M1", "C").WithLocation(9, 17),
                // (10,17): error CS0111: Type 'C' already defines a member called 'M2' with the same parameter types
                //     static void M2(R<int> r) { } // 3
                Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "M2").WithArguments("M2", "C").WithLocation(10, 17),
                // (11,17): error CS0111: Type 'C' already defines a member called 'M3' with the same parameter types
                //     static void M3(scoped ref R<int> r) { } // 4
                Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "M3").WithArguments("M3", "C").WithLocation(11, 17),
                // (12,17): error CS0111: Type 'C' already defines a member called 'M4' with the same parameter types
                //     static void M4(scoped ref R<int> r) { } // 5
                Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "M4").WithArguments("M4", "C").WithLocation(12, 17),
                // (13,17): error CS0111: Type 'C' already defines a member called 'M5' with the same parameter types
                //     static void M5(ref R<int> r) { } // 6
                Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "M5").WithArguments("M5", "C").WithLocation(13, 17));
        }
 
        [Fact]
        public void PartialMethods_01()
        {
            var sourceA =
@"ref struct R<T> { }
partial class C
{
    static partial void M1(R<int> r);
    static partial void M2(scoped R<int> r);
    static partial void M3(ref R<int> r);
    static partial void M4(scoped ref R<int> r);
    static partial void M5(in R<int> r);
    static partial void M6(scoped in R<int> r);
    private static partial void M7(out R<int> r);
    private static partial void M8(scoped out R<int> r);
}";
            var sourceB1 =
@"partial class C
{
    static partial void M1(R<int> r) { }
    static partial void M2(scoped R<int> r) { }
    static partial void M3(ref R<int> r) { }
    static partial void M4(scoped ref R<int> r) { }
    static partial void M5(in R<int> r) { }
    static partial void M6(scoped in R<int> r) { }
    private static partial void M7(out R<int> r) { r = default; }
    private static partial void M8(scoped out R<int> r) { r = default; }
}";
            var sourceB2 =
@"partial class C
{
    static partial void M1(scoped R<int> r) { } // 1
    static partial void M2(R<int> r) { } // 2
    static partial void M3(scoped ref R<int> r) { } // 3
    static partial void M4(ref R<int> r) { } // 4
    static partial void M5(scoped in R<int> r) { } // 5
    static partial void M6(in R<int> r) { } // 6
    private static partial void M7(scoped out R<int> r) { r = default; }
    private static partial void M8(out R<int> r) { r = default; }
}";
            var comp = CreateCompilation(new[] { sourceA, sourceB1 });
            comp.VerifyEmitDiagnostics();
 
            var expectedDiagnostics = new[]
            {
                // (3,25): error CS8988: The 'scoped' modifier of parameter 'r' doesn't match partial method declaration.
                //     static partial void M1(scoped R<int> r) { } // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfPartial, "M1").WithArguments("r").WithLocation(3, 25),
                // (4,25): error CS8988: The 'scoped' modifier of parameter 'r' doesn't match partial method declaration.
                //     static partial void M2(R<int> r) { } // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfPartial, "M2").WithArguments("r").WithLocation(4, 25),
                // (5,25): error CS8988: The 'scoped' modifier of parameter 'r' doesn't match partial method declaration.
                //     static partial void M3(scoped ref R<int> r) { } // 3
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfPartial, "M3").WithArguments("r").WithLocation(5, 25),
                // (6,25): error CS8988: The 'scoped' modifier of parameter 'r' doesn't match partial method declaration.
                //     static partial void M4(ref R<int> r) { } // 4
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfPartial, "M4").WithArguments("r").WithLocation(6, 25),
                // (7,25): error CS8988: The 'scoped' modifier of parameter 'r' doesn't match partial method declaration.
                //     static partial void M5(scoped in R<int> r) { } // 5
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfPartial, "M5").WithArguments("r").WithLocation(7, 25),
                // (8,25): error CS8988: The 'scoped' modifier of parameter 'r' doesn't match partial method declaration.
                //     static partial void M6(in R<int> r) { } // 6
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfPartial, "M6").WithArguments("r").WithLocation(8, 25)
            };
 
            comp = CreateCompilation(new[] { sourceA, sourceB2 });
            comp.VerifyEmitDiagnostics(expectedDiagnostics);
 
            comp = CreateCompilation(new[] { sourceB2, sourceA });
            comp.VerifyEmitDiagnostics(expectedDiagnostics);
        }
 
        [Fact]
        public void PartialMethods_02()
        {
            var sourceA =
@"partial class C
{
    private partial void F1(ref int i);
    private partial void F2(scoped ref int i);
    private partial void F3(in int i);
    private partial void F4(scoped ref int i);
    private partial void F5(out int i);
    private partial void F6(scoped out int i);
}";
            var sourceB1 =
@"partial class C
{
    private partial void F1(ref int i) { }
    private partial void F2(scoped ref int i) { }
    private partial void F3(in int i) { }
    private partial void F4(scoped ref int i) { }
    private partial void F5(out int i) { i = 0; }
    private partial void F6(scoped out int i) { i = 0; }
}";
            var sourceB2 =
@"partial class C
{
    private partial void F1(scoped ref int i) { } // 1
    private partial void F2(ref int i) { } // 2
    private partial void F3(scoped in int i) { } // 3
    private partial void F4(ref int i) { } // 4
    private partial void F5(scoped out int i) { i = 0; }
    private partial void F6(out int i) { i = 0; }
}";
            var comp = CreateCompilation(new[] { sourceA, sourceB1 });
            comp.VerifyEmitDiagnostics();
 
            var expectedDiagnostics = new[]
            {
                // (3,26): error CS8988: The 'scoped' modifier of parameter 'i' doesn't match partial method declaration.
                //     private partial void F1(scoped ref int i) { } // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfPartial, "F1").WithArguments("i").WithLocation(3, 26),
                // (4,26): error CS8988: The 'scoped' modifier of parameter 'i' doesn't match partial method declaration.
                //     private partial void F2(ref int i) { } // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfPartial, "F2").WithArguments("i").WithLocation(4, 26),
                // (5,26): error CS8988: The 'scoped' modifier of parameter 'i' doesn't match partial method declaration.
                //     private partial void F3(scoped in int i) { } // 3
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfPartial, "F3").WithArguments("i").WithLocation(5, 26),
                // (6,26): error CS8988: The 'scoped' modifier of parameter 'i' doesn't match partial method declaration.
                //     private partial void F4(ref int i) { } // 4
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfPartial, "F4").WithArguments("i").WithLocation(6, 26)
            };
 
            comp = CreateCompilation(new[] { sourceA, sourceB2 });
            comp.VerifyEmitDiagnostics(expectedDiagnostics);
 
            comp = CreateCompilation(new[] { sourceB2, sourceA });
            comp.VerifyEmitDiagnostics(expectedDiagnostics);
        }
 
        [Fact]
        public void PartialMethods_03()
        {
            var sourceA =
@"using System.Diagnostics.CodeAnalysis;
ref struct R { }
partial class C
{
    private partial void F1(out R r);
    private partial void F2([UnscopedRef] out R r);
}";
            var sourceB1 =
@"partial class C
{
    private partial void F1(out R r) { r = default; }
    private partial void F2(out R r) { r = default; }
}";
            var sourceB2 =
@"using System.Diagnostics.CodeAnalysis;
partial class C
{
    private partial void F1([UnscopedRef] out R r) { r = default; }
    private partial void F2(out R r) { r = default; }
}";
 
            // Attributes are combined across partial parts so there is essentially
            // no difference between the parts in these cases.
 
            var comp = CreateCompilation(new[] { sourceA, sourceB1, UnscopedRefAttributeDefinition });
            comp.VerifyEmitDiagnostics();
 
            comp = CreateCompilation(new[] { sourceA, sourceB2, UnscopedRefAttributeDefinition });
            comp.VerifyEmitDiagnostics();
 
            comp = CreateCompilation(new[] { sourceB2, sourceA, UnscopedRefAttributeDefinition });
            comp.VerifyEmitDiagnostics();
        }
 
        [CombinatorialData]
        [Theory]
        public void Hiding(bool useCompilationReference)
        {
            var sourceA =
@"public ref struct R<T> { }
public class A<T>
{
    public void M1(R<T> r) { }
    public void M2(scoped R<T> r) { }
    public void M3(ref R<T> r) { }
    public object this[R<T> r] { get { return null; } set { } }
    public object this[int x, scoped R<T> y] => null;
}";
            var comp = CreateCompilation(sourceA);
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class B1 : A<int>
{
    public new void M1(scoped R<int> r) { }
    public new void M2(R<int> r) { }
    public new void M3(ref R<int> r) { }
    public new object this[scoped R<int> r] { get { return null; } set { } }
    public new object this[int x, R<int> y] => null;
}
class B2 : A<string>
{
    public void M1(scoped R<string> r) { } // 1
    public void M2(R<string> r) { } // 2
    public void M3(scoped ref R<string> r) { } // 3
    public object this[scoped R<string> r] { get { return null; } set { } } // 4
    public object this[int x, R<string> y] => null; // 5
}";
            comp = CreateCompilation(sourceB, references: new[] { refA });
            comp.VerifyEmitDiagnostics(
                // (11,17): warning CS0108: 'B2.M1(scoped R<string>)' hides inherited member 'A<string>.M1(R<string>)'. Use the new keyword if hiding was intended.
                //     public void M1(scoped R<string> r) { } // 1
                Diagnostic(ErrorCode.WRN_NewRequired, "M1").WithArguments("B2.M1(scoped R<string>)", "A<string>.M1(R<string>)").WithLocation(11, 17),
                // (12,17): warning CS0108: 'B2.M2(R<string>)' hides inherited member 'A<string>.M2(scoped R<string>)'. Use the new keyword if hiding was intended.
                //     public void M2(R<string> r) { } // 2
                Diagnostic(ErrorCode.WRN_NewRequired, "M2").WithArguments("B2.M2(R<string>)", "A<string>.M2(scoped R<string>)").WithLocation(12, 17),
                // (13,17): warning CS0108: 'B2.M3(scoped ref R<string>)' hides inherited member 'A<string>.M3(ref R<string>)'. Use the new keyword if hiding was intended.
                //     public void M3(scoped ref R<string> r) { } // 3
                Diagnostic(ErrorCode.WRN_NewRequired, "M3").WithArguments("B2.M3(scoped ref R<string>)", "A<string>.M3(ref R<string>)").WithLocation(13, 17),
                // (14,19): warning CS0108: 'B2.this[scoped R<string>]' hides inherited member 'A<string>.this[R<string>]'. Use the new keyword if hiding was intended.
                //     public object this[scoped R<string> r] { get { return null; } set { } } // 4
                Diagnostic(ErrorCode.WRN_NewRequired, "this").WithArguments("B2.this[scoped R<string>]", "A<string>.this[R<string>]").WithLocation(14, 19),
                // (15,19): warning CS0108: 'B2.this[int, R<string>]' hides inherited member 'A<string>.this[int, scoped R<string>]'. Use the new keyword if hiding was intended.
                //     public object this[int x, R<string> y] => null; // 5
                Diagnostic(ErrorCode.WRN_NewRequired, "this").WithArguments("B2.this[int, R<string>]", "A<string>.this[int, scoped R<string>]").WithLocation(15, 19));
        }
 
        [CombinatorialData]
        [Theory]
        public void Overrides_01(bool useCompilationReference)
        {
            var sourceA =
@"public ref struct R<T> { }
public abstract class A<T>
{
    public abstract R<T> F1(R<T> r);
    public abstract R<T> F2(scoped R<T> r);
    public abstract R<T> F3(ref R<T> r);
    public abstract R<T> F4(scoped ref R<T> r);
    public abstract R<T> this[R<T> r] { get; set; }
    public abstract R<T> this[int x, scoped R<T> y] { get; }
}";
            var comp = CreateCompilation(sourceA);
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class B1 : A<int>
{
    public override R<int> F1(R<int> r) => default;
    public override R<int> F2(scoped R<int> r) => default;
    public override R<int> F3(ref R<int> r) => default;
    public override R<int> F4(scoped ref R<int> r) => default;
    public override R<int> this[R<int> r] { get { return default; } set { } }
    public override R<int> this[int x, scoped R<int> y] => default;
}
class B2 : A<string>
{
    public override R<string> F1(scoped R<string> r) => default;
    public override R<string> F2(R<string> r) => default; // 1
    public override R<string> F3(scoped ref R<string> r) => default;
    public override R<string> F4(ref R<string> r) => default; // 2
    public override R<string> this[scoped R<string> r] { get { return default; } set { } }
    public override R<string> this[int x, R<string> y] => default; // 3
}";
            comp = CreateCompilation(sourceB, references: new[] { refA });
            comp.VerifyEmitDiagnostics(
                // (13,31): error CS8987: The 'scoped' modifier of parameter 'r' doesn't match overridden or implemented member.
                //     public override R<string> F2(R<string> r) => default; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F2").WithArguments("r").WithLocation(13, 31),
                // (15,31): error CS8987: The 'scoped' modifier of parameter 'r' doesn't match overridden or implemented member.
                //     public override R<string> F4(ref R<string> r) => default; // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F4").WithArguments("r").WithLocation(15, 31),
                // (17,59): error CS8987: The 'scoped' modifier of parameter 'y' doesn't match overridden or implemented member.
                //     public override R<string> this[int x, R<string> y] => default; // 3
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "default").WithArguments("y").WithLocation(17, 59));
        }
 
        [CombinatorialData]
        [Theory]
        public void Overrides_02(bool useCompilationReference)
        {
            var sourceA =
@"public abstract class A<T>
{
    public abstract ref T F1(out T t);
    public abstract ref T F2(scoped out T t);
    public abstract ref T F3(ref T t);
    public abstract ref T F4(scoped ref T t);
    public abstract ref T F5(in T t);
    public abstract ref T F6(scoped in T t);
}";
            var comp = CreateCompilation(sourceA);
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class B1 : A<int>
{
    public override ref int F1(out int i) => throw null;
    public override ref int F2(scoped out int i) => throw null;
    public override ref int F3(ref int i) => throw null;
    public override ref int F4(scoped ref int i) => throw null;
    public override ref int F5(in int i) => throw null;
    public override ref int F6(scoped in int i) => throw null;
}
class B2 : A<string>
{
    public override ref string F1(scoped out string s) => throw null;
    public override ref string F2(out string s) => throw null;
    public override ref string F3(scoped ref string s) => throw null;
    public override ref string F4(ref string s) => throw null; // 1
    public override ref string F5(scoped in string s) => throw null;
    public override ref string F6(in string s) => throw null; // 2
}";
            comp = CreateCompilation(sourceB, references: new[] { refA });
            comp.VerifyEmitDiagnostics(
                // (15,32): error CS8987: The 'scoped' modifier of parameter 's' doesn't match overridden or implemented member.
                //     public override ref string F4(ref string s) => throw null; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F4").WithArguments("s").WithLocation(15, 32),
                // (17,32): error CS8987: The 'scoped' modifier of parameter 's' doesn't match overridden or implemented member.
                //     public override ref string F6(in string s) => throw null; // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F6").WithArguments("s").WithLocation(17, 32));
        }
 
        [CombinatorialData]
        [Theory]
        public void InterfaceImplementations_01(bool useCompilationReference)
        {
            var sourceA =
@"public ref struct R<T> { }
public interface I<T>
{
    R<T> F1(R<T> r);
    R<T> F2(scoped R<T> r);
    R<T> F3(ref R<T> r);
    R<T> F4(scoped ref R<T> r);
    R<T> this[R<T> r] { get; set; }
    R<T> this[int x, scoped R<T> y] { get; }
    R<T> this[object x, in R<T> y] { get; set; }
    R<T> this[scoped in R<T> x, int y] { get; }
}";
            var comp = CreateCompilation(sourceA);
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB1 =
@"class C1 : I<int>
{
    public R<int> F1(R<int> r) => default;
    public R<int> F2(scoped R<int> r) => default;
    public R<int> F3(ref R<int> r) => default;
    public R<int> F4(scoped ref R<int> r) => default;
    public R<int> this[R<int> r] { get { return default; } set { } }
    public R<int> this[int x, scoped R<int> y] => default;
    public R<int> this[object x, in R<int> y] { get { return default; } set { } }
    public R<int> this[scoped in R<int> x, int y] => default;
}
class C2 : I<string>
{
    public R<string> F1(scoped R<string> r) => default;
    public R<string> F2(R<string> r) => default; // 1
    public R<string> F3(scoped ref R<string> r) => default;
    public R<string> F4(ref R<string> r) => default; // 2
    public R<string> this[scoped R<string> r] { get { return default; } set { } }
    public R<string> this[int x, R<string> y] => default; // 3
    public R<string> this[object x, scoped in R<string> y] { get { return default; } set { } }
    public R<string> this[in R<string> x, int y] => default; // 4
}";
            comp = CreateCompilation(sourceB1, references: new[] { refA });
            comp.VerifyEmitDiagnostics(
                // (15,22): error CS8987: The 'scoped' modifier of parameter 'r' doesn't match overridden or implemented member.
                //     public R<string> F2(R<string> r) => default; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F2").WithArguments("r").WithLocation(15, 22),
                // (17,22): error CS8987: The 'scoped' modifier of parameter 'r' doesn't match overridden or implemented member.
                //     public R<string> F4(ref R<string> r) => default; // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F4").WithArguments("r").WithLocation(17, 22),
                // (19,50): error CS8987: The 'scoped' modifier of parameter 'y' doesn't match overridden or implemented member.
                //     public R<string> this[int x, R<string> y] => default; // 3
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "default").WithArguments("y").WithLocation(19, 50),
                // (21,53): error CS8987: The 'scoped' modifier of parameter 'x' doesn't match overridden or implemented member.
                //     public R<string> this[in R<string> x, int y] => default; // 4
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "default").WithArguments("x").WithLocation(21, 53));
 
            var sourceB2 =
@"class C3 : I<int>
{
    R<int> I<int>.F1(R<int> r) => default;
    R<int> I<int>.F2(scoped R<int> r) => default;
    R<int> I<int>.F3(ref R<int> r) => default;
    R<int> I<int>.F4(scoped ref R<int> r) => default;
    R<int> I<int>.this[R<int> r] { get { return default; } set { } }
    R<int> I<int>.this[int x, scoped R<int> y] => default;
    R<int> I<int>.this[object x, in R<int> y] { get { return default; } set { } }
    R<int> I<int>.this[scoped in R<int> x, int y] => default;
}
class C4 : I<string>
{
    R<string> I<string>.F1(scoped R<string> r) => default;
    R<string> I<string>.F2(R<string> r) => default; // 1
    R<string> I<string>.F3(scoped ref R<string> r) => default;
    R<string> I<string>.F4(ref R<string> r) => default; // 2
    R<string> I<string>.this[scoped R<string> r] { get { return default; } set { } }
    R<string> I<string>.this[int x, R<string> y] => default; // 3
    R<string> I<string>.this[object x, scoped in R<string> y] { get { return default; } set { } }
    R<string> I<string>.this[in R<string> x, int y] => default; // 4
}";
            comp = CreateCompilation(sourceB2, references: new[] { refA });
            comp.VerifyEmitDiagnostics(
                // (15,25): error CS8987: The 'scoped' modifier of parameter 'r' doesn't match overridden or implemented member.
                //     R<string> I<string>.F2(R<string> r) => default; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F2").WithArguments("r").WithLocation(15, 25),
                // (17,25): error CS8987: The 'scoped' modifier of parameter 'r' doesn't match overridden or implemented member.
                //     R<string> I<string>.F4(ref R<string> r) => default; // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F4").WithArguments("r").WithLocation(17, 25),
                // (19,53): error CS8987: The 'scoped' modifier of parameter 'y' doesn't match overridden or implemented member.
                //     R<string> I<string>.this[int x, R<string> y] => default; // 3
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "default").WithArguments("y").WithLocation(19, 53),
                // (21,56): error CS8987: The 'scoped' modifier of parameter 'x' doesn't match overridden or implemented member.
                //     R<string> I<string>.this[in R<string> x, int y] => default; // 4
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "default").WithArguments("x").WithLocation(21, 56));
        }
 
        [CombinatorialData]
        [Theory]
        public void InterfaceImplementations_02(bool useCompilationReference)
        {
            var sourceA =
@"public interface I<T>
{
    ref readonly T F1(out T t);
    ref readonly T F2(scoped out T t);
    ref readonly T F3(ref T t);
    ref readonly T F4(scoped ref T t);
    ref readonly T F5(in T t);
    ref readonly T F6(scoped in T t);
}";
            var comp = CreateCompilation(sourceA);
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB1 =
@"class C1 : I<int>
{
    public ref readonly int F1(out int i) => throw null;
    public ref readonly int F2(scoped out int i) => throw null;
    public ref readonly int F3(ref int i) => throw null;
    public ref readonly int F4(scoped ref int i) => throw null;
    public ref readonly int F5(in int i) => throw null;
    public ref readonly int F6(scoped in int i) => throw null;
}
class C2 : I<string>
{
    public ref readonly string F1(scoped out string s) => throw null;
    public ref readonly string F2(out string s) => throw null;
    public ref readonly string F3(scoped ref string s) => throw null;
    public ref readonly string F4(ref string s) => throw null; // 1
    public ref readonly string F5(scoped in string s) => throw null;
    public ref readonly string F6(in string s) => throw null; // 2
}";
            comp = CreateCompilation(sourceB1, references: new[] { refA });
            comp.VerifyEmitDiagnostics(
                // (15,32): error CS8987: The 'scoped' modifier of parameter 's' doesn't match overridden or implemented member.
                //     public ref readonly string F4(ref string s) => throw null; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F4").WithArguments("s").WithLocation(15, 32),
                // (17,32): error CS8987: The 'scoped' modifier of parameter 's' doesn't match overridden or implemented member.
                //     public ref readonly string F6(in string s) => throw null; // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F6").WithArguments("s").WithLocation(17, 32));
 
            var sourceB2 =
@"class C3 : I<int>
{
    ref readonly int I<int>.F1(out int i) => throw null;
    ref readonly int I<int>.F2(scoped out int i) => throw null;
    ref readonly int I<int>.F3(ref int i) => throw null;
    ref readonly int I<int>.F4(scoped ref int i) => throw null;
    ref readonly int I<int>.F5(in int i) => throw null;
    ref readonly int I<int>.F6(scoped in int i) => throw null;
}
class C4 : I<string>
{
    ref readonly string I<string>.F1(scoped out string s) => throw null;
    ref readonly string I<string>.F2(out string s) => throw null;
    ref readonly string I<string>.F3(scoped ref string s) => throw null;
    ref readonly string I<string>.F4(ref string s) => throw null; // 1
    ref readonly string I<string>.F5(scoped in string s) => throw null;
    ref readonly string I<string>.F6(in string s) => throw null; // 2
}";
            comp = CreateCompilation(sourceB2, references: new[] { refA });
            comp.VerifyEmitDiagnostics(
                // (15,35): error CS8987: The 'scoped' modifier of parameter 's' doesn't match overridden or implemented member.
                //     ref readonly string I<string>.F4(ref string s) => throw null; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F4").WithArguments("s").WithLocation(15, 35),
                // (17,35): error CS8987: The 'scoped' modifier of parameter 's' doesn't match overridden or implemented member.
                //     ref readonly string I<string>.F6(in string s) => throw null; // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F6").WithArguments("s").WithLocation(17, 35));
        }
 
        [CombinatorialData]
        [Theory]
        public void OverridesAndInterfaceImplementations_Out_01(bool useCompilationReference)
        {
            var sourceA =
@"public abstract class A<T>
{
    public abstract void F1(out T t);
}
public interface I<T>
{
    void F2(out T t);
}";
            var comp = CreateCompilation(sourceA);
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class B1 : A<int>, I<int>
{
    public override void F1(scoped out int i) { i = 0; }
    public void F2(scoped out int i) { i = 0; }
}
class B2 : I<string>
{
    void I<string>.F2(scoped out string s) { s = null; }
}";
            comp = CreateCompilation(sourceB, references: new[] { refA });
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void OverridesAndInterfaceImplementations_Out_02()
        {
            var source =
@"abstract class A
{
    public abstract void F1(out int i);
    public abstract void F2(scoped out int i);
}
class B : A
{
    public override void F1(scoped out int i) { i = 0; }
    public override void F2(out int i) { i = 0; }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void OverridesAndInterfaceImplementations_Out_03()
        {
            var source =
@"interface I
{
    void F1(out int i);
    void F2(scoped out int i);
}
class C1 : I
{
    public void F1(scoped out int i) { i = 0; }
    public void F2(out int i) { i = 0; }
}
class C2 : I
{
    void I.F1(scoped out int i) { i = 0; }
    void I.F2(out int i) { i = 0; }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void OverridesAndInterfaceImplementations_Out_04()
        {
            var source =
@"#nullable enable
abstract class A
{
    public abstract void F1<T>(out T t);
    public abstract void F2<T>(out T? t);
}
class B1 : A
{
    public override void F1<T>(out T t) { t = default!; }
    public override void F2<T>(out T? t) where T : default { t = default; }
}
class B2 : A
{
    public override void F1<T>(out T? t) where T : default { t = default; }
    public override void F2<T>(out T t) { t = default!; }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (14,26): warning CS8765: Nullability of type of parameter 't' doesn't match overridden member (possibly because of nullability attributes).
                //     public override void F1<T>(out T? t) where T : default { t = default; }
                Diagnostic(ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnOverride, "F1").WithArguments("t").WithLocation(14, 26));
 
            // https://github.com/dotnet/roslyn/issues/62780: Test with [UnscopedRef].
        }
 
        [Fact]
        public void OverridesAndInterfaceImplementations_Out_05()
        {
            var source =
@"#nullable enable
interface I
{
    void F1<T>(out T t);
    void F2<T>(out T? t);
}
class C1 : I
{
    public void F1<T>(out T t) { t = default!; }
    public void F2<T>(out T? t) { t = default; }
}
class C2 : I
{
    public void F1<T>(out T? t) { t = default; }
    public void F2<T>(out T t) { t = default!; }
}
class C3 : I
{
    void I.F1<T>(out T t) { t = default!; }
    void I.F2<T>(out T? t) where T : default { t = default; }
}
class C4 : I
{
    void I.F1<T>(out T? t) where T : default { t = default; }
    void I.F2<T>(out T t) { t = default!; }
}";
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (14,17): warning CS8767: Nullability of reference types in type of parameter 't' of 'void C2.F1<T>(out T? t)' doesn't match implicitly implemented member 'void I.F1<T>(out T t)' (possibly because of nullability attributes).
                //     public void F1<T>(out T? t) { t = default; }
                Diagnostic(ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnImplicitImplementation, "F1").WithArguments("t", "void C2.F1<T>(out T? t)", "void I.F1<T>(out T t)").WithLocation(14, 17),
                // (24,12): warning CS8769: Nullability of reference types in type of parameter 't' doesn't match implemented member 'void I.F1<T>(out T t)' (possibly because of nullability attributes).
                //     void I.F1<T>(out T? t) where T : default { t = default; }
                Diagnostic(ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnExplicitImplementation, "F1").WithArguments("t", "void I.F1<T>(out T t)").WithLocation(24, 12));
 
            // https://github.com/dotnet/roslyn/issues/62780: Test with [UnscopedRef].
        }
 
        [Fact]
        public void Overrides_Example()
        {
            var source =
@"ref struct R
{
    public ref int F;
    public R(ref int i) { F = ref i; }
}
abstract class A
{
    public abstract R F1(scoped R r);
    public abstract R F2(R r);
}
class B : A
{
    public override R F1(R r) => r;
    public override R F2(scoped R r) => default;
}
class Program
{
    static R F1(A a)
    {
        int i = 0;
        return a.F1(new R(ref i));
    }
    static R F2(B b)
    {
        int i = 0;
        return b.F2(new R(ref i)); // unsafe
    }
    static void Main()
    {
        R r1 = F1(new B()); // unsafe
        R r2 = F2(new B());
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (13,23): error CS8987: The 'scoped' modifier of parameter 'r' doesn't match overridden or implemented member.
                //     public override R F1(R r) => r;
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("r").WithLocation(13, 23));
        }
 
        [Fact]
        public void Delegates_Example()
        {
            var source =
@"ref struct R
{
    public ref int F;
    public R(ref int i) { F = ref i; }
}
delegate R D1(scoped R x);
delegate R D2(R x);
class Program
{
    static R F1(D1 d1)
    {
        int i = 0;
        return d1(new R(ref i));
    }
    static R F2(D2 d2)
    {
        int i = 0;
        return d2(new R(ref i));
    }
    static void Main()
    {
        R r1 = F1((R x) => x); // unsafe
        R r2 = F2((scoped R x) => default);
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (18,16): error CS8347: Cannot use a result of 'D2.Invoke(R)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //         return d2(new R(ref i));
                Diagnostic(ErrorCode.ERR_EscapeCall, "d2(new R(ref i))").WithArguments("D2.Invoke(R)", "x").WithLocation(18, 16),
                // (18,19): error CS8347: Cannot use a result of 'R.R(ref int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         return d2(new R(ref i));
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R(ref i)").WithArguments("R.R(ref int)", "i").WithLocation(18, 19),
                // (18,29): error CS8168: Cannot return local 'i' by reference because it is not a ref local
                //         return d2(new R(ref i));
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i").WithArguments("i").WithLocation(18, 29),
                // (22,19): error CS8989: The 'scoped' modifier of parameter 'x' doesn't match target 'D1'.
                //         R r1 = F1((R x) => x); // unsafe
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(R x) => x").WithArguments("x", "D1").WithLocation(22, 19));
        }
 
        [Fact]
        public void BestCommonType_01()
        {
            var source =
@"ref struct R { }
class Program
{
    static R F1(bool b, R x, scoped R y) => b ? x : y;
    static R F2(bool b, R x, scoped R y) => b ? y : x;
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (4,53): error CS8352: Cannot use variable 'scoped R y' in this context because it may expose referenced variables outside of their declaration scope
                //     static R F1(bool b, R x, scoped R y) => b ? x : y;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y").WithArguments("scoped R y").WithLocation(4, 53),
                // (5,49): error CS8352: Cannot use variable 'scoped R y' in this context because it may expose referenced variables outside of their declaration scope
                //     static R F2(bool b, R x, scoped R y) => b ? y : x;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y").WithArguments("scoped R y").WithLocation(5, 49));
        }
 
        [Fact]
        public void BestCommonType_01_UnsafeContext()
        {
            var source =
@"ref struct R { }
unsafe class Program
{
    static R F1(bool b, R x, scoped R y) => b ? x : y;
    static R F2(bool b, R x, scoped R y) => b ? y : x;
}";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugDll);
            comp.VerifyDiagnostics(
                // (4,53): warning CS9080: Use of variable 'scoped R y' in this context may expose referenced variables outside of their declaration scope
                //     static R F1(bool b, R x, scoped R y) => b ? x : y;
                Diagnostic(ErrorCode.WRN_EscapeVariable, "y").WithArguments("scoped R y").WithLocation(4, 53),
                // (5,49): warning CS9080: Use of variable 'scoped R y' in this context may expose referenced variables outside of their declaration scope
                //     static R F2(bool b, R x, scoped R y) => b ? y : x;
                Diagnostic(ErrorCode.WRN_EscapeVariable, "y").WithArguments("scoped R y").WithLocation(5, 49));
        }
 
        [Fact]
        public void BestCommonType_03()
        {
            var source =
@"class Program
{
    static ref int F1(bool b, scoped ref int x, ref int y) => ref b ? ref x : ref y;
    static ref int F2(bool b, scoped ref int x, ref int y) => ref b ? ref y : ref x;
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (3,75): error CS9075: Cannot return a parameter by reference 'x' because it is scoped to the current method
                //     static ref int F1(bool b, scoped ref int x, ref int y) => ref b ? ref x : ref y;
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "x").WithArguments("x").WithLocation(3, 75),
                // (4,83): error CS9075: Cannot return a parameter by reference 'x' because it is scoped to the current method
                //     static ref int F2(bool b, scoped ref int x, ref int y) => ref b ? ref y : ref x;
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "x").WithArguments("x").WithLocation(4, 83));
        }
 
        [Fact]
        public void BestCommonType_04()
        {
            var source =
@"ref struct R { }
class Program
{
    static void Main()
    {
        var f1 = new[] { (R r) => { }, (scoped R r) => { } }[0]; // 1
        var f2 = new[] { (scoped R r) => { }, (scoped R r) => { } }[0];
        var f3 = new[] { (ref R r) => { }, (scoped ref R r) => { } }[0]; // 2
        var f4 = new[] { (scoped ref R r) => { }, (scoped ref R r) => { } }[0];
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (6,18): error CS0826: No best type found for implicitly-typed array
                //         var f1 = new[] { (R r) => { }, (scoped R r) => { } }[0]; // 1
                Diagnostic(ErrorCode.ERR_ImplicitlyTypedArrayNoBestType, "new[] { (R r) => { }, (scoped R r) => { } }").WithLocation(6, 18),
                // (8,18): error CS0826: No best type found for implicitly-typed array
                //         var f3 = new[] { (ref R r) => { }, (scoped ref R r) => { } }[0]; // 2
                Diagnostic(ErrorCode.ERR_ImplicitlyTypedArrayNoBestType, "new[] { (ref R r) => { }, (scoped ref R r) => { } }").WithLocation(8, 18));
        }
 
        [Fact]
        public void InferredDelegateTypes_01()
        {
            var source =
@"ref struct R { }
class Program
{
    static void F1(R x1, scoped R y1)
    {
        var f = (R x, scoped R y) => x;
        R z;
        z = f(x1, y1);
        z = f(y1, x1); // 1
    }
    static void F3(ref int x3, scoped ref int y3)
    {
        var f = (ref int x, scoped ref int y) => ref x;
        int z;
        z = f(ref x3, ref y3);
        z = f(ref y3, ref x3);
    }
}";
            var comp = CreateCompilation(source);
            // https://github.com/dotnet/roslyn/issues/62768: Improve error message for `scoped ref` parameter returned by reference.
            comp.VerifyDiagnostics(
                // (9,13): error CS8347: Cannot use a result of '<anonymous delegate>.Invoke(R, scoped R)' in this context because it may expose variables referenced by parameter 'arg1' outside of their declaration scope
                //         z = f(y1, x1); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "f(y1, x1)").WithArguments("<anonymous delegate>.Invoke(R, scoped R)", "arg1").WithLocation(9, 13),
                // (9,15): error CS8352: Cannot use variable 'scoped R y1' in this context because it may expose referenced variables outside of their declaration scope
                //         z = f(y1, x1); // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "y1").WithArguments("scoped R y1").WithLocation(9, 15));
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Where(v => v.Identifier.Text == "f").ToArray();
            var delegateInvokeMethods = decls.Select(d => ((ILocalSymbol)model.GetDeclaredSymbol(d)).Type.GetSymbol<NamedTypeSymbol>().DelegateInvokeMethod).ToArray();
 
            VerifyParameterSymbol(delegateInvokeMethods[0].Parameters[0], "R arg1", RefKind.None, ScopedKind.None);
            VerifyParameterSymbol(delegateInvokeMethods[0].Parameters[1], "scoped R arg2", RefKind.None, ScopedKind.ScopedValue);
            VerifyParameterSymbol(delegateInvokeMethods[1].Parameters[1], "scoped ref System.Int32 arg2", RefKind.Ref, ScopedKind.ScopedRef);
        }
 
        [Fact]
        public void InferredDelegateTypes_02()
        {
            var source =
@"ref struct R { }
static class E1
{
    public static void F1(this object o, R r) { }
    public static void F2(this object o, ref R r) { }
}
static class E2
{
    public static void F1(this object o, scoped R r) { }
    public static void F2(this object o, scoped ref R r) { }
}
class Program
{
    static void Main()
    {
        object o = new object();
        var d1 = o.F1;
        var d2 = o.F2;
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (17,18): error CS0121: The call is ambiguous between the following methods or properties: 'E1.F1(object, R)' and 'E2.F1(object, scoped R)'
                //         var d1 = o.F1;
                Diagnostic(ErrorCode.ERR_AmbigCall, "o.F1").WithArguments("E1.F1(object, R)", "E2.F1(object, scoped R)").WithLocation(17, 18),
                // (18,18): error CS0121: The call is ambiguous between the following methods or properties: 'E1.F2(object, ref R)' and 'E2.F2(object, scoped ref R)'
                //         var d2 = o.F2;
                Diagnostic(ErrorCode.ERR_AmbigCall, "o.F2").WithArguments("E1.F2(object, ref R)", "E2.F2(object, scoped ref R)").WithLocation(18, 18));
        }
 
        [Fact]
        public void ScopedRefAndRefStructOnly_01()
        {
            var source =
@"struct S { }
class Program
{
    static void F1(scoped S s) { }
 
    static void F3(scoped ref S s) { }
 
    static void F5(scoped ref int i) { }
    static void F6(scoped in  int i) { }
    static void F7(scoped out int i) { i = 0; }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (4,20): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //     static void F1(scoped S s) { }
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "scoped S s").WithLocation(4, 20));
        }
 
        [Fact]
        public void ScopedRefAndRefStructOnly_02()
        {
            var source =
@"struct S { }
interface I
{
    void F1<T>(scoped T t);
    void F2<T>(scoped T t) where T : class;
    void F3<T>(scoped T t) where T : struct;
    void F4<T>(scoped T t) where T : unmanaged;
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (4,16): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //     void F1<T>(scoped T t);
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "scoped T t").WithLocation(4, 16),
                // (5,16): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //     void F2<T>(scoped T t) where T : class;
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "scoped T t").WithLocation(5, 16),
                // (6,16): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //     void F3<T>(scoped T t) where T : struct;
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "scoped T t").WithLocation(6, 16),
                // (7,16): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //     void F4<T>(scoped T t) where T : unmanaged;
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "scoped T t").WithLocation(7, 16));
        }
 
        [Fact]
        public void ScopedRefAndRefStructOnly_03()
        {
            var source =
@"enum E { }
class Program
{
    static void Main()
    {
        var f = (scoped ref E x, scoped E y) => { };
#pragma warning disable 8321
        static void L(scoped ref E x, scoped E y) { }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (6,34): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         var f = (scoped ref E x, scoped E y) => { };
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "scoped E y").WithLocation(6, 34),
                // (8,39): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         static void L(scoped ref E x, scoped E y) { }
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "scoped E y").WithLocation(8, 39));
        }
 
        [Fact]
        public void ScopedRefAndRefStructOnly_04()
        {
            var source =
@"delegate void D(scoped C c);
class C
{
    static unsafe void Main()
    {
        delegate*<scoped C, int> d = default;
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseExe);
            comp.VerifyDiagnostics(
                // (1,17): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                // delegate void D(scoped C c);
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "scoped C c").WithLocation(1, 17),
                // (6,19): error CS8755: 'scoped' cannot be used as a modifier on a function pointer parameter.
                //         delegate*<scoped C, int> d = default;
                Diagnostic(ErrorCode.ERR_BadFuncPointerParamModifier, "scoped").WithArguments("scoped").WithLocation(6, 19));
        }
 
        [Theory]
        [InlineData("ref         ")]
        [InlineData("ref readonly")]
        public void ScopedRefAndRefStructOnly_05(string refModifier)
        {
            var source =
$@"struct S {{ }}
class Program
{{
    static void F(S s)
    {{
        scoped {refModifier} S s2 = ref s;
    }}
}}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Theory]
        [InlineData("ref         ")]
        [InlineData("ref readonly")]
        public void ScopedRefAndRefStructOnly_05_RefScoped(string refModifier)
        {
            var source =
$@"struct S {{ }}
class Program
{{
    static void F(S s)
    {{
        {refModifier} scoped S s1 = ref s;
        scoped {refModifier} scoped S s3 = ref s;
    }}
}}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (6,22): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
                //         ref          scoped S s1 = ref s;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(6, 22),
                // (6,29): error CS8174: A declaration of a by-reference variable must have an initializer
                //         ref          scoped S s1 = ref s;
                Diagnostic(ErrorCode.ERR_ByReferenceVariableMustBeInitialized, "S").WithLocation(6, 29),
                // (6,29): warning CS0168: The variable 'S' is declared but never used
                //         ref          scoped S s1 = ref s;
                Diagnostic(ErrorCode.WRN_UnreferencedVar, "S").WithArguments("S").WithLocation(6, 29),
                // (6,31): error CS1002: ; expected
                //         ref          scoped S s1 = ref s;
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "s1").WithLocation(6, 31),
                // (6,31): error CS0103: The name 's1' does not exist in the current context
                //         ref          scoped S s1 = ref s;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "s1").WithArguments("s1").WithLocation(6, 31),
                // (7,29): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
                //         scoped ref          scoped S s3 = ref s;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(7, 29),
                // (7,36): error CS0128: A local variable or function named 'S' is already defined in this scope
                //         scoped ref          scoped S s3 = ref s;
                Diagnostic(ErrorCode.ERR_LocalDuplicate, "S").WithArguments("S").WithLocation(7, 36),
                // (7,36): error CS8174: A declaration of a by-reference variable must have an initializer
                //         scoped ref          scoped S s3 = ref s;
                Diagnostic(ErrorCode.ERR_ByReferenceVariableMustBeInitialized, "S").WithLocation(7, 36),
                // (7,36): warning CS0168: The variable 'S' is declared but never used
                //         scoped ref          scoped S s3 = ref s;
                Diagnostic(ErrorCode.WRN_UnreferencedVar, "S").WithArguments("S").WithLocation(7, 36),
                // (7,38): error CS1002: ; expected
                //         scoped ref          scoped S s3 = ref s;
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "s3").WithLocation(7, 38),
                // (7,38): error CS0103: The name 's3' does not exist in the current context
                //         scoped ref          scoped S s3 = ref s;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "s3").WithArguments("s3").WithLocation(7, 38)
                );
        }
 
        [Fact]
        public void ScopedRefAndRefStructOnly_06()
        {
            var source =
@"ref struct R<T> { }
struct S<T> { }
class Program
{
    static void Main()
    {
        scoped var x1 = new R<int>();
        scoped ref var x3 = ref x1; // 1
        scoped var y1 = new S<int>(); // 2
        scoped ref var y3 = ref y1;
        scoped S<int> y4 = new S<int>(), y5 = new S<int>(); // 3
        y4 = y5;
        y5 = y4;
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (8,33): error CS8352: Cannot use variable 'x1' in this context because it may expose referenced variables outside of their declaration scope
                //         scoped ref var x3 = ref x1; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "x1").WithArguments("x1").WithLocation(8, 33),
                // (9,16): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         scoped var y1 = new S<int>(); // 2
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "var").WithLocation(9, 16),
                // (11,16): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         scoped S<int> y4 = new S<int>(), y5 = new S<int>(); // 3
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "S<int>").WithLocation(11, 16),
                // (11,16): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         scoped S<int> y4 = new S<int>(), y5 = new S<int>(); // 3
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "S<int>").WithLocation(11, 16)
                );
        }
 
        [Fact]
        public void ScopedRefAndRefStructOnly_07()
        {
            var source =
@"ref struct R<T> { }
class Program
{
    static void F1(scoped Unknown x, scoped R<Unknown> y)
    {
        var f = (scoped ref Unknown u) => { };
        scoped R<Unknown> z = y;
        scoped var v = F2();
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (4,20): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //     static void F1(scoped Unknown x, scoped R<Unknown> y)
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "scoped Unknown x").WithLocation(4, 20),
                // (4,27): error CS0246: The type or namespace name 'Unknown' could not be found (are you missing a using directive or an assembly reference?)
                //     static void F1(scoped Unknown x, scoped R<Unknown> y)
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Unknown").WithArguments("Unknown").WithLocation(4, 27),
                // (4,47): error CS0246: The type or namespace name 'Unknown' could not be found (are you missing a using directive or an assembly reference?)
                //     static void F1(scoped Unknown x, scoped R<Unknown> y)
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Unknown").WithArguments("Unknown").WithLocation(4, 47),
                // (6,29): error CS0246: The type or namespace name 'Unknown' could not be found (are you missing a using directive or an assembly reference?)
                //         var f = (scoped ref Unknown u) => { };
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Unknown").WithArguments("Unknown").WithLocation(6, 29),
                // (7,18): error CS0246: The type or namespace name 'Unknown' could not be found (are you missing a using directive or an assembly reference?)
                //         scoped R<Unknown> z = y;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Unknown").WithArguments("Unknown").WithLocation(7, 18),
                // (8,24): error CS0103: The name 'F2' does not exist in the current context
                //         scoped var v = F2();
                Diagnostic(ErrorCode.ERR_NameNotInContext, "F2").WithArguments("F2").WithLocation(8, 24));
        }
 
        [Fact]
        public void Local_SequencePoints()
        {
            var source =
@"using System;
ref struct R<T>
{
    public ref T F;
    public R(ref T t) { F = ref t; }
}
class Program
{
    static void Main()
    {
        int x = 1;
        scoped R<int> y = new R<int>(ref x);
        ref R<int> z = ref y;
        z.F = 2;
        Console.WriteLine(x);
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.DebugExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped);
            verifier.VerifyIL("Program.Main",
                source: source,
                sequencePoints: "Program.Main",
                expectedIL:
@"{
  // Code size       30 (0x1e)
  .maxstack  2
  .locals init (int V_0, //x
                R<int> V_1, //y
                R<int>& V_2) //z
  // sequence point: {
  IL_0000:  nop
  // sequence point: int x = 1;
  IL_0001:  ldc.i4.1
  IL_0002:  stloc.0
  // sequence point: scoped R<int> y = new R<int>(ref x);
  IL_0003:  ldloca.s   V_0
  IL_0005:  newobj     ""R<int>..ctor(ref int)""
  IL_000a:  stloc.1
  // sequence point: ref R<int> z = ref y;
  IL_000b:  ldloca.s   V_1
  IL_000d:  stloc.2
  // sequence point: z.F = 2;
  IL_000e:  ldloc.2
  IL_000f:  ldfld      ""ref int R<int>.F""
  IL_0014:  ldc.i4.2
  IL_0015:  stind.i4
  // sequence point: Console.WriteLine(x);
  IL_0016:  ldloc.0
  IL_0017:  call       ""void System.Console.WriteLine(int)""
  IL_001c:  nop
  // sequence point: }
  IL_001d:  ret
}");
        }
 
        [Fact]
        public void SafeToEscape_01()
        {
            var source =
@"ref struct R<T> { }
class Program
{
    static R<int> F0(R<int> r0) => r0;
    static R<int> F1(scoped R<int> r1) => r1; // 1
    static R<int> F2(ref R<int> r2) => r2;
    static R<int> F3(scoped ref R<int> r3) => r3;
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (5,43): error CS8352: Cannot use variable 'scoped R<int> r1' in this context because it may expose referenced variables outside of their declaration scope
                //     static R<int> F1(scoped R<int> r1) => r1; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r1").WithArguments("scoped R<int> r1").WithLocation(5, 43));
        }
 
        [Fact]
        public void RefSafeToEscape_01()
        {
            var source =
@"ref struct R<T> { }
class Program
{
    static ref R<int> F0(R<int> r0) => ref r0; // 1
    static ref R<int> F1(scoped R<int> r1) => ref r1; // 2
    static ref R<int> F2(ref R<int> r2) => ref r2;
    static ref R<int> F3(scoped ref R<int> r3) => ref r3; // 3
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (4,44): error CS8166: Cannot return a parameter by reference 'r0' because it is not a ref parameter
                //     static ref R<int> F0(R<int> r0) => ref r0; // 1
                Diagnostic(ErrorCode.ERR_RefReturnParameter, "r0").WithArguments("r0").WithLocation(4, 44),
                // (5,51): error CS8166: Cannot return a parameter by reference 'r1' because it is not a ref parameter
                //     static ref R<int> F1(scoped R<int> r1) => ref r1; // 2
                Diagnostic(ErrorCode.ERR_RefReturnParameter, "r1").WithArguments("r1").WithLocation(5, 51),
                // (7,55): error CS9075: Cannot return a parameter by reference 'r3' because it is scoped to the current method
                //     static ref R<int> F3(scoped ref R<int> r3) => ref r3; // 3
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "r3").WithArguments("r3").WithLocation(7, 55));
        }
 
        [Fact]
        public void SafeToEscape_02()
        {
            var source =
@"ref struct R<T> { }
class Program
{
    static R<int> F0(R<int> r0)
    {
        R<int> l0 = r0;
        return l0;
    }
    static R<int> F1(scoped R<int> r1)
    {
        R<int> l1 = r1;
        return l1; // 1
    }
    static R<int> F2(ref R<int> r2)
    {
        R<int> l2 = r2;
        return l2;
    }
    static R<int> F3(scoped ref R<int> r3)
    {
        R<int> l3 = r3;
        return l3;
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (12,16): error CS8352: Cannot use variable 'l1' in this context because it may expose referenced variables outside of their declaration scope
                //         return l1; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "l1").WithArguments("l1").WithLocation(12, 16));
        }
 
        [Fact]
        public void RefSafeToEscape_02()
        {
            var source =
@"ref struct R<T> { }
class Program
{
    static ref R<int> F0(R<int> r0)
    {
        R<int> l0 = r0;
        return ref l0; // 1
    }
    static ref R<int> F1(scoped R<int> r1)
    {
        R<int> l1 = r1;
        return ref l1; // 2
    }
    static ref R<int> F2(ref R<int> r2)
    {
        R<int> l2 = r2;
        return ref l2; // 3
    }
    static ref R<int> F3(scoped ref R<int> r3)
    {
        R<int> l3 = r3;
        return ref l3; // 4
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,20): error CS8168: Cannot return local 'l0' by reference because it is not a ref local
                //         return ref l0; // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "l0").WithArguments("l0").WithLocation(7, 20),
                // (12,20): error CS8168: Cannot return local 'l1' by reference because it is not a ref local
                //         return ref l1; // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "l1").WithArguments("l1").WithLocation(12, 20),
                // (17,20): error CS8168: Cannot return local 'l2' by reference because it is not a ref local
                //         return ref l2; // 3
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "l2").WithArguments("l2").WithLocation(17, 20),
                // (22,20): error CS8168: Cannot return local 'l3' by reference because it is not a ref local
                //         return ref l3; // 4
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "l3").WithArguments("l3").WithLocation(22, 20));
        }
 
        [Fact]
        public void SafeToEscape_03()
        {
            var source =
@"ref struct R<T> { }
class Program
{
    static R<int> F0(R<int> r0)
    {
        scoped R<int> l0 = r0;
        return l0; // 1
    }
    static R<int> F1(scoped R<int> r1)
    {
        scoped R<int> l1 = r1;
        return l1; // 2
    }
    static R<int> F2(ref R<int> r2)
    {
        scoped R<int> l2 = r2;
        return l2; // 3
    }
    static R<int> F3(scoped ref R<int> r3)
    {
        scoped R<int> l3 = r3;
        return l3; // 4
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,16): error CS8352: Cannot use variable 'l0' in this context because it may expose referenced variables outside of their declaration scope
                //         return l0; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "l0").WithArguments("l0").WithLocation(7, 16),
                // (12,16): error CS8352: Cannot use variable 'l1' in this context because it may expose referenced variables outside of their declaration scope
                //         return l1; // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "l1").WithArguments("l1").WithLocation(12, 16),
                // (17,16): error CS8352: Cannot use variable 'l2' in this context because it may expose referenced variables outside of their declaration scope
                //         return l2; // 3
                Diagnostic(ErrorCode.ERR_EscapeVariable, "l2").WithArguments("l2").WithLocation(17, 16),
                // (22,16): error CS8352: Cannot use variable 'l3' in this context because it may expose referenced variables outside of their declaration scope
                //         return l3; // 4
                Diagnostic(ErrorCode.ERR_EscapeVariable, "l3").WithArguments("l3").WithLocation(22, 16));
        }
 
        [Fact]
        public void RefSafeToEscape_03()
        {
            var source =
@"ref struct R<T> { }
class Program
{
    static ref R<int> F0(R<int> r0)
    {
        scoped R<int> l0 = r0;
        return ref l0; // 1
    }
    static ref R<int> F1(scoped R<int> r1)
    {
        scoped R<int> l1 = r1;
        return ref l1; // 2
    }
    static ref R<int> F2(ref R<int> r2)
    {
        scoped R<int> l2 = r2;
        return ref l2; // 3
    }
    static ref R<int> F3(scoped ref R<int> r3)
    {
        scoped R<int> l3 = r3;
        return ref l3; // 4
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,20): error CS8168: Cannot return local 'l0' by reference because it is not a ref local
                //         return ref l0; // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "l0").WithArguments("l0").WithLocation(7, 20),
                // (12,20): error CS8168: Cannot return local 'l1' by reference because it is not a ref local
                //         return ref l1; // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "l1").WithArguments("l1").WithLocation(12, 20),
                // (17,20): error CS8168: Cannot return local 'l2' by reference because it is not a ref local
                //         return ref l2; // 3
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "l2").WithArguments("l2").WithLocation(17, 20),
                // (22,20): error CS8168: Cannot return local 'l3' by reference because it is not a ref local
                //         return ref l3; // 4
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "l3").WithArguments("l3").WithLocation(22, 20));
        }
 
        [Fact]
        public void SafeToEscape_04()
        {
            var source =
@"ref struct R<T> { }
class Program
{
    static R<int> F0(R<int> r0)
    {
        ref R<int> l0 = ref r0;
        return l0;
    }
    static R<int> F1(scoped R<int> r1)
    {
        ref R<int> l1 = ref r1;
        return l1; // 1
    }
    static R<int> F2(ref R<int> r2)
    {
        ref R<int> l2 = ref r2;
        return l2;
    }
    static R<int> F3(scoped ref R<int> r3)
    {
        ref R<int> l3 = ref r3;
        return l3;
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (12,16): error CS8352: Cannot use variable 'l1' in this context because it may expose referenced variables outside of their declaration scope
                //         return l1; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "l1").WithArguments("l1").WithLocation(12, 16));
        }
 
        [Fact]
        public void RefSafeToEscape_04()
        {
            var source =
@"ref struct R<T> { }
class Program
{
    static ref R<int> F0(R<int> r0)
    {
        ref R<int> l0 = ref r0;
        return ref l0; // 1
    }
    static ref R<int> F1(scoped R<int> r1)
    {
        ref R<int> l1 = ref r1;
        return ref l1; // 2
    }
    static ref R<int> F2(ref R<int> r2)
    {
        ref R<int> l2 = ref r2;
        return ref l2;
    }
    static ref R<int> F3(scoped ref R<int> r3)
    {
        ref R<int> l3 = ref r3;
        return ref l3; // 3
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,20): error CS8157: Cannot return 'l0' by reference because it was initialized to a value that cannot be returned by reference
                //         return ref l0; // 1
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "l0").WithArguments("l0").WithLocation(7, 20),
                // (12,20): error CS8157: Cannot return 'l1' by reference because it was initialized to a value that cannot be returned by reference
                //         return ref l1; // 2
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "l1").WithArguments("l1").WithLocation(12, 20),
                // (22,20): error CS8157: Cannot return 'l3' by reference because it was initialized to a value that cannot be returned by reference
                //         return ref l3; // 3
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "l3").WithArguments("l3").WithLocation(22, 20));
        }
 
        [Fact]
        public void SafeToEscape_05()
        {
            var source =
@"ref struct R<T> { }
class Program
{
    static R<int> F0(R<int> r0)
    {
        scoped ref R<int> l0 = ref r0;
        return l0;
    }
    static R<int> F1(scoped R<int> r1)
    {
        scoped ref R<int> l1 = ref r1; // 1
        return l1;
    }
    static R<int> F2(ref R<int> r2)
    {
        scoped ref R<int> l2 = ref r2;
        return l2;
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (11,36): error CS8352: Cannot use variable 'scoped R<int> r1' in this context because it may expose referenced variables outside of their declaration scope
                //         scoped ref R<int> l1 = ref r1; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r1").WithArguments("scoped R<int> r1").WithLocation(11, 36));
        }
 
        [Fact]
        public void RefSafeToEscape_05()
        {
            var source =
@"ref struct R<T> { }
class Program
{
    static ref R<int> F0(R<int> r0)
    {
        scoped ref R<int> l0 = ref r0;
        return ref l0; // 1
    }
    static ref R<int> F1(scoped R<int> r1)
    {
        scoped ref R<int> l1 = ref r1; // 2
        return ref l1; // 3
    }
    static ref R<int> F2(ref R<int> r2)
    {
        scoped ref R<int> l2 = ref r2;
        return ref l2; // 4
    }
    static ref R<int> F3(scoped ref R<int> r3)
    {
        scoped ref R<int> l3 = ref r3;
        return ref l3; // 5
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,20): error CS8157: Cannot return 'l0' by reference because it was initialized to a value that cannot be returned by reference
                //         return ref l0; // 1
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "l0").WithArguments("l0").WithLocation(7, 20),
                // (11,36): error CS8352: Cannot use variable 'scoped R<int> r1' in this context because it may expose referenced variables outside of their declaration scope
                //         scoped ref R<int> l1 = ref r1; // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r1").WithArguments("scoped R<int> r1").WithLocation(11, 36),
                // (12,20): error CS8157: Cannot return 'l1' by reference because it was initialized to a value that cannot be returned by reference
                //         return ref l1; // 3
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "l1").WithArguments("l1").WithLocation(12, 20),
                // (17,20): error CS8157: Cannot return 'l2' by reference because it was initialized to a value that cannot be returned by reference
                //         return ref l2; // 4
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "l2").WithArguments("l2").WithLocation(17, 20),
                // (22,20): error CS8157: Cannot return 'l3' by reference because it was initialized to a value that cannot be returned by reference
                //         return ref l3; // 5
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "l3").WithArguments("l3").WithLocation(22, 20));
        }
 
        [Fact]
        public void ReturnValueField_01()
        {
            var source =
@"ref struct R<T>
{
    public T F;
    public T GetValue() => F;
    public ref T GetRef() => ref F; // 1
    public ref readonly T GetRefReadonly() => ref F; // 2
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (5,34): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //     public ref T GetRef() => ref F; // 1
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "F").WithLocation(5, 34),
                // (6,51): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //     public ref readonly T GetRefReadonly() => ref F; // 2
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "F").WithLocation(6, 51));
        }
 
        [Fact]
        public void ReturnValueField_02()
        {
            var source =
@"struct S<T>
{
    public T F;
    public T GetValue() => F;
    public ref T GetRef() => ref F; // 1
    public ref readonly T GetRefReadonly() => ref F; // 2
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (5,34): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //     public ref T GetRef() => ref F; // 1
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "F").WithLocation(5, 34),
                // (6,51): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //     public ref readonly T GetRefReadonly() => ref F; // 2
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "F").WithLocation(6, 51));
        }
 
        [Fact]
        public void ReturnRefField()
        {
            var source =
@"ref struct R<T>
{
    public ref T F;
    public T GetValue() => F;
    public ref T GetRef() => ref F;
    public ref readonly T GetRefReadonly() => ref F;
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void ReturnRefReadonlyField()
        {
            var source =
@"ref struct R<T>
{
    public ref readonly T F;
    public T GetValue() => F;
    public ref T GetRef() => ref F; // 1
    public ref readonly T GetRefReadonly() => ref F;
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (5,34): error CS8333: Cannot return field 'F' by writable reference because it is a readonly variable
                //     public ref T GetRef() => ref F; // 1
                Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "F").WithArguments("field", "F").WithLocation(5, 34));
        }
 
        [Fact]
        public void ReturnValueFieldByValue()
        {
            var source =
@"#pragma warning disable 649
ref struct R<T>
{
    public T F;
}
class Program
{
    static T F0<T>(R<T> r0) => r0.F;
    static T F1<T>(scoped R<T> r1) => r1.F;
    static T F2<T>(ref R<T> r2) => r2.F;
    static T F3<T>(scoped ref R<T> r3) => r3.F;
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void ReturnValueFieldByRef()
        {
            var source =
@"ref struct R<T>
{
    public T F;
}
class Program
{
    static ref T F0<T>(R<T> r0) => ref r0.F; // 1
    static ref T F1<T>(scoped R<T> r1) => ref r1.F; // 2
    static ref T F2<T>(ref R<T> r2) => ref r2.F;
    static ref T F3<T>(scoped ref R<T> r3) => ref r3.F; // 3
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,40): error CS8167: Cannot return by reference a member of parameter 'r0' because it is not a ref or out parameter
                //     static ref T F0<T>(R<T> r0) => ref r0.F; // 1
                Diagnostic(ErrorCode.ERR_RefReturnParameter2, "r0").WithArguments("r0").WithLocation(7, 40),
                // (8,47): error CS8167: Cannot return by reference a member of parameter 'r1' because it is not a ref or out parameter
                //     static ref T F1<T>(scoped R<T> r1) => ref r1.F; // 2
                Diagnostic(ErrorCode.ERR_RefReturnParameter2, "r1").WithArguments("r1").WithLocation(8, 47),
                // (10,51): error CS9076: Cannot return by reference a member of parameter 'r3' because it is scoped to the current method
                //     static ref T F3<T>(scoped ref R<T> r3) => ref r3.F; // 3
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter2, "r3").WithArguments("r3").WithLocation(10, 51));
 
            // https://github.com/dotnet/roslyn/issues/62780: Test additional cases with [UnscopedRef].
        }
 
        [Fact]
        public void RefAssignMemberOfReturnOnlyParameter()
        {
            var source = @"
ref struct RS1
{
    public int I1;
}
 
ref struct RS2
{
    public ref int I2;
}
 
class Program
{
    static void M(ref RS1 rs, ref RS2 rs2)
    {
        rs2 = new RS2 { I2 = ref rs.I1 };
    }
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (16,34): error CS9078: Cannot return by reference a member of parameter 'rs' through a ref parameter; it can only be returned in a return statement
                //         rs2 = new RS2 { I2 = ref rs.I1 };
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter2, "rs").WithArguments("rs").WithLocation(16, 34)
                );
        }
 
        [Fact]
        public void RefAssignMemberOfReturnOnlyParameter_UnsafeContext()
        {
            var source = @"
ref struct RS1
{
    public int I1;
}
 
ref struct RS2
{
    public ref int I2;
}
 
class Program
{
    static unsafe void M(ref RS1 rs, ref RS2 rs2)
    {
        rs2 = new RS2 { I2 = ref rs.I1 };
    }
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }, targetFramework: TargetFramework.Net70, options: TestOptions.UnsafeDebugDll);
            comp.VerifyDiagnostics(
                // (16,34): warning CS9095: This returns by reference a member of parameter 'rs' through a ref parameter; but it can only safely be returned in a return statement
                //         rs2 = new RS2 { I2 = ref rs.I1 };
                Diagnostic(ErrorCode.WRN_RefReturnOnlyParameter2, "rs").WithArguments("rs").WithLocation(16, 34)
                );
        }
 
        [Fact]
        public void ReturnValueFieldByRef_UnsafeContext()
        {
            var source =
@"ref struct R<T>
{
    public T F;
}
unsafe class Program
{
    static ref T F0<T>(R<T> r0) => ref r0.F; // 1
    static ref T F1<T>(scoped R<T> r1) => ref r1.F; // 2
    static ref T F2<T>(ref R<T> r2) => ref r2.F;
    static ref T F3<T>(scoped ref R<T> r3) => ref r3.F; // 3
}";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugDll);
            comp.VerifyDiagnostics(
                // (7,40): warning CS9089: This returns by reference a member of parameter 'r0' that is not a ref or out parameter
                //     static ref T F0<T>(R<T> r0) => ref r0.F; // 1
                Diagnostic(ErrorCode.WRN_RefReturnParameter2, "r0").WithArguments("r0").WithLocation(7, 40),
                // (8,47): warning CS9089: This returns by reference a member of parameter 'r1' that is not a ref or out parameter
                //     static ref T F1<T>(scoped R<T> r1) => ref r1.F; // 2
                Diagnostic(ErrorCode.WRN_RefReturnParameter2, "r1").WithArguments("r1").WithLocation(8, 47),
                // (10,51): warning CS9090: This returns by reference a member of parameter 'r3' that is scoped to the current method
                //     static ref T F3<T>(scoped ref R<T> r3) => ref r3.F; // 3
                Diagnostic(ErrorCode.WRN_RefReturnScopedParameter2, "r3").WithArguments("r3").WithLocation(10, 51));
 
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped);
            verifier.VerifyIL("Program.F0<T>", @"
{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  ldflda     ""T R<T>.F""
  IL_0007:  ret
}
");
            verifier.VerifyIL("Program.F2<T>", @"
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  ldflda     ""T R<T>.F""
  IL_0006:  ret
}
");
        }
 
        [Theory]
        [InlineData("ref         ")]
        [InlineData("ref readonly")]
        public void ReturnRefFieldByValue(string refOrRefReadonly)
        {
            var source =
$@"ref struct R<T>
{{
    public {refOrRefReadonly} T F;
    public R(ref T t) {{ F = ref t; }}
}}
class Program
{{
    static T F0<T>(R<T> r) => r.F;
    static T F1<T>(ref R<T> r) => r.F;
    static T F2<T>(out R<T> r) {{ r = default; return r.F; }}
    static T F3<T>(in R<T> r) => r.F;
    static T F4<T>(scoped R<T> r) => r.F;
    static T F5<T>(scoped ref R<T> r) => r.F;
    static T F6<T>(scoped out R<T> r) {{ r = default; return r.F; }}
    static T F7<T>(scoped in R<T> r) => r.F;
}}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
        }
 
        [Theory]
        [InlineData("ref         ")]
        [InlineData("ref readonly")]
        public void ReturnRefFieldByRef_01(string refOrRefReadonly)
        {
            var source =
$@"ref struct R<T>
{{
    public {refOrRefReadonly} T F;
    public R(ref T t) {{ F = ref t; }}
}}
class Program
{{
    static {refOrRefReadonly} T F0<T>(R<T> r) => ref r.F;
    static {refOrRefReadonly} T F1<T>(ref R<T> r) => ref r.F;
    static {refOrRefReadonly} T F2<T>(out R<T> r) {{ r = default; return ref r.F; }}
    static {refOrRefReadonly} T F3<T>(in R<T> r) => ref r.F;
    static {refOrRefReadonly} T F4<T>(scoped R<T> r) => ref r.F; // 1
    static {refOrRefReadonly} T F5<T>(scoped ref R<T> r) => ref r.F;
    static {refOrRefReadonly} T F6<T>(scoped out R<T> r) {{ r = default; return ref r.F; }}
    static {refOrRefReadonly} T F7<T>(scoped in R<T> r) => ref r.F;
}}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (12,55): error CS8352: Cannot use variable 'scoped R<T> r' in this context because it may expose referenced variables outside of their declaration scope
                //     static ref          T F4<T>(scoped R<T> r) => ref r.F; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r.F").WithArguments("scoped R<T> r").WithLocation(12, 55));
        }
 
        [Fact]
        public void ReturnRefFieldByRef_02()
        {
            var source =
@"ref struct R<T>
{
    public ref readonly T F;
    public R(ref T t) { F = ref t; }
}
class Program
{
    static ref readonly T F1<T>(scoped ref T t)
    {
        R<T> r1 = new R<T>(ref t);
        return ref r1.F; // 1
    }
    static ref readonly T F2<T>(scoped ref T t)
    {
        R<T> r2;
        r2 = new R<T>(ref t); // 2
        return ref r2.F;
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (11,20): error CS8352: Cannot use variable 'r1' in this context because it may expose referenced variables outside of their declaration scope
                //         return ref r1.F; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r1.F").WithArguments("r1").WithLocation(11, 20),
                // (16,14): error CS8347: Cannot use a result of 'R<T>.R(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         r2 = new R<T>(ref t); // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R<T>(ref t)").WithArguments("R<T>.R(ref T)", "t").WithLocation(16, 14),
                // (16,27): error CS9075: Cannot return a parameter by reference 't' because it is scoped to the current method
                //         r2 = new R<T>(ref t); // 2
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "t").WithArguments("t").WithLocation(16, 27));
        }
 
        [Fact]
        public void ReturnRefFieldByRef_03()
        {
            var source =
@"ref struct R<T>
{
    public ref readonly T F;
    public R(in T t) { F = ref t; }
}
class Program
{
    static ref readonly T F1<T>(scoped in T t)
    {
        R<T> r1 = new R<T>(t);
        return ref r1.F; // 1
    }
    static ref readonly T F2<T>(scoped in T t)
    {
        R<T> r2 = new R<T>(in t);
        return ref r2.F; // 2
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (11,20): error CS8352: Cannot use variable 'r1' in this context because it may expose referenced variables outside of their declaration scope
                //         return ref r1.F; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r1.F").WithArguments("r1").WithLocation(11, 20),
                // (16,20): error CS8352: Cannot use variable 'r2' in this context because it may expose referenced variables outside of their declaration scope
                //         return ref r2.F; // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r2.F").WithArguments("r2").WithLocation(16, 20));
        }
 
        [Fact]
        public void ReturnRefStructFieldByValue_01()
        {
            var source =
@"ref struct R<T>
{
    public ref T F;
    public R(ref T t) { F = ref t; }
}
class Program
{
    static R<T> F1<T>(ref T t) => new R<T>(ref t);
    static R<T> F2<T>(out T t, T tValue) { t = tValue; return new R<T>(ref t); } // 1
    static R<T> F3<T>(scoped ref T t) => new R<T>(ref t); // 2
    static R<T> F4<T>(scoped out T t, T tValue) { t = tValue; return new R<T>(ref t); } // 3
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (9,63): error CS8347: Cannot use a result of 'R<T>.R(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static R<T> F2<T>(out T t, T tValue) { t = tValue; return new R<T>(ref t); } // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R<T>(ref t)").WithArguments("R<T>.R(ref T)", "t").WithLocation(9, 63),
                // (9,76): error CS9075: Cannot return a parameter by reference 't' because it is scoped to the current method
                //     static R<T> F2<T>(out T t, T tValue) { t = tValue; return new R<T>(ref t); } // 1
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "t").WithArguments("t").WithLocation(9, 76),
                // (10,42): error CS8347: Cannot use a result of 'R<T>.R(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static R<T> F3<T>(scoped ref T t) => new R<T>(ref t); // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R<T>(ref t)").WithArguments("R<T>.R(ref T)", "t").WithLocation(10, 42),
                // (10,55): error CS9075: Cannot return a parameter by reference 't' because it is scoped to the current method
                //     static R<T> F3<T>(scoped ref T t) => new R<T>(ref t); // 2
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "t").WithArguments("t").WithLocation(10, 55),
                // (11,70): error CS8347: Cannot use a result of 'R<T>.R(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     static R<T> F4<T>(scoped out T t, T tValue) { t = tValue; return new R<T>(ref t); } // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R<T>(ref t)").WithArguments("R<T>.R(ref T)", "t").WithLocation(11, 70),
                // (11,83): error CS9075: Cannot return a parameter by reference 't' because it is scoped to the current method
                //     static R<T> F4<T>(scoped out T t, T tValue) { t = tValue; return new R<T>(ref t); } // 3
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "t").WithArguments("t").WithLocation(11, 83));
        }
 
        [Fact]
        public void ReturnRefStructFieldByValue_02()
        {
            var source =
@"ref struct R0<T>
{
    public ref T F0;
    public R0(ref T t) { F0 = ref t; }
}
ref struct R1<T>
{
    public R0<T> F1;
    public R1(ref T t) { F1 = new R0<T>(ref t); }
}
class Program
{
    static R0<T> F0<T>(R1<T> r0) => r0.F1;
    static R0<T> F1<T>(scoped R1<T> r1) => r1.F1; // 1
    static R0<T> F2<T>(ref R1<T> r2) => r2.F1;
    static R0<T> F3<T>(scoped ref R1<T> r3) => r3.F1;
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (14,44): error CS8352: Cannot use variable 'scoped R1<T> r1' in this context because it may expose referenced variables outside of their declaration scope
                //     static R0<T> F1<T>(scoped R1<T> r1) => r1.F1; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r1.F1").WithArguments("scoped R1<T> r1").WithLocation(14, 44));
        }
 
        [Fact]
        public void ReturnRefStructFieldByRef()
        {
            var source =
@"ref struct R0<T>
{
    public ref T F0;
    public R0(ref T t) { F0 = ref t; }
}
ref struct R1<T>
{
    public R0<T> F1;
    public R1(ref T t) { F1 = new R0<T>(ref t); }
}
class Program
{
    static ref R0<T> F0<T>(R1<T> r0) => ref r0.F1; // 1
    static ref R0<T> F1<T>(scoped R1<T> r1) => ref r1.F1; // 2
    static ref R0<T> F2<T>(ref R1<T> r2) => ref r2.F1;
    static ref R0<T> F3<T>(scoped ref R1<T> r3) => ref r3.F1; // 3
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (13,45): error CS8167: Cannot return by reference a member of parameter 'r0' because it is not a ref or out parameter
                //     static ref R0<T> F0<T>(R1<T> r0) => ref r0.F1; // 1
                Diagnostic(ErrorCode.ERR_RefReturnParameter2, "r0").WithArguments("r0").WithLocation(13, 45),
                // (14,52): error CS8167: Cannot return by reference a member of parameter 'r1' because it is not a ref or out parameter
                //     static ref R0<T> F1<T>(scoped R1<T> r1) => ref r1.F1; // 2
                Diagnostic(ErrorCode.ERR_RefReturnParameter2, "r1").WithArguments("r1").WithLocation(14, 52),
                // (16,56): error CS9076: Cannot return by reference a member of parameter 'r3' because it is scoped to the current method
                //     static ref R0<T> F3<T>(scoped ref R1<T> r3) => ref r3.F1; // 3
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter2, "r3").WithArguments("r3").WithLocation(16, 56));
        }
 
        [Fact]
        public void ReturnRefFieldFromCaller()
        {
            var source =
@"ref struct R<T>
{
    public ref T F;
    public R(ref T t) { F = ref t; }
}
class Program
{
    static ref T F0<T>(R<T> r0)
    {
        return ref r0.F;
    }
    static ref T F1<T>()
    {
        return ref F0(new R<T>()); // ok, returns null
    }
    static ref T F2<T>()
    {
        T t = default;
        return ref F0(new R<T>(ref t)); // error
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (19,20): error CS8347: Cannot use a result of 'Program.F0<T>(R<T>)' in this context because it may expose variables referenced by parameter 'r0' outside of their declaration scope
                //         return ref F0(new R<T>(ref t)); // error
                Diagnostic(ErrorCode.ERR_EscapeCall, "F0(new R<T>(ref t))").WithArguments("Program.F0<T>(R<T>)", "r0").WithLocation(19, 20),
                // (19,23): error CS8347: Cannot use a result of 'R<T>.R(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         return ref F0(new R<T>(ref t)); // error
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R<T>(ref t)").WithArguments("R<T>.R(ref T)", "t").WithLocation(19, 23),
                // (19,36): error CS8168: Cannot return local 't' by reference because it is not a ref local
                //         return ref F0(new R<T>(ref t)); // error
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t").WithArguments("t").WithLocation(19, 36));
        }
 
        [Fact]
        public void PropertyReturnValue_01()
        {
            var source =
@"ref struct R
{
    private ref int _i;
    public R(ref int i) { _i = ref i; }
}
class C
{
    R this[R x, R y] => x;
    R F1(R x1, R y1)
    {
        return this[x1, y1];
    }
    R F2(R x2)
    {
        int i2 = 0;
        return this[x2, new R(ref i2)]; // 1
    }
    static R F3(C c, R x3, R y3)
    {
        return c[x3, y3];
    }
    static R F4(C c, R y4)
    {
        int i4 = 0;
        return c[new R(ref i4), y4]; // 2
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (16,16): error CS8347: Cannot use a result of 'C.this[R, R]' in this context because it may expose variables referenced by parameter 'y' outside of their declaration scope
                //         return this[x2, new R(ref i2)]; // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "this[x2, new R(ref i2)]").WithArguments("C.this[R, R]", "y").WithLocation(16, 16),
                // (16,25): error CS8347: Cannot use a result of 'R.R(ref int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         return this[x2, new R(ref i2)]; // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R(ref i2)").WithArguments("R.R(ref int)", "i").WithLocation(16, 25),
                // (16,35): error CS8168: Cannot return local 'i2' by reference because it is not a ref local
                //         return this[x2, new R(ref i2)]; // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i2").WithArguments("i2").WithLocation(16, 35),
                // (25,16): error CS8347: Cannot use a result of 'C.this[R, R]' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //         return c[new R(ref i4), y4]; // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "c[new R(ref i4), y4]").WithArguments("C.this[R, R]", "x").WithLocation(25, 16),
                // (25,18): error CS8347: Cannot use a result of 'R.R(ref int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         return c[new R(ref i4), y4]; // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R(ref i4)").WithArguments("R.R(ref int)", "i").WithLocation(25, 18),
                // (25,28): error CS8168: Cannot return local 'i4' by reference because it is not a ref local
                //         return c[new R(ref i4), y4]; // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i4").WithArguments("i4").WithLocation(25, 28));
        }
 
        [Fact]
        public void PropertyReturnValue_02()
        {
            var source =
@"ref struct R
{
    private ref readonly int _i;
    public R(in int i) { _i = ref i; }
}
class C
{
    R this[in int x, in int y] => new R(x);
    R F1(in int x1, in int y1)
    {
        return this[x1, y1];
    }
    R F2(in int x2)
    {
        int y2 = 0;
        return this[x2, y2]; // 1
    }
    static R F3(C c, in int x3, in int y3)
    {
        return c[x3, y3];
    }
    static R F4(C c, in int y4)
    {
        int x4 = 0;
        return c[x4, y4]; // 2
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (16,16): error CS8347: Cannot use a result of 'C.this[in int, in int]' in this context because it may expose variables referenced by parameter 'y' outside of their declaration scope
                //         return this[x2, y2]; // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "this[x2, y2]").WithArguments("C.this[in int, in int]", "y").WithLocation(16, 16),
                // (16,25): error CS8168: Cannot return local 'y2' by reference because it is not a ref local
                //         return this[x2, y2]; // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "y2").WithArguments("y2").WithLocation(16, 25),
                // (25,16): error CS8347: Cannot use a result of 'C.this[in int, in int]' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //         return c[x4, y4]; // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "c[x4, y4]").WithArguments("C.this[in int, in int]", "x").WithLocation(25, 16),
                // (25,18): error CS8168: Cannot return local 'x4' by reference because it is not a ref local
                //         return c[x4, y4]; // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "x4").WithArguments("x4").WithLocation(25, 18));
        }
 
        [Fact]
        public void PropertyReturnValue_03()
        {
            var source =
@"ref struct R
{
    public ref int _i;
    public R(ref int i) { _i = ref i; }
}
class C
{
    ref int this[R x, R y] => ref x._i;
    ref int F1(R x1, R y1)
    {
        return ref this[x1, y1];
    }
    ref int F2(R x2)
    {
        int i2 = 0;
        return ref this[x2, new R(ref i2)]; // 1
    }
    static ref int F3(C c, R x3, R y3)
    {
        return ref c[x3, y3];
    }
    static ref int F4(C c, R y4)
    {
        int i4 = 0;
        return ref c[new R(ref i4), y4]; // 2
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (16,20): error CS8347: Cannot use a result of 'C.this[R, R]' in this context because it may expose variables referenced by parameter 'y' outside of their declaration scope
                //         return ref this[x2, new R(ref i2)]; // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "this[x2, new R(ref i2)]").WithArguments("C.this[R, R]", "y").WithLocation(16, 20),
                // (16,29): error CS8347: Cannot use a result of 'R.R(ref int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         return ref this[x2, new R(ref i2)]; // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R(ref i2)").WithArguments("R.R(ref int)", "i").WithLocation(16, 29),
                // (16,39): error CS8168: Cannot return local 'i2' by reference because it is not a ref local
                //         return ref this[x2, new R(ref i2)]; // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i2").WithArguments("i2").WithLocation(16, 39),
                // (25,20): error CS8347: Cannot use a result of 'C.this[R, R]' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //         return ref c[new R(ref i4), y4]; // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "c[new R(ref i4), y4]").WithArguments("C.this[R, R]", "x").WithLocation(25, 20),
                // (25,22): error CS8347: Cannot use a result of 'R.R(ref int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         return ref c[new R(ref i4), y4]; // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R(ref i4)").WithArguments("R.R(ref int)", "i").WithLocation(25, 22),
                // (25,32): error CS8168: Cannot return local 'i4' by reference because it is not a ref local
                //         return ref c[new R(ref i4), y4]; // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i4").WithArguments("i4").WithLocation(25, 32));
        }
 
        [Fact]
        public void PropertyReturnValue_04()
        {
            var source =
@"class C
{
    ref readonly int this[in int x, in int y] => ref x;
    ref readonly int F1(in int x1, in int y1)
    {
        return ref this[x1, y1];
    }
    ref readonly int F2(in int x2)
    {
        int y2 = 0;
        return ref this[x2, y2]; // 1
    }
    static ref readonly int F3(C c, in int x3, in int y3)
    {
        return ref c[x3, y3];
    }
    static ref readonly int F4(C c, in int y4)
    {
        int x4 = 0;
        return ref c[x4, y4]; // 2
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (11,20): error CS8347: Cannot use a result of 'C.this[in int, in int]' in this context because it may expose variables referenced by parameter 'y' outside of their declaration scope
                //         return ref this[x2, y2]; // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "this[x2, y2]").WithArguments("C.this[in int, in int]", "y").WithLocation(11, 20),
                // (11,29): error CS8168: Cannot return local 'y2' by reference because it is not a ref local
                //         return ref this[x2, y2]; // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "y2").WithArguments("y2").WithLocation(11, 29),
                // (20,20): error CS8347: Cannot use a result of 'C.this[in int, in int]' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //         return ref c[x4, y4]; // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "c[x4, y4]").WithArguments("C.this[in int, in int]", "x").WithLocation(20, 20),
                // (20,22): error CS8168: Cannot return local 'x4' by reference because it is not a ref local
                //         return ref c[x4, y4]; // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "x4").WithArguments("x4").WithLocation(20, 22));
        }
 
        [Fact]
        public void RefStructLocal_FromLocal_01()
        {
            var source =
@"ref struct R<T>
{
    public ref T F;
    public R(ref T t) { F = ref t; }
}
class Program
{
    static R<T> Create<T>() => new R<T>();
    static R<T> Create<T>(ref T t) => new R<T>(ref t);
    static void F<T>(T t) { }
    static T F1<T>()
    {
        T t = default;
        R<T> r1 = new R<T>(ref t);
        F(r1.F);
        return r1.F;
    }
    static T F2<T>()
    {
        T t = default;
        scoped R<T> r2 = new R<T>(ref t);
        F(r2.F);
        return r2.F;
    }
    static T F3<T>()
    {
        T t = default;
        R<T> r3 = new R<T>();
        r3.F = ref t;
        F(r3.F);
        return r3.F;
    }
    static T F4<T>()
    {
        T t = default;
        scoped R<T> r4 = new R<T>();
        r4.F = ref t;
        F(r4.F);
        return r4.F;
    }
    static T F5<T>()
    {
        T t = default;
        R<T> r5 = Create(ref t);
        F(r5.F);
        return r5.F;
    }
    static T F6<T>()
    {
        T t = default;
        scoped R<T> r6 = Create(ref t);
        F(r6.F);
        return r6.F;
    }
    static T F7<T>()
    {
        T t = default;
        R<T> r7 = Create<T>();
        r7.F = ref t;
        F(r7.F);
        return r7.F;
    }
    static T F8<T>()
    {
        T t = default;
        scoped R<T> r8 = Create<T>();
        r8.F = ref t;
        F(r8.F);
        return r8.F;
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (29,9): error CS8374: Cannot ref-assign 't' to 'F' because 't' has a narrower escape scope than 'F'.
                //         r3.F = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r3.F = ref t").WithArguments("F", "t").WithLocation(29, 9),
                // (59,9): error CS8374: Cannot ref-assign 't' to 'F' because 't' has a narrower escape scope than 'F'.
                //         r7.F = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r7.F = ref t").WithArguments("F", "t").WithLocation(59, 9)
                );
        }
 
        [Fact]
        public void RefStructLocal_FromParameter_01()
        {
            var source =
@"ref struct R<T>
{
    public ref T F;
    public R(ref T t) { F = ref t; }
}
class Program
{
    static R<T> Create<T>() => new R<T>();
    static R<T> Create<T>(ref T t) => new R<T>(ref t);
    static void F<T>(T t) { }
    static T F1<T>(T t)
    {
        R<T> r1 = new R<T>(ref t);
        F(r1.F);
        return r1.F;
    }
    static T F2<T>(T t)
    {
        scoped R<T> r2 = new R<T>(ref t);
        F(r2.F);
        return r2.F;
    }
    static T F3<T>(T t)
    {
        R<T> r3 = new R<T>();
        r3.F = ref t;
        F(r3.F);
        return r3.F;
    }
    static T F4<T>(T t)
    {
        scoped R<T> r4 = new R<T>();
        r4.F = ref t;
        F(r4.F);
        return r4.F;
    }
    static T F5<T>(T t)
    {
        R<T> r5 = Create(ref t);
        F(r5.F);
        return r5.F;
    }
    static T F6<T>(T t)
    {
        scoped R<T> r6 = Create(ref t);
        F(r6.F);
        return r6.F;
    }
    static T F7<T>(T t)
    {
        R<T> r7 = Create<T>();
        r7.F = ref t;
        F(r7.F);
        return r7.F;
    }
    static T F8<T>(T t)
    {
        scoped R<T> r8 = Create<T>();
        r8.F = ref t;
        F(r8.F);
        return r8.F;
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (26,9): error CS8374: Cannot ref-assign 't' to 'F' because 't' has a narrower escape scope than 'F'.
                //         r3.F = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r3.F = ref t").WithArguments("F", "t").WithLocation(26, 9),
                // (52,9): error CS8374: Cannot ref-assign 't' to 'F' because 't' has a narrower escape scope than 'F'.
                //         r7.F = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r7.F = ref t").WithArguments("F", "t").WithLocation(52, 9));
        }
 
        [Fact]
        public void RefStructLocal_FromLocal_02()
        {
            var source =
@"ref struct R<T>
{
    public ref T F;
    public R(ref T t) { F = ref t; }
}
class Program
{
    static R<T> Create<T>() => new R<T>();
    static R<T> Create<T>(ref T t) => new R<T>(ref t);
    static void F<T>(R<T> r) { }
    static R<T> F1<T>()
    {
        T t = default;
        R<T> r1 = new R<T>(ref t);
        F(r1);
        return r1;
    }
    static R<T> F2<T>()
    {
        T t = default;
        scoped R<T> r2 = new R<T>(ref t);
        F(r2);
        return r2;
    }
    static R<T> F3<T>()
    {
        T t = default;
        R<T> r3 = new R<T>();
        r3.F = ref t;
        F(r3);
        return r3;
    }
    static R<T> F4<T>()
    {
        T t = default;
        scoped R<T> r4 = new R<T>();
        r4.F = ref t;
        F(r4);
        return r4;
    }
    static R<T> F5<T>()
    {
        T t = default;
        R<T> r5 = Create(ref t);
        F(r5);
        return r5;
    }
    static R<T> F6<T>()
    {
        T t = default;
        scoped R<T> r6 = Create(ref t);
        F(r6);
        return r6;
    }
    static R<T> F7<T>()
    {
        T t = default;
        R<T> r7 = Create<T>();
        r7.F = ref t;
        F(r7);
        return r7;
    }
    static R<T> F8<T>()
    {
        T t = default;
        scoped R<T> r8 = Create<T>();
        r8.F = ref t;
        F(r8);
        return r8;
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (16,16): error CS8352: Cannot use variable 'r1' in this context because it may expose referenced variables outside of their declaration scope
                //         return r1;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r1").WithArguments("r1").WithLocation(16, 16),
                // (23,16): error CS8352: Cannot use variable 'r2' in this context because it may expose referenced variables outside of their declaration scope
                //         return r2;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r2").WithArguments("r2").WithLocation(23, 16),
                // (29,9): error CS8374: Cannot ref-assign 't' to 'F' because 't' has a narrower escape scope than 'F'.
                //         r3.F = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r3.F = ref t").WithArguments("F", "t").WithLocation(29, 9),
                // (39,16): error CS8352: Cannot use variable 'r4' in this context because it may expose referenced variables outside of their declaration scope
                //         return r4;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r4").WithArguments("r4").WithLocation(39, 16),
                // (46,16): error CS8352: Cannot use variable 'r5' in this context because it may expose referenced variables outside of their declaration scope
                //         return r5;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r5").WithArguments("r5").WithLocation(46, 16),
                // (53,16): error CS8352: Cannot use variable 'r6' in this context because it may expose referenced variables outside of their declaration scope
                //         return r6;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r6").WithArguments("r6").WithLocation(53, 16),
                // (59,9): error CS8374: Cannot ref-assign 't' to 'F' because 't' has a narrower escape scope than 'F'.
                //         r7.F = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r7.F = ref t").WithArguments("F", "t").WithLocation(59, 9),
                // (69,16): error CS8352: Cannot use variable 'r8' in this context because it may expose referenced variables outside of their declaration scope
                //         return r8;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r8").WithArguments("r8").WithLocation(69, 16));
        }
 
        [Fact]
        public void RefStructLocal_FromParameter_02()
        {
            var source =
@"ref struct R<T>
{
    public ref T F;
    public R(ref T t) { F = ref t; }
}
class Program
{
    static R<T> Create<T>() => new R<T>();
    static R<T> Create<T>(ref T t) => new R<T>(ref t);
    static void F<T>(R<T> r) { }
    static R<T> F1<T>(T t)
    {
        R<T> r1 = new R<T>(ref t);
        F(r1);
        return r1;
    }
    static R<T> F2<T>(T t)
    {
        scoped R<T> r2 = new R<T>(ref t);
        F(r2);
        return r2;
    }
    static R<T> F3<T>(T t)
    {
        R<T> r3 = new R<T>();
        r3.F = ref t;
        F(r3);
        return r3;
    }
    static R<T> F4<T>(T t)
    {
        scoped R<T> r4 = new R<T>();
        r4.F = ref t;
        F(r4);
        return r4;
    }
    static R<T> F5<T>(T t)
    {
        R<T> r5 = Create(ref t);
        F(r5);
        return r5;
    }
    static R<T> F6<T>(T t)
    {
        scoped R<T> r6 = Create(ref t);
        F(r6);
        return r6;
    }
    static R<T> F7<T>(T t)
    {
        R<T> r7 = Create<T>();
        r7.F = ref t;
        F(r7);
        return r7;
    }
    static R<T> F8<T>(T t)
    {
        scoped R<T> r8 = Create<T>();
        r8.F = ref t;
        F(r8);
        return r8;
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (15,16): error CS8352: Cannot use variable 'r1' in this context because it may expose referenced variables outside of their declaration scope
                //         return r1;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r1").WithArguments("r1").WithLocation(15, 16),
                // (21,16): error CS8352: Cannot use variable 'r2' in this context because it may expose referenced variables outside of their declaration scope
                //         return r2;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r2").WithArguments("r2").WithLocation(21, 16),
                // (26,9): error CS8374: Cannot ref-assign 't' to 'F' because 't' has a narrower escape scope than 'F'.
                //         r3.F = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r3.F = ref t").WithArguments("F", "t").WithLocation(26, 9),
                // (35,16): error CS8352: Cannot use variable 'r4' in this context because it may expose referenced variables outside of their declaration scope
                //         return r4;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r4").WithArguments("r4").WithLocation(35, 16),
                // (41,16): error CS8352: Cannot use variable 'r5' in this context because it may expose referenced variables outside of their declaration scope
                //         return r5;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r5").WithArguments("r5").WithLocation(41, 16),
                // (47,16): error CS8352: Cannot use variable 'r6' in this context because it may expose referenced variables outside of their declaration scope
                //         return r6;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r6").WithArguments("r6").WithLocation(47, 16),
                // (52,9): error CS8374: Cannot ref-assign 't' to 'F' because 't' has a narrower escape scope than 'F'.
                //         r7.F = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r7.F = ref t").WithArguments("F", "t").WithLocation(52, 9),
                // (61,16): error CS8352: Cannot use variable 'r8' in this context because it may expose referenced variables outside of their declaration scope
                //         return r8;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r8").WithArguments("r8").WithLocation(61, 16));
        }
 
        [Fact]
        public void LocalFromRvalueInvocation()
        {
            var source =
@"ref struct R<T> { }
class Program
{
    static R<T> Create<T>(scoped ref T t)
    {
        return default;
    }
    static R<T> CreateReadonly<T>(scoped in T t)
    {
        return default;
    }
    static void F0(string s0)
    {
        R<string> r0;
        r0 = Create(ref s0);
    }
    static void F1(ref string s1)
    {
        R<string> r1;
        r1 = Create(ref s1);
    }
    static void F2(out string s2)
    {
        s2 = null;
        R<string> r2;
        r2 = Create(ref s2);
    }
    static void F3(in string s3)
    {
        R<string> r3;
        r3 = CreateReadonly(in s3);
    }
    static void F4(scoped ref string s4)
    {
        R<string> r4;
        r4 = Create(ref s4);
    }
    static void F5(scoped out string s5)
    {
        s5 = null;
        R<string> r5;
        r5 = Create(ref s5);
    }
    static void F6(scoped in string s6)
    {
        R<string> r6;
        r6 = CreateReadonly(in s6);
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void This_FromLocal()
        {
            var source =
@"ref struct R<T>
{
    static R<T> Create() => new R<T>();
    static R<T> Create(ref T t) => new R<T>(ref t);
    static void M(R<T> r) { }
    private ref T F;
    public R(ref T t) { F = ref t; }
    public R(sbyte unused)
    {
        T t1 = default;
        this = new R<T>(ref t1);
        M(this);
    }
    public R(short unused)
    {
        T t2 = default;
        this = new R<T>();
        this.F = ref t2;
        M(this);
    }
    public R(int unused)
    {
        T t3 = default;
        this = Create(ref t3);
        M(this);
    }
    public R(long unused)
    {
        T t4 = default;
        this = Create();
        this.F = ref t4;
        M(this);
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (11,16): error CS8347: Cannot use a result of 'R<T>.R(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         this = new R<T>(ref t1);
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R<T>(ref t1)").WithArguments("R<T>.R(ref T)", "t").WithLocation(11, 16),
                // (11,29): error CS8168: Cannot return local 't1' by reference because it is not a ref local
                //         this = new R<T>(ref t1);
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t1").WithArguments("t1").WithLocation(11, 29),
                // (18,9): error CS8374: Cannot ref-assign 't2' to 'F' because 't2' has a narrower escape scope than 'F'.
                //         this.F = ref t2;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "this.F = ref t2").WithArguments("F", "t2").WithLocation(18, 9),
                // (24,16): error CS8347: Cannot use a result of 'R<T>.Create(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         this = Create(ref t3);
                Diagnostic(ErrorCode.ERR_EscapeCall, "Create(ref t3)").WithArguments("R<T>.Create(ref T)", "t").WithLocation(24, 16),
                // (24,27): error CS8168: Cannot return local 't3' by reference because it is not a ref local
                //         this = Create(ref t3);
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "t3").WithArguments("t3").WithLocation(24, 27),
                // (31,9): error CS8374: Cannot ref-assign 't4' to 'F' because 't4' has a narrower escape scope than 'F'.
                //         this.F = ref t4;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "this.F = ref t4").WithArguments("F", "t4").WithLocation(31, 9));
        }
 
        [Fact]
        public void This_FromParameter()
        {
            var source =
@"ref struct R<T>
{
    static R<T> Create() => new R<T>();
    static R<T> Create(ref T t) => new R<T>(ref t);
    static void M(R<T> r) { }
    private ref T F;
    R(ref T t) { F = ref t; }
    R(sbyte unused, T t1)
    {
        this = new R<T>(ref t1);
        M(this);
    }
    R(short unused, T t2)
    {
        this = new R<T>();
        this.F = ref t2;
        M(this);
    }
    R(int unused, T t3)
    {
        this = Create(ref t3);
        M(this);
    }
    R(long unused, T t4)
    {
        this = Create();
        this.F = ref t4;
        M(this);
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (10,16): error CS8347: Cannot use a result of 'R<T>.R(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         this = new R<T>(ref t1);
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R<T>(ref t1)").WithArguments("R<T>.R(ref T)", "t").WithLocation(10, 16),
                // (10,29): error CS8166: Cannot return a parameter by reference 't1' because it is not a ref parameter
                //         this = new R<T>(ref t1);
                Diagnostic(ErrorCode.ERR_RefReturnParameter, "t1").WithArguments("t1").WithLocation(10, 29),
                // (16,9): error CS8374: Cannot ref-assign 't2' to 'F' because 't2' has a narrower escape scope than 'F'.
                //         this.F = ref t2;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "this.F = ref t2").WithArguments("F", "t2").WithLocation(16, 9),
                // (21,16): error CS8347: Cannot use a result of 'R<T>.Create(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         this = Create(ref t3);
                Diagnostic(ErrorCode.ERR_EscapeCall, "Create(ref t3)").WithArguments("R<T>.Create(ref T)", "t").WithLocation(21, 16),
                // (21,27): error CS8166: Cannot return a parameter by reference 't3' because it is not a ref parameter
                //         this = Create(ref t3);
                Diagnostic(ErrorCode.ERR_RefReturnParameter, "t3").WithArguments("t3").WithLocation(21, 27),
                // (27,9): error CS8374: Cannot ref-assign 't4' to 'F' because 't4' has a narrower escape scope than 'F'.
                //         this.F = ref t4;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "this.F = ref t4").WithArguments("F", "t4").WithLocation(27, 9));
        }
 
        [Fact]
        public void This_FromRefParameter()
        {
            var source =
@"ref struct R<T>
{
    static void M(R<T> r) { }
    private ref T F;
    R(ref T t) { F = ref t; }
    R(sbyte unused, ref T t1)
    {
        this = new R<T>(ref t1);
        M(this);
    }
    R(short unused, scoped ref T t2)
    {
        this = new R<T>(ref t2);
        M(this);
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (13,16): error CS8347: Cannot use a result of 'R<T>.R(ref T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         this = new R<T>(ref t2);
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R<T>(ref t2)").WithArguments("R<T>.R(ref T)", "t").WithLocation(13, 16),
                // (13,29): error CS9075: Cannot return a parameter by reference 't2' because it is scoped to the current method
                //         this = new R<T>(ref t2);
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "t2").WithArguments("t2").WithLocation(13, 29));
        }
 
        [Fact]
        public void This_FromRefStructParameter()
        {
            var source =
@"ref struct R<T>
{
    static void M(R<T> r) { }
    private ref T F;
    R(sbyte unused, ref R<T> r1)
    {
        this = r1;
        M(this);
    }
    R(short unused, scoped ref R<T> r2)
    {
        this = r2;
        M(this);
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (4,19): warning CS0169: The field 'R<T>.F' is never used
                //     private ref T F;
                Diagnostic(ErrorCode.WRN_UnreferencedField, "F").WithArguments("R<T>.F").WithLocation(4, 19));
        }
 
        [WorkItem(63140, "https://github.com/dotnet/roslyn/issues/63140")]
        [Fact]
        public void Scoped_Cycle()
        {
            var source =
@"interface I
{
    void M<T>(T s);
}
 
class C : I
{
    void I.M<T>(scoped T? s) {}
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (6,11): error CS0535: 'C' does not implement interface member 'I.M<T>(T)'
                // class C : I
                Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I").WithArguments("C", "I.M<T>(T)").WithLocation(6, 11),
                // (8,12): error CS0539: 'C.M<T>(scoped T?)' in explicit interface declaration is not found among members of the interface that can be implemented
                //     void I.M<T>(scoped T? s) {}
                Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M").WithArguments("C.M<T>(scoped T?)").WithLocation(8, 12),
                // (8,17): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //     void I.M<T>(scoped T? s) {}
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "scoped T? s").WithLocation(8, 17),
                // (8,25): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     void I.M<T>(scoped T? s) {}
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(8, 25),
                // (8,27): error CS0453: The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'Nullable<T>'
                //     void I.M<T>(scoped T? s) {}
                Diagnostic(ErrorCode.ERR_ValConstraintNotSatisfied, "s").WithArguments("System.Nullable<T>", "T", "T").WithLocation(8, 27));
        }
 
        [Fact]
        public void NestedScope()
        {
            var source =
@"ref struct R<T>
{
    public ref T F;
}
class Program
{
    static T F<T>()
    {
        scoped R<T> r;
        {
            T t = default;
            r.F = ref t;
        }
        return r.F;
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (12,13): error CS8374: Cannot ref-assign 't' to 'F' because 't' has a narrower escape scope than 'F'.
                //             r.F = ref t;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r.F = ref t").WithArguments("F", "t").WithLocation(12, 13));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void InstanceMethodWithOutVar_01(LanguageVersion languageVersion)
        {
            var source =
@"using System;
ref struct R
{
    public R(Span<int> s) { }
    public void F(out R r) { r = default; }
}
class Program
{
    static void F(out R r)
    {
        Span<int> s1 = stackalloc int[10];
        R r1 = new R(s1);
        r1.F(out r);
    }
}";
            var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics(
                // (13,9): error CS8352: Cannot use variable 'r1' in this context because it may expose referenced variables outside of their declaration scope
                //         r1.F(out r);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r1").WithArguments("r1").WithLocation(13, 9),
                // (13,9): error CS8350: This combination of arguments to 'R.F(out R)' is disallowed because it may expose variables referenced by parameter 'this' outside of their declaration scope
                //         r1.F(out r);
                Diagnostic(ErrorCode.ERR_CallArgMixing, "r1.F(out r)").WithArguments("R.F(out R)", "this").WithLocation(13, 9));
        }
 
        [Fact]
        public void InstanceMethodWithOutVar_02()
        {
            var source =
@"ref struct R
{
    public ref int _i;
    public R(ref int i) { _i = ref i; }
    public void F(out R r) { r = new R(ref _i); }
}
class Program
{
    static void F(out R r)
    {
        int i = 0;
        R r1 = new R(ref i);
        r1.F(out r);
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (13,9): error CS8352: Cannot use variable 'r1' in this context because it may expose referenced variables outside of their declaration scope
                //         r1.F(out r);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r1").WithArguments("r1").WithLocation(13, 9),
                // (13,9): error CS8350: This combination of arguments to 'R.F(out R)' is disallowed because it may expose variables referenced by parameter 'this' outside of their declaration scope
                //         r1.F(out r);
                Diagnostic(ErrorCode.ERR_CallArgMixing, "r1.F(out r)").WithArguments("R.F(out R)", "this").WithLocation(13, 9));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void InstanceMethodWithOutVar_03(LanguageVersion languageVersion)
        {
            var source =
@"using System;
ref struct R
{
    public void F(out Span<int> s) { s = default; }
}
class Program
{
    static void Main()
    {
        Span<int> s = stackalloc int[10];
        R r = new R();
        r.F(out s);
    }
}";
            var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), targetFramework: TargetFramework.Net50);
            if (languageVersion == LanguageVersion.CSharp10)
            {
                comp.VerifyDiagnostics(
                    // (12,9): error CS8350: This combination of arguments to 'R.F(out Span<int>)' is disallowed because it may expose variables referenced by parameter 's' outside of their declaration scope
                    //         r.F(out s);
                    Diagnostic(ErrorCode.ERR_CallArgMixing, "r.F(out s)").WithArguments("R.F(out System.Span<int>)", "s").WithLocation(12, 9),
                    // (12,17): error CS8352: Cannot use variable 's' in this context because it may expose referenced variables outside of their declaration scope
                    //         r.F(out s);
                    Diagnostic(ErrorCode.ERR_EscapeVariable, "s").WithArguments("s").WithLocation(12, 17));
            }
            else
            {
                comp.VerifyDiagnostics();
            }
        }
 
        [WorkItem(63016, "https://github.com/dotnet/roslyn/issues/63016")]
        [Fact]
        public void RefToLocalFromInstanceMethod_01()
        {
            var source =
@"ref struct R
{
    private ref int _i;
    public void M1()
    {
        int i = 42;
        M2(ref i);
    }
    private void M2(ref int i)
    {
        _i = ref i;
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (11,9): error CS9079: Cannot ref-assign 'i' to '_i' because 'i' can only escape the current method through a return statement.
                //         _i = ref i;
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "_i = ref i").WithArguments("_i", "i").WithLocation(11, 9));
        }
 
        [WorkItem(63016, "https://github.com/dotnet/roslyn/issues/63016")]
        [Fact]
        public void RefToLocalFromInstanceMethod_02()
        {
            var sourceB =
@"using System;
ref struct S
{
    private ref int _i;
    public S(ref int i)
    {
        Span<int> s = stackalloc int[100];
        M2(ref s[0]);
    }
    private void M2(ref int i)
    {
        _i = ref i;
    }
}";
            var comp = CreateCompilation(sourceB, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (12,9): error CS9079: Cannot ref-assign 'i' to '_i' because 'i' can only escape the current method through a return statement.
                //         _i = ref i;
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "_i = ref i").WithArguments("_i", "i").WithLocation(12, 9));
        }
 
        [Fact]
        public void RefStructProperty_01()
        {
            var source =
@"ref struct R<T>
{
    public R(ref T t) { }
}
class C
{
    R<object> this[R<int> r] => default;
    static R<object> F1(C c)
    {
        int i = 1;
        var r1 = new R<int>(ref i);
        return c[r1]; // 1
    }
    static R<object> F2(C c)
    {
        var r2 = new R<int>();
        return c[r2];
    }
}";
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics();
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (12,16): error CS8347: Cannot use a result of 'C.this[R<int>]' in this context because it may expose variables referenced by parameter 'r' outside of their declaration scope
                //         return c[r1]; // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "c[r1]").WithArguments("C.this[R<int>]", "r").WithLocation(12, 16),
                // (12,18): error CS8352: Cannot use variable 'r1' in this context because it may expose referenced variables outside of their declaration scope
                //         return c[r1]; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r1").WithArguments("r1").WithLocation(12, 18));
        }
 
        [Fact]
        public void RefStructProperty_02()
        {
            var source =
@"ref struct R<T>
{
}
class C
{
    R<object> this[in int i] => default;
    static R<object> F1(C c)
    {
        int i1 = 1;
        return c[i1]; // 1
    }
    static R<object> F2(C c)
    {
        return c[2]; // 2
    }
    static R<object> F2(C c, in int i3)
    {
        return c[i3];
    }
}";
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics();
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (10,16): error CS8347: Cannot use a result of 'C.this[in int]' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         return c[i1]; // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "c[i1]").WithArguments("C.this[in int]", "i").WithLocation(10, 16),
                // (10,18): error CS8168: Cannot return local 'i1' by reference because it is not a ref local
                //         return c[i1]; // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i1").WithArguments("i1").WithLocation(10, 18),
                // (14,16): error CS8347: Cannot use a result of 'C.this[in int]' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         return c[2]; // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "c[2]").WithArguments("C.this[in int]", "i").WithLocation(14, 16),
                // (14,18): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                //         return c[2]; // 2
                Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "2").WithLocation(14, 18));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void ReturnThis_01(LanguageVersion languageVersion)
        {
            var source =
@"ref struct R
{
    R F1() => this;
    ref R F2() => ref this;
    ref readonly R F3() => ref this;
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics(
                // (4,23): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //     ref R F2() => ref this;
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "this").WithLocation(4, 23),
                // (5,32): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //     ref readonly R F3() => ref this;
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "this").WithLocation(5, 32));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void ReturnThis_02(LanguageVersion languageVersion)
        {
            var source =
@"readonly ref struct R
{
    R F1() => this;
    ref R F2() => ref this;
    ref readonly R F3() => ref this;
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics(
                // (4,23): error CS8354: Cannot return 'this' by reference.
                //     ref R F2() => ref this;
                Diagnostic(ErrorCode.ERR_RefReturnThis, "this").WithLocation(4, 23),
                // (5,32): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //     ref readonly R F3() => ref this;
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "this").WithLocation(5, 32));
        }
 
        [Fact, WorkItem(63526, "https://github.com/dotnet/roslyn/issues/63526")]
        public void ReturnThis_03()
        {
            var source = """
                using System.Diagnostics.CodeAnalysis;
 
                ref struct S2 {
                    public S S;
                }
 
                ref struct S {
                    public int field;
                    public ref int refField;
 
                    ref int Prop1 => ref field; // 1
 
                    [UnscopedRef]
                    ref int Prop2 => ref field; // okay
 
                    S2 Prop3 => new S2 { S = this }; // Okay
 
                    S Prop4 => new S { refField = ref this.field }; // 2
 
                    [UnscopedRef]
                    S Prop5 => new S { refField = ref this.field }; // okay
 
                    S M1() => new S { refField = ref this.field }; // 3
 
                    [UnscopedRef]
                    S M2() => new S { refField = ref this.field }; // okay
 
                    static S M3(scoped ref S s) => new S { refField = ref s.field }; // 4
 
                    static S M4(ref S s) => new S { refField = ref s.field }; // okay
                }
                """;
 
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (11,26): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //     ref int Prop1 => ref field; // 1
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "field").WithLocation(11, 26),
                // (18,24): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //     S Prop4 => new S { refField = ref this.field }; // 2
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "refField = ref this.field").WithLocation(18, 24),
                // (23,23): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //     S M1() => new S { refField = ref this.field }; // 3
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "refField = ref this.field").WithLocation(23, 23),
                // (28,59): error CS9076: Cannot return by reference a member of parameter 's' because it is scoped to the current method
                //     static S M3(scoped ref S s) => new S { refField = ref s.field }; // 4
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter2, "s").WithArguments("s").WithLocation(28, 59));
        }
 
        [Fact]
        public void RefInitializer_LangVer()
        {
            var source = @"
int x = 42;
var r = new R() { field = ref x };
 
ref struct R
{
    public ref int field;
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (7,12): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     public ref int field;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "ref int").WithArguments("ref fields", "11.0").WithLocation(7, 12)
                );
 
            comp = CreateCompilation(source, parseOptions: TestOptions.Regular11, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void RefInitializer_LangVer_FromMetadata()
        {
            var lib_cs = @"
public ref struct R
{
    public ref int field;
}
";
            var source = @"
int x = 42;
var r1 = new R() { field = ref x }; // 1
var r2 = new R() { field = x }; // 2
 
R r3 = default;
_ = r3 with { field = ref x }; // 3
";
            var lib = CreateCompilation(lib_cs, parseOptions: TestOptions.Regular11, targetFramework: TargetFramework.Net70);
 
            var comp = CreateCompilation(source, references: new[] { lib.EmitToImageReference() }, parseOptions: TestOptions.Regular10, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (3,20): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                // var r1 = new R() { field = ref x }; // 1
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "field").WithArguments("ref fields", "11.0").WithLocation(3, 20),
                // (4,20): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                // var r2 = new R() { field = x }; // 2
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "field").WithArguments("ref fields", "11.0").WithLocation(4, 20),
                // (7,15): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                // _ = r3 with { field = ref x }; // 3
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "field").WithArguments("ref fields", "11.0").WithLocation(7, 15)
                );
 
            comp = CreateCompilation(source, references: new[] { lib.EmitToImageReference() }, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(
                // (3,20): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                // var r1 = new R() { field = ref x }; // 1
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "field").WithArguments("ref fields", "11.0").WithLocation(3, 20),
                // (3,20): error CS9064: Target runtime doesn't support ref fields.
                // var r1 = new R() { field = ref x }; // 1
                Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportRefFields, "field").WithLocation(3, 20),
                // (4,20): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                // var r2 = new R() { field = x }; // 2
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "field").WithArguments("ref fields", "11.0").WithLocation(4, 20),
                // (4,20): error CS9064: Target runtime doesn't support ref fields.
                // var r2 = new R() { field = x }; // 2
                Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportRefFields, "field").WithLocation(4, 20),
                // (7,15): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                // _ = r3 with { field = ref x }; // 3
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "field").WithArguments("ref fields", "11.0").WithLocation(7, 15),
                // (7,15): error CS9064: Target runtime doesn't support ref fields.
                // _ = r3 with { field = ref x }; // 3
                Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportRefFields, "field").WithLocation(7, 15)
                );
        }
 
        [Fact]
        public void RefInitializer()
        {
            var source = @"
public class C
{
    public static void Main()
    {
        int x = 42;
        var r = new R() { field = ref x };
        System.Console.Write(r.ToString());
    }
}
 
ref struct R
{
    public ref int field;
    public override string ToString()
    {
        return field.ToString();
    }
}
";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("42"));
            verifier.VerifyIL("C.Main",
"""
{
  // Code size       41 (0x29)
  .maxstack  2
  .locals init (int V_0, //x
                R V_1, //r
                R V_2)
  IL_0000:  ldc.i4.s   42
  IL_0002:  stloc.0
  IL_0003:  ldloca.s   V_2
  IL_0005:  initobj    "R"
  IL_000b:  ldloca.s   V_2
  IL_000d:  ldloca.s   V_0
  IL_000f:  stfld      "ref int R.field"
  IL_0014:  ldloc.2
  IL_0015:  stloc.1
  IL_0016:  ldloca.s   V_1
  IL_0018:  constrained. "R"
  IL_001e:  callvirt   "string object.ToString()"
  IL_0023:  call       "void System.Console.Write(string)"
  IL_0028:  ret
}
""");
        }
 
        [Fact]
        public void RefInitializer_RHSMustBeDefinitelyAssigned()
        {
            // The right operand must be definitely assigned at the point of the ref assignment.
            var source = @"
int x;
var r = new R() { field = ref x };
 
ref struct R
{
    public ref int field;
    public override string ToString()
    {
        return field.ToString();
    }
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (3,31): error CS0165: Use of unassigned local variable 'x'
                // var r = new R() { field = ref x };
                Diagnostic(ErrorCode.ERR_UseDefViolation, "x").WithArguments("x").WithLocation(3, 31)
                );
        }
 
        [Fact]
        public void RefInitializer_RHSTypeMustMatch()
        {
            // The right operand must be an expression that yields an lvalue designating a value of the same type as the left operand.
            var source = @"
object x = null;
var r = new R() { field = ref x };
 
ref struct R
{
    public ref int field;
    public override string ToString()
    {
        return field.ToString();
    }
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (3,31): error CS8173: The expression must be of type 'int' because it is being assigned by reference
                // var r = new R() { field = ref x };
                Diagnostic(ErrorCode.ERR_RefAssignmentMustHaveIdentityConversion, "x").WithArguments("int").WithLocation(3, 31)
                );
        }
 
        [Fact]
        public void RefInitializer_RHSTypeMustMatch_ImplicitConversionExists()
        {
            // The right operand must be an expression that yields an lvalue designating a value of the same type as the left operand.
            var source = @"
S1 x = default;
var r = new R() { field = ref x };
 
struct S1 { }
struct S2
{
    public static implicit operator S2(S1 s1) => throw null;
}
ref struct R
{
    public ref S2 field;
    public override string ToString()
    {
        return field.ToString();
    }
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (3,31): error CS8173: The expression must be of type 'S2' because it is being assigned by reference
                // var r = new R() { field = ref x };
                Diagnostic(ErrorCode.ERR_RefAssignmentMustHaveIdentityConversion, "x").WithArguments("S2").WithLocation(3, 31)
                );
        }
 
        [Fact]
        public void RefInitializer_StaticRefField()
        {
            var source = @"
int x = 0;
var r = new R() { field = ref x };
 
ref struct R
{
    public static ref int field;
    public override string ToString()
    {
        return field.ToString();
    }
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (3,19): error CS1914: Static field or property 'R.field' cannot be assigned in an object initializer
                // var r = new R() { field = ref x };
                Diagnostic(ErrorCode.ERR_StaticMemberInObjectInitializer, "field").WithArguments("R.field").WithLocation(3, 19),
                // (7,27): error CS0106: The modifier 'static' is not valid for this item
                //     public static ref int field;
                Diagnostic(ErrorCode.ERR_BadMemberFlag, "field").WithArguments("static").WithLocation(7, 27)
                );
        }
 
        [Fact]
        public void RefInitializer_VarInvocationReserved()
        {
            var source = @"
var r = new R() { field = ref var() };
 
ref struct R
{
    public ref int field;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (2,31): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
                // var r = new R() { field = ref var() };
                Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var()").WithLocation(2, 31),
                // (2,31): error CS0103: The name 'var' does not exist in the current context
                // var r = new R() { field = ref var() };
                Diagnostic(ErrorCode.ERR_NameNotInContext, "var").WithArguments("var").WithLocation(2, 31)
                );
        }
 
        [Fact]
        public void RefInitializer_ReadonlyRefField()
        {
            var source = @"
int x = 42;
var r = new R() { field = ref x };
 
ref struct R
{
    public readonly ref int field;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (3,19): 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)
                // var r = new R() { field = ref x };
                Diagnostic(ErrorCode.ERR_AssgReadonly, "field").WithLocation(3, 19)
                );
        }
 
        [Fact]
        public void RefInitializer_RefReadonlyField()
        {
            var source = @"
int x = 42;
var r = new R() { field = ref x };
 
ref struct R
{
    public ref readonly int field;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void RefInitializer_RefReadonlyValue_Field()
        {
            // If the left operand is a writeable ref (i.e. it designates anything other than a `ref readonly` local or  `in` parameter), then the right operand must be a writeable lvalue.
            var source = @"
class C
{
    ref readonly int Value() => throw null;
 
    void M()
    {
        var r = new R() { field = ref Value() };
    }
}
 
ref struct R
{
    public ref int field;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (8,39): error CS8331: Cannot assign to method 'Value' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         var r = new R() { field = ref Value() };
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "Value()").WithArguments("method", "Value").WithLocation(8, 39)
                );
        }
 
        [Fact]
        public void RefInitializer_AssignInParameter()
        {
            var source = @"
class C
{
    static void F(in int i)
    {
        _ = new R1 { _f = ref i };
        _ = new R2 { _f = ref i }; // 1
    }
}
 
ref struct R1
{
    public ref readonly int _f;
}
 
ref struct R2
{
    public ref int _f;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (7,31): error CS8331: Cannot assign to variable 'i' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         _ = new R2 { _f = ref i }; // 1
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "i").WithArguments("variable", "i").WithLocation(7, 31)
                );
        }
 
        [Fact]
        public void RefInitializer_RefReadonlyValue_GetOnlyProperty()
        {
            var source = @"
class C
{
    ref readonly int Value() => throw null;
 
    void M()
    {
        var r = new R() { Property = ref Value() };
    }
}
 
ref struct R
{
    public ref int Property { get => throw null; }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (8,27): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         var r = new R() { Property = ref Value() };
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "Property").WithLocation(8, 27)
                );
        }
 
        [Fact]
        public void RefInitializer_RefReadonlyValue_Property()
        {
            var source = @"
class C
{
    ref readonly int Value() => throw null;
 
    void M()
    {
        var r = new R() { Property = ref Value() };
    }
}
 
ref struct R
{
    public ref int Property { get => throw null; set => throw null; }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (8,27): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         var r = new R() { Property = ref Value() };
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "Property").WithLocation(8, 27),
                // (14,50): error CS8147: Properties which return by reference cannot have set accessors
                //     public ref int Property { get => throw null; set => throw null; }
                Diagnostic(ErrorCode.ERR_RefPropertyCannotHaveSetAccessor, "set").WithLocation(14, 50)
                );
        }
 
        [Fact]
        public void RefInitializer_RefReadonlyValue_Indexer()
        {
            var source = @"
var r = new R() { [0] = ref Value() }; // 1
 
R r2 = default;
r2[0] = ref Value(); // 2
 
ref readonly int Value() => throw null;
 
ref struct R
{
    public ref int this[int i] { get => throw null; }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (2,19): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                // var r = new R() { [0] = ref Value() }; // 1
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "[0]").WithLocation(2, 19),
                // (5,1): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                // r2[0] = ref Value(); // 2
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "r2[0]").WithLocation(5, 1)
                );
        }
 
        [Fact]
        public void RefInitializer_Indexer()
        {
            var source = @"
var r = new R() { [0] = ref Value() }; // 1
 
R r2 = default;
r2[0] = ref Value(); // 2
 
ref int Value() => throw null;
 
ref struct R
{
    public ref int this[int i] { get => throw null; }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (2,19): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                // var r = new R() { [0] = ref Value() }; // 1
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "[0]").WithLocation(2, 19),
                // (5,1): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                // r2[0] = ref Value(); // 2
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "r2[0]").WithLocation(5, 1)
                );
        }
 
        [Fact]
        public void RefInitializer_ValueMustReferToLocation()
        {
            var source = @"
class C
{
    int Value() => throw null;
 
    void M()
    {
        var r = new R() { field = ref Value() };
    }
}
 
ref struct R
{
    public ref int field;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (8,39): error CS1510: A ref or out value must be an assignable variable
                //         var r = new R() { field = ref Value() };
                Diagnostic(ErrorCode.ERR_RefLvalueExpected, "Value()").WithLocation(8, 39)
                );
        }
 
        [Fact]
        public void RefInitializer_RefReadonlyField_RefReadonlyValue()
        {
            var source = @"
class C
{
    ref readonly int Value() => throw null;
 
    void M()
    {
        var r = new R() { field = ref Value() };
    }
}
 
ref struct R
{
    public ref readonly int field;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void RefInitializer_OnInterface_Field()
        {
            var source = @"
class C
{
    void M<T>() where T : I, new()
    {
        int x = 42;
        var t = new T() { field = ref x };
    }
}
interface I
{
    public ref int field;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (12,20): error CS0525: Interfaces cannot contain instance fields
                //     public ref int field;
                Diagnostic(ErrorCode.ERR_InterfacesCantContainFields, "field").WithLocation(12, 20),
                // (12,20): error CS9059: A ref field can only be declared in a ref struct.
                //     public ref int field;
                Diagnostic(ErrorCode.ERR_RefFieldInNonRefStruct, "field").WithLocation(12, 20)
                );
        }
 
        [Fact]
        public void RefInitializer_OnInterface_Property()
        {
            var source = @"
class C
{
    void M<T>() where T : I, new()
    {
        int x = 42;
        var t = new T() { Property = ref x };
    }
}
 
interface I
{
    public ref int Property { get; }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,27): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         var t = new T() { Property = ref x };
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "Property").WithLocation(7, 27)
                );
        }
 
        [Fact]
        public void RefInitializer_Collection()
        {
            var source = @"
using System.Collections;
 
int x = 42;
int y = 43;
var r = new R() { ref x, ref y };
 
struct R : IEnumerable
{
    public void Add(ref int x) => throw null;
    public IEnumerator GetEnumerator() => throw null;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (4,5): warning CS0219: The variable 'x' is assigned but its value is never used
                // int x = 42;
                Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "x").WithArguments("x").WithLocation(4, 5),
                // (5,5): warning CS0219: The variable 'y' is assigned but its value is never used
                // int y = 43;
                Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "y").WithArguments("y").WithLocation(5, 5),
                // (6,19): error CS1073: Unexpected token 'ref'
                // var r = new R() { ref x, ref y };
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(6, 19),
                // (6,26): error CS1073: Unexpected token 'ref'
                // var r = new R() { ref x, ref y };
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(6, 26)
                );
        }
 
        [Fact]
        public void RefInitializer_OnNonRefField()
        {
            var source = @"
int x = 42;
var r = new R() { field = ref x }; // 1
 
R r2 = default;
r2.field = ref x; // 2
 
ref struct R
{
    public int field;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (3,19): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                // var r = new R() { field = ref x }; // 1
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "field").WithLocation(3, 19),
                // (6,1): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                // r2.field = ref x; // 2
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "r2.field").WithLocation(6, 1)
                );
        }
 
        [Fact]
        public void RefInitializer_OnNonRefProperty()
        {
            var source = @"
int x = 42;
var r = new R() { Property = ref x }; // 1
 
R r2 = default;
r2.Property = ref x; // 2
 
ref struct R
{
    public int Property { get; set; }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (3,19): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                // var r = new R() { Property = ref x }; // 1
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "Property").WithLocation(3, 19),
                // (6,1): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                // r2.Property = ref x; // 2
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "r2.Property").WithLocation(6, 1)
                );
        }
 
        [Fact]
        public void RefInitializer_OnNonRefIndexer()
        {
            var source = @"
int x = 42;
var r = new R() { [0] = ref x }; // 1
 
R r2 = default;
r2[0] = ref x; // 2
 
ref struct R
{
    public int this[int i] { get => throw null; set => throw null; }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (3,19): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                // var r = new R() { [0] = ref x }; // 1
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "[0]").WithLocation(3, 19),
                // (6,1): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                // r2[0] = ref x; // 2
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "r2[0]").WithLocation(6, 1)
                );
        }
 
        [Fact]
        public void RefInitializer_OnArray()
        {
            var source = @"
public ref struct C
{
    C M()
    {
        int x = 0;
        var c = new C { array = { [0] = ref x } }; // 1
        return c;
    }
 
    void M2()
    {
        int x = 0;
        C c2 = new C();
        c2.array[0] = ref x; // 2
    }
 
    public int[] array;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,35): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         var c = new C { array = { [0] = ref x } }; // 1
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "[0]").WithLocation(7, 35),
                // (15,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         c2.array[0] = ref x; // 2
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "c2.array[0]").WithLocation(15, 9)
                );
        }
 
        [Fact]
        public void RefInitializer_OnPointer()
        {
            var source = @"
public unsafe class C
{
    public int* pointer;
 
    C M()
    {
        int x = 0;
        var c = new C { pointer = { [0] = ref x } }; // 1
        return c;
    }
 
    void M2()
    {
        int x = 0;
        C c2 = new C();
        c2.pointer[0] = ref x; // 2
    }
}
";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugDll);
            comp.VerifyDiagnostics(
                // (9,37): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         var c = new C { pointer = { [0] = ref x } }; // 1
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "[0]").WithLocation(9, 37),
                // (17,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         c2.pointer[0] = ref x; // 2
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "c2.pointer[0]").WithLocation(17, 9)
                );
        }
 
        [Fact]
        public void RefInitializer_OnEvent()
        {
            var source = @"
int x = 42;
var r = new C { a = ref x }; // 1
 
C c = default;
c.a = ref x; // 2
 
class C
{
    public event System.Action a;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (3,17): error CS0070: The event 'C.a' can only appear on the left hand side of += or -= (except when used from within the type 'C')
                // var r = new C { a = ref x }; // 1
                Diagnostic(ErrorCode.ERR_BadEventUsage, "a").WithArguments("C.a", "C").WithLocation(3, 17),
                // (6,3): error CS0070: The event 'C.a' can only appear on the left hand side of += or -= (except when used from within the type 'C')
                // c.a = ref x; // 2
                Diagnostic(ErrorCode.ERR_BadEventUsage, "a").WithArguments("C.a", "C").WithLocation(6, 3)
                );
        }
 
        [Fact]
        public void RefInitializer_OnEvent_ThisMemberAccess()
        {
            var source = @"
int x = 42;
var r1 = new C { this.a = ref x }; // 1
 
class C
{
    public event System.Action a;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (3,16): error CS1922: Cannot initialize type 'C' with a collection initializer because it does not implement 'System.Collections.IEnumerable'
                // var r1 = new C { this.a = ref x }; // 1
                Diagnostic(ErrorCode.ERR_CollectionInitRequiresIEnumerable, "{ this.a = ref x }").WithArguments("C").WithLocation(3, 16),
                // (3,18): error CS0747: Invalid initializer member declarator
                // var r1 = new C { this.a = ref x }; // 1
                Diagnostic(ErrorCode.ERR_InvalidInitializerElementInitializer, "this.a = ref x").WithLocation(3, 18),
                // (3,18): error CS0026: Keyword 'this' is not valid in a static property, static method, or static field initializer
                // var r1 = new C { this.a = ref x }; // 1
                Diagnostic(ErrorCode.ERR_ThisInStaticMeth, "this").WithLocation(3, 18),
                // (7,32): warning CS0067: The event 'C.a' is never used
                //     public event System.Action a;
                Diagnostic(ErrorCode.WRN_UnreferencedEvent, "a").WithArguments("C.a").WithLocation(7, 32)
                );
        }
 
        [Fact]
        public void RefInitializer_OnMethodGroup()
        {
            var source = @"
int x = 42;
var r = new C { F = ref x }; // 1
 
C c = default;
c.F = ref x; // 2
 
class C
{
    public void F() { }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (3,17): error CS1913: Member 'F' cannot be initialized. It is not a field or property.
                // var r = new C { F = ref x }; // 1
                Diagnostic(ErrorCode.ERR_MemberCannotBeInitialized, "F").WithArguments("F").WithLocation(3, 17),
                // (6,1): error CS1656: Cannot assign to 'F' because it is a 'method group'
                // c.F = ref x; // 2
                Diagnostic(ErrorCode.ERR_AssgReadonlyLocalCause, "c.F").WithArguments("F", "method group").WithLocation(6, 1)
                );
        }
 
        [Fact]
        public void RefInitializer_Nested()
        {
            var source = @"
class C
{
    static void Main()
    {
        int x = 42;
        var r = new Container { item = { field = ref x } };
        System.Console.Write(r.item.field);
    }
}
ref struct Container
{
    public Item item;
}
ref struct Item
{
    public ref int field;
}
";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("42"));
            verifier.VerifyIL("C.Main", @"
{
  // Code size       43 (0x2b)
  .maxstack  2
  .locals init (int V_0, //x
                Container V_1)
  IL_0000:  ldc.i4.s   42
  IL_0002:  stloc.0
  IL_0003:  ldloca.s   V_1
  IL_0005:  initobj    ""Container""
  IL_000b:  ldloca.s   V_1
  IL_000d:  ldflda     ""Item Container.item""
  IL_0012:  ldloca.s   V_0
  IL_0014:  stfld      ""ref int Item.field""
  IL_0019:  ldloc.1
  IL_001a:  ldfld      ""Item Container.item""
  IL_001f:  ldfld      ""ref int Item.field""
  IL_0024:  ldind.i4
  IL_0025:  call       ""void System.Console.Write(int)""
  IL_002a:  ret
}
");
        }
 
        [Fact]
        public void RefInitializer_Nullability()
        {
            var source = @"
#nullable enable
 
S<object> x1 = default;
S<object?> x2 = default;
 
_ = new R<object> { field = ref x1 };
_ = new R<object> { field = ref x2 }; // 1
_ = new R<object?> { field = ref x1 }; // 2
_ = new R<object?> { field = ref x2 };
 
_ = new R<object>() with { field = ref x1 };
_ = new R<object>() with { field = ref x2 }; // 3
_ = new R<object?>() with { field = ref x1 }; // 4
_ = new R<object?>() with { field = ref x2 };
 
struct S<T> { }
ref struct R<T>
{
    public ref S<T> field;
}
";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (8,33): warning CS8619: Nullability of reference types in value of type 'S<object?>' doesn't match target type 'S<object>'.
                // _ = new R<object> { field = ref x2 }; // 1
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "x2").WithArguments("S<object?>", "S<object>").WithLocation(8, 33),
                // (9,34): warning CS8619: Nullability of reference types in value of type 'S<object>' doesn't match target type 'S<object?>'.
                // _ = new R<object?> { field = ref x1 }; // 2
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "x1").WithArguments("S<object>", "S<object?>").WithLocation(9, 34),
                // (13,40): warning CS8619: Nullability of reference types in value of type 'S<object?>' doesn't match target type 'S<object>'.
                // _ = new R<object>() with { field = ref x2 }; // 3
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "x2").WithArguments("S<object?>", "S<object>").WithLocation(13, 40),
                // (14,41): warning CS8619: Nullability of reference types in value of type 'S<object>' doesn't match target type 'S<object?>'.
                // _ = new R<object?>() with { field = ref x1 }; // 4
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "x1").WithArguments("S<object>", "S<object?>").WithLocation(14, 41)
                );
        }
 
        [Fact]
        public void RefInitializer_RefOnNestedInitializer()
        {
            var source = @"
int x = 42;
var r = new R { field = ref { item = 42 } }; // 1
 
struct S
{
    public int item;
}
ref struct R
{
    public ref S field;
}
";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (2,5): warning CS0219: The variable 'x' is assigned but its value is never used
                // int x = 42;
                Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "x").WithArguments("x").WithLocation(2, 5),
                // (3,29): error CS1525: Invalid expression term '{'
                // var r = new R { field = ref { item = 42 } }; // 1
                Diagnostic(ErrorCode.ERR_InvalidExprTerm, "{").WithArguments("{").WithLocation(3, 29),
                // (3,29): error CS1003: Syntax error, ',' expected
                // var r = new R { field = ref { item = 42 } }; // 1
                Diagnostic(ErrorCode.ERR_SyntaxError, "{").WithArguments(",").WithLocation(3, 29),
                // (3,29): error CS0747: Invalid initializer member declarator
                // var r = new R { field = ref { item = 42 } }; // 1
                Diagnostic(ErrorCode.ERR_InvalidInitializerElementInitializer, "{ item = 42 }").WithLocation(3, 29),
                // (3,31): error CS0103: The name 'item' does not exist in the current context
                // var r = new R { field = ref { item = 42 } }; // 1
                Diagnostic(ErrorCode.ERR_NameNotInContext, "item").WithArguments("item").WithLocation(3, 31)
                );
        }
 
        [Fact]
        public void RefInitializer_FieldOnDynamic()
        {
            var source = @"
int x = 42;
var r = new S { D = { field = ref x } }; // 1
 
S s = default;
s.D.field = ref x; // 2
 
struct S
{
    public dynamic D;
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (3,23): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                // var r = new S { D = { field = ref x } }; // 1
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "field").WithLocation(3, 23),
                // (6,1): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                // s.D.field = ref x; // 2
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "s.D.field").WithLocation(6, 1)
                );
        }
 
        [Fact]
        public void RefInitializer_DynamicField()
        {
            var source = @"
int i = 42;
var r = new R<dynamic> { F = ref i }; // 1
 
ref struct R<T>
{
    public ref T F;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (3,34): error CS8173: The expression must be of type 'dynamic' because it is being assigned by reference
                // var r = new R<dynamic> { F = ref i }; // 1
                Diagnostic(ErrorCode.ERR_RefAssignmentMustHaveIdentityConversion, "i").WithArguments("dynamic").WithLocation(3, 34)
                );
        }
 
        [Fact]
        public void RefInitializer_DynamicField_DynamicValue()
        {
            var source = @"
public class C
{
    public static void Main()
    {
        dynamic i = 42;
        var r = new R<dynamic> { F = ref i };
        System.Console.Write(r.F);
 
        var r2 = new R<dynamic>(ref i);
        System.Console.Write(r2.F);
    }
}
 
ref struct R<T>
{
    public R(ref T f) { F = ref f; }
    public ref T F;
}
";
            var references = TargetFrameworkUtil.GetReferences(TargetFramework.NetCoreApp, additionalReferences: null);
            var comp = CreateCompilation(source, options: TestOptions.DebugExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("4242"));
            verifier.VerifyIL("C.Main", """
{
  // Code size      257 (0x101)
  .maxstack  9
  .locals init (object V_0, //i
                R<dynamic> V_1, //r
                R<dynamic> V_2, //r2
                R<dynamic> V_3)
  IL_0000:  nop
  IL_0001:  ldc.i4.s   42
  IL_0003:  box        "int"
  IL_0008:  stloc.0
  IL_0009:  ldloca.s   V_3
  IL_000b:  initobj    "R<dynamic>"
  IL_0011:  ldloca.s   V_3
  IL_0013:  ldloca.s   V_0
  IL_0015:  stfld      "ref dynamic R<dynamic>.F"
  IL_001a:  ldloc.3
  IL_001b:  stloc.1
  IL_001c:  ldsfld     "System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, System.Type, dynamic>> C.<>o__0.<>p__0"
  IL_0021:  brfalse.s  IL_0025
  IL_0023:  br.s       IL_0064
  IL_0025:  ldc.i4     0x100
  IL_002a:  ldstr      "Write"
  IL_002f:  ldnull
  IL_0030:  ldtoken    "C"
  IL_0035:  call       "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"
  IL_003a:  ldc.i4.2
  IL_003b:  newarr     "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo"
  IL_0040:  dup
  IL_0041:  ldc.i4.0
  IL_0042:  ldc.i4.s   33
  IL_0044:  ldnull
  IL_0045:  call       "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"
  IL_004a:  stelem.ref
  IL_004b:  dup
  IL_004c:  ldc.i4.1
  IL_004d:  ldc.i4.0
  IL_004e:  ldnull
  IL_004f:  call       "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"
  IL_0054:  stelem.ref
  IL_0055:  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_005a:  call       "System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, System.Type, dynamic>> System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, System.Type, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)"
  IL_005f:  stsfld     "System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, System.Type, dynamic>> C.<>o__0.<>p__0"
  IL_0064:  ldsfld     "System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, System.Type, dynamic>> C.<>o__0.<>p__0"
  IL_0069:  ldfld      "System.Action<System.Runtime.CompilerServices.CallSite, System.Type, dynamic> System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, System.Type, dynamic>>.Target"
  IL_006e:  ldsfld     "System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, System.Type, dynamic>> C.<>o__0.<>p__0"
  IL_0073:  ldtoken    "System.Console"
  IL_0078:  call       "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"
  IL_007d:  ldloc.1
  IL_007e:  ldfld      "ref dynamic R<dynamic>.F"
  IL_0083:  ldind.ref
  IL_0084:  callvirt   "void System.Action<System.Runtime.CompilerServices.CallSite, System.Type, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, System.Type, dynamic)"
  IL_0089:  nop
  IL_008a:  ldloca.s   V_0
  IL_008c:  newobj     "R<dynamic>..ctor(ref dynamic)"
  IL_0091:  stloc.2
  IL_0092:  ldsfld     "System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, System.Type, dynamic>> C.<>o__0.<>p__1"
  IL_0097:  brfalse.s  IL_009b
  IL_0099:  br.s       IL_00da
  IL_009b:  ldc.i4     0x100
  IL_00a0:  ldstr      "Write"
  IL_00a5:  ldnull
  IL_00a6:  ldtoken    "C"
  IL_00ab:  call       "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"
  IL_00b0:  ldc.i4.2
  IL_00b1:  newarr     "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo"
  IL_00b6:  dup
  IL_00b7:  ldc.i4.0
  IL_00b8:  ldc.i4.s   33
  IL_00ba:  ldnull
  IL_00bb:  call       "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"
  IL_00c0:  stelem.ref
  IL_00c1:  dup
  IL_00c2:  ldc.i4.1
  IL_00c3:  ldc.i4.0
  IL_00c4:  ldnull
  IL_00c5:  call       "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"
  IL_00ca:  stelem.ref
  IL_00cb:  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_00d0:  call       "System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, System.Type, dynamic>> System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, System.Type, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)"
  IL_00d5:  stsfld     "System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, System.Type, dynamic>> C.<>o__0.<>p__1"
  IL_00da:  ldsfld     "System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, System.Type, dynamic>> C.<>o__0.<>p__1"
  IL_00df:  ldfld      "System.Action<System.Runtime.CompilerServices.CallSite, System.Type, dynamic> System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, System.Type, dynamic>>.Target"
  IL_00e4:  ldsfld     "System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite, System.Type, dynamic>> C.<>o__0.<>p__1"
  IL_00e9:  ldtoken    "System.Console"
  IL_00ee:  call       "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"
  IL_00f3:  ldloc.2
  IL_00f4:  ldfld      "ref dynamic R<dynamic>.F"
  IL_00f9:  ldind.ref
  IL_00fa:  callvirt   "void System.Action<System.Runtime.CompilerServices.CallSite, System.Type, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, System.Type, dynamic)"
  IL_00ff:  nop
  IL_0100:  ret
}
""");
        }
 
        [Fact]
        public void RefInitializer_SubstitutedObjectField()
        {
            var source = @"
public class C
{
    public static void Main()
    {
        object i = 42;
        var r = new R<object> { F = ref i };
        System.Console.Write(r.F);
 
        var r2 = new R<object>(ref i);
        System.Console.Write(r2.F);
    }
}
 
ref struct R<T>
{
    public R(ref T f) { F = ref f; }
    public ref T F;
}
";
            var comp = CreateCompilation(source, options: TestOptions.DebugExe, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
            comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("4242"));
            verifier.VerifyIL("C.Main", """
{
  // Code size       56 (0x38)
  .maxstack  2
  .locals init (object V_0, //i
                R<object> V_1)
  IL_0000:  ldc.i4.s   42
  IL_0002:  box        "int"
  IL_0007:  stloc.0
  IL_0008:  ldloca.s   V_1
  IL_000a:  initobj    "R<object>"
  IL_0010:  ldloca.s   V_1
  IL_0012:  ldloca.s   V_0
  IL_0014:  stfld      "ref object R<object>.F"
  IL_0019:  ldloc.1
  IL_001a:  ldfld      "ref object R<object>.F"
  IL_001f:  ldind.ref
  IL_0020:  call       "void System.Console.Write(object)"
  IL_0025:  ldloca.s   V_0
  IL_0027:  newobj     "R<object>..ctor(ref object)"
  IL_002c:  ldfld      "ref object R<object>.F"
  IL_0031:  ldind.ref
  IL_0032:  call       "void System.Console.Write(object)"
  IL_0037:  ret
}
""");
        }
 
        [Fact]
        public void RefInitializer_DynamicInstance()
        {
            var source = @"
int x = 42;
var r = new dynamic { field = ref x }; // 1
 
dynamic r2 = null;
r2.field = ref x; // 2
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (3,13): error CS8386: Invalid object creation
                // var r = new dynamic { field = ref x }; // 1
                Diagnostic(ErrorCode.ERR_InvalidObjectCreation, "dynamic").WithLocation(3, 13),
                // (3,23): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                // var r = new dynamic { field = ref x }; // 1
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "field").WithLocation(3, 23),
                // (6,1): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                // r2.field = ref x; // 2
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "r2.field").WithLocation(6, 1)
                );
        }
 
        [Fact]
        public void RefInitializer_DynamicIndexer()
        {
            var source = @"
int x = 42;
var r = new S { D = { [0] = ref x } }; // 1
 
S s = default;
s.D[0] = ref x; // 2
 
struct S
{
    public dynamic D;
}
ref struct R
{
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (3,23): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                // var r = new S { D = { [0] = ref x } }; // 1
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "[0]").WithLocation(3, 23),
                // (6,1): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                // s.D[0] = ref x; // 2
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "s.D[0]").WithLocation(6, 1)
                );
        }
 
        [Fact]
        public void RefInitializer_DynamicIndexer_Nested()
        {
            var source = @"
dynamic x = 1;
int i = 42;
var a = new A() { [y: x, x: x] = { X = ref i } }; // 1
 
A a2 = null;
a2[y: x, x: x].X = ref i; // 2
 
public class A
{
    public dynamic this[int x, int y] { get => throw null; }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (4,36): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                // var a = new A() { [y: x, x: x] = { X = ref i } }; // 1
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "X").WithLocation(4, 36),
                // (7,1): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                // a2[y: x, x: x].X = ref i; // 2
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "a2[y: x, x: x].X").WithLocation(7, 1)
                );
        }
 
        [Fact]
        public void RefInitializer_Escape()
        {
            var source = @"
public class C
{
    public static R M1()
    {
        int x = 42;
        var r = new R { field = ref x };
        return r; // 1
    }
    public static R M2(ref int x)
    {
        var r = new R { field = ref x };
        return r;
    }
    public static R M3()
    {
        R r = default;
        {
            int x = 42;
            r = new R { field = ref x }; // 2
        }
        return r;
    }
    public static R M4()
    {
        R r = default;
        int x = 42;
        {
            r = new R { field = ref x }; // 3
        }
        return r;
    }
    public static void M5(ref R r)
    {
        int x = 42;
        r = new R { field = ref x }; // 4
    }
}
 
public ref struct R
{
    public ref int field;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (8,16): error CS8352: Cannot use variable 'r' in this context because it may expose referenced variables outside of their declaration scope
                //         return r; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r").WithArguments("r").WithLocation(8, 16),
                // (20,25): error CS8168: Cannot return local 'x' by reference because it is not a ref local
                //             r = new R { field = ref x }; // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "field = ref x").WithArguments("x").WithLocation(20, 25),
                // (29,25): error CS8168: Cannot return local 'x' by reference because it is not a ref local
                //             r = new R { field = ref x }; // 3
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "field = ref x").WithArguments("x").WithLocation(29, 25),
                // (36,21): error CS8168: Cannot return local 'x' by reference because it is not a ref local
                //         r = new R { field = ref x }; // 4
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "field = ref x").WithArguments("x").WithLocation(36, 21)
                );
 
            // Initializer values behave like constructor parameters for purpose of escape analysis
            source = @"
public class C
{
    public static R M1()
    {
        int x = 42;
        var r = new R(ref x);
        return r; // 1
    }
    public static R M2(ref int x)
    {
        var r = new R(ref x);
        return r;
    }
    public static R M3()
    {
        R r = default;
        {
            int x = 42;
            r = new R(ref x); // 2
        }
        return r;
    }
    public static R M4()
    {
        R r = default;
        int x = 42;
        {
            r = new R(ref x); // 3
        }
        return r;
    }
    public static void M5(ref R r)
    {
        int x = 42;
        r = new R(ref x); // 4
    }
}
 
public ref struct R
{
    public ref int field;
    public R(ref int i) { }
}
";
            comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (8,16): error CS8352: Cannot use variable 'r' in this context because it may expose referenced variables outside of their declaration scope
                //         return r; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r").WithArguments("r").WithLocation(8, 16),
                // (20,17): error CS8347: Cannot use a result of 'R.R(ref int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //             r = new R(ref x); // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R(ref x)").WithArguments("R.R(ref int)", "i").WithLocation(20, 17),
                // (20,27): error CS8168: Cannot return local 'x' by reference because it is not a ref local
                //             r = new R(ref x); // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "x").WithArguments("x").WithLocation(20, 27),
                // (29,17): error CS8347: Cannot use a result of 'R.R(ref int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //             r = new R(ref x); // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R(ref x)").WithArguments("R.R(ref int)", "i").WithLocation(29, 17),
                // (29,27): error CS8168: Cannot return local 'x' by reference because it is not a ref local
                //             r = new R(ref x); // 3
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "x").WithArguments("x").WithLocation(29, 27),
                // (36,13): error CS8347: Cannot use a result of 'R.R(ref int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         r = new R(ref x); // 4
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R(ref x)").WithArguments("R.R(ref int)", "i").WithLocation(36, 13),
                // (36,23): error CS8168: Cannot return local 'x' by reference because it is not a ref local
                //         r = new R(ref x); // 4
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "x").WithArguments("x").WithLocation(36, 23)
                );
        }
 
        [Fact]
        public void RefInitializer_Escape_Nested()
        {
            var source = @"
class C
{
    public static Container M3()
    {
        Container r = default;
        {
            int x = 42;
            var r = new Container { item = { field = ref x } }; // 1
        }
        return r;
    }
    public static Container M4()
    {
        Container r = default;
        int x = 42;
        {
            r = new Container { item = { field = ref x } }; // 2
        }
        return r;
    }
    public static void M5(ref Container r)
    {
        int x = 42;
        r = new Container { item = { field = ref x } }; // 3
    }
    public static Container M6()
    {
        int x = 42;
        var r = new Container { item = { field = ref x } };
        return r; // 4
    }
 }
ref struct Container
{
    public Item item;
}
ref struct Item
{
    public ref int field;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (9,17): error CS0136: A local or parameter named 'r' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
                //             var r = new Container { item = { field = ref x } }; // 1
                Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "r").WithArguments("r").WithLocation(9, 17),
                // (18,42): error CS8168: Cannot return local 'x' by reference because it is not a ref local
                //             r = new Container { item = { field = ref x } }; // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "field = ref x").WithArguments("x").WithLocation(18, 42),
                // (25,38): error CS8168: Cannot return local 'x' by reference because it is not a ref local
                //         r = new Container { item = { field = ref x } }; // 3
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "field = ref x").WithArguments("x").WithLocation(25, 38),
                // (31,16): error CS8352: Cannot use variable 'r' in this context because it may expose referenced variables outside of their declaration scope
                //         return r; // 4
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r").WithArguments("r").WithLocation(31, 16)
                );
        }
 
        [Fact]
        public void RefWith()
        {
            var source = @"
public class C
{
    public static void Main()
    {
        int x = 42;
        var r = new R() with { field = ref x };
        System.Console.Write(r.ToString());
    }
}
 
ref struct R
{
    public ref int field;
    public override string ToString()
    {
        return field.ToString();
    }
}
";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("42"));
            verifier.VerifyIL("C.Main",
"""
{
  // Code size       41 (0x29)
  .maxstack  2
  .locals init (int V_0, //x
                R V_1, //r
                R V_2)
  IL_0000:  ldc.i4.s   42
  IL_0002:  stloc.0
  IL_0003:  ldloca.s   V_2
  IL_0005:  initobj    "R"
  IL_000b:  ldloca.s   V_2
  IL_000d:  ldloca.s   V_0
  IL_000f:  stfld      "ref int R.field"
  IL_0014:  ldloc.2
  IL_0015:  stloc.1
  IL_0016:  ldloca.s   V_1
  IL_0018:  constrained. "R"
  IL_001e:  callvirt   "string object.ToString()"
  IL_0023:  call       "void System.Console.Write(string)"
  IL_0028:  ret
}
""");
        }
 
        [Fact]
        public void RefWith_Escape()
        {
            var source = @"
public class C
{
    public static R M1()
    {
        int x = 42;
        var r = new R() with { field = ref x };
        return r; // 1
    }
    public static R M2(ref int x)
    {
        var r = new R() with { field = ref x };
        return r;
    }
    public static R M3()
    {
        R r = default;
        {
            int x = 42;
            r = new R() with { field = ref x }; // 2
        }
        return r;
    }
    public static R M4()
    {
        R r = default;
        int x = 42;
        {
            r = new R() with { field = ref x }; // 3
        }
        return r;
    }
    public static void M5(ref R r)
    {
        int x = 42;
        r = new R() with { field = ref x }; // 4
    }
}
 
public ref struct R
{
    public ref int field;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (8,16): error CS8352: Cannot use variable 'r' in this context because it may expose referenced variables outside of their declaration scope
                //         return r; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r").WithArguments("r").WithLocation(8, 16),
                // (20,32): error CS8168: Cannot return local 'x' by reference because it is not a ref local
                //             r = new R() with { field = ref x }; // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "field = ref x").WithArguments("x").WithLocation(20, 32),
                // (29,32): error CS8168: Cannot return local 'x' by reference because it is not a ref local
                //             r = new R() with { field = ref x }; // 3
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "field = ref x").WithArguments("x").WithLocation(29, 32),
                // (36,28): error CS8168: Cannot return local 'x' by reference because it is not a ref local
                //         r = new R() with { field = ref x }; // 4
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "field = ref x").WithArguments("x").WithLocation(36, 28)
                );
        }
 
        [Fact]
        public void RefScoped()
        {
            var source =
@"ref struct R
{
    ref scoped R field;
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (3,9): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
                //     ref scoped R field;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(3, 9),
                // (3,16): error CS0542: 'R': member names cannot be the same as their enclosing type
                //     ref scoped R field;
                Diagnostic(ErrorCode.ERR_MemberNameSameAsType, "R").WithArguments("R").WithLocation(3, 16),
                // (3,16): warning CS0169: The field 'R.R' is never used
                //     ref scoped R field;
                Diagnostic(ErrorCode.WRN_UnreferencedField, "R").WithArguments("R.R").WithLocation(3, 16),
                // (3,18): error CS1002: ; expected
                //     ref scoped R field;
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "field").WithLocation(3, 18),
                // (3,23): error CS1519: Invalid token ';' in class, record, struct, or interface member declaration
                //     ref scoped R field;
                Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ";").WithArguments(";").WithLocation(3, 23),
                // (3,23): error CS1519: Invalid token ';' in class, record, struct, or interface member declaration
                //     ref scoped R field;
                Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ";").WithArguments(";").WithLocation(3, 23)
                );
 
            source =
@"ref struct R
{
    ref scoped R Property { get => throw null; }
}";
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (3,9): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
                //     ref scoped R Property { get => throw null; }
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(3, 9),
                // (3,16): error CS9064: Target runtime doesn't support ref fields.
                //     ref scoped R Property { get => throw null; }
                Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportRefFields, "R").WithLocation(3, 16),
                // (3,16): error CS0542: 'R': member names cannot be the same as their enclosing type
                //     ref scoped R Property { get => throw null; }
                Diagnostic(ErrorCode.ERR_MemberNameSameAsType, "R").WithArguments("R").WithLocation(3, 16),
                // (3,16): warning CS0169: The field 'R.R' is never used
                //     ref scoped R Property { get => throw null; }
                Diagnostic(ErrorCode.WRN_UnreferencedField, "R").WithArguments("R.R").WithLocation(3, 16),
                // (3,18): error CS1002: ; expected
                //     ref scoped R Property { get => throw null; }
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "Property").WithLocation(3, 18),
                // (3,27): error CS1519: Invalid token '{' in class, record, struct, or interface member declaration
                //     ref scoped R Property { get => throw null; }
                Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "{").WithArguments("{").WithLocation(3, 27),
                // (3,27): error CS1519: Invalid token '{' in class, record, struct, or interface member declaration
                //     ref scoped R Property { get => throw null; }
                Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "{").WithArguments("{").WithLocation(3, 27),
                // (3,33): error CS1519: Invalid token '=>' in class, record, struct, or interface member declaration
                //     ref scoped R Property { get => throw null; }
                Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=>").WithArguments("=>").WithLocation(3, 33),
                // (3,33): error CS1519: Invalid token '=>' in class, record, struct, or interface member declaration
                //     ref scoped R Property { get => throw null; }
                Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=>").WithArguments("=>").WithLocation(3, 33),
                // (4,1): error CS1022: Type or namespace definition, or end-of-file expected
                // }
                Diagnostic(ErrorCode.ERR_EOFExpected, "}").WithLocation(4, 1)
                );
 
            source =
@"ref struct R
{
    void M(ref scoped R parameter)
    {
    }
}";
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (3,16): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
                //     void M(ref scoped R parameter)
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(3, 16),
                // (3,25): error CS1003: Syntax error, ',' expected
                //     void M(ref scoped R parameter)
                Diagnostic(ErrorCode.ERR_SyntaxError, "parameter").WithArguments(",").WithLocation(3, 25),
                // (3,25): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
                //     void M(ref scoped R parameter)
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(3, 25),
                // (3,34): error CS1001: Identifier expected
                //     void M(ref scoped R parameter)
                Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(3, 34)
                );
 
            source =
@"ref struct R
{
    void M(in scoped R parameter)
    {
    }
}";
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (3,15): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
                //     void M(in scoped R parameter)
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(3, 15),
                // (3,24): error CS1003: Syntax error, ',' expected
                //     void M(in scoped R parameter)
                Diagnostic(ErrorCode.ERR_SyntaxError, "parameter").WithArguments(",").WithLocation(3, 24),
                // (3,24): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
                //     void M(in scoped R parameter)
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(3, 24),
                // (3,33): error CS1001: Identifier expected
                //     void M(in scoped R parameter)
                Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(3, 33)
                );
 
            source =
@"ref struct R
{
    void M(out scoped R parameter)
    {
    }
}";
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (3,10): error CS0177: The out parameter 'R' must be assigned to before control leaves the current method
                //     void M(out scoped R parameter)
                Diagnostic(ErrorCode.ERR_ParamUnassigned, "M").WithArguments("R").WithLocation(3, 10),
                // (3,16): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
                //     void M(out scoped R parameter)
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(3, 16),
                // (3,25): error CS1003: Syntax error, ',' expected
                //     void M(out scoped R parameter)
                Diagnostic(ErrorCode.ERR_SyntaxError, "parameter").WithArguments(",").WithLocation(3, 25),
                // (3,25): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
                //     void M(out scoped R parameter)
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(3, 25),
                // (3,34): error CS1001: Identifier expected
                //     void M(out scoped R parameter)
                Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(3, 34)
                );
 
            source =
@"ref struct R
{
    void M(ref scoped scoped R parameter)
    {
    }
}";
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (3,16): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
                //     void M(ref scoped scoped R parameter)
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(3, 16),
                // (3,30): error CS1003: Syntax error, ',' expected
                //     void M(ref scoped scoped R parameter)
                Diagnostic(ErrorCode.ERR_SyntaxError, "R").WithArguments(",").WithLocation(3, 30)
                );
 
            source =
@"ref struct R
{
    void M()
    {
        ref scoped R local;
    }
}";
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (5,13): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
                //         ref scoped R local;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(5, 13),
                // (5,20): error CS8174: A declaration of a by-reference variable must have an initializer
                //         ref scoped R local;
                Diagnostic(ErrorCode.ERR_ByReferenceVariableMustBeInitialized, "R").WithLocation(5, 20),
                // (5,20): warning CS0168: The variable 'R' is declared but never used
                //         ref scoped R local;
                Diagnostic(ErrorCode.WRN_UnreferencedVar, "R").WithArguments("R").WithLocation(5, 20),
                // (5,22): error CS1002: ; expected
                //         ref scoped R local;
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "local").WithLocation(5, 22),
                // (5,22): error CS0103: The name 'local' does not exist in the current context
                //         ref scoped R local;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "local").WithArguments("local").WithLocation(5, 22),
                // (5,22): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement
                //         ref scoped R local;
                Diagnostic(ErrorCode.ERR_IllegalStatement, "local").WithLocation(5, 22)
                );
 
            source =
@"ref struct R
{
    void M()
    {
        scoped ref scoped R local;
    }
}";
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (5,20): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
                //         scoped ref scoped R local;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(5, 20),
                // (5,27): error CS8174: A declaration of a by-reference variable must have an initializer
                //         scoped ref scoped R local;
                Diagnostic(ErrorCode.ERR_ByReferenceVariableMustBeInitialized, "R").WithLocation(5, 27),
                // (5,27): warning CS0168: The variable 'R' is declared but never used
                //         scoped ref scoped R local;
                Diagnostic(ErrorCode.WRN_UnreferencedVar, "R").WithArguments("R").WithLocation(5, 27),
                // (5,29): error CS1002: ; expected
                //         scoped ref scoped R local;
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "local").WithLocation(5, 29),
                // (5,29): error CS0103: The name 'local' does not exist in the current context
                //         scoped ref scoped R local;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "local").WithArguments("local").WithLocation(5, 29),
                // (5,29): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement
                //         scoped ref scoped R local;
                Diagnostic(ErrorCode.ERR_IllegalStatement, "local").WithLocation(5, 29)
                );
 
            source =
@"ref struct R
{
    ref scoped R M() => throw null;
}";
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (3,9): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
                //     ref scoped R M() => throw null;
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(3, 9),
                // (3,16): error CS9064: Target runtime doesn't support ref fields.
                //     ref scoped R M() => throw null;
                Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportRefFields, "R").WithLocation(3, 16),
                // (3,16): error CS0542: 'R': member names cannot be the same as their enclosing type
                //     ref scoped R M() => throw null;
                Diagnostic(ErrorCode.ERR_MemberNameSameAsType, "R").WithArguments("R").WithLocation(3, 16),
                // (3,16): warning CS0169: The field 'R.R' is never used
                //     ref scoped R M() => throw null;
                Diagnostic(ErrorCode.WRN_UnreferencedField, "R").WithArguments("R.R").WithLocation(3, 16),
                // (3,18): error CS1002: ; expected
                //     ref scoped R M() => throw null;
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "M").WithLocation(3, 18),
                // (3,18): error CS1520: Method must have a return type
                //     ref scoped R M() => throw null;
                Diagnostic(ErrorCode.ERR_MemberNeedsType, "M").WithLocation(3, 18),
                // (3,18): error CS8958: The parameterless struct constructor must be 'public'.
                //     ref scoped R M() => throw null;
                Diagnostic(ErrorCode.ERR_NonPublicParameterlessStructConstructor, "M").WithLocation(3, 18)
                );
 
            source = @"
delegate void M(ref scoped R parameter);
ref struct R { }
";
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (2,21): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
                // delegate void M(ref scoped R parameter);
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(2, 21),
                // (2,30): error CS1003: Syntax error, ',' expected
                // delegate void M(ref scoped R parameter);
                Diagnostic(ErrorCode.ERR_SyntaxError, "parameter").WithArguments(",").WithLocation(2, 30),
                // (2,30): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
                // delegate void M(ref scoped R parameter);
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(2, 30),
                // (2,39): error CS1001: Identifier expected
                // delegate void M(ref scoped R parameter);
                Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(2, 39)
                );
 
            source = @"
ref struct R
{
    void M()
    {
        _ = void (ref scoped R parameter) => throw null;
    }
}
";
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (6,13): error CS1525: Invalid expression term 'void'
                //         _ = void (ref scoped R parameter) => throw null;
                Diagnostic(ErrorCode.ERR_InvalidExprTerm, "void").WithArguments("void").WithLocation(6, 13),
                // (6,23): error CS0103: The name 'scoped' does not exist in the current context
                //         _ = void (ref scoped R parameter) => throw null;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "scoped").WithArguments("scoped").WithLocation(6, 23),
                // (6,30): error CS1003: Syntax error, ',' expected
                //         _ = void (ref scoped R parameter) => throw null;
                Diagnostic(ErrorCode.ERR_SyntaxError, "R").WithArguments(",").WithLocation(6, 30),
                // (6,30): error CS0119: 'R' is a type, which is not valid in the given context
                //         _ = void (ref scoped R parameter) => throw null;
                Diagnostic(ErrorCode.ERR_BadSKunknown, "R").WithArguments("R", "type").WithLocation(6, 30),
                // (6,32): error CS1003: Syntax error, ',' expected
                //         _ = void (ref scoped R parameter) => throw null;
                Diagnostic(ErrorCode.ERR_SyntaxError, "parameter").WithArguments(",").WithLocation(6, 32),
                // (6,32): error CS0103: The name 'parameter' does not exist in the current context
                //         _ = void (ref scoped R parameter) => throw null;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "parameter").WithArguments("parameter").WithLocation(6, 32),
                // (6,43): error CS1002: ; expected
                //         _ = void (ref scoped R parameter) => throw null;
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "=>").WithLocation(6, 43),
                // (6,43): error CS1513: } expected
                //         _ = void (ref scoped R parameter) => throw null;
                Diagnostic(ErrorCode.ERR_RbraceExpected, "=>").WithLocation(6, 43)
                );
        }
 
        [Theory, WorkItem(62931, "https://github.com/dotnet/roslyn/issues/62931")]
        [InlineData("class")]
        [InlineData("struct")]
        [InlineData("interface")]
        [InlineData("enum")]
        [InlineData("record")]
        public void ScopedReserved_Type(string typeKind)
        {
            var source = $$"""
{{typeKind}} scoped { }
""";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.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")
                );
 
            comp = CreateCompilation(source, parseOptions: TestOptions.Regular11);
            comp.VerifyDiagnostics(
                // (1,8): error CS9062: Types and aliases cannot be named 'scoped'.
                // struct scoped { }
                Diagnostic(ErrorCode.ERR_ScopedTypeNameDisallowed, "scoped")
                );
        }
 
        [Fact, WorkItem(62931, "https://github.com/dotnet/roslyn/issues/62931")]
        public void ScopedReserved_Type_Escaped()
        {
            var source = """
class @scoped { }
""";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics();
 
            comp = CreateCompilation(source, parseOptions: TestOptions.Regular11);
            comp.VerifyDiagnostics();
        }
 
        [Fact, WorkItem(62931, "https://github.com/dotnet/roslyn/issues/62931")]
        public void ScopedReserved_TypeParameter()
        {
            var source = """
class C<scoped> { } // 1
class C2<@scoped> { }
 
class D
{
    void M()
    {
        local<object>();
        void local<scoped>() { } // 2
    }
 
    void M2()
    {
        local<object>();
        void local<@scoped>() { }
    }
}
 
class D2
{
    void M<scoped>() { } // 3
    void M2<@scoped>() { }
}
""";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(
                // (1,9): warning CS8981: The type name 'scoped' only contains lower-cased ascii characters. Such names may become reserved for the language.
                // class C<scoped> { } // 1
                Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "scoped").WithArguments("scoped").WithLocation(1, 9),
                // (9,20): warning CS8981: The type name 'scoped' only contains lower-cased ascii characters. Such names may become reserved for the language.
                //         void local<scoped>() { } // 2
                Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "scoped").WithArguments("scoped").WithLocation(9, 20),
                // (21,12): warning CS8981: The type name 'scoped' only contains lower-cased ascii characters. Such names may become reserved for the language.
                //     void M<scoped>() { } // 3
                Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "scoped").WithArguments("scoped").WithLocation(21, 12)
                );
 
            comp = CreateCompilation(source, parseOptions: TestOptions.Regular11);
            comp.VerifyDiagnostics(
                // (1,9): error CS9062: Types and aliases cannot be named 'scoped'.
                // class C<scoped> { } // 1
                Diagnostic(ErrorCode.ERR_ScopedTypeNameDisallowed, "scoped").WithLocation(1, 9),
                // (9,20): error CS9062: Types and aliases cannot be named 'scoped'.
                //         void local<scoped>() { } // 2
                Diagnostic(ErrorCode.ERR_ScopedTypeNameDisallowed, "scoped").WithLocation(9, 20),
                // (21,12): error CS9062: Types and aliases cannot be named 'scoped'.
                //     void M<scoped>() { } // 3
                Diagnostic(ErrorCode.ERR_ScopedTypeNameDisallowed, "scoped").WithLocation(21, 12)
                );
        }
 
        [Fact, WorkItem(62931, "https://github.com/dotnet/roslyn/issues/62931")]
        public void ScopedReserved_Alias()
        {
            var source = """
using scoped = System.Int32;
""";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(
                // (1,1): hidden CS8019: Unnecessary using directive.
                // using scoped = System.Int32;
                Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using scoped = System.Int32;").WithLocation(1, 1),
                // (1,7): warning CS8981: The type name 'scoped' only contains lower-cased ascii characters. Such names may become reserved for the language.
                // using scoped = System.Int32;
                Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "scoped").WithArguments("scoped").WithLocation(1, 7)
                );
 
            comp = CreateCompilation(source, parseOptions: TestOptions.Regular11);
            comp.VerifyDiagnostics(
                // (1,1): hidden CS8019: Unnecessary using directive.
                // using scoped = System.Int32;
                Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using scoped = System.Int32;").WithLocation(1, 1),
                // (1,7): error CS9062: Types and aliases cannot be named 'scoped'.
                // using scoped = System.Int32;
                Diagnostic(ErrorCode.ERR_ScopedTypeNameDisallowed, "scoped").WithLocation(1, 7)
                );
        }
 
        [Fact, WorkItem(62931, "https://github.com/dotnet/roslyn/issues/62931")]
        public void ScopedReserved_Alias_Escaped()
        {
            var source = """
using @scoped = System.Int32;
""";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(
                // (1,1): hidden CS8019: Unnecessary using directive.
                // using @scoped = System.Int32;
                Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using @scoped = System.Int32;").WithLocation(1, 1)
                );
 
            comp = CreateCompilation(source, parseOptions: TestOptions.Regular11);
            comp.VerifyDiagnostics(
                // (1,1): hidden CS8019: Unnecessary using directive.
                // using @scoped = System.Int32;
                Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using @scoped = System.Int32;").WithLocation(1, 1)
                );
        }
 
        [Theory]
        [InlineData("struct")]
        [InlineData("ref struct")]
        public void UnscopedRefAttribute_Method_01(string type)
        {
            var source =
$@"using System.Diagnostics.CodeAnalysis;
{type} S1
{{
    private int _field;
    public ref int GetField1() => ref _field; // 1
    [UnscopedRef] public ref int GetField2() => ref _field;
}}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (5,39): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //     public ref int GetField1() => ref _field; // 1
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "_field").WithLocation(5, 39));
        }
 
        [Theory]
        [InlineData("struct")]
        [InlineData("ref struct")]
        public void UnscopedRefAttribute_Method_02(string type)
        {
            var source =
$@"using System.Diagnostics.CodeAnalysis;
{type} S
{{
    ref S F1()
    {{
        ref S s1 = ref this;
        return ref s1;
    }}
    [UnscopedRef] ref S F2()
    {{
        ref S s2 = ref this;
        return ref s2;
    }}
}}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (7,20): error CS8157: Cannot return 's1' by reference because it was initialized to a value that cannot be returned by reference
                //         return ref s1;
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "s1").WithArguments("s1").WithLocation(7, 20));
        }
 
        [CombinatorialData]
        [Theory]
        public void UnscopedRefAttribute_Method_03(bool useCompilationReference)
        {
            var sourceA =
@"using System.Diagnostics.CodeAnalysis;
public struct S<T>
{
    private T _t;
    public ref T F1() => throw null;
    [UnscopedRef] public ref T F2() => ref _t;
}";
            var comp = CreateCompilation(new[] { sourceA, UnscopedRefAttributeDefinition });
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class Program
{
    static ref int F1()
    {
        var s = new S<int>();
        return ref s.F1();
    }
    static ref int F2()
    {
        var s = new S<int>();
        return ref s.F2(); // 1
    }
}";
            comp = CreateCompilation(sourceB, references: new[] { refA });
            comp.VerifyEmitDiagnostics(
                // (11,20): error CS8168: Cannot return local 's' by reference because it is not a ref local
                //         return ref s.F2(); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "s").WithArguments("s").WithLocation(11, 20));
        }
 
        [Theory]
        [InlineData("struct")]
        [InlineData("ref struct")]
        public void UnscopedRefAttribute_Method_04(string type)
        {
            var source =
$@"using System.Diagnostics.CodeAnalysis;
ref struct R
{{
    public R(ref S1 s1) {{ }}
    public R(in S2 s2) {{ }}
}}
{type} S1
{{
    void F1(ref R r1)
    {{
        r1 = new R(ref this); // 1
    }}
    [UnscopedRef] void F2(ref R r2)
    {{
        r2 = new R(ref this); // 2
    }}
}}
readonly {type} S2
{{
    void F3(ref R r3)
    {{
        r3 = new R(in this); // 3
    }}
    [UnscopedRef] void F4(ref R r4)
    {{
        r4 = new R(in this); // 4
    }}
}}
";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (11,14): error CS8347: Cannot use a result of 'R.R(ref S1)' in this context because it may expose variables referenced by parameter 's1' outside of their declaration scope
                //         r1 = new R(ref this); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R(ref this)").WithArguments("R.R(ref S1)", "s1").WithLocation(11, 14),
                // (11,24): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //         r1 = new R(ref this); // 1
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "this").WithLocation(11, 24),
                // (15,14): error CS8347: Cannot use a result of 'R.R(ref S1)' in this context because it may expose variables referenced by parameter 's1' outside of their declaration scope
                //         r2 = new R(ref this); // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R(ref this)").WithArguments("R.R(ref S1)", "s1").WithLocation(15, 14),
                // (15,24): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //         r2 = new R(ref this); // 2
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "this").WithLocation(15, 24),
                // (22,14): error CS8347: Cannot use a result of 'R.R(in S2)' in this context because it may expose variables referenced by parameter 's2' outside of their declaration scope
                //         r3 = new R(in this); // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R(in this)").WithArguments("R.R(in S2)", "s2").WithLocation(22, 14),
                // (22,23): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //         r3 = new R(in this); // 3
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "this").WithLocation(22, 23),
                // (26,14): error CS8347: Cannot use a result of 'R.R(in S2)' in this context because it may expose variables referenced by parameter 's2' outside of their declaration scope
                //         r4 = new R(in this); // 4
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R(in this)").WithArguments("R.R(in S2)", "s2").WithLocation(26, 14),
                // (26,23): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //         r4 = new R(in this); // 4
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "this").WithLocation(26, 23));
        }
 
        [Fact]
        public void UnscopedRefAttribute_Property_01()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
struct S1
{
    private int _field;
    public ref int Property1 => ref _field; // 1
    [UnscopedRef] public ref int Property2 => ref _field;
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (5,37): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //     public ref int Property1 => ref _field; // 1
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "_field").WithLocation(5, 37));
        }
 
        [CombinatorialData]
        [Theory]
        public void UnscopedRefAttribute_Property_02(bool useCompilationReference)
        {
            var sourceA =
@"using System.Diagnostics.CodeAnalysis;
public struct S<T>
{
    private T _t;
    public ref T P1 => throw null;
    [UnscopedRef] public ref T P2 => ref _t;
}";
            var comp = CreateCompilation(new[] { sourceA, UnscopedRefAttributeDefinition });
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class Program
{
    static ref int F1()
    {
        var s = new S<int>();
        return ref s.P1;
    }
    static ref int F2()
    {
        var s = new S<int>();
        return ref s.P2; // 1
    }
}";
            comp = CreateCompilation(sourceB, references: new[] { refA });
            comp.VerifyEmitDiagnostics(
                // (11,20): error CS8168: Cannot return local 's' by reference because it is not a ref local
                //         return ref s.P2; // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "s").WithArguments("s").WithLocation(11, 20));
        }
 
        [Fact]
        public void UnscopedRefAttribute_Property_03()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
struct S
{
    [UnscopedRef] object P1 { get; }
    [UnscopedRef] object P2 { get; set; }
    [UnscopedRef] object P3 { get; init; } // 1
    object P5
    {
        [UnscopedRef] get;
        [UnscopedRef] set;
    }
    object P6
    {
        [UnscopedRef] get;
        [UnscopedRef] init; // 2
    }
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition, IsExternalInitTypeDefinition });
            comp.VerifyDiagnostics(
                // (6,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] object P3 { get; init; } // 1
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(6, 6),
                // (15,10): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //         [UnscopedRef] init; // 2
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(15, 10));
        }
 
        [Theory]
        [CombinatorialData]
        public void UnscopedRefAttribute_Accessor_01(
            [CombinatorialValues("struct", "ref struct")] string type,
            [CombinatorialValues("ref", "ref readonly")] string refModifier)
        {
            var source =
$@"using System.Diagnostics.CodeAnalysis;
{type} S<T>
{{
    private T _t;
    {refModifier} T P1
    {{
        get => ref _t; // 1
    }}
    {refModifier} T P2
    {{
        [UnscopedRef]
        get => ref _t;
    }}
}}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (7,20): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //         get => ref _t; // 1
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "_t").WithLocation(7, 20));
        }
 
        [Fact]
        public void UnscopedRefAttribute_Accessor_02()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
ref struct R<T>
{
    public ref T F;
}
struct A
{
    R<A> this[int i]
    {
        get { return default; }
        set { value.F = ref this; } // 1
    }
}
struct B
{
    R<B> this[int i]
    {
        get { return default; }
        [UnscopedRef]
        set { value.F = ref this; } // 2
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (11,15): error CS8374: Cannot ref-assign 'this' to 'F' because 'this' has a narrower escape scope than 'F'.
                //         set { value.F = ref this; } // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "value.F = ref this").WithArguments("F", "this").WithLocation(11, 15),
                // (20,15): error CS9079: Cannot ref-assign 'this' to 'F' because 'this' can only escape the current method through a return statement.
                //         set { value.F = ref this; } // 2
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "value.F = ref this").WithArguments("F", "this").WithLocation(20, 15));
        }
 
        [Fact]
        public void UnscopedRefAttribute_Accessor_03()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
ref struct R<T>
{
    public ref T F;
}
struct A
{
    R<A> this[int i]
    {
        get { return default; }
        init { value.F = ref this; } // 1
    }
}
struct B
{
    R<B> this[int i]
    {
        get { return default; }
        [UnscopedRef]
        init { value.F = ref this; } // 2
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (11,16): error CS8374: Cannot ref-assign 'this' to 'F' because 'this' has a narrower escape scope than 'F'.
                //         init { value.F = ref this; } // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "value.F = ref this").WithArguments("F", "this").WithLocation(11, 16),
                // (19,10): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //         [UnscopedRef]
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(19, 10),
                // (20,16): error CS8374: Cannot ref-assign 'this' to 'F' because 'this' has a narrower escape scope than 'F'.
                //         init { value.F = ref this; } // 2
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "value.F = ref this").WithArguments("F", "this").WithLocation(20, 16));
        }
 
        [ConditionalFact(typeof(CoreClrOnly))]
        public void UnscopedRefAttribute_Event_01()
        {
            var source =
@"#pragma warning disable 67
using System.Diagnostics.CodeAnalysis;
delegate void D();
class C
{
    [UnscopedRef] event D E1; // 1
    [UnscopedRef] event D E2 { add { } remove { } } // 2
}
struct S
{
    [UnscopedRef] event D E3; // 3
    [UnscopedRef] event D E4 { add { } remove { } } // 4
}
interface I
{
    [UnscopedRef] event D E5; // 5
    [UnscopedRef] event D E6 { add { } remove { } } // 6
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }, targetFramework: TargetFramework.Net60);
            comp.VerifyDiagnostics(
                // (6,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] event D E1; // 1
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(6, 6),
                // (7,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] event D E2 { add { } remove { } } // 2
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(7, 6),
                // (11,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] event D E3; // 3
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(11, 6),
                // (12,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] event D E4 { add { } remove { } } // 4
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(12, 6),
                // (16,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] event D E5; // 5
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(16, 6),
                // (17,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] event D E6 { add { } remove { } } // 6
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(17, 6));
        }
 
        [ConditionalFact(typeof(CoreClrOnly))]
        public void UnscopedRefAttribute_Event_02()
        {
            var source =
@"#pragma warning disable 67
using System.Diagnostics.CodeAnalysis;
delegate void D();
class C
{
    event D E1 { [UnscopedRef] add { } remove { } } // 1
    event D E2 { add { } [UnscopedRef] remove { } } // 2
}
struct S
{
    event D E3 { [UnscopedRef] add { } remove { } } // 3
    event D E4 { add { } [UnscopedRef] remove { } } // 4
}
interface I
{
    event D E5 { [UnscopedRef] add { } remove { } } // 5
    event D E6 { add { } [UnscopedRef] remove { } } // 6
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (6,19): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     event D E1 { [UnscopedRef] add { } remove { } } // 1
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(6, 19),
                // (7,27): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     event D E2 { add { } [UnscopedRef] remove { } } // 2
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(7, 27),
                // (11,19): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     event D E3 { [UnscopedRef] add { } remove { } } // 3
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(11, 19),
                // (12,27): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     event D E4 { add { } [UnscopedRef] remove { } } // 4
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(12, 27),
                // (16,19): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     event D E5 { [UnscopedRef] add { } remove { } } // 5
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(16, 19),
                // (17,27): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     event D E6 { add { } [UnscopedRef] remove { } } // 6
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(17, 27));
        }
 
        [Theory]
        [InlineData("class")]
        [InlineData("struct")]
        [InlineData("ref struct")]
        public void UnscopedRefAttribute_Method_05(string type)
        {
            var source =
$@"using System.Diagnostics.CodeAnalysis;
{type} C
{{
    void F()
    {{
        var d = [UnscopedRef] (ref int i) => ref i;
        [UnscopedRef] ref int Local() => throw null;
        Local();
    }}
}}
";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (6,18): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //         var d = [UnscopedRef] (ref int i) => ref i;
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(6, 18),
                // (7,10): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //         [UnscopedRef] ref int Local() => throw null;
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(7, 10));
        }
 
        [Theory]
        [CombinatorialData]
        public void UnscopedRefAttribute_SubstitutedMembers(bool useCompilationReference)
        {
            var sourceA =
@"using System.Diagnostics.CodeAnalysis;
public ref struct R1<T>
{
    private T _t;
    public R1(T t) { _t = t; }
    public ref T Get() => ref this[0];
    public ref T this[int index] => throw null;
}
public ref struct R2<T>
{
    private T _t;
    public R2(T t) { _t = t; }
    [UnscopedRef] public ref T Get() => ref this[0];
    [UnscopedRef] public ref T this[int index] => ref _t;
}";
            var comp = CreateCompilation(new[] { sourceA, UnscopedRefAttributeDefinition });
            comp.VerifyEmitDiagnostics();
 
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class Program
{
    static ref int F1(bool b)
    {
        R1<int> r1 = new R1<int>(1);
        if (b) return ref r1.Get();
        return ref r1[0];
    }
    static ref int F2(bool b)
    {
        R2<int> r2 = new R2<int>(2);
        if (b) return ref r2.Get(); // 1
        return ref r2[0]; // 2
    }
}";
            comp = CreateCompilation(sourceB, references: new[] { refA });
            comp.VerifyDiagnostics(
                // (12,27): error CS8168: Cannot return local 'r2' by reference because it is not a ref local
                //         if (b) return ref r2.Get(); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "r2").WithArguments("r2").WithLocation(12, 27),
                // (13,20): error CS8168: Cannot return local 'r2' by reference because it is not a ref local
                //         return ref r2[0]; // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "r2").WithArguments("r2").WithLocation(13, 20));
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Where(v => v.Identifier.Text is "r1" or "r2").ToArray();
            var types = decls.Select(d => (NamedTypeSymbol)model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>().Type).ToArray();
 
            var type = types[0];
            Assert.Equal("R1<System.Int32>", type.ToTestDisplayString());
            VerifyParameterSymbol(type.GetMethod("Get").ThisParameter, "ref R1<System.Int32> this", RefKind.Ref, ScopedKind.ScopedRef, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(type.GetMethod("get_Item").ThisParameter, "ref R1<System.Int32> this", RefKind.Ref, ScopedKind.ScopedRef, expectedHasUnscopedRefAttribute: false);
 
            type = types[1];
            Assert.Equal("R2<System.Int32>", type.ToTestDisplayString());
            VerifyParameterSymbol(type.GetMethod("Get").ThisParameter, "ref R2<System.Int32> this", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(type.GetMethod("get_Item").ThisParameter, "ref R2<System.Int32> this", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
        }
 
        [Fact]
        public void UnscopedRefAttribute_RetargetingMembers()
        {
            var sourceA =
@"using System.Diagnostics.CodeAnalysis;
public ref struct R1<T>
{
    private readonly T _t;
    public R1(T t) { _t = t; }
    public ref readonly T Get() => ref this[0];
    public ref readonly T this[int index] => ref _t; // 1
}
public ref struct R2<T>
{
    private readonly T _t;
    public R2(T t) { _t = t; }
    [UnscopedRef] public ref readonly T Get() => ref this[0];
    [UnscopedRef] public ref readonly T this[int index] => ref _t;
}";
            var comp = CreateCompilation(new[] { sourceA, UnscopedRefAttributeDefinition }, targetFramework: TargetFramework.Mscorlib40);
            comp.VerifyDiagnostics(
                // (7,50): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //     public ref readonly T this[int index] => ref _t; // 1
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "_t").WithLocation(7, 50));
 
            var refA = comp.ToMetadataReference();
 
            var sourceB =
@"class Program
{
    static ref readonly int F1(bool b)
    {
        R1<int> r1 = new R1<int>(1);
        if (b) return ref r1.Get();
        return ref r1[0];
    }
    static ref readonly int F2(bool b)
    {
        R2<int> r2 = new R2<int>(2);
        if (b) return ref r2.Get(); // 1
        return ref r2[0]; // 2
    }
}";
            comp = CreateCompilation(sourceB, new[] { refA }, targetFramework: TargetFramework.Mscorlib45);
            comp.VerifyEmitDiagnostics(
                // (12,27): error CS8168: Cannot return local 'r2' by reference because it is not a ref local
                //         if (b) return ref r2.Get(); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "r2").WithArguments("r2").WithLocation(12, 27),
                // (13,20): error CS8168: Cannot return local 'r2' by reference because it is not a ref local
                //         return ref r2[0]; // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "r2").WithArguments("r2").WithLocation(13, 20));
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Where(v => v.Identifier.Text is "r1" or "r2").ToArray();
            var types = decls.Select(d => (NamedTypeSymbol)model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>().Type).ToArray();
 
            var type = types[0];
            var underlyingType = (RetargetingNamedTypeSymbol)type.OriginalDefinition;
            Assert.Equal("R1<System.Int32>", type.ToTestDisplayString());
            VerifyParameterSymbol(type.GetMethod("Get").ThisParameter, "ref R1<System.Int32> this", RefKind.Ref, ScopedKind.ScopedRef, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(type.GetMethod("get_Item").ThisParameter, "ref R1<System.Int32> this", RefKind.Ref, ScopedKind.ScopedRef, expectedHasUnscopedRefAttribute: false);
 
            type = types[1];
            underlyingType = (RetargetingNamedTypeSymbol)type.OriginalDefinition;
            Assert.Equal("R2<System.Int32>", type.ToTestDisplayString());
            VerifyParameterSymbol(type.GetMethod("Get").ThisParameter, "ref R2<System.Int32> this", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(type.GetMethod("get_Item").ThisParameter, "ref R2<System.Int32> this", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
        }
 
        [Fact]
        public void UnscopedRefAttribute_Constructor()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
ref struct R<T>
{
    public ref T F;
}
struct A
{
    A(R<A> r)
    {
        r.F = ref this; // 1
    }
}
struct B
{
    [UnscopedRef]
    B(R<B> r)
    {
        r.F = ref this; // 2
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (10,9): error CS8374: Cannot ref-assign 'this' to 'F' because 'this' has a narrower escape scope than 'F'.
                //         r.F = ref this; // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r.F = ref this").WithArguments("F", "this").WithLocation(10, 9),
                // (15,6): error CS0592: Attribute 'UnscopedRef' is not valid on this declaration type. It is only valid on 'method, property, indexer, parameter' declarations.
                //     [UnscopedRef]
                Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "UnscopedRef").WithArguments("UnscopedRef", "method, property, indexer, parameter").WithLocation(15, 6),
                // (18,9): error CS8374: Cannot ref-assign 'this' to 'F' because 'this' has a narrower escape scope than 'F'.
                //         r.F = ref this; // 2
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r.F = ref this").WithArguments("F", "this").WithLocation(18, 9));
 
            // With UnscopedRefAttribute definition that allows use on constructors.
            comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (10,9): error CS8374: Cannot ref-assign 'this' to 'F' because 'this' has a narrower escape scope than 'F'.
                //         r.F = ref this; // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r.F = ref this").WithArguments("F", "this").WithLocation(10, 9),
                // (15,6): warning CS0436: The type 'UnscopedRefAttribute' in '1.cs' conflicts with the imported type 'UnscopedRefAttribute' in 'System.Runtime, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. Using the type defined in ''.
                //     [UnscopedRef]
                Diagnostic(ErrorCode.WRN_SameFullNameThisAggAgg, "UnscopedRef").WithArguments("1.cs", "System.Diagnostics.CodeAnalysis.UnscopedRefAttribute", "System.Runtime, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Diagnostics.CodeAnalysis.UnscopedRefAttribute").WithLocation(15, 6),
                // (15,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef]
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(15, 6),
                // (18,9): error CS8374: Cannot ref-assign 'this' to 'F' because 'this' has a narrower escape scope than 'F'.
                //         r.F = ref this; // 2
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "r.F = ref this").WithArguments("F", "this").WithLocation(18, 9));
        }
 
        [Fact]
        public void UnscopedRefAttribute_Destructor()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
class C
{
    [UnscopedRef] ~C() { }
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (4,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] ~C() { }
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(4, 6));
        }
 
        [Fact]
        public void UnscopedRefAttribute_StaticMembers()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
struct S
{
    [UnscopedRef] static S() { } // 1
    [UnscopedRef] static object F() => null; // 2
    [UnscopedRef] static object P => null; // 3
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (4,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] static S() { } // 1
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(4, 6),
                // (5,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] static object F() => null; // 2
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(5, 6),
                // (6,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] static object P => null; // 3
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(6, 6));
        }
 
        [Fact]
        public void UnscopedRefAttribute_OtherTypes()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
class C
{
    [UnscopedRef] object F1() => null; // 1
}
record R
{
    [UnscopedRef] object F2() => null; // 2
}
record struct S
{
    [UnscopedRef] object F3() => null;
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (4,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] object F1() => null; // 1
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(4, 6),
                // (8,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] object F2() => null; // 2
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(8, 6));
        }
 
        [WorkItem(62691, "https://github.com/dotnet/roslyn/issues/62691")]
        [Fact]
        public void UnscopedRefAttribute_RefRefStructParameter_01()
        {
            var source =
@"
ref struct R { }
class Program
{
    static ref R ReturnRefStructRef(bool b, scoped ref R x, ref R y)
    {
        if (b)
            return ref x; // 1
        else
            return ref y;
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (8,24): error CS9075: Cannot return a parameter by reference 'x' because it is scoped to the current method
                //             return ref x; // 1
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "x").WithArguments("x").WithLocation(8, 24));
 
            var parameters = comp.GetMember<MethodSymbol>("Program.ReturnRefStructRef").Parameters;
            VerifyParameterSymbol(parameters[1], "scoped ref R x", RefKind.Ref, ScopedKind.ScopedRef);
            VerifyParameterSymbol(parameters[2], "ref R y", RefKind.Ref, ScopedKind.None);
        }
 
        [CombinatorialData]
        [Theory, WorkItem(63070, "https://github.com/dotnet/roslyn/issues/63070")]
        public void UnscopedRefAttribute_RefRefStructParameter_02(bool useCompilationReference)
        {
            var sourceA =
@"
public ref struct R<T>
{
    public ref T F;
    public R(ref T t) { F = ref t; }
}
public class A<T>
{
    public ref T F1A(ref R<T> r1)
    {
        return ref r1.F;
    }
    public ref T F2A(scoped ref R<T> r2)
    {
        return ref r2.F;
    }
}";
            var comp = CreateCompilation(sourceA, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB1 =
@"class B1 : A<int>
{
    ref int F1B()
    {
        int i = 1;
        var r = new R<int>(ref i);
        return ref F1A(ref r); // 1
    }
    ref int F2B()
    {
        int i = 2;
        var r = new R<int>(ref i);
        return ref F2A(ref r); // 2
    }
}";
            comp = CreateCompilation(sourceB1, references: new[] { refA }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (7,20): error CS8347: Cannot use a result of 'A<int>.F1A(ref R<int>)' in this context because it may expose variables referenced by parameter 'r1' outside of their declaration scope
                //         return ref F1A(ref r); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "F1A(ref r)").WithArguments("A<int>.F1A(ref R<int>)", "r1").WithLocation(7, 20),
                // (7,28): error CS8352: Cannot use variable 'r' in this context because it may expose referenced variables outside of their declaration scope
                //         return ref F1A(ref r); // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r").WithArguments("r").WithLocation(7, 28),
                // (13,20): error CS8347: Cannot use a result of 'A<int>.F2A(scoped ref R<int>)' in this context because it may expose variables referenced by parameter 'r2' outside of their declaration scope
                //         return ref F2A(ref r); // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "F2A(ref r)").WithArguments("A<int>.F2A(scoped ref R<int>)", "r2").WithLocation(13, 20),
                // (13,28): error CS8352: Cannot use variable 'r' in this context because it may expose referenced variables outside of their declaration scope
                //         return ref F2A(ref r); // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r").WithArguments("r").WithLocation(13, 28)
                );
 
            var baseType = comp.GetMember<NamedTypeSymbol>("B1").BaseTypeNoUseSiteDiagnostics;
            VerifyParameterSymbol(baseType.GetMethod("F1A").Parameters[0], "ref R<System.Int32> r1", RefKind.Ref, ScopedKind.None);
            VerifyParameterSymbol(baseType.GetMethod("F2A").Parameters[0], "scoped ref R<System.Int32> r2", RefKind.Ref, ScopedKind.ScopedRef);
 
            var sourceB2 =
@"class B2 : A<int>
{
    ref int F1B(ref int i)
    {
        var r = new R<int>(ref i);
        return ref F1A(ref r); // 1, 2
    }
    ref int F2B(ref int i)
    {
        var r = new R<int>(ref i);
        return ref F2A(ref r);
    }
 
    ref int F1C(ref int i)
    {
        var r = new R<int>(ref i);
        ref var y = ref F1A(ref r);
        return ref y; // 3
    }
    ref int F2C(ref int i)
    {
        var r = new R<int>(ref i);
        ref var y = ref F2A(ref r);
        return ref y;
    }
}";
            comp = CreateCompilation(sourceB2, references: new[] { refA }, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (6,20): error CS8347: Cannot use a result of 'A<int>.F1A(ref R<int>)' in this context because it may expose variables referenced by parameter 'r1' outside of their declaration scope
                //         return ref F1A(ref r); // 1, 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "F1A(ref r)").WithArguments("A<int>.F1A(ref R<int>)", "r1").WithLocation(6, 20),
                // (6,28): error CS8168: Cannot return local 'r' by reference because it is not a ref local
                //         return ref F1A(ref r); // 1, 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "r").WithArguments("r").WithLocation(6, 28),
                // (18,20): error CS8157: Cannot return 'y' by reference because it was initialized to a value that cannot be returned by reference
                //         return ref y; // 3
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "y").WithArguments("y").WithLocation(18, 20));
        }
 
        [Fact, WorkItem(63057, "https://github.com/dotnet/roslyn/issues/63057")]
        public void UnscopedScoped_Source()
        {
            var sourceA =
@"using System.Diagnostics.CodeAnalysis;
public ref struct R<T>
{
    public ref T F;
    public R(ref T t) { F = ref t; }
}
public class A<T>
{
    public ref T F1([UnscopedRef] scoped ref R<T> r1) // 1
    {
        return ref r1.F;
    }
    public ref T F2([UnscopedRef] scoped out T t2) // 2
    {
        t2 = default;
        return ref t2;
    }
    public ref T F3([UnscopedRef] scoped in R<T> t3) // 3
    {
        throw null;
    }
    public ref T F4([UnscopedRef] scoped R<T> t4) // 4
    {
        throw null;
    }
}";
            var comp = CreateCompilation(sourceA, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (9,22): error CS9066: UnscopedRefAttribute cannot be applied to parameters that have a 'scoped' modifier.
                //     public ref T F1([UnscopedRef] scoped ref R<T> r1) // 1
                Diagnostic(ErrorCode.ERR_UnscopedScoped, "UnscopedRef").WithLocation(9, 22),
                // (13,22): error CS9066: UnscopedRefAttribute cannot be applied to parameters that have a 'scoped' modifier.
                //     public ref T F2([UnscopedRef] scoped out T t2) // 2
                Diagnostic(ErrorCode.ERR_UnscopedScoped, "UnscopedRef").WithLocation(13, 22),
                // (18,22): error CS9066: UnscopedRefAttribute cannot be applied to parameters that have a 'scoped' modifier.
                //     public ref T F3([UnscopedRef] scoped in R<T> t3) // 3
                Diagnostic(ErrorCode.ERR_UnscopedScoped, "UnscopedRef").WithLocation(18, 22),
                // (22,22): error CS9063: UnscopedRefAttribute cannot be applied to this parameter because it is unscoped by default.
                //     public ref T F4([UnscopedRef] scoped R<T> t4) // 4
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedTarget, "UnscopedRef").WithLocation(22, 22));
 
            var type = comp.GetMember<NamedTypeSymbol>("A");
            VerifyParameterSymbol(type.GetMethod("F1").Parameters[0], "ref R<T> r1", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(type.GetMethod("F2").Parameters[0], "out T t2", RefKind.Out, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(type.GetMethod("F3").Parameters[0], "in R<T> t3", RefKind.In, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(type.GetMethod("F4").Parameters[0], "R<T> t4", RefKind.None, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
        }
 
        [Fact, WorkItem(63070, "https://github.com/dotnet/roslyn/issues/63070")]
        public void UnscopedScoped_Metadata()
        {
            // Equivalent to:
            // public class A<T>
            // {
            //      public ref T F4([UnscopedRef] scoped R<T> t4) { throw null; }
            // }
            var ilSource = """
.class public sequential ansi sealed beforefieldinit R`1<T>
	extends [mscorlib]System.ValueType
{
	.method public hidebysig specialname rtspecialname instance void .ctor ( !T& t ) cil managed
	{
        IL_0000: ldnull
        IL_0001: throw
	}
}
 
.class public auto ansi beforefieldinit A`1<T>
	extends [mscorlib]System.Object
{
    // [UnscopedRef] scoped parameter
	.method public hidebysig instance !T& F4A ( valuetype R`1<!T>& r4 ) cil managed
	{
		.param [1]
			.custom instance void System.Runtime.CompilerServices.ScopedRefAttribute::.ctor() = ( 01 00 00 00 )
			.custom instance void System.Diagnostics.CodeAnalysis.UnscopedRefAttribute::.ctor() = ( 01 00 00 00 )
        IL_0000: ldnull
        IL_0001: throw
	}
	.method public hidebysig specialname rtspecialname instance void .ctor () cil managed
	{
        IL_0000: ldnull
        IL_0001: throw
	}
}
 
.class private auto ansi sealed beforefieldinit System.Runtime.CompilerServices.ScopedRefAttribute
	extends [mscorlib]System.Attribute
{
	.method public hidebysig specialname rtspecialname instance void .ctor () cil managed
	{
        IL_0000: ldnull
        IL_0001: throw
	}
}
 
.class public auto ansi sealed beforefieldinit System.Diagnostics.CodeAnalysis.UnscopedRefAttribute
	extends [mscorlib]System.Attribute
{
	.method public hidebysig specialname rtspecialname
		instance void .ctor () cil managed
	{
        IL_0000: ldnull
        IL_0001: throw
	}
}
""";
            var refA = CompileIL(ilSource);
 
            var sourceB =
@"class B : A<int>
{
    ref int F4B()
    {
        int i = 4;
        var r = new R<int>(ref i);
        return ref F4A(ref r); // 1
    }
}";
            var comp = CreateCompilation(sourceB, references: new[] { refA });
            comp.VerifyEmitDiagnostics(
                // (7,20): error CS0570: 'A<T>.F4A(ref R<T>)' is not supported by the language
                //         return ref F4A(ref r); // 1
                Diagnostic(ErrorCode.ERR_BindToBogus, "F4A").WithArguments("A<T>.F4A(ref R<T>)").WithLocation(7, 20));
 
            var baseType = comp.GetMember<NamedTypeSymbol>("B").BaseTypeNoUseSiteDiagnostics;
            VerifyParameterSymbol(baseType.GetMethod("F4A").Parameters[0], "ref R<System.Int32> r4", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
        }
 
        [Fact]
        public void UnscopedRefAttribute_Parameter_01()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
class Program
{
    static void F([UnscopedRef] int x, [UnscopedRef] object y) { }
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (4,20): error CS9063: UnscopedRefAttribute cannot be applied to this parameter because it is unscoped by default.
                //     static void F([UnscopedRef] int x, [UnscopedRef] object y) { }
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedTarget, "UnscopedRef").WithLocation(4, 20),
                // (4,41): error CS9063: UnscopedRefAttribute cannot be applied to this parameter because it is unscoped by default.
                //     static void F([UnscopedRef] int x, [UnscopedRef] object y) { }
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedTarget, "UnscopedRef").WithLocation(4, 41));
 
            var parameters = comp.GetMember<MethodSymbol>("Program.F").Parameters;
            VerifyParameterSymbol(parameters[0], "System.Int32 x", RefKind.None, default, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(parameters[1], "System.Object y", RefKind.None, default, expectedHasUnscopedRefAttribute: true);
        }
 
        [Fact]
        public void UnscopedRefAttribute_OutParameter_01()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
class Program
{
    static ref int ReturnOut(bool b, out int x, [UnscopedRef] out int y)
    {
        x = 1;
        y = 2;
        if (b)
            return ref x; // 1
        else
            return ref y;
    }
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (9,24): error CS9075: Cannot return a parameter by reference 'x' because it is scoped to the current method
                //             return ref x; // 1
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "x").WithArguments("x").WithLocation(9, 24));
 
            var parameters = comp.GetMember<MethodSymbol>("Program.ReturnOut").Parameters;
            VerifyParameterSymbol(parameters[1], "out System.Int32 x", RefKind.Out, ScopedKind.ScopedRef, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(parameters[2], "out System.Int32 y", RefKind.Out, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
        }
 
        [CombinatorialData]
        [Theory]
        public void UnscopedRefAttribute_OutParameter_02(bool useCompilationReference)
        {
            var sourceA =
@"using System.Diagnostics.CodeAnalysis;
public class A<T>
{
    public ref T F1A(out T t1)
    {
        throw null;
    }
    public ref T F2A(scoped out T t2)
    {
        throw null;
    }
    public ref T F3A([UnscopedRef] out T t3)
    {
        t3 = default;
        return ref t3;
    }
}";
            var comp = CreateCompilation(new[] { sourceA, UnscopedRefAttributeDefinition });
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class B : A<int>
{
    ref int F1B()
    {
        int i = 1;
        return ref F1A(out i);
    }
    ref int F2B()
    {
        int i = 2;
        return ref F2A(out i);
    }
    ref int F3B()
    {
        int i = 3;
        return ref F3A(out i); // 1
    }
}";
            comp = CreateCompilation(sourceB, references: new[] { refA });
            comp.VerifyEmitDiagnostics(
                // (16,20): error CS8347: Cannot use a result of 'A<int>.F3A(out int)' in this context because it may expose variables referenced by parameter 't3' outside of their declaration scope
                //         return ref F3A(out i); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "F3A(out i)").WithArguments("A<int>.F3A(out int)", "t3").WithLocation(16, 20),
                // (16,28): error CS8168: Cannot return local 'i' by reference because it is not a ref local
                //         return ref F3A(out i); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i").WithArguments("i").WithLocation(16, 28));
 
            var baseType = comp.GetMember<NamedTypeSymbol>("B").BaseTypeNoUseSiteDiagnostics;
            VerifyParameterSymbol(baseType.GetMethod("F1A").Parameters[0], "out System.Int32 t1", RefKind.Out, ScopedKind.ScopedRef, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(baseType.GetMethod("F2A").Parameters[0], "out System.Int32 t2", RefKind.Out, ScopedKind.ScopedRef, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(baseType.GetMethod("F3A").Parameters[0], "out System.Int32 t3", RefKind.Out, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
        }
 
        [Fact]
        public void UnscopedRefAttribute_RefParameter()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
public class A<T>
{
    public ref T F1A(ref T t1) => ref t1;
    public ref T F2A(scoped ref T t2) => throw null;
    public ref T F3A([UnscopedRef] ref T t3) => ref t3;
    public ref T F4A([UnscopedRef] scoped ref T t4) => ref t4;
}
class B : A<int>
{
    ref int F1B()
    {
        int i = 1;
        return ref F1A(ref i); // 1
    }
    ref int F2B()
    {
        int i = 2;
        return ref F2A(ref i);
    }
    ref int F3B()
    {
        int i = 3;
        return ref F3A(ref i); // 2
    }
    ref int F4B()
    {
        int i = 4;
        return ref F4A(ref i); // 3
    }
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyEmitDiagnostics(
                // (7,23): error CS9066: UnscopedRefAttribute cannot be applied to parameters that have a 'scoped' modifier.
                //     public ref T F4A([UnscopedRef] scoped ref T t4) => ref t4;
                Diagnostic(ErrorCode.ERR_UnscopedScoped, "UnscopedRef").WithLocation(7, 23),
                // (14,20): error CS8347: Cannot use a result of 'A<int>.F1A(ref int)' in this context because it may expose variables referenced by parameter 't1' outside of their declaration scope
                //         return ref F1A(ref i); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "F1A(ref i)").WithArguments("A<int>.F1A(ref int)", "t1").WithLocation(14, 20),
                // (14,28): error CS8168: Cannot return local 'i' by reference because it is not a ref local
                //         return ref F1A(ref i); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i").WithArguments("i").WithLocation(14, 28),
                // (24,20): error CS8347: Cannot use a result of 'A<int>.F3A(ref int)' in this context because it may expose variables referenced by parameter 't3' outside of their declaration scope
                //         return ref F3A(ref i); // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "F3A(ref i)").WithArguments("A<int>.F3A(ref int)", "t3").WithLocation(24, 20),
                // (24,28): error CS8168: Cannot return local 'i' by reference because it is not a ref local
                //         return ref F3A(ref i); // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i").WithArguments("i").WithLocation(24, 28),
                // (29,20): error CS8347: Cannot use a result of 'A<int>.F4A(ref int)' in this context because it may expose variables referenced by parameter 't4' outside of their declaration scope
                //         return ref F4A(ref i); // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "F4A(ref i)").WithArguments("A<int>.F4A(ref int)", "t4").WithLocation(29, 20),
                // (29,28): error CS8168: Cannot return local 'i' by reference because it is not a ref local
                //         return ref F4A(ref i); // 3
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i").WithArguments("i").WithLocation(29, 28));
 
            var baseType = comp.GetMember<NamedTypeSymbol>("B").BaseTypeNoUseSiteDiagnostics;
            VerifyParameterSymbol(baseType.GetMethod("F1A").Parameters[0], "ref System.Int32 t1", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(baseType.GetMethod("F2A").Parameters[0], "scoped ref System.Int32 t2", RefKind.Ref, ScopedKind.ScopedRef, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(baseType.GetMethod("F3A").Parameters[0], "ref System.Int32 t3", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(baseType.GetMethod("F4A").Parameters[0], "ref System.Int32 t4", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
        }
 
        [Fact]
        public void UnscopedRefAttribute_InParameter()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
public class A<T>
{
    public ref readonly T F1A(in T t1) => ref t1;
    public ref readonly T F2A(scoped in T t2) => throw null;
    public ref readonly T F3A([UnscopedRef] in T t3) => ref t3;
    public ref readonly T F4A([UnscopedRef] scoped in T t4) => ref t4;
}
class B : A<int>
{
    ref readonly int F1B()
    {
        int i = 1;
        return ref F1A(in i); // 1
    }
    ref readonly int F2B()
    {
        int i = 2;
        return ref F2A(in i);
    }
    ref readonly int F3B()
    {
        int i = 3;
        return ref F3A(in i); // 2
    }
    ref readonly int F4B()
    {
        int i = 4;
        return ref F4A(in i); // 3
    }
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyEmitDiagnostics(
                // (7,32): error CS9066: UnscopedRefAttribute cannot be applied to parameters that have a 'scoped' modifier.
                //     public ref readonly T F4A([UnscopedRef] scoped in T t4) => ref t4;
                Diagnostic(ErrorCode.ERR_UnscopedScoped, "UnscopedRef").WithLocation(7, 32),
                // (14,20): error CS8347: Cannot use a result of 'A<int>.F1A(in int)' in this context because it may expose variables referenced by parameter 't1' outside of their declaration scope
                //         return ref F1A(in i); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "F1A(in i)").WithArguments("A<int>.F1A(in int)", "t1").WithLocation(14, 20),
                // (14,27): error CS8168: Cannot return local 'i' by reference because it is not a ref local
                //         return ref F1A(in i); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i").WithArguments("i").WithLocation(14, 27),
                // (24,20): error CS8347: Cannot use a result of 'A<int>.F3A(in int)' in this context because it may expose variables referenced by parameter 't3' outside of their declaration scope
                //         return ref F3A(in i); // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "F3A(in i)").WithArguments("A<int>.F3A(in int)", "t3").WithLocation(24, 20),
                // (24,27): error CS8168: Cannot return local 'i' by reference because it is not a ref local
                //         return ref F3A(in i); // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i").WithArguments("i").WithLocation(24, 27),
                // (29,20): error CS8347: Cannot use a result of 'A<int>.F4A(in int)' in this context because it may expose variables referenced by parameter 't4' outside of their declaration scope
                //         return ref F4A(in i); // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "F4A(in i)").WithArguments("A<int>.F4A(in int)", "t4").WithLocation(29, 20),
                // (29,27): error CS8168: Cannot return local 'i' by reference because it is not a ref local
                //         return ref F4A(in i); // 3
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i").WithArguments("i").WithLocation(29, 27));
 
            var baseType = comp.GetMember<NamedTypeSymbol>("B").BaseTypeNoUseSiteDiagnostics;
            VerifyParameterSymbol(baseType.GetMethod("F1A").Parameters[0], "in System.Int32 t1", RefKind.In, ScopedKind.None, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(baseType.GetMethod("F2A").Parameters[0], "scoped in System.Int32 t2", RefKind.In, ScopedKind.ScopedRef, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(baseType.GetMethod("F3A").Parameters[0], "in System.Int32 t3", RefKind.In, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(baseType.GetMethod("F4A").Parameters[0], "in System.Int32 t4", RefKind.In, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
        }
 
        [Fact]
        public void UnscopedRefAttribute_RefStructParameter_01()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
public ref struct R<T>
{
    public ref T F;
    public R(ref T t) { F = ref t; }
}
public class A<T>
{
    public ref T F1A(R<T> r1)
    {
        return ref r1.F;
    }
    public ref T F2A(scoped R<T> r2)
    {
        throw null;
    }
    public ref T F3A([UnscopedRef] R<T> r3)
    {
        return ref r3.F;
    }
    public ref T F4A([UnscopedRef] scoped R<T> r4)
    {
        return ref r4.F;
    }
}
class B : A<int>
{
    ref int F1B()
    {
        int i = 1;
        var r = new R<int>(ref i);
        return ref F1A(r); // 1
    }
    ref int F2B()
    {
        int i = 2;
        var r = new R<int>(ref i);
        return ref F2A(r);
    }
    ref int F3B()
    {
        int i = 3;
        var r = new R<int>(ref i);
        return ref F3A(r); // 2
    }
    ref int F4B()
    {
        int i = 4;
        var r = new R<int>(ref i);
        return ref F4A(r); // 3
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (17,23): error CS9063: UnscopedRefAttribute cannot be applied to this parameter because it is unscoped by default.
                //     public ref T F3A([UnscopedRef] R<T> r3)
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedTarget, "UnscopedRef").WithLocation(17, 23),
                // (21,23): error CS9063: UnscopedRefAttribute cannot be applied to this parameter because it is unscoped by default.
                //     public ref T F4A([UnscopedRef] scoped R<T> r4)
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedTarget, "UnscopedRef").WithLocation(21, 23),
                // (32,20): error CS8347: Cannot use a result of 'A<int>.F1A(R<int>)' in this context because it may expose variables referenced by parameter 'r1' outside of their declaration scope
                //         return ref F1A(r); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "F1A(r)").WithArguments("A<int>.F1A(R<int>)", "r1").WithLocation(32, 20),
                // (32,24): error CS8352: Cannot use variable 'r' in this context because it may expose referenced variables outside of their declaration scope
                //         return ref F1A(r); // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r").WithArguments("r").WithLocation(32, 24),
                // (44,20): error CS8347: Cannot use a result of 'A<int>.F3A(R<int>)' in this context because it may expose variables referenced by parameter 'r3' outside of their declaration scope
                //         return ref F3A(r); // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "F3A(r)").WithArguments("A<int>.F3A(R<int>)", "r3").WithLocation(44, 20),
                // (44,24): error CS8352: Cannot use variable 'r' in this context because it may expose referenced variables outside of their declaration scope
                //         return ref F3A(r); // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r").WithArguments("r").WithLocation(44, 24),
                // (50,20): error CS8347: Cannot use a result of 'A<int>.F4A(R<int>)' in this context because it may expose variables referenced by parameter 'r4' outside of their declaration scope
                //         return ref F4A(r); // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "F4A(r)").WithArguments("A<int>.F4A(R<int>)", "r4").WithLocation(50, 20),
                // (50,24): error CS8352: Cannot use variable 'r' in this context because it may expose referenced variables outside of their declaration scope
                //         return ref F4A(r); // 3
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r").WithArguments("r").WithLocation(50, 24));
 
            var baseType = comp.GetMember<NamedTypeSymbol>("B").BaseTypeNoUseSiteDiagnostics;
            VerifyParameterSymbol(baseType.GetMethod("F1A").Parameters[0], "R<System.Int32> r1", RefKind.None, ScopedKind.None, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(baseType.GetMethod("F2A").Parameters[0], "scoped R<System.Int32> r2", RefKind.None, ScopedKind.ScopedValue, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(baseType.GetMethod("F3A").Parameters[0], "R<System.Int32> r3", RefKind.None, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(baseType.GetMethod("F4A").Parameters[0], "R<System.Int32> r4", RefKind.None, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
        }
 
        [Fact]
        public void UnscopedRefAttribute_RefStructParameter_02()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
public ref struct R<T>
{
    public ref T F;
}
class Program
{
    static void F1<T>([UnscopedRef] R<T> r1) { } // 1
    static void F2<T>([UnscopedRef] ref R<T> r2) { }
    static void F3<T>([UnscopedRef] in R<T> r3) { }
    static void F4<T>([UnscopedRef] out R<T> r4) { r4 = default; }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (8,24): error CS9063: UnscopedRefAttribute cannot be applied to this parameter because it is unscoped by default.
                //     static void F1<T>([UnscopedRef] R<T> r1) { } // 1
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedTarget, "UnscopedRef").WithLocation(8, 24));
 
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F1").Parameters[0], "R<T> r1", RefKind.None, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F2").Parameters[0], "ref R<T> r2", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F3").Parameters[0], "in R<T> r3", RefKind.In, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F4").Parameters[0], "out R<T> r4", RefKind.Out, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
        }
 
        [Fact]
        public void UnscopedRefAttribute_Overrides_01()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
abstract class A<T>
{
    internal abstract ref T F1(out T t);
    internal abstract ref T F2([UnscopedRef] out T t);
}
class B1 : A<int>
{
    internal override ref int F1(out int i) => throw null;
    internal override ref int F2([UnscopedRef] out int i) => throw null;
}
class B2 : A<int>
{
    internal override ref int F1([UnscopedRef] out int i) => throw null; // 1
    internal override ref int F2(out int i) => throw null;
}
";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (14,31): error CS8987: The 'scoped' modifier of parameter 'i' doesn't match overridden or implemented member.
                //     internal override ref int F1([UnscopedRef] out int i) => throw null; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("i").WithLocation(14, 31));
        }
 
        [Fact]
        public void UnscopedRefAttribute_Overrides_02()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
abstract class A<T>
{
    internal abstract ref T F1(ref T t);
    internal abstract ref T F2([UnscopedRef] ref T t);
}
class B1 : A<int>
{
    internal override ref int F1(ref int i) => throw null;
    internal override ref int F2([UnscopedRef] ref int i) => throw null;
}
class B2 : A<int>
{
    internal override ref int F1([UnscopedRef] ref int i) => throw null; // 1
    internal override ref int F2(ref int i) => throw null;
}
";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (14,31): error CS8987: The 'scoped' modifier of parameter 'i' doesn't match overridden or implemented member.
                //     internal override ref int F1([UnscopedRef] ref int i) => throw null; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("i").WithLocation(14, 31));
        }
 
        [Fact]
        public void UnscopedRefAttribute_Overrides_03()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
ref struct R<T>
{
}
abstract class A<T>
{
    internal abstract ref T F1(ref R<T> r);
    internal abstract ref T F2([UnscopedRef] ref R<T> r);
}
class B1 : A<int>
{
    internal override ref int F1(ref R<int> r) => throw null;
    internal override ref int F2([UnscopedRef] ref R<int> r) => throw null;
}
class B2 : A<int>
{
    internal override ref int F1([UnscopedRef] ref R<int> r) => throw null; // 1
    internal override ref int F2(ref R<int> r) => throw null;
}
";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (17,31): error CS8987: The 'scoped' modifier of parameter 'r' doesn't match overridden or implemented member.
                //     internal override ref int F1([UnscopedRef] ref R<int> r) => throw null; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("r").WithLocation(17, 31));
        }
 
        [Fact]
        public void UnscopedRefAttribute_Implementations_01()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
interface I<T>
{
    ref readonly T F1(out T t);
    ref readonly T F2([UnscopedRef] out T t);
}
class C1 : I<int>
{
    public ref readonly int F1(out int i) => throw null;
    public ref readonly int F2([UnscopedRef] out int i) => throw null;
}
class C2 : I<int>
{
    public ref readonly int F1([UnscopedRef] out int i) => throw null; // 1
    public ref readonly int F2(out int i) => throw null;
}
class C3 : I<object>
{
    ref readonly object I<object>.F1(out object o) => throw null;
    ref readonly object I<object>.F2([UnscopedRef] out object o) => throw null;
}
class C4 : I<object>
{
    ref readonly object I<object>.F1([UnscopedRef] out object o) => throw null; // 2
    ref readonly object I<object>.F2(out object o) => throw null;
}
";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (14,29): error CS8987: The 'scoped' modifier of parameter 'i' doesn't match overridden or implemented member.
                //     public ref readonly int F1([UnscopedRef] out int i) => throw null; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("i").WithLocation(14, 29),
                // (24,35): error CS8987: The 'scoped' modifier of parameter 'o' doesn't match overridden or implemented member.
                //     ref readonly object I<object>.F1([UnscopedRef] out object o) => throw null; // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("o").WithLocation(24, 35));
        }
 
        [Fact]
        public void UnscopedRefAttribute_Implementations_02()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
interface I<T>
{
    ref readonly T F1(ref T t);
    ref readonly T F2([UnscopedRef] ref T t);
}
class C1 : I<int>
{
    public ref readonly int F1(ref int i) => throw null;
    public ref readonly int F2([UnscopedRef] ref int i) => throw null;
}
class C2 : I<int>
{
    public ref readonly int F1([UnscopedRef] ref int i) => throw null; // 1
    public ref readonly int F2(ref int i) => throw null;
}
class C3 : I<object>
{
    ref readonly object I<object>.F1(ref object o) => throw null;
    ref readonly object I<object>.F2([UnscopedRef] ref object o) => throw null;
}
class C4 : I<object>
{
    ref readonly object I<object>.F1([UnscopedRef] ref object o) => throw null; // 2
    ref readonly object I<object>.F2(ref object o) => throw null;
}
";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (14,29): error CS8987: The 'scoped' modifier of parameter 'i' doesn't match overridden or implemented member.
                //     public ref readonly int F1([UnscopedRef] ref int i) => throw null; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("i").WithLocation(14, 29),
                // (24,35): error CS8987: The 'scoped' modifier of parameter 'o' doesn't match overridden or implemented member.
                //     ref readonly object I<object>.F1([UnscopedRef] ref object o) => throw null; // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("o").WithLocation(24, 35));
        }
 
        [Fact]
        public void ScopedRefToRefStruct_Implementations_03()
        {
            var source =
@"
ref struct R<T>
{
}
interface I<T>
{
    ref readonly T F1(scoped ref R<T> r);
    ref readonly T F2(ref R<T> r);
}
class C1 : I<int>
{
    public ref readonly int F1(scoped ref R<int> r) => throw null;
    public ref readonly int F2(ref R<int> r) => throw null;
}
class C2 : I<int>
{
    public ref readonly int F1(ref R<int> r) => throw null; // 1
    public ref readonly int F2(scoped ref R<int> r) => throw null;
}
class C3 : I<object>
{
    ref readonly object I<object>.F1(scoped ref R<object> r) => throw null;
    ref readonly object I<object>.F2(ref R<object> r) => throw null;
}
class C4 : I<object>
{
    ref readonly object I<object>.F1(ref R<object> r) => throw null; // 2
    ref readonly object I<object>.F2(scoped ref R<object> r) => throw null;
}
";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (17,29): error CS8987: The 'scoped' modifier of parameter 'r' doesn't match overridden or implemented member.
                //     public ref readonly int F1(ref R<int> r) => throw null; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("r").WithLocation(17, 29),
                // (27,35): error CS8987: The 'scoped' modifier of parameter 'r' doesn't match overridden or implemented member.
                //     ref readonly object I<object>.F1(ref R<object> r) => throw null; // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("r").WithLocation(27, 35));
        }
 
        [Fact]
        public void UnscopedRefAttribute_Delegates_01()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
delegate ref T D1<T>(out T t);
delegate ref T D2<T>([UnscopedRef] out T t);
class Program
{
    static void Main()
    {
        D1<int> d1;
        d1 = (out int i1) => { i1 = 1; return ref F<int>(); };
        d1 = ([UnscopedRef] out int i2) => { i2 = 2; return ref F<int>(); }; // 1
        D2<object> d2;
        d2 = (out object o1) => { o1 = 1; return ref F<object>(); };
        d2 = ([UnscopedRef] out object o2) => { o2 = 2; return ref F<object>(); };
    }
    static ref T F<T>() => throw null;
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (10,14): error CS8986: The 'scoped' modifier of parameter 'i2' doesn't match target 'D1<int>'.
                //         d1 = ([UnscopedRef] out int i2) => { i2 = 2; return ref F<int>(); }; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "([UnscopedRef] out int i2) => { i2 = 2; return ref F<int>(); }").WithArguments("i2", "D1<int>").WithLocation(10, 14));
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var lambdas = tree.GetRoot().DescendantNodes().OfType<ParenthesizedLambdaExpressionSyntax>().Select(e => model.GetSymbolInfo(e).Symbol.GetSymbol<LambdaSymbol>()).ToArray();
 
            VerifyParameterSymbol(lambdas[0].Parameters[0], "out System.Int32 i1", RefKind.Out, ScopedKind.ScopedRef, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(lambdas[1].Parameters[0], "out System.Int32 i2", RefKind.Out, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(lambdas[2].Parameters[0], "out System.Object o1", RefKind.Out, ScopedKind.ScopedRef, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(lambdas[3].Parameters[0], "out System.Object o2", RefKind.Out, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
        }
 
        [Fact]
        public void UnscopedRefAttribute_Delegates_02()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
delegate ref T D1<T>(ref T t);
delegate ref T D2<T>([UnscopedRef] ref T t);
class Program
{
    static void Main()
    {
        D1<int> d1;
        d1 = (ref int i1) => ref F<int>();
        d1 = ([UnscopedRef] ref int i2) => ref F<int>(); // 1
        D2<object> d2;
        d2 = (ref object o1) => ref F<object>();
        d2 = ([UnscopedRef] ref object o2) => ref F<object>();
    }
    static ref T F<T>() => throw null;
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (10,14): error CS8986: The 'scoped' modifier of parameter 'i2' doesn't match target 'D1<int>'.
                //         d1 = ([UnscopedRef] ref int i2) => ref F<int>();
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "([UnscopedRef] ref int i2) => ref F<int>()").WithArguments("i2", "D1<int>").WithLocation(10, 14));
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var lambdas = tree.GetRoot().DescendantNodes().OfType<ParenthesizedLambdaExpressionSyntax>().Select(e => model.GetSymbolInfo(e).Symbol.GetSymbol<LambdaSymbol>()).ToArray();
 
            VerifyParameterSymbol(lambdas[0].Parameters[0], "ref System.Int32 i1", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(lambdas[1].Parameters[0], "ref System.Int32 i2", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(lambdas[2].Parameters[0], "ref System.Object o1", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(lambdas[3].Parameters[0], "ref System.Object o2", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
        }
 
        [Fact]
        public void UnscopedRefAttribute_Delegates_03()
        {
            var source =
@"
ref struct R<T> { }
delegate ref readonly T D1<T>(scoped ref R<T> r);
delegate ref readonly T D2<T>(ref R<T> r);
class Program
{
    static void Main()
    {
        D1<int> d1;
        d1 = (scoped ref R<int> r1) => ref F<int>();
        d1 = (ref R<int> r2) => ref F<int>(); // 1
        D2<object> d2;
        d2 = (scoped ref R<object> r1) => ref F<object>();
        d2 = (ref R<object> r2) => ref F<object>();
    }
    static ref readonly T F<T>() => throw null;
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (11,14): error CS8986: The 'scoped' modifier of parameter 'r2' doesn't match target 'D1<int>'.
                //         d1 = (ref R<int> r2) => ref F<int>(); // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "(ref R<int> r2) => ref F<int>()").WithArguments("r2", "D1<int>").WithLocation(11, 14));
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var lambdas = tree.GetRoot().DescendantNodes().OfType<ParenthesizedLambdaExpressionSyntax>().Select(e => model.GetSymbolInfo(e).Symbol.GetSymbol<LambdaSymbol>()).ToArray();
 
            VerifyParameterSymbol(lambdas[0].Parameters[0], "scoped ref R<System.Int32> r1", RefKind.Ref, ScopedKind.ScopedRef, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(lambdas[1].Parameters[0], "ref R<System.Int32> r2", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(lambdas[2].Parameters[0], "scoped ref R<System.Object> r1", RefKind.Ref, ScopedKind.ScopedRef, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(lambdas[3].Parameters[0], "ref R<System.Object> r2", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: false);
        }
 
        [WorkItem(64569, "https://github.com/dotnet/roslyn/issues/64569")]
        [Fact]
        public void UnscopedRefAttribute_RefParameter_01()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
ref struct R
{
    public R(in int i) { }
    void SetRef(ref int i1)
    {
        this = new R(in i1); // 1
    }
    void SetIn(in int i2)
    {
        this = new R(in i2); // 2
    }
    void SetOut(out int i3)
    {
        i3 = 0;
        this = new R(in i3); // 3
    }
    void SetUnscopedRef([UnscopedRef] ref int i4)
    {
        this = new R(in i4);
    }
    void SetUnscopedIn([UnscopedRef] in int i5)
    {
        this = new R(in i5);
    }
    void SetUnscopedOut([UnscopedRef] out int i6)
    {
        i6 = 0;
        this = new R(in i6); // 4
    }
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (7,16): error CS8347: Cannot use a result of 'R.R(in int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         this = new R(in i1); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R(in i1)").WithArguments("R.R(in int)", "i").WithLocation(7, 16),
                // (7,25): error CS9077: Cannot return a parameter by reference 'i1' through a ref parameter; it can only be returned in a return statement
                //         this = new R(in i1); // 1
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "i1").WithArguments("i1").WithLocation(7, 25),
                // (11,16): error CS8347: Cannot use a result of 'R.R(in int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         this = new R(in i2); // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R(in i2)").WithArguments("R.R(in int)", "i").WithLocation(11, 16),
                // (11,25): error CS9077: Cannot return a parameter by reference 'i2' through a ref parameter; it can only be returned in a return statement
                //         this = new R(in i2); // 2
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "i2").WithArguments("i2").WithLocation(11, 25),
                // (16,16): error CS8347: Cannot use a result of 'R.R(in int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         this = new R(in i3); // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R(in i3)").WithArguments("R.R(in int)", "i").WithLocation(16, 16),
                // (16,25): error CS9075: Cannot return a parameter by reference 'i3' because it is scoped to the current method
                //         this = new R(in i3); // 3
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "i3").WithArguments("i3").WithLocation(16, 25),
                // (29,16): error CS8347: Cannot use a result of 'R.R(in int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         this = new R(in i6); // 4
                Diagnostic(ErrorCode.ERR_EscapeCall, "new R(in i6)").WithArguments("R.R(in int)", "i").WithLocation(29, 16),
                // (29,25): error CS9077: Cannot return a parameter by reference 'i6' through a ref parameter; it can only be returned in a return statement
                //         this = new R(in i6); // 4
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "i6").WithArguments("i6").WithLocation(29, 25));
        }
 
        [WorkItem(64569, "https://github.com/dotnet/roslyn/issues/64569")]
        [Fact]
        public void UnscopedRefAttribute_RefParameter_02()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
ref struct R
{
    private ref readonly int _i;
    void SetRef(ref int i1)
    {
        _i = ref i1; // 1
    }
    void SetIn(in int i2)
    {
        _i = ref i2; // 2
    }
    void SetOut(out int i3)
    {
        i3 = 0;
        _i = ref i3; // 3
    }
    void SetUnscopedRef([UnscopedRef] ref int i4)
    {
        _i = ref i4;
    }
    void SetUnscopedIn([UnscopedRef] in int i5)
    {
        _i = ref i5;
    }
    void SetUnscopedOut([UnscopedRef] out int i6)
    {
        i6 = 0;
        _i = ref i6; // 4
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (7,9): error CS9079: Cannot ref-assign 'i1' to '_i' because 'i1' can only escape the current method through a return statement.
                //         _i = ref i1; // 1
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "_i = ref i1").WithArguments("_i", "i1").WithLocation(7, 9),
                // (11,9): error CS9079: Cannot ref-assign 'i2' to '_i' because 'i2' can only escape the current method through a return statement.
                //         _i = ref i2; // 2
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "_i = ref i2").WithArguments("_i", "i2").WithLocation(11, 9),
                // (16,9): error CS8374: Cannot ref-assign 'i3' to '_i' because 'i3' has a narrower escape scope than '_i'.
                //         _i = ref i3; // 3
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "_i = ref i3").WithArguments("_i", "i3").WithLocation(16, 9),
                // (29,9): error CS9079: Cannot ref-assign 'i6' to '_i' because 'i6' can only escape the current method through a return statement.
                //         _i = ref i6; // 4
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "_i = ref i6").WithArguments("_i", "i6").WithLocation(29, 9));
        }
 
        [Theory]
        [CombinatorialData]
        public void UnscopedRefAttribute_RefParameter_03(bool useCompilationReference)
        {
            var sourceA =
@"using System.Diagnostics.CodeAnalysis;
public ref struct R1<T>
{
    public R1(ref T t) { }
}
public ref struct R2<T>
{
    public R2(in T t) { }
}
public class A<T>
{
    public static ref T Ref(ref T t1, ref R1<T> r1)
    {
        return ref t1;
    }
    public static ref T UnscopedRef([UnscopedRef] ref T t2, ref R1<T> r2)
    {
        r2 = new R1<T>(ref t2);
        return ref t2;
    }
    public static ref readonly T In(in T t3, ref R2<T> r3)
    {
        return ref t3;
    }
    public static ref readonly T UnscopedIn([UnscopedRef] in T t4, ref R2<T> r4)
    {
        r4 = new R2<T>(in t4);
        return ref t4;
    }
    public static ref T Out(out T t5)
    {
        t5 = default;
        throw null;
    }
    public static ref T UnscopedOut([UnscopedRef] out T t6)
    {
        t6 = default;
        return ref t6;
    }
}";
            var comp = CreateCompilation(new[] { sourceA, UnscopedRefAttributeDefinition });
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class B : A<int>
{
    static void F1(ref R1<int> r1)
    {
        int i1 = 1;
        Ref(ref i1, ref r1);
    }
    static void F2(ref R1<int> r2)
    {
        int i2 = 2;
        UnscopedRef(ref i2, ref r2); // 1
    }
    static void F3(ref R2<int> r3)
    {
        int i3 = 3;
        In(in i3, ref r3);
    }
    static void F4(ref R2<int> r4)
    {
        int i4 = 4;
        UnscopedIn(in i4, ref r4); // 2
    }
    static ref int F5()
    {
        int i5;
        return ref Out(out i5);
    }
    static ref int F6()
    {
        int i6;
        return ref UnscopedOut(out i6); // 3
    }
}";
            comp = CreateCompilation(new[] { sourceB, UnscopedRefAttributeDefinition }, references: new[] { refA });
            comp.VerifyEmitDiagnostics(
                // (11,9): error CS8350: This combination of arguments to 'A<int>.UnscopedRef(ref int, ref R1<int>)' is disallowed because it may expose variables referenced by parameter 't2' outside of their declaration scope
                //         UnscopedRef(ref i2, ref r2); // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, "UnscopedRef(ref i2, ref r2)").WithArguments("A<int>.UnscopedRef(ref int, ref R1<int>)", "t2").WithLocation(11, 9),
                // (11,25): error CS8168: Cannot return local 'i2' by reference because it is not a ref local
                //         UnscopedRef(ref i2, ref r2); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i2").WithArguments("i2").WithLocation(11, 25),
                // (21,9): error CS8350: This combination of arguments to 'A<int>.UnscopedIn(in int, ref R2<int>)' is disallowed because it may expose variables referenced by parameter 't4' outside of their declaration scope
                //         UnscopedIn(in i4, ref r4); // 2
                Diagnostic(ErrorCode.ERR_CallArgMixing, "UnscopedIn(in i4, ref r4)").WithArguments("A<int>.UnscopedIn(in int, ref R2<int>)", "t4").WithLocation(21, 9),
                // (21,23): error CS8168: Cannot return local 'i4' by reference because it is not a ref local
                //         UnscopedIn(in i4, ref r4); // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i4").WithArguments("i4").WithLocation(21, 23),
                // (31,20): error CS8347: Cannot use a result of 'A<int>.UnscopedOut(out int)' in this context because it may expose variables referenced by parameter 't6' outside of their declaration scope
                //         return ref UnscopedOut(out i6); // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "UnscopedOut(out i6)").WithArguments("A<int>.UnscopedOut(out int)", "t6").WithLocation(31, 20),
                // (31,36): error CS8168: Cannot return local 'i6' by reference because it is not a ref local
                //         return ref UnscopedOut(out i6); // 3
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i6").WithArguments("i6").WithLocation(31, 36));
        }
 
        [Fact]
        public void UnscopedRefAttribute_Cycle()
        {
            var source =
@"namespace System.Diagnostics.CodeAnalysis
{
    public sealed class UnscopedRefAttribute : Attribute
    {
        public UnscopedRefAttribute([UnscopedRef] out int i) { i = 0; }
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (5,38): error CS7036: There is no argument given that corresponds to the required parameter 'i' of 'UnscopedRefAttribute.UnscopedRefAttribute(out int)'
                //         public UnscopedRefAttribute([UnscopedRef] out int i) { i = 0; }
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "UnscopedRef").WithArguments("i", "System.Diagnostics.CodeAnalysis.UnscopedRefAttribute.UnscopedRefAttribute(out int)").WithLocation(5, 38));
        }
 
        [Fact]
        public void UnscopedRefAttribute_UnexpectedConstructorArgument()
        {
            var sourceA =
@"namespace System.Diagnostics.CodeAnalysis
{
    public sealed class UnscopedRefAttribute : Attribute
    {
        public UnscopedRefAttribute(bool b) { }
    }
}";
            var sourceB =
@"using System.Diagnostics.CodeAnalysis;
class Program
{
    static ref int F1([UnscopedRef] out int i1)
    {
        i1 = 0;
        return ref i1;
    }
    static ref int F2([UnscopedRef(true)] out int i2)
    {
        i2 = 0;
        return ref i2;
    }
    static ref int F3()
    {
        int i3;
        return ref F1(out i3);
    }
    static ref int F4()
    {
        int i4;
        return ref F2(out i4);
    }
}";
            var comp = CreateCompilation(new[] { sourceA, sourceB });
            comp.VerifyDiagnostics(
                // (4,24): error CS7036: There is no argument given that corresponds to the required parameter 'b' of 'UnscopedRefAttribute.UnscopedRefAttribute(bool)'
                //     static ref int F1([UnscopedRef] out int i1)
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "UnscopedRef").WithArguments("b", "System.Diagnostics.CodeAnalysis.UnscopedRefAttribute.UnscopedRefAttribute(bool)").WithLocation(4, 24),
                // (12,20): error CS9075: Cannot return a parameter by reference 'i2' because it is scoped to the current method
                //         return ref i2;
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "i2").WithArguments("i2").WithLocation(12, 20),
                // (17,20): error CS8347: Cannot use a result of 'Program.F1(out int)' in this context because it may expose variables referenced by parameter 'i1' outside of their declaration scope
                //         return ref F1(out i3);
                Diagnostic(ErrorCode.ERR_EscapeCall, "F1(out i3)").WithArguments("Program.F1(out int)", "i1").WithLocation(17, 20),
                // (17,27): error CS8168: Cannot return local 'i3' by reference because it is not a ref local
                //         return ref F1(out i3);
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i3").WithArguments("i3").WithLocation(17, 27));
        }
 
        [Fact]
        public void UnscopedRefAttribute_InvalidConstructorArgument()
        {
            var sourceA =
@"namespace System.Diagnostics.CodeAnalysis
{
    public sealed class UnscopedRefAttribute : Attribute
    {
        public UnscopedRefAttribute(bool b) { }
    }
}";
            var sourceB =
@"using System.Diagnostics.CodeAnalysis;
class Program
{
    static bool F1()
    {
        return true;
    }
    static ref int F2([UnscopedRef(F1())] out int i)
    {
        i = 0;
        return ref i;
    }
}";
            var comp = CreateCompilation(new[] { sourceA, sourceB });
            comp.VerifyDiagnostics(
                // (8,36): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
                //     static ref int F2([UnscopedRef(F1())] out int i)
                Diagnostic(ErrorCode.ERR_BadAttributeArgument, "F1()").WithLocation(8, 36),
                // (11,20): error CS9075: Cannot return a parameter by reference 'i' because it is scoped to the current method
                //         return ref i;
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "i").WithArguments("i").WithLocation(11, 20));
        }
 
        [Fact]
        public void UnscopedRefAttribute_ScopeRefAttribute_Out()
        {
            var sourceA =
@".assembly extern mscorlib { .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89) }
.assembly '<<GeneratedFileName>>' { }
.module '<<GeneratedFileName>>.dll'
.custom instance void System.Runtime.CompilerServices.RefSafetyRulesAttribute::.ctor(int32) = { int32(11) }
.class private System.Runtime.CompilerServices.RefSafetyRulesAttribute extends [mscorlib]System.Attribute
{
  .method public hidebysig specialname rtspecialname instance void .ctor(int32 version) cil managed { ret }
  .field public int32 Version
}
.class private System.Diagnostics.CodeAnalysis.UnscopedRefAttribute extends [mscorlib]System.Attribute
{
  .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret }
}
.class private System.Runtime.CompilerServices.ScopedRefAttribute extends [mscorlib]System.Attribute
{
  .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret }
}
.class public A
{
  .method public static int32& NoAttributes([out] int32& i)
  {
    ldnull
    throw
  }
  .method public static int32& ScopedRefOnly([out] int32& i)
  {
    .param [1]
    .custom instance void System.Runtime.CompilerServices.ScopedRefAttribute::.ctor() = ( 01 00 00 00 )
    ldnull
    throw
  }
  .method public static int32& UnscopedRefOnly([out] int32& i)
  {
    .param [1]
    .custom instance void System.Diagnostics.CodeAnalysis.UnscopedRefAttribute::.ctor() = ( 01 00 00 00 )
    ldnull
    throw
  }
  .method public static int32& ScopedRefAndUnscopedRef([out] int32& i)
  {
    .param [1]
    .custom instance void System.Diagnostics.CodeAnalysis.UnscopedRefAttribute::.ctor() = ( 01 00 00 00 )
    .param [1]
    .custom instance void System.Runtime.CompilerServices.ScopedRefAttribute::.ctor() = ( 01 00 00 00 )
    ldnull
    throw
  }
}
";
            var refA = CompileIL(sourceA, prependDefaultHeader: false);
 
            var sourceB =
@"class Program
{
    static ref int F1()
    {
        int i;
        return ref A.NoAttributes(out i);
    }
    static ref int F2()
    {
        int i;
        return ref A.ScopedRefOnly(out i);
    }
    static ref int F3()
    {
        int i;
        return ref A.UnscopedRefOnly(out i); // 1
    }
    static ref int F4()
    {
        int i;
        return ref A.ScopedRefAndUnscopedRef(out i); // 2
    }
}";
            var comp = CreateCompilation(sourceB, new[] { refA });
            comp.VerifyEmitDiagnostics(
                // (16,20): error CS8347: Cannot use a result of 'A.UnscopedRefOnly(out int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         return ref A.UnscopedRefOnly(out i); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "A.UnscopedRefOnly(out i)").WithArguments("A.UnscopedRefOnly(out int)", "i").WithLocation(16, 20),
                // (16,42): error CS8168: Cannot return local 'i' by reference because it is not a ref local
                //         return ref A.UnscopedRefOnly(out i); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i").WithArguments("i").WithLocation(16, 42),
                // (21,22): error CS0570: 'A.ScopedRefAndUnscopedRef(out int)' is not supported by the language
                //         return ref A.ScopedRefAndUnscopedRef(out i); // 2
                Diagnostic(ErrorCode.ERR_BindToBogus, "ScopedRefAndUnscopedRef").WithArguments("A.ScopedRefAndUnscopedRef(out int)").WithLocation(21, 22));
 
            var typeA = comp.GetMember<NamedTypeSymbol>("A");
            VerifyParameterSymbol(typeA.GetMethod("NoAttributes").Parameters[0], "out System.Int32 i", RefKind.Out, ScopedKind.ScopedRef, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(typeA.GetMethod("ScopedRefOnly").Parameters[0], "out System.Int32 i", RefKind.Out, ScopedKind.ScopedRef, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(typeA.GetMethod("UnscopedRefOnly").Parameters[0], "out System.Int32 i", RefKind.Out, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(typeA.GetMethod("ScopedRefAndUnscopedRef").Parameters[0], "out System.Int32 i", RefKind.Out, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
        }
 
        [WorkItem(64778, "https://github.com/dotnet/roslyn/issues/64778")]
        [Fact]
        public void UnscopedRefAttribute_ScopeRefAttribute_RefToRefStruct()
        {
            // class A
            // {
            //     static void NoAttributes(ref R x, ref R y) { }
            //     static void ScopedRefOnly([ScopedRef] ref R x, ref R y) { }
            //     static void UnscopedRefOnly([UnscopedRef] ref R x, ref R y) { }
            //     static void ScopedRefAndUnscopedRef([ScopedRef][UnscopedRef] ref R x, ref R y) { }
            // }
            var sourceA =
@".assembly extern mscorlib { .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89) }
.assembly '<<GeneratedFileName>>' { }
.module '<<GeneratedFileName>>.dll'
.custom instance void System.Runtime.CompilerServices.RefSafetyRulesAttribute::.ctor(int32) = { int32(11) }
.class private System.Runtime.CompilerServices.RefSafetyRulesAttribute extends [mscorlib]System.Attribute
{
  .method public hidebysig specialname rtspecialname instance void .ctor(int32 version) cil managed { ret }
  .field public int32 Version
}
.class private System.Diagnostics.CodeAnalysis.UnscopedRefAttribute extends [mscorlib]System.Attribute
{
  .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret }
}
.class private System.Runtime.CompilerServices.ScopedRefAttribute extends [mscorlib]System.Attribute
{
  .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret }
}
.class public sealed R extends [mscorlib]System.ValueType
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = (01 00 00 00)
  .field public int32& F
}
.class public A
{
  .method public static void NoAttributes(valuetype R& x, valuetype R& y)
  {
    ret
  }
  .method public static void ScopedRefOnly(valuetype R& x, valuetype R& y)
  {
    .param [1]
    .custom instance void System.Runtime.CompilerServices.ScopedRefAttribute::.ctor() = ( 01 00 00 00 )
    ret
  }
  .method public static void UnscopedRefOnly(valuetype R& x, valuetype R& y)
  {
    .param [1]
    .custom instance void System.Diagnostics.CodeAnalysis.UnscopedRefAttribute::.ctor() = ( 01 00 00 00 )
    ret
  }
  .method public static void ScopedRefAndUnscopedRef(valuetype R& x, valuetype R& y)
  {
    .param [1]
    .custom instance void System.Diagnostics.CodeAnalysis.UnscopedRefAttribute::.ctor() = ( 01 00 00 00 )
    .custom instance void System.Runtime.CompilerServices.ScopedRefAttribute::.ctor() = ( 01 00 00 00 )
    ret
  }
}
";
            var refA = CompileIL(sourceA, prependDefaultHeader: false);
 
            var sourceB =
@"class Program
{
    static void F1(ref R x, ref R y)
    {
        A.NoAttributes(ref x, ref y);
    }
    static void F2(ref R x, ref R y)
    {
        A.ScopedRefOnly(ref x, ref y);
    }
    static void F3(ref R x, ref R y)
    {
        A.UnscopedRefOnly(ref x, ref y); // 1
    }
    static void F4(ref R x, ref R y)
    {
        A.ScopedRefAndUnscopedRef(ref x, ref y); // 2
    }
}";
            var comp = CreateCompilation(sourceB, new[] { refA });
            comp.VerifyEmitDiagnostics(
                // (13,9): error CS8350: This combination of arguments to 'A.UnscopedRefOnly(ref R, ref R)' is disallowed because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //         A.UnscopedRefOnly(ref x, ref y); // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, "A.UnscopedRefOnly(ref x, ref y)").WithArguments("A.UnscopedRefOnly(ref R, ref R)", "x").WithLocation(13, 9),
                // (13,31): error CS9077: Cannot return a parameter by reference 'x' through a ref parameter; it can only be returned in a return statement
                //         A.UnscopedRefOnly(ref x, ref y); // 1
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "x").WithArguments("x").WithLocation(13, 31),
                // (17,11): error CS0570: 'A.ScopedRefAndUnscopedRef(ref R, ref R)' is not supported by the language
                //         A.ScopedRefAndUnscopedRef(ref x, ref y); // 2
                Diagnostic(ErrorCode.ERR_BindToBogus, "ScopedRefAndUnscopedRef").WithArguments("A.ScopedRefAndUnscopedRef(ref R, ref R)").WithLocation(17, 11));
 
            var typeA = comp.GetMember<NamedTypeSymbol>("A");
            VerifyParameterSymbol(typeA.GetMethod("NoAttributes").Parameters[0], "ref R x", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(typeA.GetMethod("ScopedRefOnly").Parameters[0], "scoped ref R x", RefKind.Ref, ScopedKind.ScopedRef, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(typeA.GetMethod("UnscopedRefOnly").Parameters[0], "ref R x", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(typeA.GetMethod("ScopedRefAndUnscopedRef").Parameters[0], "ref R x", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
        }
 
        // As above, but with ref readonly parameters.
        [WorkItem(64778, "https://github.com/dotnet/roslyn/issues/64778")]
        [Fact]
        public void UnscopedRefAttribute_ScopeRefAttribute_RefReadOnlyToRefStruct()
        {
            // class A
            // {
            //     static void NoAttributes(in R x, ref R y) { }
            //     static void ScopedRefOnly([ScopedRef] in R x, ref R y) { }
            //     static void UnscopedRefOnly([UnscopedRef] in R x, ref R y) { }
            //     static void ScopedRefAndUnscopedRef([ScopedRef][UnscopedRef] in R x, ref R y) { }
            // }
            var sourceA =
@".assembly extern mscorlib { .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89) }
.assembly '<<GeneratedFileName>>' { }
.module '<<GeneratedFileName>>.dll'
.custom instance void System.Runtime.CompilerServices.RefSafetyRulesAttribute::.ctor(int32) = { int32(11) }
.class private System.Runtime.CompilerServices.RefSafetyRulesAttribute extends [mscorlib]System.Attribute
{
  .method public hidebysig specialname rtspecialname instance void .ctor(int32 version) cil managed { ret }
  .field public int32 Version
}
.class private System.Diagnostics.CodeAnalysis.UnscopedRefAttribute extends [mscorlib]System.Attribute
{
  .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret }
}
.class private System.Runtime.CompilerServices.ScopedRefAttribute extends [mscorlib]System.Attribute
{
  .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret }
}
.class public sealed R extends [mscorlib]System.ValueType
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = (01 00 00 00)
  .field public int32& F
}
.class public A
{
  .method public static void NoAttributes([in] valuetype R& x, valuetype R& y)
  {
    .param [1]
    .custom instance void [mscorlib]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 ) 
    ret
  }
  .method public static void ScopedRefOnly([in] valuetype R& x, valuetype R& y)
  {
    .param [1]
    .custom instance void [mscorlib]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 ) 
    .custom instance void System.Runtime.CompilerServices.ScopedRefAttribute::.ctor() = ( 01 00 00 00 )
    ret
  }
  .method public static void UnscopedRefOnly([in] valuetype R& x, valuetype R& y)
  {
    .param [1]
    .custom instance void [mscorlib]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 ) 
    .custom instance void System.Diagnostics.CodeAnalysis.UnscopedRefAttribute::.ctor() = ( 01 00 00 00 )
    ret
  }
  .method public static void ScopedRefAndUnscopedRef([in] valuetype R& x, valuetype R& y)
  {
    .param [1]
    .custom instance void [mscorlib]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 ) 
    .custom instance void System.Diagnostics.CodeAnalysis.UnscopedRefAttribute::.ctor() = ( 01 00 00 00 )
    .custom instance void System.Runtime.CompilerServices.ScopedRefAttribute::.ctor() = ( 01 00 00 00 )
    ret
  }
}
";
            var refA = CompileIL(sourceA, prependDefaultHeader: false);
 
            var sourceB =
@"class Program
{
    static void F1(in R x, ref R y)
    {
        A.NoAttributes(in x, ref y);
    }
    static void F2(in R x, ref R y)
    {
        A.ScopedRefOnly(in x, ref y);
    }
    static void F3(in R x, ref R y)
    {
        A.UnscopedRefOnly(in x, ref y); // 1
    }
    static void F4(in R x, ref R y)
    {
        A.ScopedRefAndUnscopedRef(in x, ref y); // 2
    }
}";
            var comp = CreateCompilation(sourceB, new[] { refA });
            comp.VerifyEmitDiagnostics(
                // (13,9): error CS8350: This combination of arguments to 'A.UnscopedRefOnly(in R, ref R)' is disallowed because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //         A.UnscopedRefOnly(in x, ref y); // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, "A.UnscopedRefOnly(in x, ref y)").WithArguments("A.UnscopedRefOnly(in R, ref R)", "x").WithLocation(13, 9),
                // (13,30): error CS9077: Cannot return a parameter by reference 'x' through a ref parameter; it can only be returned in a return statement
                //         A.UnscopedRefOnly(in x, ref y); // 1
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "x").WithArguments("x").WithLocation(13, 30),
                // (17,11): error CS0570: 'A.ScopedRefAndUnscopedRef(in R, ref R)' is not supported by the language
                //         A.ScopedRefAndUnscopedRef(in x, ref y); // 2
                Diagnostic(ErrorCode.ERR_BindToBogus, "ScopedRefAndUnscopedRef").WithArguments("A.ScopedRefAndUnscopedRef(in R, ref R)").WithLocation(17, 11));
 
            var typeA = comp.GetMember<NamedTypeSymbol>("A");
            VerifyParameterSymbol(typeA.GetMethod("NoAttributes").Parameters[0], "in R x", RefKind.In, ScopedKind.None, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(typeA.GetMethod("ScopedRefOnly").Parameters[0], "scoped in R x", RefKind.In, ScopedKind.ScopedRef, expectedHasUnscopedRefAttribute: false);
            VerifyParameterSymbol(typeA.GetMethod("UnscopedRefOnly").Parameters[0], "in R x", RefKind.In, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(typeA.GetMethod("ScopedRefAndUnscopedRef").Parameters[0], "in R x", RefKind.In, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
        }
 
        [Fact]
        [WorkItem(63529, "https://github.com/dotnet/roslyn/issues/63529")]
        public void CallUnscopedRefMethodFromScopedOne()
        {
            var source =
@"using System;
using System.Diagnostics.CodeAnalysis;
 
ref struct A
{
    void Test()
    {
        this.GetSpan();
    }
 
    [UnscopedRef]
    Span<byte> GetSpan() => default;
}
";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }, targetFramework: TargetFramework.Net50, options: TestOptions.ReleaseDll);
            comp.VerifyDiagnostics(
                );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefSafetyRulesAttribute_01(LanguageVersion languageVersion)
        {
            var source =
@"ref struct R
{
}
struct S1
{
    void F1() { }
}
readonly struct S2
{
    void F2() { }
}
class A
{
    static void F3(out int i3) { i3 = 0; }
    static void F4(ref R r4) { }
    static void F5(in R r5) { }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics();
 
            bool useUpdatedRules = languageVersion == LanguageVersion.CSharp11;
 
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("S1.F1").ThisParameter, "ref S1 this", RefKind.Ref, ScopedKind.ScopedRef);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("S2.F2").ThisParameter, "in S2 this", RefKind.In, ScopedKind.ScopedRef);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("A.F3").Parameters[0], "out System.Int32 i3", RefKind.Out, useUpdatedRules ? ScopedKind.ScopedRef : ScopedKind.None);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("A.F4").Parameters[0], "ref R r4", RefKind.Ref, ScopedKind.None);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("A.F5").Parameters[0], "in R r5", RefKind.In, ScopedKind.None);
        }
 
        [Theory]
        [CombinatorialData]
        public void RefSafetyRulesAttribute_02(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionA,
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionB,
            bool useCompilationReference)
        {
            var sourceA =
@"public ref struct R
{
}
public struct S1
{
    public void F1() { }
}
public readonly struct S2
{
    public void F2() { }
}
public class A
{
    public static void F3(out int i3) { i3 = 0; }
    public static void F4(ref R r4) { }
    public static void F5(in R r5) { }
}";
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionA));
            comp.VerifyDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"";
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionB));
            comp.VerifyDiagnostics();
 
            bool useUpdatedRules = languageVersionA == LanguageVersion.CSharp11;
 
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("S1.F1").ThisParameter, "ref S1 this", RefKind.Ref, ScopedKind.ScopedRef);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("S2.F2").ThisParameter, "in S2 this", RefKind.In, ScopedKind.ScopedRef);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("A.F3").Parameters[0], "out System.Int32 i3", RefKind.Out, useUpdatedRules ? ScopedKind.ScopedRef : ScopedKind.None);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("A.F4").Parameters[0], "ref R r4", RefKind.Ref, ScopedKind.None);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("A.F5").Parameters[0], "in R r5", RefKind.In, ScopedKind.None);
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefSafetyRulesAttribute_03(LanguageVersion languageVersion)
        {
            var source =
@"ref struct R { }
class Program
{
    static void Main()
    {
        var f1 = (out int i1) => { i1 = 0; };
        var f2 = (R r2) => { };
        var f3 = (ref R r3) => { };
        var f4 = (in R r4) => { };
        var f5 = (out R r5) => { r5 = default; };
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics();
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var delegateTypesAndLambdas = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Select(d => getDelegateTypeAndLambda(model, d)).ToArray();
 
            bool useUpdatedRules = languageVersion == LanguageVersion.CSharp11;
 
            verifyParameter(delegateTypesAndLambdas[0], 0, "out System.Int32", "i1", RefKind.Out, useUpdatedRules ? ScopedKind.ScopedRef : ScopedKind.None);
            verifyParameter(delegateTypesAndLambdas[1], 0, "R", "r2", RefKind.None, ScopedKind.None);
            verifyParameter(delegateTypesAndLambdas[2], 0, "ref R", "r3", RefKind.Ref, ScopedKind.None);
            verifyParameter(delegateTypesAndLambdas[3], 0, "in R", "r4", RefKind.In, ScopedKind.None);
            verifyParameter(delegateTypesAndLambdas[4], 0, "out R", "r5", RefKind.Out, useUpdatedRules ? ScopedKind.ScopedRef : ScopedKind.None);
 
            static void verifyParameter((NamedTypeSymbol, LambdaSymbol) delegateTypeAndLambda, int parameterIndex, string expectedDisplayType, string expectedDisplayName, RefKind expectedRefKind, ScopedKind expectedScope)
            {
                var (delegateType, lambda) = delegateTypeAndLambda;
                VerifyParameterSymbol(delegateType.DelegateInvokeMethod.Parameters[parameterIndex], $"{expectedDisplayType} arg", expectedRefKind, expectedScope);
                VerifyParameterSymbol(lambda.Parameters[parameterIndex], $"{expectedDisplayType} {expectedDisplayName}", expectedRefKind, expectedScope);
            }
 
            static (NamedTypeSymbol, LambdaSymbol) getDelegateTypeAndLambda(SemanticModel model, VariableDeclaratorSyntax decl)
            {
                var delegateType = (NamedTypeSymbol)model.GetDeclaredSymbol(decl).GetSymbol<LocalSymbol>().Type;
                var value = decl.DescendantNodes().OfType<ParenthesizedLambdaExpressionSyntax>().Single();
                var lambda = model.GetSymbolInfo(value).Symbol.GetSymbol<LambdaSymbol>();
                return (delegateType, lambda);
            }
        }
 
        [Theory]
        [CombinatorialData]
        public void RefSafetyRulesAttribute_04(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionA,
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionB,
            bool useCompilationReference)
        {
            var sourceA =
@"public ref struct R { }
unsafe public class A
{
    public delegate*<out int, void> F1 = null;
    public delegate*<R, void> F2 = null;
    public delegate*<ref R, void> F3 = null;
    public delegate*<in R, void> F4 = null;
    public delegate*<out R, void> F5 = null;
}";
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionA), options: TestOptions.UnsafeReleaseDll);
            comp.VerifyDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"";
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionB));
            comp.VerifyDiagnostics();
 
            bool useUpdatedRules = languageVersionA == LanguageVersion.CSharp11;
 
            VerifyParameterSymbol(getFunctionPointerMethod(comp, "A.F1").Parameters[0], "out modreq(System.Runtime.InteropServices.OutAttribute) System.Int32", RefKind.Out, useUpdatedRules ? ScopedKind.ScopedRef : ScopedKind.None);
            VerifyParameterSymbol(getFunctionPointerMethod(comp, "A.F2").Parameters[0], "R", RefKind.None, ScopedKind.None);
            VerifyParameterSymbol(getFunctionPointerMethod(comp, "A.F3").Parameters[0], "ref R", RefKind.Ref, ScopedKind.None);
            VerifyParameterSymbol(getFunctionPointerMethod(comp, "A.F4").Parameters[0], "in modreq(System.Runtime.InteropServices.InAttribute) R", RefKind.In, ScopedKind.None);
            VerifyParameterSymbol(getFunctionPointerMethod(comp, "A.F5").Parameters[0], "out modreq(System.Runtime.InteropServices.OutAttribute) R", RefKind.Out, useUpdatedRules ? ScopedKind.ScopedRef : ScopedKind.None);
 
            static MethodSymbol getFunctionPointerMethod(CSharpCompilation comp, string qualifiedName) =>
                ((FunctionPointerTypeSymbol)comp.GetMember<FieldSymbol>(qualifiedName).Type).Signature;
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefSafetyRulesAttribute_05(LanguageVersion languageVersion)
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
ref struct R { }
struct S
{
    [UnscopedRef] ref int F() => throw null;
    [UnscopedRef] ref int P => throw null;
}
class Program
{
    static void F1([UnscopedRef] out int i1) { i1 = 0; }
    static void F2([UnscopedRef] R r2) { }
    static void F3([UnscopedRef] ref R r3) { }
    static void F4([UnscopedRef] in R r4) { }
    static void F5([UnscopedRef] out R r5) { }
}";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
 
            if (languageVersion == LanguageVersion.CSharp11)
            {
                comp.VerifyEmitDiagnostics(
                    // (11,21): error CS9063: UnscopedRefAttribute cannot be applied to this parameter because it is unscoped by default.
                    //     static void F2([UnscopedRef] R r2) { }
                    Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedTarget, "UnscopedRef").WithLocation(11, 21));
            }
            else
            {
                comp.VerifyEmitDiagnostics(
                    // (10,21): error CS9063: UnscopedRefAttribute cannot be applied to this parameter because it is unscoped by default.
                    //     static void F1([UnscopedRef] out int i1) { i1 = 0; }
                    Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedTarget, "UnscopedRef").WithLocation(10, 21),
                    // (11,21): error CS9063: UnscopedRefAttribute cannot be applied to this parameter because it is unscoped by default.
                    //     static void F2([UnscopedRef] R r2) { }
                    Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedTarget, "UnscopedRef").WithLocation(11, 21),
                    // (12,21): error CS9063: UnscopedRefAttribute cannot be applied to this parameter because it is unscoped by default.
                    //     static void F3([UnscopedRef] ref R r3) { }
                    Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedTarget, "UnscopedRef").WithLocation(12, 21),
                    // (13,21): error CS9063: UnscopedRefAttribute cannot be applied to this parameter because it is unscoped by default.
                    //     static void F4([UnscopedRef] in R r4) { }
                    Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedTarget, "UnscopedRef").WithLocation(13, 21),
                    // (14,21): error CS9063: UnscopedRefAttribute cannot be applied to this parameter because it is unscoped by default.
                    //     static void F5([UnscopedRef] out R r5) { }
                    Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedTarget, "UnscopedRef").WithLocation(14, 21));
            }
 
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("S.F").ThisParameter, "ref S this", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(comp.GetMember<PropertySymbol>("S.P").GetMethod.ThisParameter, "ref S this", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F1").Parameters[0], "out System.Int32 i1", RefKind.Out, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F2").Parameters[0], "R r2", RefKind.None, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F3").Parameters[0], "ref R r3", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F4").Parameters[0], "in R r4", RefKind.In, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            VerifyParameterSymbol(comp.GetMember<MethodSymbol>("Program.F5").Parameters[0], "out R r5", RefKind.Out, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
        }
 
        [Theory]
        [CombinatorialData]
        public void RefSafetyRulesAttribute_06(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionA,
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionB,
            bool useCompilationReference)
        {
            var sourceA =
@"public ref struct R<T>
{
}
public abstract class A<T>
{
    public abstract ref T F1(out T t1);
    public abstract ref T F2(R<T> r2);
    public abstract ref T F3(ref R<T> r3);
    public abstract ref T F4(in R<T> r4);
    public abstract ref T F5(out R<T> r5);
}";
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionA));
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class B : A<int>
{
    public override ref int F1(out int i1) => throw null; // 1
    public override ref int F2(R<int> r2) => throw null;
    public override ref int F3(ref R<int> r3) => throw null;
    public override ref int F4(in R<int> r4) => throw null;
    public override ref int F5(out R<int> r5) => throw null; // 2
}";
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionB));
 
            if (languageVersionA == LanguageVersion.CSharp11 &&
                languageVersionB == LanguageVersion.CSharp10)
            {
                comp.VerifyEmitDiagnostics(
                    // (3,29): warning CS9074: The 'scoped' modifier of parameter 'i1' doesn't match overridden or implemented member.
                    //     public override ref int F1(out int i1) => throw null; // 1
                    Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("i1").WithLocation(3, 29),
                    // (7,29): warning CS9074: The 'scoped' modifier of parameter 'r5' doesn't match overridden or implemented member.
                    //     public override ref int F5(out R<int> r5) => throw null; // 2
                    Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfOverrideOrImplementation, "F5").WithArguments("r5").WithLocation(7, 29));
            }
            else
            {
                comp.VerifyEmitDiagnostics();
            }
        }
 
        [Theory]
        [CombinatorialData]
        public void RefSafetyRulesAttribute_07(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionA,
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionB,
            bool useCompilationReference)
        {
            var sourceA =
@"public ref struct R<T>
{
}
public interface I<T>
{
    ref readonly T F1(out T t1);
    ref readonly T F2(R<T> r2);
    ref readonly T F3(ref R<T> r3);
    ref readonly T F4(in R<T> r4);
    ref readonly T F5(out R<T> r5);
}";
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionA));
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class B1 : I<int>
{
    public ref readonly int F1(out int i1) => throw null; // 1
    public ref readonly int F2(R<int> r2) => throw null;
    public ref readonly int F3(ref R<int> r3) => throw null;
    public ref readonly int F4(in R<int> r4) => throw null;
    public ref readonly int F5(out R<int> r5) => throw null; // 2
}
class B2 : I<object>
{
    ref readonly object I<object>.F1(out object o1) => throw null; // 3
    ref readonly object I<object>.F2(R<object> r2) => throw null;
    ref readonly object I<object>.F3(ref R<object> r3) => throw null;
    ref readonly object I<object>.F4(in R<object> r4) => throw null;
    ref readonly object I<object>.F5(out R<object> r5) => throw null; // 4
}";
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionB));
 
            if (languageVersionA == LanguageVersion.CSharp11 &&
                languageVersionB == LanguageVersion.CSharp10)
            {
                comp.VerifyEmitDiagnostics(
                // (3,29): warning CS9074: The 'scoped' modifier of parameter 'i1' doesn't match overridden or implemented member.
                //     public ref readonly int F1(out int i1) => throw null; // 1
                Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("i1").WithLocation(3, 29),
                // (7,29): warning CS9074: The 'scoped' modifier of parameter 'r5' doesn't match overridden or implemented member.
                //     public ref readonly int F5(out R<int> r5) => throw null; // 2
                Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfOverrideOrImplementation, "F5").WithArguments("r5").WithLocation(7, 29),
                // (11,35): warning CS9074: The 'scoped' modifier of parameter 'o1' doesn't match overridden or implemented member.
                //     ref readonly object I<object>.F1(out object o1) => throw null; // 3
                Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("o1").WithLocation(11, 35),
                // (15,35): warning CS9074: The 'scoped' modifier of parameter 'r5' doesn't match overridden or implemented member.
                //     ref readonly object I<object>.F5(out R<object> r5) => throw null; // 4
                Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfOverrideOrImplementation, "F5").WithArguments("r5").WithLocation(15, 35));
            }
            else
            {
                comp.VerifyEmitDiagnostics();
            }
        }
 
        [Theory]
        [CombinatorialData]
        public void RefSafetyRulesAttribute_08(bool useCompilationReference)
        {
            var sourceA =
@"using System.Diagnostics.CodeAnalysis;
public ref struct R<T> { }
public abstract class A<T>
{
    public abstract void F1([UnscopedRef] out T t1);
    public abstract void F2(ref R<T> r2);
    public abstract void F3(in R<T> r3);
}";
            var comp = CreateCompilation(new[] { sourceA, UnscopedRefAttributeDefinition });
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class B : A<int>
{
    public override void F1(out int i1) { i1 = 0; }
    public override void F2(scoped ref R<int> r3) { }
    public override void F3(scoped in R<int> r4) { }
}";
            comp = CreateCompilation(sourceB, references: new[] { refA });
            comp.VerifyEmitDiagnostics();
        }
 
        [Theory]
        [CombinatorialData]
        public void RefSafetyRulesAttribute_09(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionB,
            bool useCompilationReference)
        {
            var sourceA =
@"using System.Diagnostics.CodeAnalysis;
public ref struct R<T> { }
public interface I<T>
{
    void F1([UnscopedRef] out T t1);
    void F2(ref R<T> r2);
    void F3(in R<T> r3);
}";
            var comp = CreateCompilation(new[] { sourceA, UnscopedRefAttributeDefinition });
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class B1 : I<int>
{
    public void F1(out int i1) { i1 = 0; }
    public void F2(ref R<int> r2) { }
    public void F3(in R<int> r3) { }
}
class B2 : I<object>
{
    void I<object>.F1(out object o1) { o1 = null; }
    void I<object>.F2(ref R<object> r2) { }
    void I<object>.F3(in R<object> r3) { }
}";
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionB));
            comp.VerifyEmitDiagnostics();
        }
 
        [Theory]
        [CombinatorialData]
        public void RefSafetyRulesAttribute_10(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionA,
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionB,
            bool useCompilationReference)
        {
            var sourceA =
@"public ref struct R<T>
{
}
public delegate ref T D1<T>(out T t1);
public delegate ref T D2<T>(R<T> r2);
public delegate ref T D3<T>(ref R<T> r3);
public delegate ref T D4<T>(in R<T> r4);
public delegate ref T D5<T>(out R<T> r5);
";
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionA));
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class Program
{
    static ref int F1(out int i1) => throw null;
    static ref int F2(R<int> r2) => throw null;
    static ref int F3(ref R<int> r3) => throw null;
    static ref int F4(in R<int> r4) => throw null;
    static ref int F5(out R<int> r5) => throw null;
    static void Main()
    {
        D1<int> d1 = F1; // 1
        D2<int> d2 = F2;
        D3<int> d3 = F3;
        D4<int> d4 = F4;
        D5<int> d5 = F5; // 2
    }
}";
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionB));
 
            if (languageVersionA == LanguageVersion.CSharp11 &&
                languageVersionB == LanguageVersion.CSharp10)
            {
                comp.VerifyEmitDiagnostics(
                // (10,22): warning CS9073: The 'scoped' modifier of parameter 'i1' doesn't match target 'D1<int>'.
                //         D1<int> d1 = F1; // 1
                Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfTarget, "F1").WithArguments("i1", "D1<int>").WithLocation(10, 22),
                // (14,22): warning CS9073: The 'scoped' modifier of parameter 'r5' doesn't match target 'D5<int>'.
                //         D5<int> d5 = F5; // 2
                Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfTarget, "F5").WithArguments("r5", "D5<int>").WithLocation(14, 22));
            }
            else
            {
                comp.VerifyEmitDiagnostics();
            }
        }
 
        [WorkItem(63761, "https://github.com/dotnet/roslyn/issues/63761")]
        [Theory]
        [CombinatorialData]
        public void RefSafetyRulesAttribute_11(bool useCompilationReference)
        {
            var sourceA =
@"public ref struct R<T>
{
}
public abstract class A<T>
{
    public abstract ref readonly T F1(out T t);
}
public interface I<T>
{
    ref T F2(out T t);
}
public delegate ref T D3<T>(out T t);
";
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular);
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB1 =
@"class B : A<int>, I<string>
{
    public override ref readonly int F1(out int i) => throw null; // 1
    ref string I<string>.F2(out string s) => throw null; // 2
}
class Program
{
    static ref object F3(out object o) => throw null;
    static void Main()
    {
        D3<object> d3 = F3; // 3
    }
}";
            comp = CreateCompilation(sourceB1, references: new[] { refA }, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (3,38): warning CS9074: The 'scoped' modifier of parameter 'i' doesn't match overridden or implemented member.
                //     public override ref readonly int F1(out int i) => throw null; // 1
                Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("i").WithLocation(3, 38),
                // (4,26): warning CS9074: The 'scoped' modifier of parameter 's' doesn't match overridden or implemented member.
                //     ref string I<string>.F2(out string s) => throw null; // 2
                Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfOverrideOrImplementation, "F2").WithArguments("s").WithLocation(4, 26),
                // (11,25): warning CS9073: The 'scoped' modifier of parameter 'o' doesn't match target 'D3<object>'.
                //         D3<object> d3 = F3; // 3
                Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfTarget, "F3").WithArguments("o", "D3<object>").WithLocation(11, 25));
 
            var sourceB2 =
@"using System.Diagnostics.CodeAnalysis;
class B : A<int>, I<string>
{
    public override ref readonly int F1([UnscopedRef] out int i) => throw null; // 1
    ref string I<string>.F2([UnscopedRef] out string s) => throw null; // 2
}
class Program
{
    static ref object F3([UnscopedRef] out object o) => throw null;
    static void Main()
    {
        D3<object> d3 = F3; // 3
    }
}";
            comp = CreateCompilation(new[] { sourceB2, UnscopedRefAttributeDefinition }, references: new[] { refA }, parseOptions: TestOptions.Regular);
            comp.VerifyEmitDiagnostics(
                // (4,38): error CS8987: The 'scoped' modifier of parameter 'i' doesn't match overridden or implemented member.
                //     public override ref readonly int F1([UnscopedRef] out int i) => throw null; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("i").WithLocation(4, 38),
                // (5,26): error CS8987: The 'scoped' modifier of parameter 's' doesn't match overridden or implemented member.
                //     ref string I<string>.F2([UnscopedRef] out string s) => throw null; // 2
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F2").WithArguments("s").WithLocation(5, 26),
                // (12,25): error CS8986: The 'scoped' modifier of parameter 'o' doesn't match target 'D3<object>'.
                //         D3<object> d3 = F3; // 3
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "F3").WithArguments("o", "D3<object>").WithLocation(12, 25));
        }
 
        [Theory]
        [CombinatorialData]
        public void RefSafetyRulesAttribute_12(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionB,
            bool useCompilationReference)
        {
            var sourceA =
@"public ref struct R<T>
{
}
public abstract class A<T>
{
    public abstract ref readonly T F1(scoped R<T> r);
}
public interface I<T>
{
    ref T F2(scoped R<T> r);
}
public delegate ref T D3<T>(scoped R<T> r);
";
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular);
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class B : A<int>, I<string>
{
    public override ref readonly int F1(R<int> r) => throw null; // 1
    ref string I<string>.F2(R<string> r) => throw null; // 2
}
class Program
{
    static ref object F3(R<object> r) => throw null;
    static void Main()
    {
        D3<object> d3 = F3; // 3
    }
}";
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionB));
 
            if (languageVersionB == LanguageVersion.CSharp10)
            {
                comp.VerifyEmitDiagnostics(
                    // (3,38): warning CS9074: The 'scoped' modifier of parameter 'r' doesn't match overridden or implemented member.
                    //     public override ref readonly int F1(R<int> r) => throw null; // 1
                    Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("r").WithLocation(3, 38),
                    // (4,26): warning CS9074: The 'scoped' modifier of parameter 'r' doesn't match overridden or implemented member.
                    //     ref string I<string>.F2(R<string> r) => throw null; // 2
                    Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfOverrideOrImplementation, "F2").WithArguments("r").WithLocation(4, 26),
                    // (11,25): warning CS9073: The 'scoped' modifier of parameter 'r' doesn't match target 'D3<object>'.
                    //         D3<object> d3 = F3; // 3
                    Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfTarget, "F3").WithArguments("r", "D3<object>").WithLocation(11, 25));
            }
            else
            {
                comp.VerifyEmitDiagnostics(
                    // (3,38): error CS8987: The 'scoped' modifier of parameter 'r' doesn't match overridden or implemented member.
                    //     public override ref readonly int F1(R<int> r) => throw null; // 1
                    Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("r").WithLocation(3, 38),
                    // (4,26): error CS8987: The 'scoped' modifier of parameter 'r' doesn't match overridden or implemented member.
                    //     ref string I<string>.F2(R<string> r) => throw null; // 2
                    Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F2").WithArguments("r").WithLocation(4, 26),
                    // (11,25): error CS8986: The 'scoped' modifier of parameter 'r' doesn't match target 'D3<object>'.
                    //         D3<object> d3 = F3; // 3
                    Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "F3").WithArguments("r", "D3<object>").WithLocation(11, 25));
            }
        }
 
        [Theory]
        [CombinatorialData]
        public void UnscopedRefAttribute_Overrides_04(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionA,
            bool useCompilationReference)
        {
            var sourceA =
@"public abstract class A<T>
{
    public abstract ref readonly T F1(ref T t);
    public abstract ref readonly T F2(in T t);
    public abstract ref readonly T F3(out T t);
}
public interface I<T>
{
    ref T F1(ref T t);
    ref T F2(in T t);
    ref T F3(out T t);
}
public delegate ref T D2<T>(ref T t);
public delegate ref T D3<T>(in T t);
public delegate ref T D4<T>(out T t);
";
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionA));
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"using System.Diagnostics.CodeAnalysis;
class B : A<int>, I<string>
{
    public override ref readonly int F1([UnscopedRef] ref int i) => throw null; // 1
    public override ref readonly int F2([UnscopedRef] in int i) => throw null; // 2
    public override ref readonly int F3([UnscopedRef] out int i) => throw null; // 3
    ref string I<string>.F1([UnscopedRef] ref string s) => throw null; // 4
    ref string I<string>.F2([UnscopedRef] in string s) => throw null; // 5
    ref string I<string>.F3([UnscopedRef] out string s) => throw null; // 6
}
class Program
{
    static ref object F1([UnscopedRef] ref object o) => throw null;
    static ref object F2([UnscopedRef] in object o) => throw null;
    static ref object F3([UnscopedRef] out object o) => throw null;
    static void Main()
    {
        D2<object> d1 = F1; // 7
        D3<object> d2 = F2; // 8
        D4<object> d3 = F3; // 9
    }
}";
            comp = CreateCompilation(new[] { sourceB, UnscopedRefAttributeDefinition }, references: new[] { refA });
            if (languageVersionA == LanguageVersion.CSharp10)
            {
                comp.VerifyEmitDiagnostics(
                    // (4,38): warning CS9074: The 'scoped' modifier of parameter 'i' doesn't match overridden or implemented member.
                    //     public override ref readonly int F1([UnscopedRef] ref int i) => throw null; // 1
                    Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("i").WithLocation(4, 38),
                    // (5,38): warning CS9074: The 'scoped' modifier of parameter 'i' doesn't match overridden or implemented member.
                    //     public override ref readonly int F2([UnscopedRef] in int i) => throw null; // 2
                    Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfOverrideOrImplementation, "F2").WithArguments("i").WithLocation(5, 38),
                    // (6,38): warning CS9074: The 'scoped' modifier of parameter 'i' doesn't match overridden or implemented member.
                    //     public override ref readonly int F3([UnscopedRef] out int i) => throw null; // 3
                    Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfOverrideOrImplementation, "F3").WithArguments("i").WithLocation(6, 38),
                    // (7,26): warning CS9074: The 'scoped' modifier of parameter 's' doesn't match overridden or implemented member.
                    //     ref string I<string>.F1([UnscopedRef] ref string s) => throw null; // 4
                    Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("s").WithLocation(7, 26),
                    // (8,26): warning CS9074: The 'scoped' modifier of parameter 's' doesn't match overridden or implemented member.
                    //     ref string I<string>.F2([UnscopedRef] in string s) => throw null; // 5
                    Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfOverrideOrImplementation, "F2").WithArguments("s").WithLocation(8, 26),
                    // (9,26): warning CS9074: The 'scoped' modifier of parameter 's' doesn't match overridden or implemented member.
                    //     ref string I<string>.F3([UnscopedRef] out string s) => throw null; // 6
                    Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfOverrideOrImplementation, "F3").WithArguments("s").WithLocation(9, 26),
                    // (18,25): warning CS9073: The 'scoped' modifier of parameter 'o' doesn't match target 'D2<object>'.
                    //         D2<object> d1 = F1; // 7
                    Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfTarget, "F1").WithArguments("o", "D2<object>").WithLocation(18, 25),
                    // (19,25): warning CS9073: The 'scoped' modifier of parameter 'o' doesn't match target 'D3<object>'.
                    //         D3<object> d2 = F2; // 8
                    Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfTarget, "F2").WithArguments("o", "D3<object>").WithLocation(19, 25),
                    // (20,25): warning CS9073: The 'scoped' modifier of parameter 'o' doesn't match target 'D4<object>'.
                    //         D4<object> d3 = F3; // 9
                    Diagnostic(ErrorCode.WRN_ScopedMismatchInParameterOfTarget, "F3").WithArguments("o", "D4<object>").WithLocation(20, 25));
            }
            else
            {
                comp.VerifyEmitDiagnostics(
                    // (4,38): error CS8987: The 'scoped' modifier of parameter 'i' doesn't match overridden or implemented member.
                    //     public override ref readonly int F1([UnscopedRef] ref int i) => throw null; // 1
                    Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("i").WithLocation(4, 38),
                    // (5,38): error CS8987: The 'scoped' modifier of parameter 'i' doesn't match overridden or implemented member.
                    //     public override ref readonly int F2([UnscopedRef] in int i) => throw null; // 2
                    Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F2").WithArguments("i").WithLocation(5, 38),
                    // (6,38): error CS8987: The 'scoped' modifier of parameter 'i' doesn't match overridden or implemented member.
                    //     public override ref readonly int F3([UnscopedRef] out int i) => throw null; // 3
                    Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F3").WithArguments("i").WithLocation(6, 38),
                    // (7,26): error CS8987: The 'scoped' modifier of parameter 's' doesn't match overridden or implemented member.
                    //     ref string I<string>.F1([UnscopedRef] ref string s) => throw null; // 4
                    Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F1").WithArguments("s").WithLocation(7, 26),
                    // (8,26): error CS8987: The 'scoped' modifier of parameter 's' doesn't match overridden or implemented member.
                    //     ref string I<string>.F2([UnscopedRef] in string s) => throw null; // 5
                    Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F2").WithArguments("s").WithLocation(8, 26),
                    // (9,26): error CS8987: The 'scoped' modifier of parameter 's' doesn't match overridden or implemented member.
                    //     ref string I<string>.F3([UnscopedRef] out string s) => throw null; // 6
                    Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "F3").WithArguments("s").WithLocation(9, 26),
                    // (18,25): error CS8986: The 'scoped' modifier of parameter 'o' doesn't match target 'D2<object>'.
                    //         D2<object> d1 = F1; // 7
                    Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "F1").WithArguments("o", "D2<object>").WithLocation(18, 25),
                    // (19,25): error CS8986: The 'scoped' modifier of parameter 'o' doesn't match target 'D3<object>'.
                    //         D3<object> d2 = F2; // 8
                    Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "F2").WithArguments("o", "D3<object>").WithLocation(19, 25),
                    // (20,25): error CS8986: The 'scoped' modifier of parameter 'o' doesn't match target 'D4<object>'.
                    //         D4<object> d3 = F3; // 9
                    Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "F3").WithArguments("o", "D4<object>").WithLocation(20, 25));
            }
        }
 
        [Theory]
        [CombinatorialData]
        public void UnscopedRefAttribute_Overrides_05(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionB,
            bool useCompilationReference)
        {
            var sourceA =
@"using System.Diagnostics.CodeAnalysis;
public abstract class A<T>
{
    public abstract ref readonly T F1([UnscopedRef] ref T t);
    public abstract ref readonly T F2([UnscopedRef] in T t);
    public abstract ref readonly T F3([UnscopedRef] out T t);
}
public interface I<T>
{
    ref T F1([UnscopedRef] ref T t);
    ref T F2([UnscopedRef] in T t);
    ref T F3([UnscopedRef] out T t);
}
public delegate ref T D2<T>([UnscopedRef] ref T t);
public delegate ref T D3<T>([UnscopedRef] in T t);
public delegate ref T D4<T>([UnscopedRef] out T t);
";
            var comp = CreateCompilation(new[] { sourceA, UnscopedRefAttributeDefinition }, parseOptions: TestOptions.Regular);
            comp.VerifyEmitDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class B : A<int>, I<string>
{
    public override ref readonly int F1(ref int i) => throw null;
    public override ref readonly int F2(in int i) => throw null;
    public override ref readonly int F3(out int i) => throw null;
    ref string I<string>.F1(ref string s) => throw null;
    ref string I<string>.F2(in string s) => throw null;
    ref string I<string>.F3(out string s) => throw null;
}
class Program
{
    static ref object F1(ref object o) => throw null;
    static ref object F2(in object o) => throw null;
    static ref object F3(out object o) => throw null;
    static void Main()
    {
        D2<object> d1 = F1;
        D3<object> d2 = F2;
        D4<object> d3 = F3;
    }
}";
            comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionB));
            comp.VerifyEmitDiagnostics();
        }
 
        [Theory]
        [CombinatorialData]
        public void UnscopedRefAttribute_Overrides_06(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersionB,
            bool useCompilationReference)
        {
            var sourceA =
@"using System.Diagnostics.CodeAnalysis;
public ref struct R { }
public class A
{
    public static void F1(ref R x, ref R y) { }
    public static void F2([UnscopedRef] ref R x, ref R y) { }
    public static void F3(in R x, ref R y) { }
    public static void F4([UnscopedRef] in R x, ref R y) { }
}
";
            var comp = CreateCompilation(new[] { sourceA, UnscopedRefAttributeDefinition });
            comp.VerifyEmitDiagnostics();
            verifyParameters(comp.GetMember<NamedTypeSymbol>("A"));
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"class B
{
    static void F1(ref R x, ref R y)
    {
        A.F1(ref x, ref y);
    }
    static void F2(ref R x, ref R y)
    {
        A.F2(ref x, ref y); // 1
    }
    static void F3(in R x, ref R y)
    {
        A.F3(in x, ref y);
    }
    static void F4(in R x, ref R y)
    {
        A.F4(in x, ref y); // 2
    }
}";
            comp = CreateCompilation(sourceB, new[] { refA }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersionB));
            comp.VerifyEmitDiagnostics(
                // (9,9): error CS8350: This combination of arguments to 'A.F2(ref R, ref R)' is disallowed because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //         A.F2(ref x, ref y); // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, "A.F2(ref x, ref y)").WithArguments("A.F2(ref R, ref R)", "x").WithLocation(9, 9),
                // (9,18): error CS9077: Cannot return a parameter by reference 'x' through a ref parameter; it can only be returned in a return statement
                //         A.F2(ref x, ref y); // 1
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "x").WithArguments("x").WithLocation(9, 18),
                // (17,9): error CS8350: This combination of arguments to 'A.F4(in R, ref R)' is disallowed because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //         A.F4(in x, ref y); // 2
                Diagnostic(ErrorCode.ERR_CallArgMixing, "A.F4(in x, ref y)").WithArguments("A.F4(in R, ref R)", "x").WithLocation(17, 9),
                // (17,17): error CS9077: Cannot return a parameter by reference 'x' through a ref parameter; it can only be returned in a return statement
                //         A.F4(in x, ref y); // 2
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "x").WithArguments("x").WithLocation(17, 17));
 
            static void verifyParameters(NamedTypeSymbol typeA)
            {
                VerifyParameterSymbol(typeA.GetMethod("F1").Parameters[0], "ref R x", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: false);
                VerifyParameterSymbol(typeA.GetMethod("F2").Parameters[0], "ref R x", RefKind.Ref, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
                VerifyParameterSymbol(typeA.GetMethod("F3").Parameters[0], "in R x", RefKind.In, ScopedKind.None, expectedHasUnscopedRefAttribute: false);
                VerifyParameterSymbol(typeA.GetMethod("F4").Parameters[0], "in R x", RefKind.In, ScopedKind.None, expectedHasUnscopedRefAttribute: true);
            }
        }
 
        [Fact]
        [WorkItem(64508, "https://github.com/dotnet/roslyn/issues/64508")]
        public void UnscopedRefAttribute_InterfaceImplementation_01()
        {
            string source = """
                using System.Diagnostics.CodeAnalysis;
                ref struct R<T>
                {
                    public R(ref T t) { }
                }
                interface I<T>
                {
                    ref T F1();
                    void F2();
                    void F3(out R<T> r);
                    ref T P { get; }
                }
                struct S1 : I<int>
                {
                    public ref int F1() => throw null;
                    public void F2() { }
                    public void F3(out R<int> r) { r = default; }
                    public ref int P => throw null;
                }
                struct S2 : I<int>
                {
                    private int _f2;
                    [UnscopedRef] public ref int F1() => ref _f2; // 1
                    [UnscopedRef] public void F2() { } // 2
                    [UnscopedRef] public void F3(out R<int> r) { r = new R<int>(ref _f2); } // 3
                    [UnscopedRef] public ref int P => ref _f2; // 4
                }
                struct S3 : I<int>
                {
                    ref int I<int>.F1() => throw null;
                    void I<int>.F2() { }
                    void I<int>.F3(out R<int> r) { r = default; }
                    ref int I<int>.P => throw null;
                }
                struct S4 : I<int>
                {
                    private int _f4;
                    [UnscopedRef] ref int I<int>.F1() => ref _f4; // 5
                    [UnscopedRef] void I<int>.F2() { } // 6
                    [UnscopedRef] void I<int>.F3(out R<int> r) { r = new R<int>(ref _f4); } // 7
                    [UnscopedRef] ref int I<int>.P => ref _f4; // 8
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (23,34): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     [UnscopedRef] public ref int F1() => ref _f2; // 1
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F1").WithLocation(23, 34),
                // (24,31): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     [UnscopedRef] public void F2() { } // 2
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F2").WithLocation(24, 31),
                // (25,31): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     [UnscopedRef] public void F3(out R<int> r) { r = new R<int>(ref _f2); } // 3
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F3").WithLocation(25, 31),
                // (26,39): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     [UnscopedRef] public ref int P => ref _f2; // 4
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "ref _f2").WithLocation(26, 39),
                // (38,34): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     [UnscopedRef] ref int I<int>.F1() => ref _f4; // 5
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F1").WithLocation(38, 34),
                // (39,31): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     [UnscopedRef] void I<int>.F2() { } // 6
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F2").WithLocation(39, 31),
                // (40,31): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     [UnscopedRef] void I<int>.F3(out R<int> r) { r = new R<int>(ref _f4); } // 7
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F3").WithLocation(40, 31),
                // (41,39): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     [UnscopedRef] ref int I<int>.P => ref _f4; // 8
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "ref _f4").WithLocation(41, 39));
        }
 
        // As above, but interface members are also marked [UnscopedRef].
        [Fact]
        [WorkItem(64508, "https://github.com/dotnet/roslyn/issues/64508")]
        public void UnscopedRefAttribute_InterfaceImplementation_02()
        {
            string source = """
                using System.Diagnostics.CodeAnalysis;
                ref struct R<T>
                {
                    public R(ref T t) { }
                }
                interface I<T>
                {
                    [UnscopedRef] ref T F1(); // 1
                    [UnscopedRef] void F2(); // 2
                    [UnscopedRef] void F3(out R<T> r); // 3
                    [UnscopedRef] ref T P { get; } // 4
                }
                struct S1 : I<int>
                {
                    public ref int F1() => throw null;
                    public void F2() { }
                    public void F3(out R<int> r) { r = default; }
                    public ref int P => throw null;
                }
                struct S2 : I<int>
                {
                    private int _f2;
                    [UnscopedRef] public ref int F1() => ref _f2; // 5
                    [UnscopedRef] public void F2() { } // 6
                    [UnscopedRef] public void F3(out R<int> r) { r = new R<int>(ref _f2); } // 7
                    [UnscopedRef] public ref int P => ref _f2; // 8
                }
                struct S3 : I<int>
                {
                    ref int I<int>.F1() => throw null;
                    void I<int>.F2() { }
                    void I<int>.F3(out R<int> r) { r = default; }
                    ref int I<int>.P => throw null;
                }
                struct S4 : I<int>
                {
                    private int _f4;
                    [UnscopedRef] ref int I<int>.F1() => ref _f4; // 9
                    [UnscopedRef] void I<int>.F2() { } // 10
                    [UnscopedRef] void I<int>.F3(out R<int> r) { r = new R<int>(ref _f4); } // 11
                    [UnscopedRef] ref int I<int>.P => ref _f4; // 12
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (8,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] ref T F1(); // 1
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(8, 6),
                // (9,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] void F2(); // 2
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(9, 6),
                // (10,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] void F3(out R<T> r); // 3
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(10, 6),
                // (11,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] ref T P { get; } // 4
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(11, 6),
                // (23,34): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     [UnscopedRef] public ref int F1() => ref _f2; // 5
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F1").WithLocation(23, 34),
                // (24,31): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     [UnscopedRef] public void F2() { } // 6
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F2").WithLocation(24, 31),
                // (25,31): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     [UnscopedRef] public void F3(out R<int> r) { r = new R<int>(ref _f2); } // 7
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F3").WithLocation(25, 31),
                // (26,39): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     [UnscopedRef] public ref int P => ref _f2; // 8
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "ref _f2").WithLocation(26, 39),
                // (38,34): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     [UnscopedRef] ref int I<int>.F1() => ref _f4; // 9
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F1").WithLocation(38, 34),
                // (39,31): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     [UnscopedRef] void I<int>.F2() { } // 10
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F2").WithLocation(39, 31),
                // (40,31): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     [UnscopedRef] void I<int>.F3(out R<int> r) { r = new R<int>(ref _f4); } // 11
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F3").WithLocation(40, 31),
                // (41,39): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     [UnscopedRef] ref int I<int>.P => ref _f4; // 12
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "ref _f4").WithLocation(41, 39));
        }
 
        [Fact]
        [WorkItem(64508, "https://github.com/dotnet/roslyn/issues/64508")]
        public void UnscopedRefAttribute_InterfaceImplementation_03()
        {
            string source = """
                using System.Diagnostics.CodeAnalysis;
                interface I1<T>
                {
                    ref T P1 { get; }
                }
                interface I2<T>
                {
                    T P2 { get; set; }
                }
                interface I3<T>
                {
                    T P3 { set; }
                }
                struct S1 : I1<int>, I2<int>
                {
                    [UnscopedRef] public ref int P1 => throw null; // 1
                    [UnscopedRef] public int P2 { get; set; } // 2, 3
                }
                struct S2 : I1<int>, I2<int>
                {
                    public ref int P1 { [UnscopedRef] get => throw null; } // 4
                    public int P2 { [UnscopedRef] get; set; } // 5
                }
                struct S3 : I2<int>, I3<int>
                {
                    public int P2 { get; [UnscopedRef] set; } // 6
                    public int P3 { [UnscopedRef] set { } } // 7
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (16,40): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     [UnscopedRef] public ref int P1 => throw null; // 1
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "throw null").WithLocation(16, 40),
                // (17,35): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     [UnscopedRef] public int P2 { get; set; } // 2, 3
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "get").WithLocation(17, 35),
                // (17,40): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     [UnscopedRef] public int P2 { get; set; } // 2, 3
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "set").WithLocation(17, 40),
                // (21,39): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     public ref int P1 { [UnscopedRef] get => throw null; } // 4
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "get").WithLocation(21, 39),
                // (22,35): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     public int P2 { [UnscopedRef] get; set; } // 5
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "get").WithLocation(22, 35),
                // (26,40): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     public int P2 { get; [UnscopedRef] set; } // 6
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "set").WithLocation(26, 40),
                // (27,35): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation.
                //     public int P3 { [UnscopedRef] set { } } // 7
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "set").WithLocation(27, 35));
        }
 
        [Fact]
        public void UnscopedRefAttribute_InterfaceImplementation_04()
        {
            string source = """
                using System.Diagnostics.CodeAnalysis;
                interface I<T>
                {
                    ref T F();
                    ref T P { get; }
                }
                struct S : I<int>
                {
                    private int _f;
                    [UnscopedRef] public ref int F() => ref _f;
                    [UnscopedRef] public ref int P => ref _f;
                    ref int I<int>.F() => throw null;
                    ref int I<int>.P => throw null;
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        public void UnscopedRefAttribute_InterfaceImplementation_05()
        {
            string source = """
                using System.Diagnostics.CodeAnalysis;
                interface I<T>
                {
                    ref T F1();
                    [UnscopedRef] ref T F2(); // 1
                }
                class C1 : I<int>
                {
                    private int _f1;
                    [UnscopedRef] public ref int F1() => ref _f1; // 2
                    [UnscopedRef] public ref int F2() => ref _f1; // 3
                }
                class C2 : I<int>
                {
                    private int _f2;
                    [UnscopedRef] ref int I<int>.F1() => ref _f2; // 4
                    [UnscopedRef] ref int I<int>.F2() => ref _f2; // 5
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (5,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] ref T F2(); // 1
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(5, 6),
                // (10,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] public ref int F1() => ref _f1; // 2
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(10, 6),
                // (11,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] public ref int F2() => ref _f1; // 3
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(11, 6),
                // (16,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] ref int I<int>.F1() => ref _f2; // 4
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(16, 6),
                // (17,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] ref int I<int>.F2() => ref _f2; // 5
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(17, 6));
        }
 
        [Fact]
        public void UnscopedRefAttribute_InterfaceImplementation_06()
        {
            string source = """
                using System.Diagnostics.CodeAnalysis;
                interface I<T>
                {
                    ref T F();
                    ref T P { get; }
                }
                class A
                {
                    [UnscopedRef] public ref int F() => throw null; // 1
                    [UnscopedRef] public ref int P => throw null; // 2
                }
                class B : A, I<int>
                {
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (9,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] public ref int F() => throw null; // 1
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(9, 6),
                // (10,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] public ref int P => throw null; // 2
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(10, 6));
        }
 
        [ConditionalFact(typeof(CoreClrOnly))]
        public void UnscopedRefAttribute_InterfaceImplementation_07()
        {
            string source = """
                using System.Diagnostics.CodeAnalysis;
                interface IA<T>
                {
                    ref T F();
                    ref T P { get; }
                }
                interface IB : IA<int>
                {
                    [UnscopedRef] ref int IA<int>.F() => throw null; // 1
                    [UnscopedRef] ref int IA<int>.P => throw null; // 2
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (9,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] ref int IA<int>.F() => throw null; // 1
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(9, 6),
                // (10,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] ref int IA<int>.P => throw null; // 2
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(10, 6));
        }
 
        [Fact]
        public void UnscopedRefAttribute_InterfaceImplementation_08()
        {
            string source = """
                #pragma warning disable 67
                using System.Diagnostics.CodeAnalysis;
                delegate void D<T>();
                interface I<T>
                {
                    event D<T> E;
                }
                class C1 : I<int>
                {
                    [UnscopedRef] public event D<int> E; // 1
                }
                class C2 : I<int>
                {
                    [UnscopedRef] public event D<int> E { add { } remove { } } // 2
                }
                class C3 : I<object>
                {
                    [UnscopedRef] event D<object> I<object>.E { add { } remove { } } // 3
                }
                struct S1 : I<int>
                {
                    [UnscopedRef] public event D<int> E; // 4
                }
                struct S2 : I<int>
                {
                    [UnscopedRef] public event D<int> E { add { } remove { } } // 5
                }
                struct S3 : I<object>
                {
                    [UnscopedRef] event D<object> I<object>.E { add { } remove { } } // 6
                }
                """;
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyEmitDiagnostics(
                // (10,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] public event D<int> E; // 1
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(10, 6),
                // (14,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] public event D<int> E { add { } remove { } } // 2
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(14, 6),
                // (18,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] event D<object> I<object>.E { add { } remove { } } // 3
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(18, 6),
                // (22,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] public event D<int> E; // 4
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(22, 6),
                // (26,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] public event D<int> E { add { } remove { } } // 5
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(26, 6),
                // (30,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] event D<object> I<object>.E { add { } remove { } } // 6
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(30, 6));
        }
 
        [Fact]
        public void UnscopedRefAttribute_InterfaceImplementation_09()
        {
            string source = """
                #pragma warning disable 67
                using System.Diagnostics.CodeAnalysis;
                delegate void D<T>();
                interface I<T>
                {
                    event D<T> E1;
                    event D<T> E2;
                }
                class C1 : I<int>
                {
                    public event D<int> E1 { [UnscopedRef] add { } remove { } } // 1
                    public event D<int> E2 { add { } [UnscopedRef] remove { } } // 2
                }
                class C2 : I<object>
                {
                    event D<object> I<object>.E1 { [UnscopedRef] add { } remove { } } // 3
                    event D<object> I<object>.E2 { add { } [UnscopedRef] remove { } } // 4
                }
                struct S1 : I<int>
                {
                    public event D<int> E1 { [UnscopedRef] add { } remove { } } // 5
                    public event D<int> E2 { add { } [UnscopedRef] remove { } } // 6
                }
                struct S2 : I<object>
                {
                    event D<object> I<object>.E1 { [UnscopedRef] add { } remove { } } // 7
                    event D<object> I<object>.E2 { add { } [UnscopedRef] remove { } } // 8
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (11,31): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     public event D<int> E1 { [UnscopedRef] add { } remove { } } // 1
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(11, 31),
                // (12,39): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     public event D<int> E2 { add { } [UnscopedRef] remove { } } // 2
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(12, 39),
                // (16,37): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     event D<object> I<object>.E1 { [UnscopedRef] add { } remove { } } // 3
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(16, 37),
                // (17,45): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     event D<object> I<object>.E2 { add { } [UnscopedRef] remove { } } // 4
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(17, 45),
                // (21,31): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     public event D<int> E1 { [UnscopedRef] add { } remove { } } // 5
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(21, 31),
                // (22,39): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     public event D<int> E2 { add { } [UnscopedRef] remove { } } // 6
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(22, 39),
                // (26,37): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     event D<object> I<object>.E1 { [UnscopedRef] add { } remove { } } // 7
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(26, 37),
                // (27,45): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     event D<object> I<object>.E2 { add { } [UnscopedRef] remove { } } // 8
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(27, 45));
        }
 
        [ConditionalFact(typeof(CoreClrOnly))]
        public void UnscopedRefAttribute_InterfaceImplementation_10()
        {
            string source = """
                using System.Diagnostics.CodeAnalysis;
                delegate void D<T>();
                interface I<T>
                {
                    event D<T> E;
                }
                interface IA : I<int>
                {
                    [UnscopedRef] event D<int> I<int>.E { add { } remove { } } // 1
                }
                interface IB : I<object>
                {
                    event D<object> I<object>.E { [UnscopedRef] add { } remove { } } // 2
                }
                interface IC : I<string>
                {
                    event D<string> I<string>.E { add { } [UnscopedRef] remove { } } // 3
                }
                """;
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }, targetFramework: TargetFramework.Net60);
            comp.VerifyEmitDiagnostics(
                // (9,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] event D<int> I<int>.E { add { } remove { } } // 1
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(9, 6),
                // (13,36): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     event D<object> I<object>.E { [UnscopedRef] add { } remove { } } // 2
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(13, 36),
                // (17,44): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     event D<string> I<string>.E { add { } [UnscopedRef] remove { } } // 3
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(17, 44));
        }
 
        [Fact]
        public void UnscopedRefAttribute_InterfaceImplementation_11()
        {
            string source = """
                #pragma warning disable 67
                using System.Diagnostics.CodeAnalysis;
                delegate void D<T>();
                interface I<T>
                {
                    [UnscopedRef] event D<T> E; // 1
                }
                class C : I<int>
                {
                    [UnscopedRef] public event D<int> E; // 2
                }
                struct S : I<object>
                {
                    [UnscopedRef] event D<object> I<object>.E { add { } remove { } } // 3
                }
                """;
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyEmitDiagnostics(
                // (6,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] event D<T> E; // 1
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(6, 6),
                // (10,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] public event D<int> E; // 2
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(10, 6),
                // (14,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] event D<object> I<object>.E { add { } remove { } } // 3
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(14, 6));
        }
 
        [Theory]
        [InlineData("class")]
        [InlineData("struct")]
        public void UnscopedRefAttribute_InterfaceImplementation_12(string type)
        {
            string source = $$"""
                using System.Diagnostics.CodeAnalysis;
                delegate void D<T>();
                ref struct R<T> { }
                interface I<T>
                {
                    static abstract R<T> F();
                    static abstract R<T> P1 { get; }
                    static abstract R<T> P2 { get; set; }
                    static abstract event D<T> E;
                }
                {{type}} C1 : I<int>
                {
                    [UnscopedRef] public static R<int> F() => default; // 1
                    [UnscopedRef] public static R<int> P1 { get { return default; } set { } } // 2
                    public static R<int> P2 { [UnscopedRef] get { return default; } [UnscopedRef] set { } } // 3, 4
                    public static event D<int> E { [UnscopedRef] add { } [UnscopedRef] remove { } } // 5, 6
                }
                {{type}} C2 : I<object>
                {
                    [UnscopedRef] static R<object> I<object>.F() => default; // 7
                    [UnscopedRef] static R<object> I<object>.P1 => default; // 8
                    static R<object> I<object>.P2 { [UnscopedRef] get { return default; } [UnscopedRef] set { } } // 9, 10
                    static event D<object> I<object>.E { [UnscopedRef] add { } [UnscopedRef] remove { } } // 11, 12
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (13,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] public static R<int> F() => default; // 1
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(13, 6),
                // (14,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] public static R<int> P1 { get { return default; } set { } } // 2
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(14, 6),
                // (15,32): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     public static R<int> P2 { [UnscopedRef] get { return default; } [UnscopedRef] set { } } // 3, 4
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(15, 32),
                // (15,70): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     public static R<int> P2 { [UnscopedRef] get { return default; } [UnscopedRef] set { } } // 3, 4
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(15, 70),
                // (16,37): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     public static event D<int> E { [UnscopedRef] add { } [UnscopedRef] remove { } } // 5, 6
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(16, 37),
                // (16,59): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     public static event D<int> E { [UnscopedRef] add { } [UnscopedRef] remove { } } // 5, 6
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(16, 59),
                // (20,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] static R<object> I<object>.F() => default; // 7
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(20, 6),
                // (21,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] static R<object> I<object>.P1 => default; // 8
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(21, 6),
                // (22,38): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     static R<object> I<object>.P2 { [UnscopedRef] get { return default; } [UnscopedRef] set { } } // 9, 10
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(22, 38),
                // (22,76): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     static R<object> I<object>.P2 { [UnscopedRef] get { return default; } [UnscopedRef] set { } } // 9, 10
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(22, 76),
                // (23,43): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     static event D<object> I<object>.E { [UnscopedRef] add { } [UnscopedRef] remove { } } // 11, 12
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(23, 43),
                // (23,65): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     static event D<object> I<object>.E { [UnscopedRef] add { } [UnscopedRef] remove { } } // 11, 12
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(23, 65));
        }
 
        [Fact]
        public void UnscopedRefAttribute_InterfaceImplementation_13()
        {
            string source = """
                using System.Diagnostics.CodeAnalysis;
                delegate void D<T>();
                ref struct R<T> { }
                interface IA<T>
                {
                    static abstract R<T> F();
                    static abstract R<T> P1 { get; }
                    static abstract R<T> P2 { get; set; }
                    static abstract event D<T> E;
                }
                interface IB : IA<object>
                {
                    [UnscopedRef] static R<object> IA<object>.F() => default; // 1
                    [UnscopedRef] static R<object> IA<object>.P1 => default; // 2
                    static R<object> IA<object>.P2 { [UnscopedRef] get { return default; } [UnscopedRef] set { } } // 3, 4
                    static event D<object> IA<object>.E { [UnscopedRef] add { } [UnscopedRef] remove { } } // 5, 6
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (13,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] static R<object> IA<object>.F() => default; // 1
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(13, 6),
                // (14,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] static R<object> IA<object>.P1 => default; // 2
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(14, 6),
                // (15,39): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     static R<object> IA<object>.P2 { [UnscopedRef] get { return default; } [UnscopedRef] set { } } // 3, 4
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(15, 39),
                // (15,77): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     static R<object> IA<object>.P2 { [UnscopedRef] get { return default; } [UnscopedRef] set { } } // 3, 4
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(15, 77),
                // (16,44): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     static event D<object> IA<object>.E { [UnscopedRef] add { } [UnscopedRef] remove { } } // 5, 6
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(16, 44),
                // (16,66): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     static event D<object> IA<object>.E { [UnscopedRef] add { } [UnscopedRef] remove { } } // 5, 6
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(16, 66));
        }
 
        [Fact]
        public void UnscopedRefAttribute_Overrides_07()
        {
            string source = """
                using System.Diagnostics.CodeAnalysis;
                abstract class A<T>
                {
                    public abstract ref T F1();
                    [UnscopedRef] public abstract ref T F2(); // 1
                }
                class B1 : A<int>
                {
                    private int _f1;
                    public override ref int F1() => ref _f1;
                    public override ref int F2() => ref _f1;
                }
                class B2 : A<string>
                {
                    private string _f2;
                    [UnscopedRef] public override ref string F1() => ref _f2; // 2
                    [UnscopedRef] public override ref string F2() => ref _f2; // 3
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (5,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] public abstract ref T F2(); // 1
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(5, 6),
                // (16,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] public override ref string F1() => ref _f2; // 2
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(16, 6),
                // (17,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.
                //     [UnscopedRef] public override ref string F2() => ref _f2; // 3
                Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(17, 6));
        }
 
        [WorkItem(64507, "https://github.com/dotnet/roslyn/issues/64507")]
        [Theory]
        [InlineData(0)]
        [InlineData(-1)]
        [InlineData(10)]
        [InlineData(11)]
        [InlineData(12)]
        [InlineData(int.MinValue)]
        [InlineData(int.MaxValue)]
        public void RefSafetyRulesAttribute_Version(int version)
        {
            var sourceA =
$@".assembly extern mscorlib {{ .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89) }}
.assembly '<<GeneratedFileName>>' {{ }}
.module '<<GeneratedFileName>>.dll'
.custom instance void System.Runtime.CompilerServices.RefSafetyRulesAttribute::.ctor(int32) = {{ int32({version}) }}
.class private System.Runtime.CompilerServices.RefSafetyRulesAttribute extends [mscorlib]System.Attribute
{{
  .method public hidebysig specialname rtspecialname instance void .ctor(int32 version) cil managed {{ ret }}
  .field public int32 Version
}}
.class public A
{{
  .method public static int32& F1([out] int32& i)
  {{
    ldnull
    throw
  }}
}}
";
            var refA = CompileIL(sourceA, prependDefaultHeader: false);
 
            var sourceB =
@"class B
{
    static ref int F2(out int i) => ref A.F1(out i);
}";
            var comp = CreateCompilation(sourceB, references: new[] { refA });
            if (version == 11)
            {
                comp.VerifyDiagnostics();
            }
            else
            {
                comp.VerifyDiagnostics(
                    // (3,41): error CS9103: 'A.F1(out int)' is defined in a module with an unrecognized RefSafetyRulesAttribute version, expecting '11'.
                    //     static ref int F2(out int i) => ref A.F1(out i);
                    Diagnostic(ErrorCode.ERR_UnrecognizedRefSafetyRulesAttributeVersion, "A.F1").WithArguments("A.F1(out int)").WithLocation(3, 41));
            }
 
            var method = comp.GetMember<MethodSymbol>("A.F1");
            VerifyParameterSymbol(method.Parameters[0], "out System.Int32 i", RefKind.Out, version == 11 ? ScopedKind.ScopedRef : ScopedKind.None);
 
            Assert.Equal(version == 11, method.ContainingModule.UseUpdatedEscapeRules);
        }
 
        [WorkItem(64507, "https://github.com/dotnet/roslyn/issues/64507")]
        [Fact]
        public void RefSafetyRulesAttribute_UnrecognizedConstructor_NoArguments()
        {
            // [module: RefSafetyRules()]
            var sourceA = """
                .assembly extern mscorlib { .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89) }
                .assembly '<<GeneratedFileName>>' { }
                .module '<<GeneratedFileName>>.dll'
                .custom instance void System.Runtime.CompilerServices.RefSafetyRulesAttribute::.ctor() = ( 01 00 00 00 ) 
                .class private System.Runtime.CompilerServices.RefSafetyRulesAttribute extends [mscorlib]System.Attribute
                {
                  .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret }
                }
                .class public A
                {
                  .method public static int32& F1([out] int32& i) { ldnull throw }
                }
                """;
            var refA = CompileIL(sourceA, prependDefaultHeader: false);
 
            var sourceB = """
                class B
                {
                    static ref int F2(out int i) => ref A.F1(out i);
                }
                """;
            var comp = CreateCompilation(sourceB, references: new[] { refA });
            comp.VerifyDiagnostics(
                // (3,41): error CS9103: 'A.F1(out int)' is defined in a module with an unrecognized RefSafetyRulesAttribute version, expecting '11'.
                //     static ref int F2(out int i) => ref A.F1(out i);
                Diagnostic(ErrorCode.ERR_UnrecognizedRefSafetyRulesAttributeVersion, "A.F1").WithArguments("A.F1(out int)").WithLocation(3, 41));
 
            var method = comp.GetMember<MethodSymbol>("A.F1");
            VerifyParameterSymbol(method.Parameters[0], "out System.Int32 i", RefKind.Out, ScopedKind.None);
 
            Assert.False(method.ContainingModule.UseUpdatedEscapeRules);
        }
 
        [WorkItem(64507, "https://github.com/dotnet/roslyn/issues/64507")]
        [Fact]
        public void RefSafetyRulesAttribute_UnrecognizedConstructor_StringArgument()
        {
            // [module: RefSafetyRules("11")]
            var sourceA = """
                .assembly extern mscorlib { .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89) }
                .assembly '<<GeneratedFileName>>' { }
                .module '<<GeneratedFileName>>.dll'
                .custom instance void System.Runtime.CompilerServices.RefSafetyRulesAttribute::.ctor(string) = {string('11')}
                .class private System.Runtime.CompilerServices.RefSafetyRulesAttribute extends [mscorlib]System.Attribute
                {
                  .method public hidebysig specialname rtspecialname instance void .ctor(string version) cil managed { ret }
                }
                .class public A
                {
                  .method public static int32& F1([out] int32& i) { ldnull throw }
                }
                """;
            var refA = CompileIL(sourceA, prependDefaultHeader: false);
 
            var sourceB = """
                class B
                {
                    static ref int F2(out int i) => ref A.F1(out i);
                }
                """;
            var comp = CreateCompilation(sourceB, references: new[] { refA });
            comp.VerifyDiagnostics(
                // (3,41): error CS9103: 'A.F1(out int)' is defined in a module with an unrecognized RefSafetyRulesAttribute version, expecting '11'.
                //     static ref int F2(out int i) => ref A.F1(out i);
                Diagnostic(ErrorCode.ERR_UnrecognizedRefSafetyRulesAttributeVersion, "A.F1").WithArguments("A.F1(out int)").WithLocation(3, 41));
 
            var method = comp.GetMember<MethodSymbol>("A.F1");
            VerifyParameterSymbol(method.Parameters[0], "out System.Int32 i", RefKind.Out, ScopedKind.None);
 
            Assert.False(method.ContainingModule.UseUpdatedEscapeRules);
        }
 
        /// <summary>
        /// Use updated escape rules with either -langversion:11 or higher, or
        /// with System.Runtime.CompilerServices.RuntimeFeature.ByRefFields.
        /// </summary>
        [Theory]
        [InlineData(LanguageVersion.CSharp10, TargetFramework.Net60, false, false)]
        [InlineData(LanguageVersion.CSharp11, TargetFramework.Net60, false, true)]
        [InlineData(LanguageVersion.Latest, TargetFramework.Net60, false, true)]
        [InlineData(LanguageVersion.CSharp10, TargetFramework.Net70, true, true)]
        [InlineData(LanguageVersion.CSharp11, TargetFramework.Net70, true, true)]
        [InlineData(LanguageVersion.Latest, TargetFramework.Net70, true, true)]
        public void UseUpdatedEscapeRules(LanguageVersion languageVersion, TargetFramework targetFramework, bool supportsRefFields, bool expectedUseUpdatedEscapeRules)
        {
            var source =
@"class Program
{
    static ref T F1<T>(out T t) => throw null;
    static ref T F2<T>() => ref F1(out T t);
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), targetFramework: targetFramework);
            if (expectedUseUpdatedEscapeRules)
            {
                comp.VerifyEmitDiagnostics();
            }
            else
            {
                comp.VerifyEmitDiagnostics(
                    // (4,33): error CS8347: Cannot use a result of 'Program.F1<T>(out T)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                    //     static ref T F2<T>() => ref F1(out T t);
                    Diagnostic(ErrorCode.ERR_EscapeCall, "F1(out T t)").WithArguments("Program.F1<T>(out T)", "t").WithLocation(4, 33),
                    // (4,40): error CS8168: Cannot return local 't' by reference because it is not a ref local
                    //     static ref T F2<T>() => ref F1(out T t);
                    Diagnostic(ErrorCode.ERR_RefReturnLocal, "T t").WithArguments("t").WithLocation(4, 40));
            }
 
            Assert.Equal(supportsRefFields, comp.SourceAssembly.RuntimeSupportsByRefFields);
 
            var runtimeFeature = (FieldSymbol)comp.GetMember<NamedTypeSymbol>("System.Runtime.CompilerServices.RuntimeFeature").GetMembers("ByRefFields").SingleOrDefault();
            Assert.Equal(supportsRefFields, runtimeFeature is { });
            if (supportsRefFields)
            {
                Assert.Equal("System.String System.Runtime.CompilerServices.RuntimeFeature.ByRefFields", runtimeFeature.ToTestDisplayString());
            }
 
            var method = comp.GetMember<MethodSymbol>("Program.F1");
            VerifyParameterSymbol(method.Parameters[0], "out T t", RefKind.Out, expectedUseUpdatedEscapeRules ? ScopedKind.ScopedRef : ScopedKind.None);
 
            Assert.Equal(expectedUseUpdatedEscapeRules, method.UseUpdatedEscapeRules);
            Assert.Equal(expectedUseUpdatedEscapeRules, method.ContainingModule.UseUpdatedEscapeRules);
        }
 
        [WorkItem(63691, "https://github.com/dotnet/roslyn/issues/63691")]
        [Theory]
        [CombinatorialData]
        public void DetectUpdatedEscapeRulesFromCorlib(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersion,
            [CombinatorialValues(6, 7, 8)] int majorVersion)
        {
            var source0 =
@"namespace System
{
    public class Object { }
    public class String { }
    public abstract class ValueType { }
    public struct Void { }
    public struct Boolean { }
    public struct Int32 { }
    public class Attribute { }
    public class AttributeUsageAttribute : Attribute
    {
        public AttributeUsageAttribute(AttributeTargets t) { }
        public bool AllowMultiple { get; set; }
        public bool Inherited { get; set; }
    }
    public struct Enum { }
    public enum AttributeTargets { }
}";
            var assemblyIdentity = new AssemblyIdentity("System.Runtime", new System.Version(majorVersion, 0, 0, 0));
            var comp = CreateCompilation(assemblyIdentity, new[] { source0 }, references: null, parseOptions: TestOptions.Regular10);
            var ref0 = comp.EmitToImageReference(Microsoft.CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("0.0.0.0"));
 
            var source1 =
@"public class A<T>
{
    public static void F() { }
}";
            comp = CreateEmptyCompilation(source1, references: new[] { ref0 }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics();
            var ref1 = comp.EmitToImageReference();
 
            var source2 =
@"class B : A<int>
{
    static void Main() { }
}";
            comp = CreateEmptyCompilation(source2, references: new[] { ref0, ref1 }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics();
 
            var module = comp.GetMember<NamedTypeSymbol>("A").ContainingModule;
            Assert.Equal(assemblyIdentity, module.ReferencedAssemblies.Single());
            Assert.Equal(assemblyIdentity, module.ContainingAssembly.CorLibrary.Identity);
 
            Assert.Equal(languageVersion == LanguageVersion.CSharp11, module.UseUpdatedEscapeRules);
 
            module = comp.GetMember<NamedTypeSymbol>("System.Object").ContainingModule;
            Assert.False(module.UseUpdatedEscapeRules);
        }
 
        [WorkItem(63691, "https://github.com/dotnet/roslyn/issues/63691")]
        [Theory]
        [CombinatorialData]
        public void DetectUpdatedEscapeRulesFromCorlib_Retargeting(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersion,
            [CombinatorialValues(7, 8)] int higherVersion)
        {
            var source0 =
@"namespace System
{
    public class Object { }
    public class String { }
    public abstract class ValueType { }
    public struct Void { }
    public struct Boolean { }
    public struct Int32 { }
    public class Attribute { }
    public class AttributeUsageAttribute : Attribute
    {
        public AttributeUsageAttribute(AttributeTargets t) { }
        public bool AllowMultiple { get; set; }
        public bool Inherited { get; set; }
    }
    public struct Enum { }
    public enum AttributeTargets { }
}";
            var assemblyIdentityLowerVersion = new AssemblyIdentity("System.Runtime", new System.Version(6, 0, 0, 0));
            var comp = CreateCompilation(assemblyIdentityLowerVersion, new[] { source0 }, references: null, parseOptions: TestOptions.Regular10);
            var refLowerVersion = comp.EmitToImageReference();
 
            var assemblyIdentityHigherVersion = new AssemblyIdentity("System.Runtime", new System.Version(higherVersion, 0, 0, 0));
            comp = CreateCompilation(assemblyIdentityHigherVersion, new[] { source0 }, references: null, parseOptions: TestOptions.Regular10);
            var refHigherVersion = comp.EmitToImageReference();
 
            var source1 =
@"public class A<T>
{
    public static void F() { }
}";
            comp = CreateEmptyCompilation(source1, references: new[] { refLowerVersion }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics();
            var ref1 = comp.EmitToImageReference();
            var module = comp.GetMember<NamedTypeSymbol>("System.Object").ContainingModule;
            Assert.False(module.UseUpdatedEscapeRules);
 
            module = comp.GetMember<NamedTypeSymbol>("A").ContainingModule;
            Assert.Equal(languageVersion == LanguageVersion.CSharp11, module.UseUpdatedEscapeRules);
            Assert.Equal(languageVersion == LanguageVersion.CSharp11, ((SourceModuleSymbol)module).RequiresRefSafetyRulesAttribute());
 
            var source2 =
@"class B : A<int>
{
    static void Main() { }
}";
            comp = CreateEmptyCompilation(source2, references: new[] { refHigherVersion, ref1 }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics();
 
            module = comp.GetMember<NamedTypeSymbol>("A").ContainingModule;
            Assert.Equal(assemblyIdentityLowerVersion, module.ReferencedAssemblies.Single());
            Assert.Equal(assemblyIdentityHigherVersion, module.ContainingAssembly.CorLibrary.Identity);
            Assert.Equal(languageVersion == LanguageVersion.CSharp11, module.UseUpdatedEscapeRules);
 
            module = module.ContainingAssembly.CorLibrary.Modules[0];
            Assert.False(module.UseUpdatedEscapeRules);
        }
 
        [WorkItem(63691, "https://github.com/dotnet/roslyn/issues/63691")]
        [Theory]
        [InlineData("System.Runtime", 7, 0, false)]
        [InlineData("System.Runtime", 7, 1, false)]
        [InlineData("System.Runtime", 8, 0, false)]
        [InlineData("mscorlib", 7, 0, false)]
        [InlineData("System.Core", 7, 0, false)]
        public void DetectUpdatedEscapeRulesFromCorlib_SystemRuntime70Only(string assemblyName, int majorVersion, int minorVersion, bool expectedUseUpdatedEscapeRules)
        {
            var source0 =
@"namespace System
{
    public class Object { }
    public class String { }
    public abstract class ValueType { }
    public struct Void { }
    public struct Boolean { }
    public struct Int32 { }
    public class Attribute { }
    public class AttributeUsageAttribute : Attribute
    {
        public AttributeUsageAttribute(AttributeTargets t) { }
        public bool AllowMultiple { get; set; }
        public bool Inherited { get; set; }
    }
    public struct Enum { }
    public enum AttributeTargets { }
}";
            var assemblyIdentity = new AssemblyIdentity(assemblyName, new System.Version(majorVersion, minorVersion, 0, 0));
            var comp = CreateCompilation(assemblyIdentity, new[] { source0 }, references: null, parseOptions: TestOptions.Regular10);
            var ref0 = comp.EmitToImageReference(Microsoft.CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("0.0.0.0"));
 
            var source1 =
@"public class A<T>
{
    public static void F() { }
}";
            comp = CreateEmptyCompilation(source1, references: new[] { ref0 }, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics();
            var ref1 = comp.EmitToImageReference();
            var module = comp.GetMember<NamedTypeSymbol>("System.Object").ContainingModule;
            Assert.Equal(expectedUseUpdatedEscapeRules, module.UseUpdatedEscapeRules);
 
            module = comp.GetMember<NamedTypeSymbol>("A").ContainingModule;
            Assert.False(module.UseUpdatedEscapeRules);
            Assert.False(((SourceModuleSymbol)module).RequiresRefSafetyRulesAttribute());
 
            var source2 =
@"class B : A<int>
{
    static void Main() { }
}";
            comp = CreateEmptyCompilation(source2, references: new[] { ref0, ref1 });
            comp.VerifyEmitDiagnostics();
 
            module = comp.GetMember<NamedTypeSymbol>("A").ContainingModule;
            Assert.Equal(assemblyIdentity, module.ReferencedAssemblies.Single());
            Assert.Equal(assemblyIdentity, module.ContainingAssembly.CorLibrary.Identity);
 
            Assert.Equal(expectedUseUpdatedEscapeRules, module.UseUpdatedEscapeRules);
 
            module = comp.GetMember<NamedTypeSymbol>("System.Object").ContainingModule;
            Assert.Equal(expectedUseUpdatedEscapeRules, module.UseUpdatedEscapeRules);
        }
 
        [Fact]
        [WorkItem(63565, "https://github.com/dotnet/roslyn/issues/63565")]
        public void UnscopedRefInInferredDelegateType_01()
        {
            var source =
@"
using System.Diagnostics.CodeAnalysis;
 
public ref struct RefStruct { }
public struct RegularStruct { }
 
delegate void D1(ref RefStruct s);
delegate void D2([UnscopedRef] out RegularStruct s);
delegate void D3([UnscopedRef] out RefStruct s);
 
public class C
{
  public void M()
  {
    var a = (ref RefStruct s) => { };
    var b = ([UnscopedRef] out RegularStruct s) => { };
    var c = ([UnscopedRef] out RefStruct s) => { };
 
    D1 x = (ref RefStruct s) => { };
    D2 y = ([UnscopedRef] out RegularStruct s) => { };
    D3 z = ([UnscopedRef] out RefStruct s) => { };
  }
}
";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }, options: TestOptions.ReleaseDll);
            comp.VerifyEmitDiagnostics();
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
 
            int count = 0;
            foreach (var node in tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Where(d => d.Identifier.ValueText is "a" or "b" or "c"))
            {
                count++;
                var type = (NamedTypeSymbol)model.GetDeclaredSymbol(node).GetSymbol<LocalSymbol>().Type;
                Assert.True(type.IsImplicitlyDeclared);
                Assert.True(type.IsAnonymousType);
                Assert.Equal(ScopedKind.None, type.DelegateInvokeMethod.Parameters.Single().EffectiveScope);
            }
 
            Assert.Equal(3, count);
        }
 
        [Fact]
        [WorkItem(63565, "https://github.com/dotnet/roslyn/issues/63565")]
        public void UnscopedRefInInferredDelegateType_02()
        {
            var source =
@"
using System.Diagnostics.CodeAnalysis;
 
public ref struct RefStruct { }
public struct RegularStruct { }
 
delegate void D1(ref RefStruct s);
delegate void D2([UnscopedRef] out RegularStruct s);
delegate void D3([UnscopedRef] out RefStruct s);
 
public class C
{
  public void M()
  {
    void localA(ref RefStruct s) { };
    void localB([UnscopedRef] out RegularStruct s) { };
    void localC([UnscopedRef] out RefStruct s) { };
 
    var a = localA;
    var b = localB;
    var c = localC;
 
    D1 x = localA;
    D2 y = localB;
    D3 z = localC;
  }
}
";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }, options: TestOptions.ReleaseDll);
            comp.VerifyEmitDiagnostics();
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
 
            int count = 0;
            foreach (var node in tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Where(d => d.Identifier.ValueText is "a" or "b" or "c"))
            {
                count++;
                var type = (NamedTypeSymbol)model.GetDeclaredSymbol(node).GetSymbol<LocalSymbol>().Type;
                Assert.True(type.IsImplicitlyDeclared);
                Assert.True(type.IsAnonymousType);
                Assert.Equal(ScopedKind.None, type.DelegateInvokeMethod.Parameters.Single().EffectiveScope);
            }
 
            Assert.Equal(3, count);
        }
 
        [Fact]
        [WorkItem(63565, "https://github.com/dotnet/roslyn/issues/63565")]
        public void UnscopedRefInInferredDelegateType_03()
        {
            var source =
@"
using System.Diagnostics.CodeAnalysis;
 
public ref struct RefStruct { }
public struct RegularStruct { }
 
delegate void D1(ref RefStruct s);
delegate void D2([UnscopedRef] out RegularStruct s);
delegate void D3([UnscopedRef] out RefStruct s);
 
public class C1
{
  public void M()
  {
    var a = A;
    var b = B;
    var c = C;
 
    D1 x = A;
    D2 y = B;
    D3 z = C;
  }
 
  void A(ref RefStruct s) { }
  void B([UnscopedRef] out RegularStruct s) { }
  void C([UnscopedRef] out RefStruct s) { }
}
";
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }, options: TestOptions.ReleaseDll);
            comp.VerifyEmitDiagnostics();
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
 
            int count = 0;
            foreach (var node in tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Where(d => d.Identifier.ValueText is "a" or "b" or "c"))
            {
                count++;
                var type = (NamedTypeSymbol)model.GetDeclaredSymbol(node).GetSymbol<LocalSymbol>().Type;
                Assert.True(type.IsImplicitlyDeclared);
                Assert.True(type.IsAnonymousType);
                Assert.Equal(ScopedKind.None, type.DelegateInvokeMethod.Parameters.Single().EffectiveScope);
            }
 
            Assert.Equal(3, count);
        }
 
        [Fact, WorkItem(63526, "https://github.com/dotnet/roslyn/issues/63526")]
        public void UnscopedRef_ArgumentsMustMatch_01()
        {
            var source = """
                using System.Diagnostics.CodeAnalysis;
 
                ref struct RefByteContainer
                {
                    public ref byte RB;
 
                    public RefByteContainer(ref byte rb)
                    {
                        RB = ref rb;
                    }
                }
 
                ref struct ByteContainer
                {
                    public byte B;
 
                    [UnscopedRef]
                    public RefByteContainer ByteRef => new RefByteContainer(ref B);
 
                    [UnscopedRef]
                    public RefByteContainer GetByteRef() => new RefByteContainer(ref B);
                }
 
                public class Program
                {
                    static void M11(ref ByteContainer bc)
                    {
                        // ok. because ref-safe-to-escape of 'this' in 'ByteContainer.ByteRef.get' is 'ReturnOnly',
                        // we know that 'ref bc' will not end up written to a ref field within 'bc'.
                        _ = bc.ByteRef;
                    }
                    static void M12(ref ByteContainer bc)
                    {
                        // ok. because ref-safe-to-escape of 'this' in 'ByteContainer.GetByteRef()' is 'ReturnOnly',
                        // we know that 'ref bc' will not end up written to a ref field within 'bc'.
                        _ = bc.GetByteRef();
                    }
 
                    static void M21(ref ByteContainer bc, ref RefByteContainer rbc)
                    {
                        // error. ref-safe-to-escape of 'bc' is 'ReturnOnly', therefore 'bc.ByteRef' can't be assigned to a ref parameter.
                        rbc = bc.ByteRef; // 1
                    }
                    static void M22(ref ByteContainer bc, ref RefByteContainer rbc)
                    {
                        // error. ref-safe-to-escape of 'bc' is 'ReturnOnly', therefore 'bc.ByteRef' can't be assigned to a ref parameter.
                        rbc = bc.GetByteRef(); // 2
                    }
 
                    static RefByteContainer M31(ref ByteContainer bc)
                        // ok. ref-safe-to-escape of 'bc' is 'ReturnOnly'.
                        => bc.ByteRef;
 
                    static RefByteContainer M32(ref ByteContainer bc)
                        // ok. ref-safe-to-escape of 'bc' is 'ReturnOnly'.
                        => bc.GetByteRef();
 
                    static RefByteContainer M41(scoped ref ByteContainer bc)
                        // error: `bc.ByteRef` may contain a reference to `bc`, whose ref-safe-to-escape is CurrentMethod.
                        => bc.ByteRef; // 3
 
                    static RefByteContainer M42(scoped ref ByteContainer bc)
                        // error: `bc.GetByteRef()` may contain a reference to `bc`, whose ref-safe-to-escape is CurrentMethod.
                        => bc.GetByteRef(); // 4
                }
                """;
 
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (42,15): error CS9077: Cannot return a parameter by reference 'bc' through a ref parameter; it can only be returned in a return statement
                //         rbc = bc.ByteRef; // 1
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "bc").WithArguments("bc").WithLocation(42, 15),
                // (47,15): error CS9077: Cannot return a parameter by reference 'bc' through a ref parameter; it can only be returned in a return statement
                //         rbc = bc.GetByteRef(); // 2
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "bc").WithArguments("bc").WithLocation(47, 15),
                // (60,12): error CS9075: Cannot return a parameter by reference 'bc' because it is scoped to the current method
                //         => bc.ByteRef; // 3
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "bc").WithArguments("bc").WithLocation(60, 12),
                // (64,12): error CS9075: Cannot return a parameter by reference 'bc' because it is scoped to the current method
                //         => bc.GetByteRef(); // 4
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "bc").WithArguments("bc").WithLocation(64, 12));
        }
 
        [Fact]
        public void LocalScope_01_UsingDecl()
        {
            var source =
@"#pragma warning disable 219
 
class Program
{
    static void F(ref R r)
    {
        using scoped R r1 = default;
        using scoped ref R r2 = ref r;
        using scoped ref readonly R r5 = ref r;
    }
}
 
ref struct R
{
    public void Dispose() {}
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (7,15): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         using scoped R r1 = default;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(7, 15),
                // (8,15): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         using scoped ref R r2 = ref r;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(8, 15),
                // (8,22): error CS1073: Unexpected token 'ref'
                //         using scoped ref R r2 = ref r;
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(8, 22),
                // (9,15): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         using scoped ref readonly R r5 = ref r;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(9, 15),
                // (9,22): error CS1073: Unexpected token 'ref'
                //         using scoped ref readonly R r5 = ref r;
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(9, 22)
                );
            verify(comp);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (8,22): error CS1073: Unexpected token 'ref'
                //         using scoped ref R r2 = ref r;
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(8, 22),
                // (9,22): error CS1073: Unexpected token 'ref'
                //         using scoped ref readonly R r5 = ref r;
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(9, 22)
                );
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                VerifyLocalSymbol(locals[0], "scoped R r1", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[1], "scoped ref R r2", RefKind.Ref, ScopedKind.ScopedRef);
                VerifyLocalSymbol(locals[2], "scoped ref readonly R r5", RefKind.RefReadOnly, ScopedKind.ScopedRef);
 
                foreach (var decl in decls)
                {
                    var type = ((VariableDeclarationSyntax)decl.Parent).Type;
 
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type));
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type.SkipScoped(out _)));
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type.SkipScoped(out _).SkipRef()));
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("R", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("R", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
            }
        }
 
        [Fact]
        public void LocalScope_01_UsingStmt()
        {
            var source =
@"#pragma warning disable 219
 
class Program
{
    static void F(ref R r)
    {
        using (scoped R r1 = default) {}
        using (scoped ref R r2 = ref r) {}
        using (scoped ref readonly R r5 = ref r) {}
    }
}
 
ref struct R
{
    public void Dispose() {}
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (7,16): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         using (scoped R r1 = default) {}
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(7, 16),
                // (8,16): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         using (scoped ref R r2 = ref r) {}
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(8, 16),
                // (8,23): error CS1073: Unexpected token 'ref'
                //         using (scoped ref R r2 = ref r) {}
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(8, 23),
                // (9,16): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         using (scoped ref readonly R r5 = ref r) {}
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(9, 16),
                // (9,23): error CS1073: Unexpected token 'ref'
                //         using (scoped ref readonly R r5 = ref r) {}
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(9, 23)
                );
            verify(comp);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (8,23): error CS1073: Unexpected token 'ref'
                //         using (scoped ref R r2 = ref r) {}
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(8, 23),
                // (9,23): error CS1073: Unexpected token 'ref'
                //         using (scoped ref readonly R r5 = ref r) {}
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(9, 23)
                );
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                VerifyLocalSymbol(locals[0], "scoped R r1", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[1], "scoped ref R r2", RefKind.Ref, ScopedKind.ScopedRef);
                VerifyLocalSymbol(locals[2], "scoped ref readonly R r5", RefKind.RefReadOnly, ScopedKind.ScopedRef);
 
                foreach (var decl in decls)
                {
                    var type = ((VariableDeclarationSyntax)decl.Parent).Type;
 
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type));
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type.SkipScoped(out _)));
                    Assert.True(SyntaxFacts.IsInTypeOnlyContext(type.SkipScoped(out _).SkipRef()));
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    if (type is RefTypeSyntax refType)
                    {
                        Assert.Null(model.GetSymbolInfo(type).Symbol);
                        Assert.Null(model.GetTypeInfo(type).Type);
 
                        type = refType.Type;
                    }
 
                    Assert.Equal("R", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("R", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
            }
        }
 
        [Fact]
        public void LocalScope_04_UsingDecl()
        {
            var source =
@"using scoped s1 = default;
using ref scoped s2 = ref s1; // 1
using ref @scoped s3 = ref s1;
using scoped scoped s4 = default; // 2
using scoped ref scoped s5 = ref s1; // 3
using scoped ref @scoped s6 = ref s1; // 4
ref struct @scoped
{
    public void Dispose() {}
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (2,7): error CS1073: Unexpected token 'ref'
                // using ref scoped s2 = ref s1; // 1
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(2, 7),
                // (2,27): error CS1657: Cannot use 's1' as a ref or out value because it is a 'using variable'
                // using ref scoped s2 = ref s1; // 1
                Diagnostic(ErrorCode.ERR_RefReadonlyLocalCause, "s1").WithArguments("s1", "using variable").WithLocation(2, 27),
                // (3,7): error CS1073: Unexpected token 'ref'
                // using ref @scoped s3 = ref s1;
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(3, 7),
                // (3,28): error CS1657: Cannot use 's1' as a ref or out value because it is a 'using variable'
                // using ref @scoped s3 = ref s1;
                Diagnostic(ErrorCode.ERR_RefReadonlyLocalCause, "s1").WithArguments("s1", "using variable").WithLocation(3, 28),
                // (4,7): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                // using scoped scoped s4 = default; // 2
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(4, 7),
                // (5,7): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                // using scoped ref scoped s5 = ref s1; // 3
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(5, 7),
                // (5,14): error CS1073: Unexpected token 'ref'
                // using scoped ref scoped s5 = ref s1; // 3
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(5, 14),
                // (5,34): error CS1657: Cannot use 's1' as a ref or out value because it is a 'using variable'
                // using scoped ref scoped s5 = ref s1; // 3
                Diagnostic(ErrorCode.ERR_RefReadonlyLocalCause, "s1").WithArguments("s1", "using variable").WithLocation(5, 34),
                // (6,7): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                // using scoped ref @scoped s6 = ref s1; // 4
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(6, 7),
                // (6,14): error CS1073: Unexpected token 'ref'
                // using scoped ref @scoped s6 = ref s1; // 4
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(6, 14),
                // (6,35): error CS1657: Cannot use 's1' as a ref or out value because it is a 'using variable'
                // using scoped ref @scoped s6 = ref s1; // 4
                Diagnostic(ErrorCode.ERR_RefReadonlyLocalCause, "s1").WithArguments("s1", "using variable").WithLocation(6, 35)
                );
            verify(comp);
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (2,7): error CS1073: Unexpected token 'ref'
                // using ref scoped s2 = ref s1; // 1
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(2, 7),
                // (2,27): error CS1657: Cannot use 's1' as a ref or out value because it is a 'using variable'
                // using ref scoped s2 = ref s1; // 1
                Diagnostic(ErrorCode.ERR_RefReadonlyLocalCause, "s1").WithArguments("s1", "using variable").WithLocation(2, 27),
                // (3,7): error CS1073: Unexpected token 'ref'
                // using ref @scoped s3 = ref s1;
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(3, 7),
                // (3,28): error CS1657: Cannot use 's1' as a ref or out value because it is a 'using variable'
                // using ref @scoped s3 = ref s1;
                Diagnostic(ErrorCode.ERR_RefReadonlyLocalCause, "s1").WithArguments("s1", "using variable").WithLocation(3, 28),
                // (5,14): error CS1073: Unexpected token 'ref'
                // using scoped ref scoped s5 = ref s1; // 3
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(5, 14),
                // (5,34): error CS1657: Cannot use 's1' as a ref or out value because it is a 'using variable'
                // using scoped ref scoped s5 = ref s1; // 3
                Diagnostic(ErrorCode.ERR_RefReadonlyLocalCause, "s1").WithArguments("s1", "using variable").WithLocation(5, 34),
                // (6,14): error CS1073: Unexpected token 'ref'
                // using scoped ref @scoped s6 = ref s1; // 4
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(6, 14),
                // (6,35): error CS1657: Cannot use 's1' as a ref or out value because it is a 'using variable'
                // using scoped ref @scoped s6 = ref s1; // 4
                Diagnostic(ErrorCode.ERR_RefReadonlyLocalCause, "s1").WithArguments("s1", "using variable").WithLocation(6, 35)
                );
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                VerifyLocalSymbol(locals[0], "scoped s1", RefKind.None, ScopedKind.None);
                VerifyLocalSymbol(locals[1], "ref scoped s2", RefKind.Ref, ScopedKind.None);
                VerifyLocalSymbol(locals[2], "ref scoped s3", RefKind.Ref, ScopedKind.None);
                VerifyLocalSymbol(locals[3], "scoped scoped s4", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[4], "scoped ref scoped s5", RefKind.Ref, ScopedKind.ScopedRef);
                VerifyLocalSymbol(locals[5], "scoped ref scoped s6", RefKind.Ref, ScopedKind.ScopedRef);
            }
        }
 
        [Fact]
        public void LocalScope_04_UsingStmt()
        {
            var source =
@"
using (scoped s1 = default)
    using (ref scoped s2 = ref s1)
        using (ref @scoped s3 = ref s1)
            using (scoped scoped s4 = default)
                using (scoped ref scoped s5 = ref s1)
                    using (scoped ref @scoped s6 = ref s1)
                    {}
 
ref struct @scoped
{
    public void Dispose() {}
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (3,12): error CS1073: Unexpected token 'ref'
                //     using (ref scoped s2 = ref s1)
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(3, 12),
                // (3,32): error CS1657: Cannot use 's1' as a ref or out value because it is a 'using variable'
                //     using (ref scoped s2 = ref s1)
                Diagnostic(ErrorCode.ERR_RefReadonlyLocalCause, "s1").WithArguments("s1", "using variable").WithLocation(3, 32),
                // (4,16): error CS1073: Unexpected token 'ref'
                //         using (ref @scoped s3 = ref s1)
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(4, 16),
                // (4,37): error CS1657: Cannot use 's1' as a ref or out value because it is a 'using variable'
                //         using (ref @scoped s3 = ref s1)
                Diagnostic(ErrorCode.ERR_RefReadonlyLocalCause, "s1").WithArguments("s1", "using variable").WithLocation(4, 37),
                // (5,20): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //             using (scoped scoped s4 = default)
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(5, 20),
                // (6,24): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //                 using (scoped ref scoped s5 = ref s1)
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(6, 24),
                // (6,31): error CS1073: Unexpected token 'ref'
                //                 using (scoped ref scoped s5 = ref s1)
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(6, 31),
                // (6,51): error CS1657: Cannot use 's1' as a ref or out value because it is a 'using variable'
                //                 using (scoped ref scoped s5 = ref s1)
                Diagnostic(ErrorCode.ERR_RefReadonlyLocalCause, "s1").WithArguments("s1", "using variable").WithLocation(6, 51),
                // (7,28): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //                     using (scoped ref @scoped s6 = ref s1)
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(7, 28),
                // (7,35): error CS1073: Unexpected token 'ref'
                //                     using (scoped ref @scoped s6 = ref s1)
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(7, 35),
                // (7,56): error CS1657: Cannot use 's1' as a ref or out value because it is a 'using variable'
                //                     using (scoped ref @scoped s6 = ref s1)
                Diagnostic(ErrorCode.ERR_RefReadonlyLocalCause, "s1").WithArguments("s1", "using variable").WithLocation(7, 56)
                );
            verify(comp);
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (3,12): error CS1073: Unexpected token 'ref'
                //     using (ref scoped s2 = ref s1)
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(3, 12),
                // (3,32): error CS1657: Cannot use 's1' as a ref or out value because it is a 'using variable'
                //     using (ref scoped s2 = ref s1)
                Diagnostic(ErrorCode.ERR_RefReadonlyLocalCause, "s1").WithArguments("s1", "using variable").WithLocation(3, 32),
                // (4,16): error CS1073: Unexpected token 'ref'
                //         using (ref @scoped s3 = ref s1)
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(4, 16),
                // (4,37): error CS1657: Cannot use 's1' as a ref or out value because it is a 'using variable'
                //         using (ref @scoped s3 = ref s1)
                Diagnostic(ErrorCode.ERR_RefReadonlyLocalCause, "s1").WithArguments("s1", "using variable").WithLocation(4, 37),
                // (6,31): error CS1073: Unexpected token 'ref'
                //                 using (scoped ref scoped s5 = ref s1)
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(6, 31),
                // (6,51): error CS1657: Cannot use 's1' as a ref or out value because it is a 'using variable'
                //                 using (scoped ref scoped s5 = ref s1)
                Diagnostic(ErrorCode.ERR_RefReadonlyLocalCause, "s1").WithArguments("s1", "using variable").WithLocation(6, 51),
                // (7,35): error CS1073: Unexpected token 'ref'
                //                     using (scoped ref @scoped s6 = ref s1)
                Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(7, 35),
                // (7,56): error CS1657: Cannot use 's1' as a ref or out value because it is a 'using variable'
                //                     using (scoped ref @scoped s6 = ref s1)
                Diagnostic(ErrorCode.ERR_RefReadonlyLocalCause, "s1").WithArguments("s1", "using variable").WithLocation(7, 56)
                );
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                VerifyLocalSymbol(locals[0], "scoped s1", RefKind.None, ScopedKind.None);
                VerifyLocalSymbol(locals[1], "ref scoped s2", RefKind.Ref, ScopedKind.None);
                VerifyLocalSymbol(locals[2], "ref scoped s3", RefKind.Ref, ScopedKind.None);
                VerifyLocalSymbol(locals[3], "scoped scoped s4", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[4], "scoped ref scoped s5", RefKind.Ref, ScopedKind.ScopedRef);
                VerifyLocalSymbol(locals[5], "scoped ref scoped s6", RefKind.Ref, ScopedKind.ScopedRef);
            }
        }
 
        [Fact]
        public void LocalScope_06_UsingDecl()
        {
            var source =
@"#pragma warning disable CS0219 // The variable is assigned but its value is never used
class Program
{
    static void M(R<int> r0)
    {
        using scoped var r1 = new R<int>();
        using scoped var r3 = M(ref r0);
    }
 
    static R<int> M(ref R<int> x) => x;
}
 
ref struct R<T>
{
    public void Dispose() {}
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
 
            verifyModel(comp);
 
            comp = CreateCompilation(source, parseOptions: TestOptions.RegularDefault.WithFeature("run-nullable-analysis", "never"));
            verifyModel(comp);
 
            static void verifyModel(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                foreach (SourceLocalSymbol local in locals)
                {
                    Assert.True(local.IsVar);
                    Assert.Equal("R<System.Int32>", local.Type.ToTestDisplayString());
                }
 
                VerifyLocalSymbol(locals[0], "scoped R<System.Int32> r1", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[1], "scoped R<System.Int32> r3", RefKind.None, ScopedKind.ScopedValue);
 
                foreach (var decl in decls)
                {
                    var type = ((VariableDeclarationSyntax)decl.Parent).Type;
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    Assert.Equal("R<System.Int32>", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("R<System.Int32>", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
            }
        }
 
        [Fact]
        public void LocalScope_06_UsingStmt()
        {
            var source =
@"#pragma warning disable CS0219 // The variable is assigned but its value is never used
class Program
{
    static void M(R<int> r0)
    {
        using (scoped var r1 = new R<int>()) {}
        using (scoped var r3 = M(ref r0)) {}
    }
 
    static R<int> M(ref R<int> x) => x;
}
 
ref struct R<T>
{
    public void Dispose() {}
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
 
            verifyModel(comp);
 
            comp = CreateCompilation(source, parseOptions: TestOptions.RegularDefault.WithFeature("run-nullable-analysis", "never"));
            verifyModel(comp);
 
            static void verifyModel(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                foreach (SourceLocalSymbol local in locals)
                {
                    Assert.True(local.IsVar);
                    Assert.Equal("R<System.Int32>", local.Type.ToTestDisplayString());
                }
 
                VerifyLocalSymbol(locals[0], "scoped R<System.Int32> r1", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[1], "scoped R<System.Int32> r3", RefKind.None, ScopedKind.ScopedValue);
 
                foreach (var decl in decls)
                {
                    var type = ((VariableDeclarationSyntax)decl.Parent).Type;
 
                    Assert.Null(model.GetSymbolInfo(type).Symbol);
                    Assert.Null(model.GetTypeInfo(type).Type);
 
                    type = type.SkipScoped(out _);
 
                    Assert.Equal("R<System.Int32>", model.GetSymbolInfo(type).Symbol.ToTestDisplayString());
                    Assert.Equal("R<System.Int32>", model.GetTypeInfo(type).Type.ToTestDisplayString());
                }
            }
        }
 
        [Fact]
        public void LocalScope_10_UsingDecl_01()
        {
            var source =
@"{
    int i = 0;
    using S s1 = new S(ref i);
    scoped S s2 = s1;
}
ref struct S
{
    public S(ref int i) { }
    public void Dispose() {}
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void LocalScope_10_UsingDecl_02()
        {
            var source =
@"{
    int i = 0;
    S s1 = new S(ref i);
    using scoped S s2 = s1;
}
ref struct S
{
    public S(ref int i) { }
    public void Dispose() {}
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void LocalScope_10_UsingStmt_01()
        {
            var source =
@"{
    int i = 0;
    using (S s1 = new S(ref i))
    {
        scoped S s2 = s1;
    }
}
ref struct S
{
    public S(ref int i) { }
    public void Dispose() {}
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void LocalScope_10_UsingStmt_02()
        {
            var source =
@"{
    int i = 0;
    S s1 = new S(ref i);
    using (scoped S s2 = s1) {}
}
ref struct S
{
    public S(ref int i) { }
    public void Dispose() {}
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void LocalScope_12_UsingDecl()
        {
            var source =
@"class Program
{
    static void Main()
    {
        int i0 = 0;
        S s0 = new S(ref i0);
        {
            int i1 = 1;
            using S s1 = new S(ref i1);
            s0 = s1; // 1
        }
        {
            using scoped S s2 = s0;
            s0 = s2; // 2
        }
        {
            using S s3 = s0;
            s0 = s3;
        }
    }
}
ref struct S
{
    public S(ref int i) { }
    public void Dispose() {}
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (10,18): error CS8352: Cannot use variable 's1' in this context because it may expose referenced variables outside of their declaration scope
                //             s0 = s1; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s1").WithArguments("s1").WithLocation(10, 18),
                // (14,18): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                //             s0 = s2; // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(14, 18));
        }
 
        [Fact]
        public void LocalScope_12_UsingStmt()
        {
            var source =
@"class Program
{
    static void Main()
    {
        int i0 = 0;
        S s0 = new S(ref i0);
        {
            int i1 = 1;
            using (S s1 = new S(ref i1))
            {
                s0 = s1; // 1
            }
        }
        {
            using (scoped S s2 = s0)
            {
                s0 = s2; // 2
            }
        }
        {
            using (S s3 = s0)
            {
                s0 = s3;
            }
        }
    }
}
ref struct S
{
    public S(ref int i) { }
    public void Dispose() {}
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (11,22): error CS8352: Cannot use variable 's1' in this context because it may expose referenced variables outside of their declaration scope
                //                 s0 = s1; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s1").WithArguments("s1").WithLocation(11, 22),
                // (17,22): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                //                 s0 = s2; // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(17, 22)
                );
        }
 
        [Fact]
        public void LocalScope_13_UsingDecl()
        {
            var source =
@"#pragma warning disable 219
 
class Program
{
    static void F(R r)
    {
        using scoped  R r2 = r, r5 = r;
    }
}
 
ref struct R
{
    public void Dispose() {}
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (7,15): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         using scoped  R r2 = r, r5 = r;
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(7, 15)
                );
 
            verify(comp);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                VerifyLocalSymbol(locals[0], "scoped R r2", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[1], "scoped R r5", RefKind.None, ScopedKind.ScopedValue);
 
                var type = ((VariableDeclarationSyntax)decls[0].Parent).Type;
                Assert.Null(model.GetTypeInfo(type).Type);
                Assert.Equal("R", model.GetSymbolInfo(type.SkipScoped(out _).SkipRef()).Symbol.ToTestDisplayString());
            }
        }
 
        [Fact]
        public void LocalScope_13_UsingStmt()
        {
            var source =
@"#pragma warning disable 219
 
class Program
{
    static void F(R r)
    {
        using (scoped  R r2 = r, r5 = r) {}
    }
}
 
ref struct R
{
    public void Dispose() {}
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyEmitDiagnostics(
                // (7,16): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //         using (scoped  R r2 = r, r5 = r) {}
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(7, 16)
                );
 
            verify(comp);
 
            comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
            verify(comp);
 
            static void verify(CSharpCompilation comp)
            {
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var decls = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ToArray();
                var locals = decls.Select(d => model.GetDeclaredSymbol(d).GetSymbol<LocalSymbol>()).ToArray();
 
                VerifyLocalSymbol(locals[0], "scoped R r2", RefKind.None, ScopedKind.ScopedValue);
                VerifyLocalSymbol(locals[1], "scoped R r5", RefKind.None, ScopedKind.ScopedValue);
 
                var type = ((VariableDeclarationSyntax)decls[0].Parent).Type;
                Assert.Null(model.GetTypeInfo(type).Type);
                Assert.Equal("R", model.GetSymbolInfo(type.SkipScoped(out _).SkipRef()).Symbol.ToTestDisplayString());
            }
        }
 
        [Fact]
        public void ScopedRefAndRefStructOnly_06_UsingDecl()
        {
            var source =
@"
class Program
{
    static void Main()
    {
        using scoped var x1 = new R<int>();
        using scoped var y1 = new S<int>();
        using scoped S<int> y4 = new S<int>(), y5 = new S<int>();
    }
}
 
ref struct R<T>
{
    public void Dispose() {}
}
 
struct S<T> : System.IDisposable
{
    public void Dispose() {}
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,22): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         using scoped var y1 = new S<int>();
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "var").WithLocation(7, 22),
                // (8,22): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         using scoped S<int> y4 = new S<int>(), y5 = new S<int>();
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "S<int>").WithLocation(8, 22),
                // (8,22): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         using scoped S<int> y4 = new S<int>(), y5 = new S<int>();
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "S<int>").WithLocation(8, 22)
                );
        }
 
        [Fact]
        public void ScopedRefAndRefStructOnly_06_UsingStmt()
        {
            var source =
@"
class Program
{
    static void Main()
    {
        using (scoped var x1 = new R<int>()) {}
        using (scoped var y1 = new S<int>()) {}
        using (scoped S<int> y4 = new S<int>(), y5 = new S<int>()) {}
    }
}
 
ref struct R<T>
{
    public void Dispose() {}
}
 
struct S<T> : System.IDisposable
{
    public void Dispose() {}
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,23): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         using (scoped var y1 = new S<int>()) {}
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "var").WithLocation(7, 23),
                // (8,23): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         using (scoped S<int> y4 = new S<int>(), y5 = new S<int>()) {}
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "S<int>").WithLocation(8, 23),
                // (8,23): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
                //         using (scoped S<int> y4 = new S<int>(), y5 = new S<int>()) {}
                Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "S<int>").WithLocation(8, 23)
                );
        }
 
        [Fact, WorkItem(63526, "https://github.com/dotnet/roslyn/issues/63526")]
        public void ReturnOnlyScope_01()
        {
            // test that return scope is used in all return-ey locations.
            var source = """
                using System.Diagnostics.CodeAnalysis;
 
                ref struct RS
                {
                    public byte B;
 
                    [UnscopedRef]
                    public RSOut ToRSOut()
                    {
                        return new RSOut { RB = ref this.B };
                    }
                }
 
                ref struct RSOut
                {
                    public ref byte RB;
                }
 
                class Program
                {
                    RS M1(ref RS rs) => rs;
                    void M2(ref RS rs, out RSOut rs1) => rs1 = rs.ToRSOut();
 
                    RS M3(ref RS rs)
                    {
                        return rs;
                    }
                    void M4(ref RS rs, out RSOut rs1)
                    {
                        rs1 = rs.ToRSOut();
                    }
 
                    void localContainer()
                    {
                #pragma warning disable 8321
                        RS M1(ref RS rs) => rs;
                        void M2(ref RS rs, out RSOut rs1) => rs1 = rs.ToRSOut();
 
                        RS M3(ref RS rs)
                        {
                            return rs;
                        }
                        void M4(ref RS rs, out RSOut rs1)
                        {
                            rs1 = rs.ToRSOut(); // 4
                        }
                    }
 
                    delegate RS ReturnsRefStruct(ref RS rs);
                    delegate void RefStructOut(ref RS rs, out RSOut rs1);
 
                    void lambdaContainer()
                    {
                        ReturnsRefStruct d1 = (ref RS rs) => rs;
                        RefStructOut d2 = (ref RS rs, out RSOut rs1) => rs1 = rs.ToRSOut();
 
                        ReturnsRefStruct d3 = (ref RS rs) =>
                        {
                            return rs;
                        };
                        RefStructOut d4 = (ref RS rs, out RSOut rs1) =>
                        {
                            rs1 = rs.ToRSOut();
                        };
                    }
                }
                """;
 
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
        }
 
        [Fact, WorkItem(63526, "https://github.com/dotnet/roslyn/issues/63526")]
        public void ReturnOnlyScope_02()
        {
            var source = """
                using System.Diagnostics.CodeAnalysis;
 
                #pragma warning disable 8321 // unused local function
                static bool condition() => false;
 
                static void M1(scoped ref S p1, ref S p2) {
                    p2.refField = ref p1.field; // 1
                    p2.refField = ref p1.refField; // Okay
                }
 
                static void M2(scoped ref S p1, out S p2) {
                    p2 = default;
                    p2.refField = ref p1.field; // 2
                    p2.refField = ref p1.refField; // Okay
                }
 
                static void M3(out S p1, ref S p2) {
                    p1 = default;
                    p2.refField = ref p1.field; // 3
                    p2.refField = ref p1.refField; // 4
                }
 
                // The [UnscopedRef] moves `out` to default RSTE which is *return only*
                static void M4([UnscopedRef] out S p1, ref S p2) {
                    p1 = default;
                    p2.refField = ref p1.field; // 5
                    p2.refField = ref p1.refField; // 6
                }
 
                static void M5(ref S p1, ref S2 p2) {
                    p2 = Inner1(ref p1); // 7
                    p2 = Inner2(ref p1); // Okay
                }
 
                static void M6(ref S p1, out S2 p2) {
                    p2 = Inner1(ref p1); // Okay
                    p2 = Inner2(ref p1); // Okay
                }
 
                static void M7(scoped ref S p1, ref S2 p2) {
                    p2 = Inner1(ref p1); // 8
                    p2 = Inner2(ref p1); // Okay
                }
 
                static S2 M8(scoped ref S p) {
                    if (condition()) return Inner1(ref p); // 9
                    if (condition()) return Inner2(ref p); // Okay
 
                    throw null!;
                }
 
                static S2 M9(ref S p) {
                    if (condition()) return Inner1(ref p); // Okay
                    if (condition()) return Inner2(ref p); // Okay
 
                    throw null!;
                }
 
                static S2 Inner1(ref S s) => new S2 { S = s };
                static S2 Inner2(scoped ref S s) => new S2 { S = s };
 
                ref struct S {
                    public int field;
                    public ref int refField;
                }
 
                ref struct S2 {
                    public S S;
                }
                """;
 
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (7,5): error CS8374: Cannot ref-assign 'p1.field' to 'refField' because 'p1.field' has a narrower escape scope than 'refField'.
                //     p2.refField = ref p1.field; // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "p2.refField = ref p1.field").WithArguments("refField", "p1.field").WithLocation(7, 5),
                // (13,5): error CS8374: Cannot ref-assign 'p1.field' to 'refField' because 'p1.field' has a narrower escape scope than 'refField'.
                //     p2.refField = ref p1.field; // 2
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "p2.refField = ref p1.field").WithArguments("refField", "p1.field").WithLocation(13, 5),
                // (19,5): error CS8374: Cannot ref-assign 'p1.field' to 'refField' because 'p1.field' has a narrower escape scope than 'refField'.
                //     p2.refField = ref p1.field; // 3
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "p2.refField = ref p1.field").WithArguments("refField", "p1.field").WithLocation(19, 5),
                // (20,5): error CS9079: Cannot ref-assign 'p1.refField' to 'refField' because 'p1.refField' can only escape the current method through a return statement.
                //     p2.refField = ref p1.refField; // 4
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "p2.refField = ref p1.refField").WithArguments("refField", "p1.refField").WithLocation(20, 5),
                // (26,5): error CS9079: Cannot ref-assign 'p1.field' to 'refField' because 'p1.field' can only escape the current method through a return statement.
                //     p2.refField = ref p1.field; // 5
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "p2.refField = ref p1.field").WithArguments("refField", "p1.field").WithLocation(26, 5),
                // (27,5): error CS9079: Cannot ref-assign 'p1.refField' to 'refField' because 'p1.refField' can only escape the current method through a return statement.
                //     p2.refField = ref p1.refField; // 6
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "p2.refField = ref p1.refField").WithArguments("refField", "p1.refField").WithLocation(27, 5),
                // (31,10): error CS8347: Cannot use a result of 'Inner1(ref S)' in this context because it may expose variables referenced by parameter 's' outside of their declaration scope
                //     p2 = Inner1(ref p1); // 7
                Diagnostic(ErrorCode.ERR_EscapeCall, "Inner1(ref p1)").WithArguments("Inner1(ref S)", "s").WithLocation(31, 10),
                // (31,21): error CS9077: Cannot return a parameter by reference 'p1' through a ref parameter; it can only be returned in a return statement
                //     p2 = Inner1(ref p1); // 7
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "p1").WithArguments("p1").WithLocation(31, 21),
                // (41,10): error CS8347: Cannot use a result of 'Inner1(ref S)' in this context because it may expose variables referenced by parameter 's' outside of their declaration scope
                //     p2 = Inner1(ref p1); // 8
                Diagnostic(ErrorCode.ERR_EscapeCall, "Inner1(ref p1)").WithArguments("Inner1(ref S)", "s").WithLocation(41, 10),
                // (41,21): error CS9075: Cannot return a parameter by reference 'p1' because it is scoped to the current method
                //     p2 = Inner1(ref p1); // 8
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "p1").WithArguments("p1").WithLocation(41, 21),
                // (46,29): error CS8347: Cannot use a result of 'Inner1(ref S)' in this context because it may expose variables referenced by parameter 's' outside of their declaration scope
                //     if (condition()) return Inner1(ref p); // 9
                Diagnostic(ErrorCode.ERR_EscapeCall, "Inner1(ref p)").WithArguments("Inner1(ref S)", "s").WithLocation(46, 29),
                // (46,40): error CS9075: Cannot return a parameter by reference 'p' because it is scoped to the current method
                //     if (condition()) return Inner1(ref p); // 9
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "p").WithArguments("p").WithLocation(46, 40)
                );
        }
 
        [Fact, WorkItem(63526, "https://github.com/dotnet/roslyn/issues/63526")]
        public void ReturnOnlyScope_02_UnsafeContext()
        {
            var source = """
                using System.Diagnostics.CodeAnalysis;
 
                #pragma warning disable 8321 // unused local function
                static bool condition() => false;
 
                static unsafe void M1(scoped ref S p1, ref S p2) {
                    p2.refField = ref p1.field; // 1
                    p2.refField = ref p1.refField; // Okay
                }
 
                static unsafe void M2(scoped ref S p1, out S p2) {
                    p2 = default;
                    p2.refField = ref p1.field; // 2
                    p2.refField = ref p1.refField; // Okay
                }
 
                static unsafe void M3(out S p1, ref S p2) {
                    p1 = default;
                    p2.refField = ref p1.field; // 3
                    p2.refField = ref p1.refField; // 4
                }
 
                // The [UnscopedRef] moves `out` to default RSTE which is *return only*
                static unsafe void M4([UnscopedRef] out S p1, ref S p2) {
                    p1 = default;
                    p2.refField = ref p1.field; // 5
                    p2.refField = ref p1.refField; // 6
                }
 
                static unsafe void M5(ref S p1, ref S2 p2) {
                    p2 = Inner1(ref p1); // 7
                    p2 = Inner2(ref p1); // Okay
                }
 
                static unsafe void M6(ref S p1, out S2 p2) {
                    p2 = Inner1(ref p1); // Okay
                    p2 = Inner2(ref p1); // Okay
                }
 
                static unsafe void M7(scoped ref S p1, ref S2 p2) {
                    p2 = Inner1(ref p1); // 8
                    p2 = Inner2(ref p1); // Okay
                }
 
                static unsafe S2 M8(scoped ref S p) {
                    if (condition()) return Inner1(ref p); // 9
                    if (condition()) return Inner2(ref p); // Okay
 
                    throw null!;
                }
 
                static S2 M9(ref S p) {
                    if (condition()) return Inner1(ref p); // Okay
                    if (condition()) return Inner2(ref p); // Okay
 
                    throw null!;
                }
 
                static S2 Inner1(ref S s) => new S2 { S = s };
                static S2 Inner2(scoped ref S s) => new S2 { S = s };
 
                ref struct S {
                    public int field;
                    public ref int refField;
                }
 
                ref struct S2 {
                    public S S;
                }
                """;
 
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70, options: TestOptions.UnsafeDebugExe);
            comp.VerifyDiagnostics(
                // (7,5): warning CS9085: This ref-assigns 'p1.field' to 'refField' but 'p1.field' has a narrower escape scope than 'refField'.
                //     p2.refField = ref p1.field; // 1
                Diagnostic(ErrorCode.WRN_RefAssignNarrower, "p2.refField = ref p1.field").WithArguments("refField", "p1.field").WithLocation(7, 5),
                // (13,5): warning CS9085: This ref-assigns 'p1.field' to 'refField' but 'p1.field' has a narrower escape scope than 'refField'.
                //     p2.refField = ref p1.field; // 2
                Diagnostic(ErrorCode.WRN_RefAssignNarrower, "p2.refField = ref p1.field").WithArguments("refField", "p1.field").WithLocation(13, 5),
                // (19,5): warning CS9085: This ref-assigns 'p1.field' to 'refField' but 'p1.field' has a narrower escape scope than 'refField'.
                //     p2.refField = ref p1.field; // 3
                Diagnostic(ErrorCode.WRN_RefAssignNarrower, "p2.refField = ref p1.field").WithArguments("refField", "p1.field").WithLocation(19, 5),
                // (20,5): warning CS9093: This ref-assigns 'p1.refField' to 'refField' but 'p1.refField' can only escape the current method through a return statement.
                //     p2.refField = ref p1.refField; // 4
                Diagnostic(ErrorCode.WRN_RefAssignReturnOnly, "p2.refField = ref p1.refField").WithArguments("refField", "p1.refField").WithLocation(20, 5),
                // (26,5): warning CS9093: This ref-assigns 'p1.field' to 'refField' but 'p1.field' can only escape the current method through a return statement.
                //     p2.refField = ref p1.field; // 5
                Diagnostic(ErrorCode.WRN_RefAssignReturnOnly, "p2.refField = ref p1.field").WithArguments("refField", "p1.field").WithLocation(26, 5),
                // (27,5): warning CS9093: This ref-assigns 'p1.refField' to 'refField' but 'p1.refField' can only escape the current method through a return statement.
                //     p2.refField = ref p1.refField; // 6
                Diagnostic(ErrorCode.WRN_RefAssignReturnOnly, "p2.refField = ref p1.refField").WithArguments("refField", "p1.refField").WithLocation(27, 5),
                // (31,21): warning CS9094: This returns a parameter by reference 'p1' through a ref parameter; but it can only safely be returned in a return statement
                //     p2 = Inner1(ref p1); // 7
                Diagnostic(ErrorCode.WRN_RefReturnOnlyParameter, "p1").WithArguments("p1").WithLocation(31, 21),
                // (41,21): warning CS9088: This returns a parameter by reference 'p1' but it is scoped to the current method
                //     p2 = Inner1(ref p1); // 8
                Diagnostic(ErrorCode.WRN_RefReturnScopedParameter, "p1").WithArguments("p1").WithLocation(41, 21),
                // (46,40): warning CS9088: This returns a parameter by reference 'p' but it is scoped to the current method
                //     if (condition()) return Inner1(ref p); // 9
                Diagnostic(ErrorCode.WRN_RefReturnScopedParameter, "p").WithArguments("p").WithLocation(46, 40)
                );
        }
 
        [Fact, WorkItem(63526, "https://github.com/dotnet/roslyn/issues/63526")]
        public void ReturnOnlyScope_03()
        {
            var source = """
                using System.Diagnostics.CodeAnalysis;
 
                #pragma warning disable 8321 // unused local function
                ref struct S2 {
                    public S S;
                }
 
                ref struct S {
                    public int field;
                    public ref int refField;
 
                    void M1(ref S p) {
                        p.refField = ref this.field; // 1
                        p.refField = ref this.refField; // Okay
                    }
 
                    [UnscopedRef]
                    void M2(ref S p) {
                        p.refField = ref this.field; // 2
                        p.refField = ref this.refField; // Okay
                    }
 
                    [UnscopedRef]
                    void M3(out S p) {
                        p = default;
                        p.refField = ref this.field; // Okay (was 3)
                        p.refField = ref this.refField; // Okay
                    }
 
                    void M4(ref S2 p) {
                        p = Inner1(ref this); // 4
                        p = Inner2(ref this); // Okay
                    }
 
                    void M5(out S2 p) {
                        p = Inner1(ref this); // 5
                        p = Inner2(ref this); // Okay
                    }
 
                    static S2 Inner1(ref S s) => new S2 { S = s };
                    static S2 Inner2(scoped ref S s) => new S2 { S = s };
                }
                """;
 
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (13,9): error CS8374: Cannot ref-assign 'this.field' to 'refField' because 'this.field' has a narrower escape scope than 'refField'.
                //         p.refField = ref this.field; // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "p.refField = ref this.field").WithArguments("refField", "this.field").WithLocation(13, 9),
                // (19,9): error CS9079: Cannot ref-assign 'this.field' to 'refField' because 'this.field' can only escape the current method through a return statement.
                //         p.refField = ref this.field; // 2
                Diagnostic(ErrorCode.ERR_RefAssignReturnOnly, "p.refField = ref this.field").WithArguments("refField", "this.field").WithLocation(19, 9),
                // (31,13): error CS8347: Cannot use a result of 'S.Inner1(ref S)' in this context because it may expose variables referenced by parameter 's' outside of their declaration scope
                //         p = Inner1(ref this); // 4
                Diagnostic(ErrorCode.ERR_EscapeCall, "Inner1(ref this)").WithArguments("S.Inner1(ref S)", "s").WithLocation(31, 13),
                // (31,24): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //         p = Inner1(ref this); // 4
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "this").WithLocation(31, 24),
                // (36,13): error CS8347: Cannot use a result of 'S.Inner1(ref S)' in this context because it may expose variables referenced by parameter 's' outside of their declaration scope
                //         p = Inner1(ref this); // 5
                Diagnostic(ErrorCode.ERR_EscapeCall, "Inner1(ref this)").WithArguments("S.Inner1(ref S)", "s").WithLocation(36, 13),
                // (36,24): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //         p = Inner1(ref this); // 5
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "this").WithLocation(36, 24));
        }
 
        [Fact]
        public void ReturnOnlyScope_03_UnsafeContext()
        {
            var source = """
                using System.Diagnostics.CodeAnalysis;
 
                #pragma warning disable 8321 // unused local function
                ref struct S2 {
                    public S S;
                }
 
                unsafe ref struct S {
                    public int field;
                    public ref int refField;
 
                    void M1(ref S p) {
                        p.refField = ref this.field; // 1
                        p.refField = ref this.refField; // Okay
                    }
 
                    [UnscopedRef]
                    void M2(ref S p) {
                        p.refField = ref this.field; // 2
                        p.refField = ref this.refField; // Okay
                    }
 
                    [UnscopedRef]
                    void M3(out S p) {
                        p = default;
                        p.refField = ref this.field; // Okay (was 3)
                        p.refField = ref this.refField; // Okay
                    }
 
                    void M4(ref S2 p) {
                        p = Inner1(ref this); // 4
                        p = Inner2(ref this); // Okay
                    }
 
                    void M5(out S2 p) {
                        p = Inner1(ref this); // 5
                        p = Inner2(ref this); // Okay
                    }
 
                    static S2 Inner1(ref S s) => new S2 { S = s };
                    static S2 Inner2(scoped ref S s) => new S2 { S = s };
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70, options: TestOptions.UnsafeDebugDll);
            comp.VerifyDiagnostics(
                // (13,9): warning CS9085: This ref-assigns 'this.field' to 'refField' but 'this.field' has a narrower escape scope than 'refField'.
                //         p.refField = ref this.field; // 1
                Diagnostic(ErrorCode.WRN_RefAssignNarrower, "p.refField = ref this.field").WithArguments("refField", "this.field").WithLocation(13, 9),
                // (19,9): warning CS9093: This ref-assigns 'this.field' to 'refField' but 'this.field' can only escape the current method through a return statement.
                //         p.refField = ref this.field; // 2
                Diagnostic(ErrorCode.WRN_RefAssignReturnOnly, "p.refField = ref this.field").WithArguments("refField", "this.field").WithLocation(19, 9),
                // (31,24): warning CS9084: Struct member returns 'this' or other instance members by reference
                //         p = Inner1(ref this); // 4
                Diagnostic(ErrorCode.WRN_RefReturnStructThis, "this").WithLocation(31, 24),
                // (36,24): warning CS9084: Struct member returns 'this' or other instance members by reference
                //         p = Inner1(ref this); // 5
                Diagnostic(ErrorCode.WRN_RefReturnStructThis, "this").WithLocation(36, 24));
        }
 
        [Fact]
        public void ReturnOnlyScope_04()
        {
            // This shows that constructors end up being less "capable" than factory methods.
            // We might want to adjust the rules for 'out' parameters (including 'this' in constructors).
            // https://github.com/dotnet/roslyn/issues/64155
            var source = """
                ref struct ByteContainer
                {
                    public byte B;
                }
 
                ref struct RefByteContainer
                {
                    public ref byte RB;
 
                    public RefByteContainer(ref ByteContainer bc)
                    {
                        RB = ref bc.B; // 1
                    }
 
                    public RefByteContainer Create(ref ByteContainer bc)
                    {
                        return new RefByteContainer { RB = ref bc.B }; // ok
                    }
                }
                """;
 
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
        }
 
        [Fact, WorkItem(63526, "https://github.com/dotnet/roslyn/issues/63526")]
        public void ReturnOnlyScope_UnsafeStatement()
        {
            var source = """
                #pragma warning disable 8321 // unused local function
                static void M1(scoped ref S p1, ref S p2, ref S p3)
                {
                    unsafe
                    {
                        p2.refField = ref p1.field; // 1
                    }
                    {
                        p3.refField = ref p1.field; // 2
                    }
                }
                ref struct S
                {
                    public int field;
                    public ref int refField;
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70, options: TestOptions.UnsafeReleaseExe);
            comp.VerifyDiagnostics(
                // (6,9): warning CS9085: This ref-assigns 'p1.field' to 'refField' but 'p1.field' has a narrower escape scope than 'refField'.
                //         p2.refField = ref p1.field; // 1
                Diagnostic(ErrorCode.WRN_RefAssignNarrower, "p2.refField = ref p1.field").WithArguments("refField", "p1.field").WithLocation(6, 9),
                // (9,9): error CS8374: Cannot ref-assign 'p1.field' to 'refField' because 'p1.field' has a narrower escape scope than 'refField'.
                //         p3.refField = ref p1.field; // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "p3.refField = ref p1.field").WithArguments("refField", "p1.field").WithLocation(9, 9));
        }
 
        /// <summary>
        /// Validate that this is properly represented as an out parameter in a constructor and
        /// can capture ref as ref.
        /// </summary>
        [Fact]
        public void OutReturnOnly_Ctor1()
        {
            var source = """
                ref struct RS
                {
                    ref int field;
                    public RS(ref int i)
                    {
                        field = ref i;
                    }
 
                    static RS M1(ref int i) => new RS(ref i);
                    static RS M2()
                    {
                        int i = 0;
                        return new RS(ref i);
                    }
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (13,16): error CS8347: Cannot use a result of 'RS.RS(ref int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         return new RS(ref i);
                Diagnostic(ErrorCode.ERR_EscapeCall, "new RS(ref i)").WithArguments("RS.RS(ref int)", "i").WithLocation(13, 16),
                // (13,27): error CS8168: Cannot return local 'i' by reference because it is not a ref local
                //         return new RS(ref i);
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "i").WithArguments("i").WithLocation(13, 27));
        }
 
        /// <summary>
        /// Out and ref have different return scopes
        /// </summary>
        [Fact]
        public void OutReturnOnly_1()
        {
            var source = """
                ref struct RS
                {
                    ref int field;
                    public RS(ref int i)
                    {
                        field = ref i;
                    }
 
                    static void M1(ref int i, ref RS rs) => rs = new RS(ref i); // 1
                    static void M2(ref int i, out RS rs) => rs = new RS(ref i);
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (9,50): error CS8347: Cannot use a result of 'RS.RS(ref int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //     static void M1(ref int i, ref RS rs) => rs = new RS(ref i); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "new RS(ref i)").WithArguments("RS.RS(ref int)", "i").WithLocation(9, 50),
                // (9,61): error CS9077: Cannot return a parameter by reference 'i' through a ref parameter; it can only be returned in a return statement
                //     static void M1(ref int i, ref RS rs) => rs = new RS(ref i); // 1
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "i").WithArguments("i").WithLocation(9, 61));
        }
 
        /// <summary>
        /// Out and in have different return scopes
        /// </summary>
        [Fact]
        public void OutReturnOnly_2()
        {
            var source = """
                readonly ref struct RS
                {
                    readonly ref readonly int field;
                    public RS(in int i)
                    {
                        field = ref i;
                    }
 
                    static void M1(in int i, ref RS rs) => rs = new RS(in i); // 1
                    static void M2(in int i, out RS rs) => rs = new RS(in i);
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (9,49): error CS8347: Cannot use a result of 'RS.RS(in int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //     static void M1(in int i, ref RS rs) => rs = new RS(in i); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "new RS(in i)").WithArguments("RS.RS(in int)", "i").WithLocation(9, 49),
                // (9,59): error CS9077: Cannot return a parameter by reference 'i' through a ref parameter; it can only be returned in a return statement
                //     static void M1(in int i, ref RS rs) => rs = new RS(in i); // 1
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "i").WithArguments("i").WithLocation(9, 59));
        }
 
        /// <summary>
        /// Out and ref have different return scopes
        /// </summary>
        [Fact]
        public void OutReturnOnly_3()
        {
            var source = """
                using System.Diagnostics.CodeAnalysis;
                ref struct RS
                {
                    int field;
                    ref int refField;
                    public RS(ref int i)
                    {
                        refField = ref i;
                    }
 
                    static void M1(ref RS i, ref RS rs) => rs = new RS(ref i.field); // 1
                    static void M2(ref RS i, out RS rs) => rs = new RS(ref i.field);
                    static void M3(ref RS i, [UnscopedRef] out RS rs) => rs = new RS(ref i.field);
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (11,49): error CS8347: Cannot use a result of 'RS.RS(ref int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //     static void M1(ref RS i, ref RS rs) => rs = new RS(ref i.field); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "new RS(ref i.field)").WithArguments("RS.RS(ref int)", "i").WithLocation(11, 49),
                // (11,60): error CS9078: Cannot return by reference a member of parameter 'i' through a ref parameter; it can only be returned in a return statement
                //     static void M1(ref RS i, ref RS rs) => rs = new RS(ref i.field); // 1
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter2, "i").WithArguments("i").WithLocation(11, 60));
        }
 
        [Fact]
        [WorkItem(62094, "https://github.com/dotnet/roslyn/issues/62094")]
        public void OutReturnOnly_4()
        {
            var source = """
                ref struct R
                {
                    public R(ref int i) { }
                }
 
                class Program
                {
                    static void F0(ref R a, out R b)
                    {
                        b = a;
                    }
 
                    static void F1(ref R x)
                    {
                        int i = 1;
                        R y = new R(ref i);
                        F0(ref x, out y);
                    }
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void OutReturnOnly_5()
        {
            var source = """
                ref struct R
                {
                    public R(ref int i) { }
                }
 
                class Program
                {
                    public static void F1(R a, out R d) => throw null;
                    public static void F2(ref R a, out R d) => throw null;
                    public static void F3(in R a, out R d) => throw null;
                    public static void F4(scoped ref R a, out R d) => throw null;
                    public static void F5(scoped in R a, out R d) => throw null;
 
                    public void Test()
                    {
                        R local = default;
                        F1(local, out local);
                        F2(ref local, out local); // 1
                        F3(in local, out local); // 2
                        F4(ref local, out local);
                        F5(in local, out local);
                    }
                }
                """;
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (18,9): error CS8350: This combination of arguments to 'Program.F2(ref R, out R)' is disallowed because it may expose variables referenced by parameter 'a' outside of their declaration scope
                //         F2(ref local, out local); // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F2(ref local, out local)").WithArguments("Program.F2(ref R, out R)", "a").WithLocation(18, 9),
                // (18,16): error CS8168: Cannot return local 'local' by reference because it is not a ref local
                //         F2(ref local, out local); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "local").WithArguments("local").WithLocation(18, 16),
                // (19,9): error CS8350: This combination of arguments to 'Program.F3(in R, out R)' is disallowed because it may expose variables referenced by parameter 'a' outside of their declaration scope
                //         F3(in local, out local); // 2
                Diagnostic(ErrorCode.ERR_CallArgMixing, "F3(in local, out local)").WithArguments("Program.F3(in R, out R)", "a").WithLocation(19, 9),
                // (19,15): error CS8168: Cannot return local 'local' by reference because it is not a ref local
                //         F3(in local, out local); // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "local").WithArguments("local").WithLocation(19, 15)
                );
        }
 
        [WorkItem(64720, "https://github.com/dotnet/roslyn/issues/64720")]
        [ConditionalTheory(typeof(CoreClrOnly))]
        [InlineData("ref")]
        [InlineData("ref readonly")]
        public void FieldInitializer_01(string refModifier)
        {
            var sourceA =
$@"ref struct R
{{
    public static byte S = 1;
    public {refModifier} byte F = ref S;
    public R() {{ }}
}}";
            var sourceB =
@"using System;
class Program
{
    static void Main()
    {
        var r = new R();
        Console.WriteLine(r.F);
        R.S++;
        Console.WriteLine(r.F);
    }
}";
            var comp = CreateCompilation(new[] { sourceA, sourceB }, targetFramework: TargetFramework.Net70, options: TestOptions.ReleaseExe);
            comp.VerifyEmitDiagnostics();
            var verifier = CompileAndVerify(comp, expectedOutput:
@"1
2
");
            verifier.VerifyIL("R..ctor",
$@"{{
    // Code size       12 (0xc)
    .maxstack  2
    IL_0000:  ldarg.0
    IL_0001:  ldsflda    ""byte R.S""
    IL_0006:  stfld      ""{refModifier} byte R.F""
    IL_000b:  ret
}}
");
        }
 
        [WorkItem(64720, "https://github.com/dotnet/roslyn/issues/64720")]
        [ConditionalFact(typeof(CoreClrOnly))]
        public void FieldInitializer_02A()
        {
            var source =
@"using System;
ref struct R
{
    public ref byte _f1 = ref F(stackalloc byte[1]);
    public ref readonly byte _f2 = ref F(stackalloc byte[1]);
    public R(object o) { }
    static ref byte F(Span<byte> s) => ref _s;
    public static byte _s;
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (4,31): error CS8347: Cannot use a result of 'R.F(Span<byte>)' in this context because it may expose variables referenced by parameter 's' outside of their declaration scope
                //     public ref byte _f1 = ref F(stackalloc byte[1]);
                Diagnostic(ErrorCode.ERR_EscapeCall, "F(stackalloc byte[1])").WithArguments("R.F(System.Span<byte>)", "s").WithLocation(4, 31),
                // (4,33): error CS8353: A result of a stackalloc expression of type 'Span<byte>' cannot be used in this context because it may be exposed outside of the containing method
                //     public ref byte _f1 = ref F(stackalloc byte[1]);
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc byte[1]").WithArguments("System.Span<byte>").WithLocation(4, 33),
                // (5,40): error CS8347: Cannot use a result of 'R.F(Span<byte>)' in this context because it may expose variables referenced by parameter 's' outside of their declaration scope
                //     public ref readonly byte _f2 = ref F(stackalloc byte[1]);
                Diagnostic(ErrorCode.ERR_EscapeCall, "F(stackalloc byte[1])").WithArguments("R.F(System.Span<byte>)", "s").WithLocation(5, 40),
                // (5,42): error CS8353: A result of a stackalloc expression of type 'Span<byte>' cannot be used in this context because it may be exposed outside of the containing method
                //     public ref readonly byte _f2 = ref F(stackalloc byte[1]);
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc byte[1]").WithArguments("System.Span<byte>").WithLocation(5, 42));
        }
 
        // Similar to above but with scoped parameter.
        [WorkItem(64720, "https://github.com/dotnet/roslyn/issues/64720")]
        [ConditionalFact(typeof(CoreClrOnly))]
        public void FieldInitializer_02B()
        {
            var source =
@"using System;
ref struct R
{
    public ref byte _f1 = ref F(stackalloc byte[1]);
    public ref readonly byte _f2 = ref F(stackalloc byte[1]);
    public R(object o) { }
    static ref byte F(scoped Span<byte> s) => ref _s;
    public static byte _s = 1;
}
class Program
{
    static void Main()
    {
        var r = new R(null);
        Console.WriteLine((r._f1, r._f2));
        R._s = 2;
        Console.WriteLine((r._f1, r._f2));
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70, options: TestOptions.ReleaseExe);
            comp.VerifyEmitDiagnostics();
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput:
@"(1, 1)
(2, 2)
");
            verifier.VerifyIL("R..ctor(object)",
@"{
    // Code size       47 (0x2f)
    .maxstack  2
    .locals init (System.Span<byte> V_0)
    IL_0000:  ldc.i4.1
    IL_0001:  conv.u
    IL_0002:  localloc
    IL_0004:  ldc.i4.1
    IL_0005:  newobj     ""System.Span<byte>..ctor(void*, int)""
    IL_000a:  stloc.0
    IL_000b:  ldarg.0
    IL_000c:  ldloc.0
    IL_000d:  call       ""ref byte R.F(scoped System.Span<byte>)""
    IL_0012:  stfld      ""ref byte R._f1""
    IL_0017:  ldc.i4.1
    IL_0018:  conv.u
    IL_0019:  localloc
    IL_001b:  ldc.i4.1
    IL_001c:  newobj     ""System.Span<byte>..ctor(void*, int)""
    IL_0021:  stloc.0
    IL_0022:  ldarg.0
    IL_0023:  ldloc.0
    IL_0024:  call       ""ref byte R.F(scoped System.Span<byte>)""
    IL_0029:  stfld      ""ref readonly byte R._f2""
    IL_002e:  ret
}");
        }
 
        [WorkItem(64725, "https://github.com/dotnet/roslyn/issues/64725")]
        [ConditionalFact(typeof(CoreClrOnly))]
        public void FieldInitializer_03()
        {
            var source =
@"#pragma warning disable 414
ref struct R
{
    ref int _f1 = 1;
    ref readonly int _f2 = 2;
    public R() { }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (4,17): error CS8172: Cannot initialize a by-reference variable with a value
                //     ref int _f1 = 1;
                Diagnostic(ErrorCode.ERR_InitializeByReferenceVariableWithValue, "= 1").WithLocation(4, 17),
                // (4,19): error CS1510: A ref or out value must be an assignable variable
                //     ref int _f1 = 1;
                Diagnostic(ErrorCode.ERR_RefLvalueExpected, "1").WithLocation(4, 19),
                // (5,26): error CS8172: Cannot initialize a by-reference variable with a value
                //     ref readonly int _f2 = 2;
                Diagnostic(ErrorCode.ERR_InitializeByReferenceVariableWithValue, "= 2").WithLocation(5, 26),
                // (5,28): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                //     ref readonly int _f2 = 2;
                Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "2").WithLocation(5, 28));
        }
 
        [WorkItem(64725, "https://github.com/dotnet/roslyn/issues/64725")]
        [ConditionalFact(typeof(CoreClrOnly))]
        public void FieldInitializer_04()
        {
            var source =
@"using System;
ref struct R
{
    ref byte _f1 = F(stackalloc byte[1]);
    ref readonly byte _f2 = F(stackalloc byte[1]);
    public R() { }
    static ref T F<T>(Span<T> s) => throw null;
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (4,18): error CS8172: Cannot initialize a by-reference variable with a value
                //     ref byte _f1 = F(stackalloc byte[1]);
                Diagnostic(ErrorCode.ERR_InitializeByReferenceVariableWithValue, "= F(stackalloc byte[1])").WithLocation(4, 18),
                // (4,20): error CS8347: Cannot use a result of 'R.F<byte>(Span<byte>)' in this context because it may expose variables referenced by parameter 's' outside of their declaration scope
                //     ref byte _f1 = F(stackalloc byte[1]);
                Diagnostic(ErrorCode.ERR_EscapeCall, "F(stackalloc byte[1])").WithArguments("R.F<byte>(System.Span<byte>)", "s").WithLocation(4, 20),
                // (4,22): error CS8353: A result of a stackalloc expression of type 'Span<byte>' cannot be used in this context because it may be exposed outside of the containing method
                //     ref byte _f1 = F(stackalloc byte[1]);
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc byte[1]").WithArguments("System.Span<byte>").WithLocation(4, 22),
                // (5,27): error CS8172: Cannot initialize a by-reference variable with a value
                //     ref readonly byte _f2 = F(stackalloc byte[1]);
                Diagnostic(ErrorCode.ERR_InitializeByReferenceVariableWithValue, "= F(stackalloc byte[1])").WithLocation(5, 27),
                // (5,29): error CS8347: Cannot use a result of 'R.F<byte>(Span<byte>)' in this context because it may expose variables referenced by parameter 's' outside of their declaration scope
                //     ref readonly byte _f2 = F(stackalloc byte[1]);
                Diagnostic(ErrorCode.ERR_EscapeCall, "F(stackalloc byte[1])").WithArguments("R.F<byte>(System.Span<byte>)", "s").WithLocation(5, 29),
                // (5,31): error CS8353: A result of a stackalloc expression of type 'Span<byte>' cannot be used in this context because it may be exposed outside of the containing method
                //     ref readonly byte _f2 = F(stackalloc byte[1]);
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc byte[1]").WithArguments("System.Span<byte>").WithLocation(5, 31));
        }
 
        [WorkItem(64725, "https://github.com/dotnet/roslyn/issues/64725")]
        [ConditionalFact(typeof(CoreClrOnly))]
        public void FieldInitializer_05()
        {
            var source =
@"using System;
ref struct R
{
    ref readonly Span<int> _s = ref F(stackalloc int[1]);
    public R() { }
    static ref readonly Span<T> F<T>(in Span<T> s) => ref s;
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (4,5): error CS9050: A ref field cannot refer to a ref struct.
                //     ref readonly Span<int> _s = ref F(stackalloc int[1]);
                Diagnostic(ErrorCode.ERR_RefFieldCannotReferToRefStruct, "ref readonly Span<int>").WithLocation(4, 5),
                // (4,37): error CS8347: Cannot use a result of 'R.F<int>(in Span<int>)' in this context because it may expose variables referenced by parameter 's' outside of their declaration scope
                //     ref readonly Span<int> _s = ref F(stackalloc int[1]);
                Diagnostic(ErrorCode.ERR_EscapeCall, "F(stackalloc int[1])").WithArguments("R.F<int>(in System.Span<int>)", "s").WithLocation(4, 37),
                // (4,39): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                //     ref readonly Span<int> _s = ref F(stackalloc int[1]);
                Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "stackalloc int[1]").WithLocation(4, 39));
        }
 
        [WorkItem(64720, "https://github.com/dotnet/roslyn/issues/64720")]
        [ConditionalFact(typeof(CoreClrOnly))]
        public void FieldInitializer_06A()
        {
            var source =
@"ref struct R
{
    ref byte _f1 = ref F<byte>(out var b1);
    ref readonly byte _f2 = ref F<byte>(out var b2);
    public R() { }
    static ref T F<T>(out T t)
    {
        throw null;
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
        }
 
        // Similar to above but with [UnscopedRef] out parameter.
        [WorkItem(64720, "https://github.com/dotnet/roslyn/issues/64720")]
        [ConditionalFact(typeof(CoreClrOnly))]
        public void FieldInitializer_06B()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
ref struct R
{
    ref byte _f1 = ref F<byte>(out var b1); // 1
    ref readonly byte _f2 = ref F<byte>(out var b2); // 2
    public R() { }
    static ref T F<T>([UnscopedRef] out T t)
    {
        t = default;
        return ref t;
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (4,24): error CS8347: Cannot use a result of 'R.F<byte>(out byte)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     ref byte _f1 = ref F<byte>(out var b1); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "F<byte>(out var b1)").WithArguments("R.F<byte>(out byte)", "t").WithLocation(4, 24),
                // (4,36): error CS8168: Cannot return local 'b1' by reference because it is not a ref local
                //     ref byte _f1 = ref F<byte>(out var b1); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "var b1").WithArguments("b1").WithLocation(4, 36),
                // (5,33): error CS8347: Cannot use a result of 'R.F<byte>(out byte)' in this context because it may expose variables referenced by parameter 't' outside of their declaration scope
                //     ref readonly byte _f2 = ref F<byte>(out var b2); // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "F<byte>(out var b2)").WithArguments("R.F<byte>(out byte)", "t").WithLocation(5, 33),
                // (5,45): error CS8168: Cannot return local 'b2' by reference because it is not a ref local
                //     ref readonly byte _f2 = ref F<byte>(out var b2); // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "var b2").WithArguments("b2").WithLocation(5, 45));
        }
 
        [WorkItem(64720, "https://github.com/dotnet/roslyn/issues/64720")]
        [ConditionalFact(typeof(CoreClrOnly))]
        public void FieldInitializer_07()
        {
            var source =
@"using System;
ref struct R
{
    public ref int F1 = ref C.Instance.F();
    public ref readonly int F2;
    public R(object obj)
    {
        F2 = ref F1;
    }
}
class C
{
    public static C Instance = new C();
    int _b = 1;
    public ref int F() => ref _b;
    static void Main()
    {
        var r = new R(null);
        Instance._b += 2;
        Console.WriteLine((r.F1, r.F2));
    }
}";
 
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70, options: TestOptions.ReleaseExe);
            comp.VerifyEmitDiagnostics();
            var verifier = CompileAndVerify(comp, expectedOutput: "(3, 3)");
            verifier.VerifyIL("R..ctor(object)",
@"{
    // Code size       29 (0x1d)
    .maxstack  2
    IL_0000:  ldarg.0
    IL_0001:  ldsfld     ""C C.Instance""
    IL_0006:  callvirt   ""ref int C.F()""
    IL_000b:  stfld      ""ref int R.F1""
    IL_0010:  ldarg.0
    IL_0011:  ldarg.0
    IL_0012:  ldfld      ""ref int R.F1""
    IL_0017:  stfld      ""ref readonly int R.F2""
    IL_001c:  ret
}
");
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var fieldInitializerSyntax = tree.GetRoot().DescendantNodes().OfType<EqualsValueClauseSyntax>().First();
            var symbol = model.GetDeclaredSymbol(fieldInitializerSyntax.Parent);
            Assert.Equal("ref System.Int32 R.F1", symbol.ToTestDisplayString());
 
            var fieldInitializerOperation = (Microsoft.CodeAnalysis.Operations.IFieldInitializerOperation)model.GetOperation(fieldInitializerSyntax);
            OperationTreeVerifier.Verify(
@"IFieldInitializerOperation (Field: ref System.Int32 R.F1) (OperationKind.FieldInitializer, Type: null) (Syntax: '= ref C.Instance.F()')
  IInvocationOperation ( ref System.Int32 C.F()) (OperationKind.Invocation, Type: System.Int32) (Syntax: 'C.Instance.F()')
    Instance Receiver:
      IFieldReferenceOperation: C C.Instance (Static) (OperationKind.FieldReference, Type: C) (Syntax: 'C.Instance')
        Instance Receiver:
          null
    Arguments(0)
",
                OperationTreeVerifier.GetOperationTree(comp, fieldInitializerOperation));
 
            var controlFlowGraph = Microsoft.CodeAnalysis.FlowAnalysis.ControlFlowGraph.Create(fieldInitializerOperation);
            ControlFlowGraphVerifier.VerifyGraph(comp,
@"    Block[B0] - Entry
    Statements (0)
    Next (Regular) Block[B1]
Block[B1] - Block
    Predecessors: [B0]
    Statements (1)
        ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32, IsImplicit) (Syntax: '= ref C.Instance.F()')
          Left:
            IFieldReferenceOperation: ref System.Int32 R.F1 (OperationKind.FieldReference, Type: System.Int32, IsImplicit) (Syntax: '= ref C.Instance.F()')
              Instance Receiver:
                IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: R, IsImplicit) (Syntax: '= ref C.Instance.F()')
          Right:
            IInvocationOperation ( ref System.Int32 C.F()) (OperationKind.Invocation, Type: System.Int32) (Syntax: 'C.Instance.F()')
              Instance Receiver:
                IFieldReferenceOperation: C C.Instance (Static) (OperationKind.FieldReference, Type: C) (Syntax: 'C.Instance')
                  Instance Receiver:
                    null
              Arguments(0)
    Next (Regular) Block[B2]
Block[B2] - Exit
    Predecessors: [B1]
    Statements (0)
",
                controlFlowGraph, symbol);
 
            var constructorSyntax = tree.GetRoot().DescendantNodes().OfType<ConstructorDeclarationSyntax>().Single();
            symbol = model.GetDeclaredSymbol(constructorSyntax);
            Assert.Equal("R..ctor(System.Object obj)", symbol.ToTestDisplayString());
 
            var constructorOperation = (Microsoft.CodeAnalysis.Operations.IConstructorBodyOperation)model.GetOperation(constructorSyntax);
            OperationTreeVerifier.Verify(
@"IConstructorBodyOperation (OperationKind.ConstructorBody, Type: null) (Syntax: 'public R(ob ... }')
  Initializer:
    null
  BlockBody:
    IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
      IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'F2 = ref F1;')
        Expression:
          ISimpleAssignmentOperation (IsRef) (OperationKind.SimpleAssignment, Type: System.Int32) (Syntax: 'F2 = ref F1')
            Left:
              IFieldReferenceOperation: ref readonly System.Int32 R.F2 (OperationKind.FieldReference, Type: System.Int32) (Syntax: 'F2')
                Instance Receiver:
                  IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: R, IsImplicit) (Syntax: 'F2')
            Right:
              IFieldReferenceOperation: ref System.Int32 R.F1 (OperationKind.FieldReference, Type: System.Int32) (Syntax: 'F1')
                Instance Receiver:
                  IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: R, IsImplicit) (Syntax: 'F1')
  ExpressionBody:
    null
",
                OperationTreeVerifier.GetOperationTree(comp, constructorOperation));
 
            controlFlowGraph = Microsoft.CodeAnalysis.FlowAnalysis.ControlFlowGraph.Create(constructorOperation);
            ControlFlowGraphVerifier.VerifyGraph(comp,
@"Block[B0] - Entry
    Statements (0)
    Next (Regular) Block[B1]
Block[B1] - Block
    Predecessors: [B0]
    Statements (1)
        IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'F2 = ref F1;')
          Expression:
            ISimpleAssignmentOperation (IsRef) (OperationKind.SimpleAssignment, Type: System.Int32) (Syntax: 'F2 = ref F1')
              Left:
                IFieldReferenceOperation: ref readonly System.Int32 R.F2 (OperationKind.FieldReference, Type: System.Int32) (Syntax: 'F2')
                  Instance Receiver:
                    IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: R, IsImplicit) (Syntax: 'F2')
              Right:
                IFieldReferenceOperation: ref System.Int32 R.F1 (OperationKind.FieldReference, Type: System.Int32) (Syntax: 'F1')
                  Instance Receiver:
                    IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: R, IsImplicit) (Syntax: 'F1')
    Next (Regular) Block[B2]
Block[B2] - Exit
    Predecessors: [B1]
    Statements (0)
",
                controlFlowGraph, symbol);
        }
 
        [Fact]
        [WorkItem(63565, "https://github.com/dotnet/roslyn/issues/63565")]
        public void UnscopedRefAttribute_DelegateConversion_01()
        {
            string source = """
                using System.Diagnostics.CodeAnalysis;
                ref struct R { }
                class Program
                {
                    static void Main()
                    {
                        var a = ([UnscopedRef] ref int x1, ref int y1) => ref y1;
                        var b = ([UnscopedRef] ref int x2, R y2) => y2;
                        var c = ([UnscopedRef] ref int x3, ref R y3) => { };
                        var d = ([UnscopedRef] out int x4) => { x4 = 0; return ref x4; };
                        var e = ([UnscopedRef] ref int x5) => x5;
                        var f = ([UnscopedRef] ref int x6) => ref x6;
                        var g = ref readonly int ([UnscopedRef] in int x7) => ref x7;
                    }
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        [WorkItem(63565, "https://github.com/dotnet/roslyn/issues/63565")]
        public void UnscopedRefAttribute_DelegateConversion_02()
        {
            string source = """
                using System.Diagnostics.CodeAnalysis;
                ref struct R { }
                class Program
                {
                    static ref int F1(ref int y1, [UnscopedRef] ref int x1) => ref y1;
                    static R F2(R y2, [UnscopedRef] ref int x2) => y2;
                    static void F3(ref R y3, [UnscopedRef] ref int x3) { }
                    static ref int F4([UnscopedRef] out int x4) { x4 = 0; return ref x4; }
                    static int F5([UnscopedRef] ref int x5) => x5;
                    static ref int F6([UnscopedRef] ref int x6) => ref x6;
                    static ref readonly int F7([UnscopedRef] in int x7) => ref x7;
                    static void Main()
                    {
                        var a = F1;
                        var b = F2;
                        var c = F3;
                        var d = F4;
                        var e = F5;
                        var f = F6;
                        var g = F7;
                    }
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact]
        [WorkItem(63565, "https://github.com/dotnet/roslyn/issues/63565")]
        public void UnscopedRefAttribute_DelegateConversion_03()
        {
            string source = """
                using System.Diagnostics.CodeAnalysis;
                class Program
                {
                    static ref int F1(ref int x, ref int y) => ref x;
                    static ref int F2(ref int x, [UnscopedRef] ref int y) => ref x;
                    static ref int F3([UnscopedRef] ref int x, [UnscopedRef] ref int y) => ref x;
                    static void Main()
                    {
                        var d1 = F1;
                        var d2 = F2;
                        var d3 = F3;
                        d1 = F2; // 1
                        d1 = F3; // 2, 3
                        d2 = F1;
                        d2 = F3; // 4
                        d3 = F1;
                        d2 = F2;
                    }
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (12,14): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target '<anonymous delegate>'.
                //         d1 = F2; // 1
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "F2").WithArguments("y", "<anonymous delegate>").WithLocation(12, 14),
                // (13,14): error CS8986: The 'scoped' modifier of parameter 'x' doesn't match target '<anonymous delegate>'.
                //         d1 = F3; // 2, 3
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "F3").WithArguments("x", "<anonymous delegate>").WithLocation(13, 14),
                // (13,14): error CS8986: The 'scoped' modifier of parameter 'y' doesn't match target '<anonymous delegate>'.
                //         d1 = F3; // 2, 3
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "F3").WithArguments("y", "<anonymous delegate>").WithLocation(13, 14),
                // (15,14): error CS8986: The 'scoped' modifier of parameter 'x' doesn't match target '<anonymous delegate>'.
                //         d2 = F3; // 4
                Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfTarget, "F3").WithArguments("x", "<anonymous delegate>").WithLocation(15, 14));
        }
 
        [Fact, WorkItem(64045, "https://github.com/dotnet/roslyn/issues/64045")]
        public void ConstructorInvocationValEscape_01()
        {
            var source = """
                class Program
                {
                    static RS M1(scoped ref int i1) => new(ref i1);
                    static RS M2(scoped ref int i2)
                    {
                        return new(ref i2);
                    }
 
                    static RS M3(scoped ref int i3) => new RS(ref i3);
                    static RS M4(scoped ref int i4)
                    {
                        return new RS(ref i4);
                    }
                }
 
                ref struct RS
                {
                    public RS(ref int i0) => throw null!;
                }
                """;
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (3,40): error CS8347: Cannot use a result of 'RS.RS(ref int)' in this context because it may expose variables referenced by parameter 'i0' outside of their declaration scope
                //     static RS M1(scoped ref int i1) => new(ref i1);
                Diagnostic(ErrorCode.ERR_EscapeCall, "new(ref i1)").WithArguments("RS.RS(ref int)", "i0").WithLocation(3, 40),
                // (3,48): error CS9075: Cannot return a parameter by reference 'i1' because it is scoped to the current method
                //     static RS M1(scoped ref int i1) => new(ref i1);
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "i1").WithArguments("i1").WithLocation(3, 48),
                // (6,16): error CS8347: Cannot use a result of 'RS.RS(ref int)' in this context because it may expose variables referenced by parameter 'i0' outside of their declaration scope
                //         return new(ref i2);
                Diagnostic(ErrorCode.ERR_EscapeCall, "new(ref i2)").WithArguments("RS.RS(ref int)", "i0").WithLocation(6, 16),
                // (6,24): error CS9075: Cannot return a parameter by reference 'i2' because it is scoped to the current method
                //         return new(ref i2);
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "i2").WithArguments("i2").WithLocation(6, 24),
                // (9,40): error CS8347: Cannot use a result of 'RS.RS(ref int)' in this context because it may expose variables referenced by parameter 'i0' outside of their declaration scope
                //     static RS M3(scoped ref int i3) => new RS(ref i3);
                Diagnostic(ErrorCode.ERR_EscapeCall, "new RS(ref i3)").WithArguments("RS.RS(ref int)", "i0").WithLocation(9, 40),
                // (9,51): error CS9075: Cannot return a parameter by reference 'i3' because it is scoped to the current method
                //     static RS M3(scoped ref int i3) => new RS(ref i3);
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "i3").WithArguments("i3").WithLocation(9, 51),
                // (12,16): error CS8347: Cannot use a result of 'RS.RS(ref int)' in this context because it may expose variables referenced by parameter 'i0' outside of their declaration scope
                //         return new RS(ref i4);
                Diagnostic(ErrorCode.ERR_EscapeCall, "new RS(ref i4)").WithArguments("RS.RS(ref int)", "i0").WithLocation(12, 16),
                // (12,27): error CS9075: Cannot return a parameter by reference 'i4' because it is scoped to the current method
                //         return new RS(ref i4);
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "i4").WithArguments("i4").WithLocation(12, 27));
        }
 
        [Fact, WorkItem(64045, "https://github.com/dotnet/roslyn/issues/64045")]
        public void ConstructorInvocationValEscape_02()
        {
            var source = """
                class Program
                {
                    static void M()
                    {
                        Del lam1 = (scoped ref int i1) => new(ref i1); // 1
                        Del lam2 = (scoped ref int i2) =>
                        {
                            return new(ref i2); // 2
                        };
 
                        Del lam3 = (scoped ref int i3) => new RS(ref i3); // 3
                        Del lam4 = (scoped ref int i4) =>
                        {
                            return new RS(ref i4); // 4
                        };
                    }
                }
 
                ref struct RS
                {
                    public RS(ref int i0) => throw null!;
                }
 
                delegate RS Del(scoped ref int i);
                """;
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (5,43): error CS8347: Cannot use a result of 'RS.RS(ref int)' in this context because it may expose variables referenced by parameter 'i0' outside of their declaration scope
                //         Del lam1 = (scoped ref int i1) => new(ref i1); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "new(ref i1)").WithArguments("RS.RS(ref int)", "i0").WithLocation(5, 43),
                // (5,51): error CS9075: Cannot return a parameter by reference 'i1' because it is scoped to the current method
                //         Del lam1 = (scoped ref int i1) => new(ref i1); // 1
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "i1").WithArguments("i1").WithLocation(5, 51),
                // (8,20): error CS8347: Cannot use a result of 'RS.RS(ref int)' in this context because it may expose variables referenced by parameter 'i0' outside of their declaration scope
                //             return new(ref i2); // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "new(ref i2)").WithArguments("RS.RS(ref int)", "i0").WithLocation(8, 20),
                // (8,28): error CS9075: Cannot return a parameter by reference 'i2' because it is scoped to the current method
                //             return new(ref i2); // 2
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "i2").WithArguments("i2").WithLocation(8, 28),
                // (11,43): error CS8347: Cannot use a result of 'RS.RS(ref int)' in this context because it may expose variables referenced by parameter 'i0' outside of their declaration scope
                //         Del lam3 = (scoped ref int i3) => new RS(ref i3); // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "new RS(ref i3)").WithArguments("RS.RS(ref int)", "i0").WithLocation(11, 43),
                // (11,54): error CS9075: Cannot return a parameter by reference 'i3' because it is scoped to the current method
                //         Del lam3 = (scoped ref int i3) => new RS(ref i3); // 3
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "i3").WithArguments("i3").WithLocation(11, 54),
                // (14,20): error CS8347: Cannot use a result of 'RS.RS(ref int)' in this context because it may expose variables referenced by parameter 'i0' outside of their declaration scope
                //             return new RS(ref i4); // 4
                Diagnostic(ErrorCode.ERR_EscapeCall, "new RS(ref i4)").WithArguments("RS.RS(ref int)", "i0").WithLocation(14, 20),
                // (14,31): error CS9075: Cannot return a parameter by reference 'i4' because it is scoped to the current method
                //             return new RS(ref i4); // 4
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "i4").WithArguments("i4").WithLocation(14, 31));
        }
 
        [Fact, WorkItem(65648, "https://github.com/dotnet/roslyn/issues/65648")]
        public void ReturnRefToRefStruct_ValEscape_01()
        {
            var source = """
                using System.Diagnostics.CodeAnalysis;
 
                public class Repro
                {
                    private static void Bad1(int value)
                    {
                        RefStruct s1 = new RefStruct();
                        s1.RefField = ref value; // 1
                    }
 
                    private static void Bad2(int value)
                    {
                        RefStruct s1 = new RefStruct();
                        s1.RefProperty.RefField = ref value; // 2
                    }
 
                    private static void Bad3(int value)
                    {
                        RefStruct s1 = new RefStruct();
                        s1.RefMethod().RefField = ref value; // 3
                    }
 
                    private ref struct RefStruct
                    {
                        public ref int RefField;
                        [UnscopedRef] public ref RefStruct RefProperty => ref this;
                        [UnscopedRef] public ref RefStruct RefMethod() => ref this;
                    }
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (8,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'.
                //         s1.RefField = ref value; // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s1.RefField = ref value").WithArguments("RefField", "value").WithLocation(8, 9),
                // (14,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'.
                //         s1.RefProperty.RefField = ref value; // 2
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s1.RefProperty.RefField = ref value").WithArguments("RefField", "value").WithLocation(14, 9),
                // (20,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'.
                //         s1.RefMethod().RefField = ref value; // 3
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s1.RefMethod().RefField = ref value").WithArguments("RefField", "value").WithLocation(20, 9));
        }
 
        [Fact, WorkItem(65648, "https://github.com/dotnet/roslyn/issues/65648")]
        public void ReturnRefToRefStruct_ValEscape_02()
        {
            var source = """
                using System.Diagnostics.CodeAnalysis;
 
                public class Repro
                {
                    private static void Bad1(scoped ref RefStruct s1, int value)
                    {
                        s1.RefField = ref value; // 1
                    }
 
                    private static void Bad2(scoped ref RefStruct s1, int value)
                    {
                        s1.RefProperty.RefField = ref value; // 2
                    }
 
                    private static void Bad3(scoped ref RefStruct s1, int value)
                    {
                        s1.RefMethod().RefField = ref value; // 3
                    }
 
                    private static void Bad4(scoped in RefStruct s1, int value)
                    {
                        s1.RefField = ref value; // 4
                    }
 
                    private static void Bad5(scoped in RefStruct s1, int value)
                    {
                        s1.RefProperty.RefField = ref value; // 5
                    }
 
                    private static void Bad6(scoped in RefStruct s1, int value)
                    {
                        s1.RefMethod().RefField = ref value; // 6
                    }
 
                    private static void Bad7(in RefStruct s1, int value)
                    {
                        s1.RefField = ref value; // 7
                    }
 
                    private static void Bad8(in RefStruct s1, int value)
                    {
                        s1.RefProperty.RefField = ref value; // 8
                    }
 
                    private static void Bad9(in RefStruct s1, int value)
                    {
                        s1.RefMethod().RefField = ref value; // 9
                    }
 
                    private ref struct RefStruct
                    {
                        public ref int RefField;
                        [UnscopedRef] public ref RefStruct RefProperty => ref this;
                        [UnscopedRef] public ref RefStruct RefMethod() => ref this;
                    }
                }
                """;
 
            // NB: 8 and 9 are not strictly necessary here because they are assigning to an implicit copy of a readonly variable, not to the original variable.
            // However, it is not deeply problematic that an error is given here.
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (7,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'.
                //         s1.RefField = ref value; // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s1.RefField = ref value").WithArguments("RefField", "value").WithLocation(7, 9),
                // (12,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'.
                //         s1.RefProperty.RefField = ref value; // 2
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s1.RefProperty.RefField = ref value").WithArguments("RefField", "value").WithLocation(12, 9),
                // (17,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'.
                //         s1.RefMethod().RefField = ref value; // 3
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s1.RefMethod().RefField = ref value").WithArguments("RefField", "value").WithLocation(17, 9),
                // (22,9): error CS8332: Cannot assign to a member of variable 's1' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         s1.RefField = ref value; // 4
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "s1.RefField").WithArguments("variable", "s1").WithLocation(22, 9),
                // (27,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'.
                //         s1.RefProperty.RefField = ref value; // 5
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s1.RefProperty.RefField = ref value").WithArguments("RefField", "value").WithLocation(27, 9),
                // (32,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'.
                //         s1.RefMethod().RefField = ref value; // 6
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s1.RefMethod().RefField = ref value").WithArguments("RefField", "value").WithLocation(32, 9),
                // (37,9): error CS8332: Cannot assign to a member of variable 's1' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         s1.RefField = ref value; // 7
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "s1.RefField").WithArguments("variable", "s1").WithLocation(37, 9),
                // (42,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'.
                //         s1.RefProperty.RefField = ref value; // 8
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s1.RefProperty.RefField = ref value").WithArguments("RefField", "value").WithLocation(42, 9),
                // (47,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'.
                //         s1.RefMethod().RefField = ref value; // 9
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s1.RefMethod().RefField = ref value").WithArguments("RefField", "value").WithLocation(47, 9));
        }
 
        [Fact, WorkItem(65648, "https://github.com/dotnet/roslyn/issues/65648")]
        public void ReturnRefToRefStruct_ValEscape_03()
        {
            var source = """
                using System.Diagnostics.CodeAnalysis;
 
                public class Repro
                {
                    private static void Bad1(ref RefStruct s1, int value)
                    {
                        s1 = new RefStruct(ref value); // 1
                    }
 
                    private static void Bad2(scoped ref RefStruct s1, int value)
                    {
                        s1.RefProperty = new RefStruct(ref value); // 2
                    }
 
                    private static void Bad3(scoped ref RefStruct s1, int value)
                    {
                        s1.RefMethod() = new RefStruct(ref value); // 3
                    }
 
                    private static void Bad4(scoped ref RefStruct s1, int value)
                    {
                        GetRef(ref s1) = new RefStruct(ref value); // 4
                    }
 
                    private static ref RefStruct GetRef(ref RefStruct s) => ref s;
 
                    private ref struct RefStruct
                    {
                        public RefStruct(ref int i) => RefField = ref i;
                        public ref int RefField;
                        [UnscopedRef] public ref RefStruct RefProperty => ref this;
                        [UnscopedRef] public ref RefStruct RefMethod() => ref this;
                    }
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (7,14): error CS8347: Cannot use a result of 'Repro.RefStruct.RefStruct(ref int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         s1 = new RefStruct(ref value); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "new RefStruct(ref value)").WithArguments("Repro.RefStruct.RefStruct(ref int)", "i").WithLocation(7, 14),
                // (7,32): error CS8166: Cannot return a parameter by reference 'value' because it is not a ref parameter
                //         s1 = new RefStruct(ref value); // 1
                Diagnostic(ErrorCode.ERR_RefReturnParameter, "value").WithArguments("value").WithLocation(7, 32),
                // (12,26): error CS8347: Cannot use a result of 'Repro.RefStruct.RefStruct(ref int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         s1.RefProperty = new RefStruct(ref value); // 2
                Diagnostic(ErrorCode.ERR_EscapeCall, "new RefStruct(ref value)").WithArguments("Repro.RefStruct.RefStruct(ref int)", "i").WithLocation(12, 26),
                // (12,44): error CS8166: Cannot return a parameter by reference 'value' because it is not a ref parameter
                //         s1.RefProperty = new RefStruct(ref value); // 2
                Diagnostic(ErrorCode.ERR_RefReturnParameter, "value").WithArguments("value").WithLocation(12, 44),
                // (17,26): error CS8347: Cannot use a result of 'Repro.RefStruct.RefStruct(ref int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         s1.RefMethod() = new RefStruct(ref value); // 3
                Diagnostic(ErrorCode.ERR_EscapeCall, "new RefStruct(ref value)").WithArguments("Repro.RefStruct.RefStruct(ref int)", "i").WithLocation(17, 26),
                // (17,44): error CS8166: Cannot return a parameter by reference 'value' because it is not a ref parameter
                //         s1.RefMethod() = new RefStruct(ref value); // 3
                Diagnostic(ErrorCode.ERR_RefReturnParameter, "value").WithArguments("value").WithLocation(17, 44),
                // (22,26): error CS8347: Cannot use a result of 'Repro.RefStruct.RefStruct(ref int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         GetRef(ref s1) = new RefStruct(ref value); // 4
                Diagnostic(ErrorCode.ERR_EscapeCall, "new RefStruct(ref value)").WithArguments("Repro.RefStruct.RefStruct(ref int)", "i").WithLocation(22, 26),
                // (22,44): error CS8166: Cannot return a parameter by reference 'value' because it is not a ref parameter
                //         GetRef(ref s1) = new RefStruct(ref value); // 4
                Diagnostic(ErrorCode.ERR_RefReturnParameter, "value").WithArguments("value").WithLocation(22, 44));
        }
 
        [Fact, WorkItem(65648, "https://github.com/dotnet/roslyn/issues/65648")]
        public void ReturnRefToRefStruct_ValEscape_04()
        {
            // test that the appropriate filtering of escape-values is occurring when the RTRS expression is on the RHS of an an assignment.
            var source = """
                using System.Diagnostics.CodeAnalysis;
 
                public class Repro
                {
                    private static void M1(ref RefStruct s1, int value)
                    {
                        // 's2' only contributes STE, not RSTE, to the STE of 'RefMethod()' invocation.
                        // STE is equal to RSTE for 's2', so it doesn't matter.
                        var s2 = new RefStruct(ref value);
                        s1 = s2.RefMethod(); // 1
                    }
                    
                    private static void M2(ref RefStruct s1, ref RefStruct s2)
                    {
                        // 's2' only contributes STE, not RSTE, to the STE of 'RefMethod()' invocation.
                        // RSTE of `s2` is narrower than STE of 's1', but STE of 's2' equals STE of 's1', so we expect no error here.
                        s1 = s2.RefMethod();
                    }
 
                    private ref struct RefStruct
                    {
                        public RefStruct(ref int i) => RefField = ref i;
                        public ref int RefField;
                        [UnscopedRef] public ref RefStruct RefMethod() => ref this;
                    }
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (10,14): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                //         s1 = s2.RefMethod(); // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(10, 14));
        }
 
        [Fact, WorkItem(65648, "https://github.com/dotnet/roslyn/issues/65648")]
        public void ReturnRefToRefStruct_RefEscape_01()
        {
            var source = """
                public class Repro
                {
                    private static ref RefStruct M1(ref RefStruct s1, ref RefStruct s2)
                    {
                        bool b = false;
                        return ref b ? ref s1 : ref s2;
                    }
 
                    private static ref RefStruct M2(ref RefStruct s1)
                    {
                        RefStruct s2 = default;
                        // RSTE of s1 is ReturnOnly
                        // RSTE of s2 is CurrentMethod
                        return ref M1(ref s1, ref s2); // 1
                    }
                    
                    private static ref RefStruct M3(ref RefStruct s1)
                    {
                        return ref M1(ref s1, ref s1);
                    }
 
                    private ref struct RefStruct { }
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (14,20): error CS8347: Cannot use a result of 'Repro.M1(ref Repro.RefStruct, ref Repro.RefStruct)' in this context because it may expose variables referenced by parameter 's2' outside of their declaration scope
                //         return ref M1(ref s1, ref s2); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "M1(ref s1, ref s2)").WithArguments("Repro.M1(ref Repro.RefStruct, ref Repro.RefStruct)", "s2").WithLocation(14, 20),
                // (14,35): error CS8168: Cannot return local 's2' by reference because it is not a ref local
                //         return ref M1(ref s1, ref s2); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "s2").WithArguments("s2").WithLocation(14, 35)
                );
        }
 
        [Fact, WorkItem(65648, "https://github.com/dotnet/roslyn/issues/65648")]
        public void ReturnRefToRefStruct_RefEscape_BothScopedAndUnscopedRefParameters()
        {
            var source = """
                public class Repro
                {
                    private static ref RefStruct M1(ref RefStruct s1, scoped ref RefStruct s2)
                    {
                        return ref s1;
                    }
 
                    private static ref RefStruct M2(ref RefStruct s1)
                    {
                        RefStruct s2 = default;
                        // RSTE of s1 is ReturnOnly
                        // RSTE of s2 is CurrentMethod, but it doesn't contribute to RSTE of the invocation.
                        return ref M1(ref s1, ref s2);
                    }
                    
                    private static ref RefStruct M3(ref RefStruct s1)
                    {
                        return ref M1(ref s1, ref s1);
                    }
 
                    private ref struct RefStruct { }
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
        }
 
        [Fact, WorkItem(65648, "https://github.com/dotnet/roslyn/issues/65648")]
        public void ReturnRefToRefStruct_RefEscape_02()
        {
            var source = """
                public class Repro
                {
                    private static ref RefStruct M1(ref RefStruct s1, RefStruct s2)
                    {
                        return ref s1;
                    }
 
                    private static ref RefStruct M2(ref RefStruct s1, int param)
                    {
                        RefStruct s2 = new RefStruct(ref param);
                        // RSTE of s1 is ReturnOnly
                        // STE of s2 is CurrentMethod, but this is not contributed to the call to M1.
                        // We error due to arg mixing, not due to the return value.
                        return ref M1(ref s1, s2);
                    }
 
                    private ref struct RefStruct
                    {
                        public RefStruct(ref int i) { }
                    }
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (14,20): error CS8350: This combination of arguments to 'Repro.M1(ref Repro.RefStruct, Repro.RefStruct)' is disallowed because it may expose variables referenced by parameter 's2' outside of their declaration scope
                //         return ref M1(ref s1, s2);
                Diagnostic(ErrorCode.ERR_CallArgMixing, "M1(ref s1, s2)").WithArguments("Repro.M1(ref Repro.RefStruct, Repro.RefStruct)", "s2").WithLocation(14, 20),
                // (14,31): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                //         return ref M1(ref s1, s2);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(14, 31)
                );
        }
 
        [Fact, WorkItem(65648, "https://github.com/dotnet/roslyn/issues/65648")]
        public void ReturnRefToRefStruct_VariousInputAndOutputRefKinds()
        {
            var source = """
                using System.Diagnostics.CodeAnalysis;
 
                public class Repro
                {
                    private static void Bad1(int value)
                    {
                        RefStruct s1 = new RefStruct();
                        GetReference1(ref s1).RefField = ref value; // 1
                        GetReference2(in s1).RefField = ref value; // 2
                        GetReference3(out s1).RefField = ref value; // 3
 
                        GetReadonlyReference1(ref s1).RefField = ref value; // 4
                        GetReadonlyReference2(in s1).RefField = ref value; // 5
                        GetReadonlyReference3(out s1).RefField = ref value; // 6
                    }
 
                    static ref RefStruct GetReference1(ref RefStruct rs) => throw null!;
                    static ref RefStruct GetReference2(in RefStruct rs) => throw null!;
                    static ref RefStruct GetReference3([UnscopedRef] out RefStruct rs) => throw null!;
 
                    static ref readonly RefStruct GetReadonlyReference1(ref RefStruct rs) => throw null!;
                    static ref readonly RefStruct GetReadonlyReference2(in RefStruct rs) => throw null!;
                    static ref readonly RefStruct GetReadonlyReference3([UnscopedRef] out RefStruct rs) => throw null!;
 
                    private ref struct RefStruct
                    {
                        public ref int RefField;
                    }
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (8,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'.
                //         GetReference1(ref s1).RefField = ref value; // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "GetReference1(ref s1).RefField = ref value").WithArguments("RefField", "value").WithLocation(8, 9),
                // (9,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'.
                //         GetReference2(in s1).RefField = ref value; // 2
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "GetReference2(in s1).RefField = ref value").WithArguments("RefField", "value").WithLocation(9, 9),
                // (10,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'.
                //         GetReference3(out s1).RefField = ref value; // 3
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "GetReference3(out s1).RefField = ref value").WithArguments("RefField", "value").WithLocation(10, 9),
                // (12,9): error CS8332: Cannot assign to a member of method 'GetReadonlyReference1' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         GetReadonlyReference1(ref s1).RefField = ref value; // 4
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "GetReadonlyReference1(ref s1).RefField").WithArguments("method", "GetReadonlyReference1").WithLocation(12, 9),
                // (13,9): error CS8332: Cannot assign to a member of method 'GetReadonlyReference2' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         GetReadonlyReference2(in s1).RefField = ref value; // 5
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "GetReadonlyReference2(in s1).RefField").WithArguments("method", "GetReadonlyReference2").WithLocation(13, 9),
                // (14,9): error CS8332: Cannot assign to a member of method 'GetReadonlyReference3' or use it as the right hand side of a ref assignment because it is a readonly variable
                //         GetReadonlyReference3(out s1).RefField = ref value; // 6
                Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "GetReadonlyReference3(out s1).RefField").WithArguments("method", "GetReadonlyReference3").WithLocation(14, 9));
        }
 
        [WorkItem(66128, "https://github.com/dotnet/roslyn/issues/66128")]
        [ConditionalFact(typeof(CoreClrOnly))]
        public void DefensiveCopy_RefReadOnlyReceiver_01()
        {
            var source = """
                using System;
                class Program
                {
                    static void Main()
                    {
                        S s = new();
                        ref readonly S r = ref s;
                        M(in r);
                        Console.WriteLine(r);
                    }
                    static void M(in S s)
                    {
                        R r = new(in s);
                        r.S.M();
                    }
                }
                struct S
                {
                    int i;
                    public void M() { i++; }
                    public readonly override string ToString() => i.ToString();
                }
                ref struct R
                {
                    public ref readonly S S;
                    public R(in S s) { S = ref s; }
                }
                """;
            var verifier = CompileAndVerify(source, targetFramework: TargetFramework.Net70, expectedOutput: "0");
            verifier.VerifyIL("Program.M", """
                {
                  // Code size       27 (0x1b)
                  .maxstack  1
                  .locals init (R V_0, //r
                                S V_1)
                  IL_0000:  ldarg.0
                  IL_0001:  newobj     "R..ctor(in S)"
                  IL_0006:  stloc.0
                  IL_0007:  ldloc.0
                  IL_0008:  ldfld      "ref readonly S R.S"
                  IL_000d:  ldobj      "S"
                  IL_0012:  stloc.1
                  IL_0013:  ldloca.s   V_1
                  IL_0015:  call       "void S.M()"
                  IL_001a:  ret
                }
                """);
        }
 
        [WorkItem(66128, "https://github.com/dotnet/roslyn/issues/66128")]
        [ConditionalFact(typeof(CoreClrOnly))]
        public void DefensiveCopy_RefReadOnlyReceiver_02()
        {
            var source = """
                using System;
                class Program
                {
                    static void Main()
                    {
                        R r = new R(new S());
                        Console.WriteLine(r.S);
                    }
                }
                struct S
                {
                    int i;
                    public void M1() { i++; }
                    public readonly void M2() { }
                    public readonly override string ToString() => i.ToString();
                }
                ref struct R
                {
                    public ref readonly S S;
                    public R(in S s)
                    {
                        S = ref s;
                        S.M1();
                    }
                    public R(in S s, object o)
                    {
                        S = ref s;
                        S.M2();
                    }
                }
                """;
            var verifier = CompileAndVerify(source, targetFramework: TargetFramework.Net70, expectedOutput: "0");
            verifier.VerifyIL("R..ctor(in S)", """
                {
                  // Code size       27 (0x1b)
                  .maxstack  2
                  .locals init (S V_0)
                  IL_0000:  ldarg.0
                  IL_0001:  ldarg.1
                  IL_0002:  stfld      "ref readonly S R.S"
                  IL_0007:  ldarg.0
                  IL_0008:  ldfld      "ref readonly S R.S"
                  IL_000d:  ldobj      "S"
                  IL_0012:  stloc.0
                  IL_0013:  ldloca.s   V_0
                  IL_0015:  call       "void S.M1()"
                  IL_001a:  ret
                }
                """);
            verifier.VerifyIL("R..ctor(in S, object)", """
                {
                  // Code size       19 (0x13)
                  .maxstack  2
                  IL_0000:  ldarg.0
                  IL_0001:  ldarg.1
                  IL_0002:  stfld      "ref readonly S R.S"
                  IL_0007:  ldarg.0
                  IL_0008:  ldfld      "ref readonly S R.S"
                  IL_000d:  call       "readonly void S.M2()"
                  IL_0012:  ret
                }
                """);
        }
 
        [WorkItem(66128, "https://github.com/dotnet/roslyn/issues/66128")]
        [ConditionalFact(typeof(CoreClrOnly))]
        public void DefensiveCopy_RefReadOnlyReceiver_03()
        {
            var source = """
                using System;
                class Program
                {
                    static void Main()
                    {
                        R r1 = new R(new S()) { P1 = 1 };
                        Console.WriteLine(r1.S);
                        R r2 = new R(new S()) { P2 = 2 };
                        Console.WriteLine(r2.S);
                    }
                }
                struct S
                {
                    int i;
                    public void M() { i++; }
                    public readonly override string ToString() => i.ToString();
                }
                ref struct R
                {
                    public ref readonly S S;
                    public R(in S s)
                    {
                        S = ref s;
                    }
                    public object P1
                    {
                        get { return null; }
                        set { S.M(); }
                    }
                    public object P2
                    {
                        get { return null; }
                        init { S.M(); }
                    }
                }
                """;
            var verifier = CompileAndVerify(source, targetFramework: TargetFramework.Net70, expectedOutput: """
                0
                0
                """);
            string expectedIL = """
                {
                  // Code size       20 (0x14)
                  .maxstack  1
                  .locals init (S V_0)
                  IL_0000:  ldarg.0
                  IL_0001:  ldfld      "ref readonly S R.S"
                  IL_0006:  ldobj      "S"
                  IL_000b:  stloc.0
                  IL_000c:  ldloca.s   V_0
                  IL_000e:  call       "void S.M()"
                  IL_0013:  ret
                }
                """;
            verifier.VerifyIL("R.P1.set", expectedIL);
            verifier.VerifyIL("R.P2.init", expectedIL);
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void ConstructorInitializer_01(LanguageVersion languageVersion)
        {
            var source = """
                using System;
                class A
                {
                    public A(ref Span<int> x, Span<int> y) { }
                    A(ref Span<int> s) : this(ref s, new Span<int>()) { }
                    A(ref Span<int> s, int i) : this(ref s, stackalloc int[1]) { } // 1
                }
                class B : A
                {
                    B(ref Span<int> s) : base(ref s, new Span<int>()) { }
                    B(ref Span<int> s, int i) : base(ref s, stackalloc int[2]) { } // 2
                }
                """;
            var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics(
                // (6,31): error CS8350: This combination of arguments to 'A.A(ref Span<int>, Span<int>)' is disallowed because it may expose variables referenced by parameter 'y' outside of their declaration scope
                //     A(ref Span<int> s, int i) : this(ref s, stackalloc int[1]) { } // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, ": this(ref s, stackalloc int[1])").WithArguments("A.A(ref System.Span<int>, System.Span<int>)", "y").WithLocation(6, 31),
                // (6,45): error CS8353: A result of a stackalloc expression of type 'Span<int>' cannot be used in this context because it may be exposed outside of the containing method
                //     A(ref Span<int> s, int i) : this(ref s, stackalloc int[1]) { } // 1
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(6, 45),
                // (11,31): error CS8350: This combination of arguments to 'A.A(ref Span<int>, Span<int>)' is disallowed because it may expose variables referenced by parameter 'y' outside of their declaration scope
                //     B(ref Span<int> s, int i) : base(ref s, stackalloc int[2]) { } // 2
                Diagnostic(ErrorCode.ERR_CallArgMixing, ": base(ref s, stackalloc int[2])").WithArguments("A.A(ref System.Span<int>, System.Span<int>)", "y").WithLocation(11, 31),
                // (11,45): error CS8353: A result of a stackalloc expression of type 'Span<int>' cannot be used in this context because it may be exposed outside of the containing method
                //     B(ref Span<int> s, int i) : base(ref s, stackalloc int[2]) { } // 2
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[2]").WithArguments("System.Span<int>").WithLocation(11, 45));
        }
 
        [Fact]
        public void ConstructorInitializer_02()
        {
            var source = """
                ref struct R
                {
                    R(in int i) { }
                    R(int x, int y) : this(x) { } // 1
                }
                """;
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (4,21): error CS8350: This combination of arguments to 'R.R(in int)' is disallowed because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //     R(int x, int y) : this(x) { } // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, ": this(x)").WithArguments("R.R(in int)", "i").WithLocation(4, 21),
                // (4,28): error CS8166: Cannot return a parameter by reference 'x' because it is not a ref parameter
                //     R(int x, int y) : this(x) { } // 1
                Diagnostic(ErrorCode.ERR_RefReturnParameter, "x").WithArguments("x").WithLocation(4, 28));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void FunctionPointerInvocation_01(LanguageVersion languageVersion)
        {
            var source = """
                using System;
                class Program
                {
                    static void F0(ref Span<int> x, Span<int> y)
                    {
                    }
                    static unsafe void F1(ref Span<int> s)
                    {
                        delegate*<ref Span<int>, Span<int>, void> f = &F0;
                        f(ref s, new Span<int>());
                        f(ref s, stackalloc int[1]); // 1
                    }
                }
                """;
            var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.UnsafeReleaseDll);
            comp.VerifyDiagnostics(
                // (11,18): warning CS9081: A result of a stackalloc expression of type 'Span<int>' in this context may be exposed outside of the containing method
                //         f(ref s, stackalloc int[1]); // 1
                Diagnostic(ErrorCode.WRN_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(11, 18));
        }
 
        [Fact]
        public void FunctionPointerInvocation_02()
        {
            var source = """
                ref struct R
                {
                }
                class Program
                {
                    static void F0(out R r, in int i)
                    {
                        r = default;
                    }
                    static unsafe void F1(out R r1, in int i1)
                    {
                        delegate*<out R, in int, void> f = &F0;
                        f(out r1, i1);
                    }
                    static unsafe void F2(out R r1, int i2)
                    {
                        delegate*<out R, in int, void> f = &F0;
                        f(out r1, i2); // 1
                    }
                }
                """;
            var comp = CreateCompilationWithSpan(source, options: TestOptions.UnsafeReleaseDll);
            comp.VerifyDiagnostics(
                // (18,19): warning CS9087: This returns a parameter by reference 'i2' but it is not a ref parameter
                //         f(out r1, i2); // 1
                Diagnostic(ErrorCode.WRN_RefReturnParameter, "i2").WithArguments("i2").WithLocation(18, 19));
        }
 
        [Fact]
        public void PatternIndex_01()
        {
            string source = """
                using System;
                using System.Diagnostics.CodeAnalysis;
                ref struct R
                {
                    public int Length => 0;
                    [UnscopedRef] public ref int this[int i] => throw null;
                }
                class Program
                {
                    static ref int F1(ref R r1)
                    {
                        ref int i1 = ref r1[^1];
                        return ref i1;
                    }
                    static ref int F2(ref R r2, Index i)
                    {
                        ref int i2 = ref r2[i];
                        return ref i2;
                    }
                    static ref int F3()
                    {
                        R r3 = new R();
                        ref int i3 = ref r3[^3];
                        return ref i3; // 1
                    }
                    static ref int F4(Index i)
                    {
                        R r4 = new R();
                        ref int i4 = ref r4[i];
                        return ref i4; // 2
                    }
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (24,20): error CS8157: Cannot return 'i3' by reference because it was initialized to a value that cannot be returned by reference
                //         return ref i3; // 1
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "i3").WithArguments("i3").WithLocation(24, 20),
                // (30,20): error CS8157: Cannot return 'i4' by reference because it was initialized to a value that cannot be returned by reference
                //         return ref i4; // 2
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "i4").WithArguments("i4").WithLocation(30, 20));
        }
 
        [Fact]
        public void PatternIndex_02()
        {
            string source = """
                ref struct R
                {
                    public R(ref int i) { }
                    public int Length => 0;
                    public R this[int i] => throw null;
                }
                class Program
                {
                    static R F1()
                    {
                        R r1 = new R();
                        if (r1 is [.., var r]) return r;
                        return r1;
                    }
                    static R F2()
                    {
                        int i2 = 2;
                        R r2 = new R(ref i2);
                        if (r2 is [.., var r]) return r; // 1
                        return r2; // 2
                    }
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (19,39): error CS8352: Cannot use variable 'r' in this context because it may expose referenced variables outside of their declaration scope
                //         if (r2 is [.., var r]) return r; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r").WithArguments("r").WithLocation(19, 39),
                // (20,16): error CS8352: Cannot use variable 'r2' in this context because it may expose referenced variables outside of their declaration scope
                //         return r2; // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r2").WithArguments("r2").WithLocation(20, 16));
        }
 
        [Fact]
        public void PatternIndex_03()
        {
            string source = """
                ref struct R
                {
                    public R(ref int i) { }
                    public int Length => 0;
                    public int this[int i] => 0;
                    public R Slice(int x, int y) => this;
                }
                class Program
                {
                    static R F1()
                    {
                        R r1 = new R();
                        if (r1 is [.. [> 0] r]) return r;
                        return r1;
                    }
                    static R F2()
                    {
                        int i2 = 2;
                        R r2 = new R(ref i2);
                        if (r2 is [.. [> 0] r]) return r; // 1
                        return r2; // 2
                    }
                }
                """;
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (20,40): error CS8352: Cannot use variable 'r' in this context because it may expose referenced variables outside of their declaration scope
                //         if (r2 is [.. [> 0] r]) return r; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r").WithArguments("r").WithLocation(20, 40),
                // (21,16): error CS8352: Cannot use variable 'r2' in this context because it may expose referenced variables outside of their declaration scope
                //         return r2; // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "r2").WithArguments("r2").WithLocation(21, 16));
        }
 
        [Fact]
        public void TopLevelStatementLocal()
        {
            var source = """
                int i = 0;
                ref int r = ref i;
                class C
                {
                    static void F1() { F2(ref r); }
                    static ref int F2(ref int r) => ref r;
                }
                """;
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (5,31): error CS8801: Cannot use local variable or local function 'r' declared in a top-level statement in this context.
                //     static void F1() { F2(ref r); }
                Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "r").WithArguments("r").WithLocation(5, 31),
                // (5,31): error CS0165: Use of unassigned local variable 'r'
                //     static void F1() { F2(ref r); }
                Diagnostic(ErrorCode.ERR_UseDefViolation, "r").WithArguments("r").WithLocation(5, 31));
        }
 
        [Fact]
        public void Discard_01()
        {
            var source = """
                class Program
                {
                    static ref int F1()
                    {
                        return ref F2(out _);
                    }
                    static ref int F2(out int i)
                    {
                        i = 0;
                        return ref i;
                    }
                }
                """;
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(
                // (5,20): error CS8347: Cannot use a result of 'Program.F2(out int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         return ref F2(out _);
                Diagnostic(ErrorCode.ERR_EscapeCall, "F2(out _)").WithArguments("Program.F2(out int)", "i").WithLocation(5, 20),
                // (5,27): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                //         return ref F2(out _);
                Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "_").WithLocation(5, 27));
        }
 
        [Fact]
        public void Discard_02()
        {
            var source = """
                using System.Diagnostics.CodeAnalysis;
                class Program
                {
                    static ref int F1()
                    {
                        return ref F2(out _);
                    }
                    static ref int F2([UnscopedRef] out int i)
                    {
                        i = 0;
                        return ref i;
                    }
                }
                """;
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (6,20): error CS8347: Cannot use a result of 'Program.F2(out int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         return ref F2(out _);
                Diagnostic(ErrorCode.ERR_EscapeCall, "F2(out _)").WithArguments("Program.F2(out int)", "i").WithLocation(6, 20),
                // (6,27): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                //         return ref F2(out _);
                Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "_").WithLocation(6, 27));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Discard_03(LanguageVersion languageVersion)
        {
            var source = """
                ref struct R
                {
                    public void Deconstruct(out int x, out R y)
                    {
                        x = 0;
                        y = default;
                    }
                }
                class Program
                {
                    static R F1()
                    {
                        R r1 = default;
                        int i;
                        (i, _) = r1;
                        return r1;
                    }
                    static R F2()
                    {
                        R r2 = default;
                        int i;
                        r2.Deconstruct(out i, out _);
                        return r2;
                    }
                }
                """;
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void SwitchExpression_Assignment()
        {
            var source = """
                using System;
                class Program
                {
                    static void M()
                    {
                        Span<int> s;
                        Span<int> outer = stackalloc int[100];
                        s = outer switch
                        {
                            Span<int> inner => inner
                        };
                    }
                }
                """;
            var comp = CreateCompilationWithSpan(source);
            comp.VerifyDiagnostics(
                // (10,32): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //             Span<int> inner => inner
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(10, 32));
        }
 
        [Fact]
        public void SwitchExpression_Argument()
        {
            var source = """
                using System;
                class Program
                {
                    static Span<int> F(Span<int> x, Span<int> y)
                    {
                        return x;
                    }
                    static void M()
                    {
                        Span<int> x = default;
                        Span<int> y = stackalloc int[100];
                        x = F(x, y switch { Span<int> inner => inner });
                    }
                }
                """;
            var comp = CreateCompilationWithSpan(source);
            comp.VerifyDiagnostics(
                // (12,13): error CS8347: Cannot use a result of 'Program.F(Span<int>, Span<int>)' in this context because it may expose variables referenced by parameter 'y' outside of their declaration scope
                //         x = F(x, y switch { Span<int> inner => inner });
                Diagnostic(ErrorCode.ERR_EscapeCall, "F(x, y switch { Span<int> inner => inner })").WithArguments("Program.F(System.Span<int>, System.Span<int>)", "y").WithLocation(12, 13),
                // (12,48): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //         x = F(x, y switch { Span<int> inner => inner });
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(12, 48));
        }
 
        [Fact]
        public void SwitchExpression_Return()
        {
            var source = """
                using System;
                class Program
                {
                    static Span<int> M()
                    {
                        Span<int> outer = stackalloc int[100];
                        return outer switch
                        {
                            Span<int> inner => inner
                        };
                    }
                }
                """;
            var comp = CreateCompilationWithSpan(source);
            comp.VerifyDiagnostics(
                // (9,32): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //             Span<int> inner => inner
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(9, 32));
        }
 
        [Fact]
        public void SwitchExpression_YieldReturn()
        {
            var source = """
                using System;
                using System.Collections.Generic;
                class Program
                {
                    static IEnumerable<int> M()
                    {
                        Span<int> outer = stackalloc int[100];
                        yield return (outer switch
                        {
                            Span<int> inner => inner
                        })[0];
                    }
                }
                """;
            var comp = CreateCompilationWithSpan(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void SwitchExpression_FieldInitializer()
        {
            var source = """
                using System;
                class Program
                {
                    static int F = (new Span<int>() switch
                        {
                            Span<int> inner => inner
                        })[0];
                }
                """;
            var comp = CreateCompilationWithSpan(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void UnsafeContext_LocalFunction_01()
        {
            var source = """
                #pragma warning disable 8321
                class Program
                {
                    static ref int F0(ref int x, ref int y)
                    {
                        return ref x;
                    }
                    static void F1()
                    {
                        static ref int Local1(ref int x1, int y1)
                        {
                            return ref F0(ref x1, ref y1);
                        }
                        unsafe static ref int Local2(ref int x2, int y2)
                        {
                            return ref F0(ref x2, ref y2);
                        }
                        unsafe
                        {
                            static ref int Local3(ref int x3, int y3)
                            {
                                return ref F0(ref x3, ref y3);
                            }
                            unsafe static ref int Local4(ref int x4, int y4)
                            {
                                return ref F0(ref x4, ref y4);
                            }
                        }
                    }
                }
                """;
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll);
            comp.VerifyDiagnostics(
                // (12,24): error CS8347: Cannot use a result of 'Program.F0(ref int, ref int)' in this context because it may expose variables referenced by parameter 'y' outside of their declaration scope
                //             return ref F0(ref x1, ref y1);
                Diagnostic(ErrorCode.ERR_EscapeCall, "F0(ref x1, ref y1)").WithArguments("Program.F0(ref int, ref int)", "y").WithLocation(12, 24),
                // (12,39): error CS8166: Cannot return a parameter by reference 'y1' because it is not a ref parameter
                //             return ref F0(ref x1, ref y1);
                Diagnostic(ErrorCode.ERR_RefReturnParameter, "y1").WithArguments("y1").WithLocation(12, 39),
                // (16,39): warning CS9087: This returns a parameter by reference 'y2' but it is not a ref parameter
                //             return ref F0(ref x2, ref y2);
                Diagnostic(ErrorCode.WRN_RefReturnParameter, "y2").WithArguments("y2").WithLocation(16, 39),
                // (22,43): warning CS9087: This returns a parameter by reference 'y3' but it is not a ref parameter
                //                 return ref F0(ref x3, ref y3);
                Diagnostic(ErrorCode.WRN_RefReturnParameter, "y3").WithArguments("y3").WithLocation(22, 43),
                // (26,43): warning CS9087: This returns a parameter by reference 'y4' but it is not a ref parameter
                //                 return ref F0(ref x4, ref y4);
                Diagnostic(ErrorCode.WRN_RefReturnParameter, "y4").WithArguments("y4").WithLocation(26, 43));
        }
 
        [Fact]
        public void UnsafeContext_LocalFunction_02()
        {
            var source = """
                #pragma warning disable 8321
                class A
                {
                    internal static ref int F0(ref int x, ref int y)
                    {
                        return ref x;
                    }
                }
                class B1 : A
                {
                    unsafe static void F1()
                    {
                        static ref int Local1(ref int x1, int y1)
                        {
                            return ref F0(ref x1, ref y1);
                        }
                }
                unsafe class B2 : A
                {
                    static void F2()
                    {
                        static ref int Local2(ref int x2, int y2)
                        {
                            return ref F0(ref x2, ref y2);
                        }
                    }
                }
                """;
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll);
            comp.VerifyDiagnostics(
                // (15,39): warning CS9087: This returns a parameter by reference 'y1' but it is not a ref parameter
                //             return ref F0(ref x1, ref y1);
                Diagnostic(ErrorCode.WRN_RefReturnParameter, "y1").WithArguments("y1").WithLocation(15, 39),
                // (24,39): warning CS9087: This returns a parameter by reference 'y2' but it is not a ref parameter
                //             return ref F0(ref x2, ref y2);
                Diagnostic(ErrorCode.WRN_RefReturnParameter, "y2").WithArguments("y2").WithLocation(24, 39),
                // (27,2): error CS1513: } expected
                // }
                Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(27, 2));
        }
    }
}