File: Semantics\RefEscapingTests.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.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Semantics
{
    [CompilerTrait(CompilerFeature.ReadOnlyReferences)]
    public class RefEscapingTests : CompilingTestBase
    {
        [Fact]
        public void RefStructSemanticModel()
        {
            var tree = SyntaxFactory.ParseSyntaxTree(@"
using System;
struct S1 { }
ref struct S2 { public S1 F1; }
enum E1 { }
class C<T>
{
    unsafe void M<U>() where U : unmanaged
    {
        Span<int> span = default;
        var s1 = new S1();
        var s2 = new S2();
        var i0 = 0;
        var e1 = new E1();
        var o1 = new object();
        var c1 = new C<int>();
        var t1 = default(T);
        var u1 = default(U);
        void* p1 = null;
        var a1 = new { X = 0 };
        var a2 = new int[1];
        var t2 = (0, 0);
    }
}", options: TestOptions.Regular7_3);
            var comp = CreateCompilationWithSpan(tree, TestOptions.UnsafeDebugDll);
            Assert.True(comp.GetDiagnostics().All(d => d.Severity != DiagnosticSeverity.Error));
            var model = comp.GetSemanticModel(tree);
            var root = tree.GetRoot();
 
            Assert.True(getLocalType("span").IsRefLikeType);
            Assert.False(getLocalType("s1").IsRefLikeType);
            Assert.True(getLocalType("s2").IsRefLikeType);
            Assert.False(getLocalType("i0").IsRefLikeType);
            Assert.False(getLocalType("t1").IsRefLikeType);
            Assert.False(getLocalType("e1").IsRefLikeType);
            Assert.False(getLocalType("o1").IsRefLikeType);
            Assert.False(getLocalType("c1").IsRefLikeType);
            Assert.False(getLocalType("t1").IsRefLikeType);
            Assert.False(getLocalType("u1").IsRefLikeType);
            Assert.False(getLocalType("p1").IsRefLikeType);
            Assert.False(getLocalType("a1").IsRefLikeType);
            Assert.False(getLocalType("a2").IsRefLikeType);
            Assert.False(getLocalType("t2").IsRefLikeType);
 
            ITypeSymbol getLocalType(string name)
            {
                var decl = root.DescendantNodes()
                    .OfType<VariableDeclaratorSyntax>()
                    .Single(n => n.Identifier.ValueText == name);
                return ((ILocalSymbol)model.GetDeclaredSymbol(decl)).Type;
            }
        }
 
        [Fact]
        public void RefStructUsing()
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
class C
{
    void M()
    {
        using (var x = GetRefStruct())
        {
        }
    }
    S2 GetRefStruct() => default;
    ref struct S2
    {
    }
}");
            comp.VerifyDiagnostics(
                // (6,16): error CS1674: 'C.S2': type used in a using statement must be implicitly convertible to 'System.IDisposable'.
                //         using (var x = GetRefStruct())
                Diagnostic(ErrorCode.ERR_NoConvToIDisp, "var x = GetRefStruct()").WithArguments("C.S2").WithLocation(6, 16));
        }
 
        [Fact]
        public void RefStructAnonymous()
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    object M()
    {
        Span<int> outer = new Span<int>(new int[10]);
        Span<int> inner = stackalloc int[10];
 
        return new { Outer = outer, Inner = inner };
    }
}", options: TestOptions.UnsafeDebugDll);
            comp.VerifyDiagnostics(
                // (10,22): error CS0828: Cannot assign 'Span<int>' to anonymous type property
                //         return new { Outer = outer, Inner = inner };
                Diagnostic(ErrorCode.ERR_AnonymousTypePropertyAssignedBadValue, "Outer = outer").WithArguments("System.Span<int>").WithLocation(10, 22),
                // (10,37): error CS0828: Cannot assign 'Span<int>' to anonymous type property
                //         return new { Outer = outer, Inner = inner };
                Diagnostic(ErrorCode.ERR_AnonymousTypePropertyAssignedBadValue, "Inner = inner").WithArguments("System.Span<int>").WithLocation(10, 37));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefStructInFor(LanguageVersion languageVersion)
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    void M()
    {
        Span<int> outer;
        for (Span<int> inner = stackalloc int[10];; inner = outer)
        {
            outer = inner;
        }
    }
}", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics(
                // (10,21): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //             outer = inner;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(10, 21));
        }
 
        [Fact]
        public void RefStructInLock()
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
 
class C
{
    void M()
    {
        Span<int> s = stackalloc int[10];
        lock (s)
        {
        }
    }
}");
            comp.VerifyDiagnostics(
                // (9,15): error CS0185: 'Span<int>' is not a reference type as required by the lock statement
                //         lock (s)
                Diagnostic(ErrorCode.ERR_LockNeedsReference, "s").WithArguments("System.Span<int>").WithLocation(9, 15));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefStructEscapeInIterator(LanguageVersion languageVersion)
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
using System.Collections;
class C
{
    IEnumerable F1()
    {
        Span<int> s1 = stackalloc int[10];
        yield return s1;
    }
    IEnumerable F2()
    {
        Span<int> s2 = default;
        yield return s2;
    }
}", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            // Note: an escape analysis error is not given here because we already gave a conversion error.
            comp.VerifyDiagnostics(
                // (9,22): error CS0029: Cannot implicitly convert type 'System.Span<int>' to 'object'
                //         yield return s1;
                Diagnostic(ErrorCode.ERR_NoImplicitConv, "s1").WithArguments("System.Span<int>", "object").WithLocation(9, 22),
                // (14,22): error CS0029: Cannot implicitly convert type 'System.Span<int>' to 'object'
                //         yield return s2;
                Diagnostic(ErrorCode.ERR_NoImplicitConv, "s2").WithArguments("System.Span<int>", "object").WithLocation(14, 22));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefLikeReturnEscape(LanguageVersion languageVersion)
        {
            var text = @"using System;
 
 
    class Program
    {
        static void Main()
        {
        }
 
        static ref int Test1(S1 arg)
        {
            return ref (new int[1])[0];
        }
 
        static S1 MayWrap(ref Span<int> arg)
        {
            return default;
        }
 
        static ref int Test3()
        {
            Span<int> local = stackalloc int[1];
            return ref Test1(MayWrap(ref local));
        }
 
        ref struct S1
        {
        }
    }
";
            var comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics(
                // (23,42): error CS8526: Cannot use variable 'local' in this context because it may expose referenced variables outside of their declaration scope
                //             return ref Test1(MayWrap(ref local));
                Diagnostic(ErrorCode.ERR_EscapeVariable, "local").WithArguments("local").WithLocation(23, 42),
                // (23,30): error CS8521: Cannot use a result of 'Program.MayWrap(ref Span<int>)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //             return ref Test1(MayWrap(ref local));
                Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(ref local)").WithArguments("Program.MayWrap(ref System.Span<int>)", "arg").WithLocation(23, 30),
                // (23,24): error CS8521: Cannot use a result of 'Program.Test1(Program.S1)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //             return ref Test1(MayWrap(ref local));
                Diagnostic(ErrorCode.ERR_EscapeCall, "Test1(MayWrap(ref local))").WithArguments("Program.Test1(Program.S1)", "arg").WithLocation(23, 24)
            );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefLikeReturnEscape1(LanguageVersion languageVersion)
        {
            var text = @"
    using System;
 
    class Program
    {
        static void Main()
        {
        }
 
        static ref int Test1(S1 arg)
        {
            return ref (new int[1])[0];
        }
 
        static S1 MayWrap(Span<int> arg)
        {
            return default;
        }
 
        static ref int Test3()
        {
            Span<int> local = stackalloc int[1];
            var sp = MayWrap(local);
            return ref Test1(sp);
        }
 
        ref struct S1
        {
        }
    }
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (24,30): error CS8526: Cannot use variable 'sp' in this context because it may expose referenced variables outside of their declaration scope
                //             return ref Test1(sp);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "sp").WithArguments("sp").WithLocation(24, 30),
                // (24,24): error CS8521: Cannot use a result of 'Program.Test1(Program.S1)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //             return ref Test1(sp);
                Diagnostic(ErrorCode.ERR_EscapeCall, "Test1(sp)").WithArguments("Program.Test1(Program.S1)", "arg").WithLocation(24, 24)
            );
        }
 
        [Fact]
        public void RefLikeReturnEscapeWithRefLikes()
        {
            var text = @"
    using System;
    class Program
    {
        static void Main()
        {
        }
 
        static ref int Test1(ref S1 arg)
        {
            return ref (new int[1])[0];
        }
 
        static S1 MayWrap(Span<int> arg)
        {
            return default;
        }
 
        static ref int Test3()
        {
            Span<int> local = stackalloc int[1];
            var sp = MayWrap(local);
            return ref Test1(ref sp);    // error1
        }
 
        static ref int Test4()
        {
            var sp = MayWrap(default);
            return ref Test1(ref sp);    // error2
        }
 
        ref struct S1
        {
        }
    }
";
 
            var comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(
                // (23,34): error CS8168: Cannot return local 'sp' by reference because it is not a ref local
                //             return ref Test1(ref sp);    // error1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "sp").WithArguments("sp").WithLocation(23, 34),
                // (23,24): error CS8347: Cannot use a result of 'Program.Test1(ref Program.S1)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //             return ref Test1(ref sp);    // error1
                Diagnostic(ErrorCode.ERR_EscapeCall, "Test1(ref sp)").WithArguments("Program.Test1(ref Program.S1)", "arg").WithLocation(23, 24),
                // (29,34): error CS8168: Cannot return local 'sp' by reference because it is not a ref local
                //             return ref Test1(ref sp);    // error2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "sp").WithArguments("sp").WithLocation(29, 34),
                // (29,24): error CS8347: Cannot use a result of 'Program.Test1(ref Program.S1)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //             return ref Test1(ref sp);    // error2
                Diagnostic(ErrorCode.ERR_EscapeCall, "Test1(ref sp)").WithArguments("Program.Test1(ref Program.S1)", "arg").WithLocation(29, 24)
                );
 
            comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular11);
            comp.VerifyDiagnostics(
                // (23,34): error CS8352: Cannot use variable 'sp' in this context because it may expose referenced variables outside of their declaration scope
                //             return ref Test1(ref sp);    // error1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "sp").WithArguments("sp").WithLocation(23, 34),
                // (23,24): error CS8347: Cannot use a result of 'Program.Test1(ref Program.S1)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //             return ref Test1(ref sp);    // error1
                Diagnostic(ErrorCode.ERR_EscapeCall, "Test1(ref sp)").WithArguments("Program.Test1(ref Program.S1)", "arg").WithLocation(23, 24),
                // (29,34): error CS8168: Cannot return local 'sp' by reference because it is not a ref local
                //             return ref Test1(ref sp);    // error2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "sp").WithArguments("sp").WithLocation(29, 34),
                // (29,24): error CS8347: Cannot use a result of 'Program.Test1(ref Program.S1)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //             return ref Test1(ref sp);    // error2
                Diagnostic(ErrorCode.ERR_EscapeCall, "Test1(ref sp)").WithArguments("Program.Test1(ref Program.S1)", "arg").WithLocation(29, 24)
                );
        }
 
        [Fact]
        public void RefLikeReturnEscapeWithRefLikes1()
        {
            var text = @"
    using System;
    class Program
    {
        static void Main()
        {
        }
 
        static ref Span<int> Test1(scoped ref S1 arg)
        {
            throw null;
        }
 
        static S1 MayWrap(Span<int> arg)
        {
            return default;
        }
 
        static void Test5()
        {
            var sp = MayWrap(default);
 
            // returnable. 
            var spR = MayWrap(Test1(ref sp));   
 
            Span<int> local = stackalloc int[1];
            var sp1 = MayWrap(local);
 
            // not returnable by value. (since it refers to a local data)
            var spNr = MayWrap(Test1(ref sp1));   
 
            // error
            spR = spNr;
 
            // ok, picks the narrowest val-escape
            var ternary =  true? spR: spNr;
 
            // error
            spR = ternary;
        }
 
        ref struct S1
        {
        }
    }
";
            var comp = CreateCompilationWithMscorlibAndSpan(text);
            comp.VerifyDiagnostics(
                // (33,19): error CS8526: Cannot use variable 'spNr' in this context because it may expose referenced variables outside of their declaration scope
                //             spR = spNr;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "spNr").WithArguments("spNr").WithLocation(33, 19),
                // (39,19): error CS8526: Cannot use variable 'ternary' in this context because it may expose referenced variables outside of their declaration scope
                //             spR = ternary;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "ternary").WithArguments("ternary").WithLocation(39, 19)
            );
        }
 
        [Fact]
        public void RefLikeReturnEscapeInParam()
        {
            var text = @"using System;
 
    class Program
    {
        static void Main()
        {
        }
 
        static ref int Test1(S1 arg)
        {
            return ref (new int[1])[0];
        }
 
        static S1 MayWrap(scoped in Span<int> arg)
        {
            return default;
        }
 
        static ref int Test3()
        {
            Span<int> local = stackalloc int[1];
            var sp = MayWrap(local);
 
            // not an error
            sp = MayWrap(local);
 
            // not an error
            sp = sp;
 
            // error here
            return ref Test1(sp);
        }
 
        ref struct S1
        {
        }
    }
";
            var comp = CreateCompilationWithMscorlibAndSpan(text);
            comp.VerifyDiagnostics(
                // (31,30): error CS8352: Cannot use variable 'sp' in this context because it may expose referenced variables outside of their declaration scope
                //             return ref Test1(sp);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "sp").WithArguments("sp").WithLocation(31, 30),
                // (31,24): error CS8347: Cannot use a result of 'Program.Test1(Program.S1)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //             return ref Test1(sp);
                Diagnostic(ErrorCode.ERR_EscapeCall, "Test1(sp)").WithArguments("Program.Test1(Program.S1)", "arg").WithLocation(31, 24),
                // (28,13): warning CS1717: Assignment made to same variable; did you mean to assign something else?
                //             sp = sp;
                Diagnostic(ErrorCode.WRN_AssignmentToSelf, "sp = sp").WithLocation(28, 13)
            );
        }
 
        [Fact()]
        public void RefLikeReturnEscapeInParamOptional()
        {
            var text = @"
    class Program
    {
        static void Main()
        {
        }
 
        static ref int Test1(S1 arg)
        {
            return ref (new int[1])[0];
        }
 
        static S1 MayNotWrap(in int arg = 123)
        {
            return default;
        }
 
        static ref int Test3()
        {
            // ok
            return ref Test1(MayNotWrap());
        }
 
        ref struct S1
        {
        }
    }
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular10).VerifyDiagnostics();
 
            // 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, including in arguments and default values.
            CreateCompilationWithMscorlibAndSpan(text).VerifyDiagnostics(
                // (21,24): error CS8347: Cannot use a result of 'Program.Test1(Program.S1)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //             return ref Test1(MayNotWrap());
                Diagnostic(ErrorCode.ERR_EscapeCall, "Test1(MayNotWrap())").WithArguments("Program.Test1(Program.S1)", "arg").WithLocation(21, 24),
                // (21,30): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                //             return ref Test1(MayNotWrap());
                Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "MayNotWrap()").WithLocation(21, 30),
                // (21,30): error CS8347: Cannot use a result of 'Program.MayNotWrap(in int)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //             return ref Test1(MayNotWrap());
                Diagnostic(ErrorCode.ERR_EscapeCall, "MayNotWrap()").WithArguments("Program.MayNotWrap(in int)", "arg").WithLocation(21, 30));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefLikeScopeEscape(LanguageVersion languageVersion)
        {
            var text = @"
    using System;
    class Program
    {
        static void Main()
        {
            Span<int> outer = default;
 
            S1 x = MayWrap(outer);
 
            {
                 Span<int> inner = stackalloc int[1];
 
                // valid
                x = MayWrap(outer);
    
                // error
                x = MayWrap(inner);
            }
        }
 
        static S1 MayWrap(Span<int> arg)
        {
            return default;
        }
 
        ref struct S1
        {
        }
    }
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (18,29): error CS8526: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //                 x = MayWrap(inner);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(18, 29),
                // (18,21): error CS8521: Cannot use a result of 'Program.MayWrap(Span<int>)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //                 x = MayWrap(inner);
                Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(inner)").WithArguments("Program.MayWrap(System.Span<int>)", "arg").WithLocation(18, 21)
            );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefLikeScopeEscapeVararg(LanguageVersion languageVersion)
        {
            var text = @"
using System;
class Program
{
    static void Main()
    {
        Span<int> outer = default;
 
        S1 x = MayWrap(__arglist(outer));
 
        {
            Span<int> inner = stackalloc int[1];
 
            // valid
            x = MayWrap(__arglist(outer));
 
            // error
            x = MayWrap(__arglist(inner));
        }
    }
 
    static S1 MayWrap(__arglist)
    {
        return default;
    }
 
    ref struct S1
    {
    }
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (18,35): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //             x = MayWrap(__arglist(inner));
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(18, 35),
                // (18,17): error CS8347: Cannot use a result of 'Program.MayWrap(__arglist)' in this context because it may expose variables referenced by parameter '__arglist' outside of their declaration scope
                //             x = MayWrap(__arglist(inner));
                Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(__arglist(inner))").WithArguments("Program.MayWrap(__arglist)", "__arglist").WithLocation(18, 17)
            );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefScopeEscapeVararg(LanguageVersion languageVersion)
        {
            var text = @"
using System;
class Program
{
    static void Main()
    {
 
    }    
 
    static ref int ReturnsRef()
    {
        int local = 42;
 
        // OK (also in 7.0)
        // __refvalue is not ref-returnable, so ref varargs can't come back
        return ref ReturnsRef1(__arglist(ref local));
    }
 
    static ref int ReturnsRef1(__arglist)
    {
        var ai = new ArgIterator(__arglist);
 
        // ERROR here. __refvalue is not ref-returnable
        return ref __refvalue(ai.GetNextArg(), int);
    }
 
    static ref int ReturnsRefSpan()
    {
        Span<int> local = stackalloc int[1];
        
        // error here;
        return ref ReturnsRefSpan1(__arglist(ref local));
    }
 
    static ref int ReturnsRefSpan1(__arglist)
    {
        var ai = new ArgIterator(__arglist);
 
        // this is ok
        return ref __refvalue(ai.GetNextArg(), Span<int>)[0];
    }
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (24,20): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                //         return ref __refvalue(ai.GetNextArg(), int);
                Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "__refvalue(ai.GetNextArg(), int)").WithLocation(24, 20),
                // (32,50): error CS8352: Cannot use variable 'local' in this context because it may expose referenced variables outside of their declaration scope
                //         return ref ReturnsRefSpan1(__arglist(ref local));
                Diagnostic(ErrorCode.ERR_EscapeVariable, "local").WithArguments("local").WithLocation(32, 50),
                // (32,20): error CS8347: Cannot use a result of 'Program.ReturnsRefSpan1(__arglist)' in this context because it may expose variables referenced by parameter '__arglist' outside of their declaration scope
                //         return ref ReturnsRefSpan1(__arglist(ref local));
                Diagnostic(ErrorCode.ERR_EscapeCall, "ReturnsRefSpan1(__arglist(ref local))").WithArguments("Program.ReturnsRefSpan1(__arglist)", "__arglist").WithLocation(32, 20)
            );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void ThrowExpression(LanguageVersion languageVersion)
        {
            var text = @"
using System;
class Program
{
    static void Main()
    {
 
    }    
 
    static ref int M1() => throw null;
 
    static ref readonly int M2() => throw null;
 
    static ref Span<int> M3() => throw null;
 
    static ref readonly Span<int> M4() => throw null;
 
    static Span<int> M5() => throw null;
 
    static Span<int> M6() => M5().Length !=0 ? M5() : throw null;
 
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics();
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void UserDefinedLogical(LanguageVersion languageVersion)
        {
            var text = @"
using System;
class Program
{
    static void Main()
    {
    }
 
    S1 Test()
    {
        S1 global = default;
        S1 local = stackalloc int[100];
 
        // ok
        local = global && local;
        local = local && local;
 
        // ok
        global = global && global;
 
        // error
        global = local && global;
 
        // error
        return global || local;
    }
}
 
ref struct S1
{
    public static implicit operator S1(Span<int> o) => default;
 
    public static bool operator true(S1 o) => true;
    public static bool operator false(S1 o) => false;
 
    public static S1 operator &(S1 x, S1 y) => x;
    public static S1 operator |(S1 x, S1 y) => x;
}
 
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (22,18): error CS8352: Cannot use variable 'local' in this context because it may expose referenced variables outside of their declaration scope
                //         global = local && global;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "local").WithArguments("local").WithLocation(22, 18),
                // (25,26): error CS8352: Cannot use variable 'local' in this context because it may expose referenced variables outside of their declaration scope
                //         return global || local;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "local").WithArguments("local").WithLocation(25, 26)
             );
        }
 
        [Fact()]
        public void DiscardExpressionRef()
        {
            var text = @"
 
class Program
{
    static void Main()
    {
 
    }
 
    static ref int ReturnsRefTest()
    {
        return ref ReturnsRef1(out var _);
    }
 
    static ref int ReturnsRef1(out int x)
    {
        x = 42;
        return ref x;
    }
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular10).VerifyDiagnostics(
                // (12,36): error CS8156: An expression cannot be used in this context because it may not be returned by reference
                //         return ref ReturnsRef1(out var _);
                Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "var _").WithLocation(12, 36),
                // (12,20): error CS8347: Cannot use a result of 'Program.ReturnsRef1(out int)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //         return ref ReturnsRef1(out var _);
                Diagnostic(ErrorCode.ERR_EscapeCall, "ReturnsRef1(out var _)").WithArguments("Program.ReturnsRef1(out int)", "x").WithLocation(12, 20)
                );
            CreateCompilationWithMscorlibAndSpan(text).VerifyDiagnostics(
                // (18,20): error CS9075: Cannot return a parameter by reference 'x' because it is scoped to the current method
                //         return ref x;
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "x").WithArguments("x").WithLocation(18, 20)
                );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DiscardExpressionRef_UnsafeContext(LanguageVersion languageVersion)
        {
            var text = @"
 
unsafe class Program
{
    static ref int ReturnsRefTest()
    {
        return ref ReturnsRef1(out var _);
    }
 
    static ref int ReturnsRef1(out int x)
    {
        x = 42;
        return ref x;
    }
}
";
            var comp = CreateCompilationWithMscorlibAndSpan(text, options: TestOptions.UnsafeDebugDll, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            if (languageVersion == LanguageVersion.CSharp10)
            {
                comp.VerifyDiagnostics(
                    // (7,20): error CS8347: Cannot use a result of 'Program.ReturnsRef1(out int)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                    //         return ref ReturnsRef1(out var _);
                    Diagnostic(ErrorCode.ERR_EscapeCall, "ReturnsRef1(out var _)").WithArguments("Program.ReturnsRef1(out int)", "x").WithLocation(7, 20),
                    // (7,36): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                    //         return ref ReturnsRef1(out var _);
                    Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "var _").WithLocation(7, 36));
            }
            else
            {
                comp.VerifyDiagnostics(
                    // (13,20): warning CS9085: This returns a parameter by reference 'x' but it is scoped to the current method
                    //         return ref x;
                    Diagnostic(ErrorCode.WRN_RefReturnScopedParameter, "x").WithArguments("x").WithLocation(13, 20));
            }
        }
 
        [Fact()]
        public void OrdinaryLocalAndOutRef()
        {
            var text = @"
 
class Program
{
    static void Main()
    {
 
    }
 
    static ref int ReturnsRefTest1()
    {       
        return ref ReturnsRef(out var z);
    }
 
    static ref int ReturnsRefTest2()
    {   int z;
        return ref ReturnsRef(out z);
    }
 
 
    static ref int ReturnsRef(out int x)
    {
        x = 42;
        return ref x;
    }
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular10).VerifyDiagnostics(
                // (12,35): error CS8168: Cannot return local 'z' by reference because it is not a ref local
                //         return ref ReturnsRef(out var z);
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "var z").WithArguments("z").WithLocation(12, 35),
                // (12,20): error CS8347: Cannot use a result of 'Program.ReturnsRef(out int)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //         return ref ReturnsRef(out var z);
                Diagnostic(ErrorCode.ERR_EscapeCall, "ReturnsRef(out var z)").WithArguments("Program.ReturnsRef(out int)", "x").WithLocation(12, 20),
                // (17,35): error CS8168: Cannot return local 'z' by reference because it is not a ref local
                //         return ref ReturnsRef(out z);
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "z").WithArguments("z").WithLocation(17, 35),
                // (17,20): error CS8347: Cannot use a result of 'Program.ReturnsRef(out int)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //         return ref ReturnsRef(out z);
                Diagnostic(ErrorCode.ERR_EscapeCall, "ReturnsRef(out z)").WithArguments("Program.ReturnsRef(out int)", "x").WithLocation(17, 20)
                );
            CreateCompilationWithMscorlibAndSpan(text).VerifyDiagnostics(
                // (24,20): error CS9075: Cannot return a parameter by reference 'x' because it is scoped to the current method
                //         return ref x;
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "x").WithArguments("x").WithLocation(24, 20)
                );
        }
 
        [Fact]
        public void DiscardExpressionSpan_01()
        {
            var text = @"
using System;
class Program
{
    static void Main()
    {
 
    }
 
    static Span<int> Test1()
    {
        var s = ReturnsSpan(out var _);
 
        // ok
        return s;
    }
 
    static Span<int> Test2()
    {
        ref var s = ref ReturnsSpan(out var _);
 
        // error
        s = stackalloc int[1]; // 1
 
        // ok
        return s;
    }
 
    static void Test3()
    {
        // error
        ReturnsSpan(out var _ ) = stackalloc int[1]; // 2
    }
 
    static ref Span<int> ReturnsSpan(out Span<int> x)
    {
        x = default;
        return ref x; // 3
    }
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular10).VerifyDiagnostics(
                // (23,13): 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
                //         s = stackalloc int[1]; // 1
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(23, 13),
                // (32,35): 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
                //         ReturnsSpan(out var _ ) = stackalloc int[1]; // 2
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(32, 35)
                );
            CreateCompilationWithMscorlibAndSpan(text).VerifyDiagnostics(
                // (23,13): 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
                //         s = stackalloc int[1]; // 1
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(23, 13),
                // (32,35): 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
                //         ReturnsSpan(out var _ ) = stackalloc int[1]; // 2
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(32, 35),
                // (38,20): error CS9075: Cannot return a parameter by reference 'x' because it is scoped to the current method
                //         return ref x; // 3
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "x").WithArguments("x").WithLocation(38, 20)
                );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DiscardExpressionSpan_UnsafeContext(LanguageVersion languageVersion)
        {
            var text = @"
using System;
unsafe class Program
{
    static Span<int> Test1()
    {
        var s = ReturnsSpan(out var _);
        return s;
    }
 
    static Span<int> Test2()
    {
        ref var s = ref ReturnsSpan(out var _);
        s = stackalloc int[1]; // 1
        return s;
    }
 
    static void Test3()
    {
        ReturnsSpan(out var _ ) = stackalloc int[1]; // 2
    }
 
    static ref Span<int> ReturnsSpan(out Span<int> x)
    {
        x = default;
        return ref x; // 3
    }
}
";
            var comp = CreateCompilationWithMscorlibAndSpan(text, options: TestOptions.UnsafeDebugDll, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            if (languageVersion == LanguageVersion.CSharp10)
            {
                comp.VerifyDiagnostics(
                    // (14,13): warning CS9081: A result of a stackalloc expression of type 'Span<int>' in this context may be exposed outside of the containing method
                    //         s = stackalloc int[1]; // 1
                    Diagnostic(ErrorCode.WRN_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(14, 13),
                    // (20,35): warning CS9081: A result of a stackalloc expression of type 'Span<int>' in this context may be exposed outside of the containing method
                    //         ReturnsSpan(out var _ ) = stackalloc int[1]; // 2
                    Diagnostic(ErrorCode.WRN_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(20, 35));
            }
            else
            {
                comp.VerifyDiagnostics(
                    // (14,13): warning CS9078: A result of a stackalloc expression of type 'Span<int>' in this context may be exposed outside of the containing method
                    //         s = stackalloc int[1]; // 1
                    Diagnostic(ErrorCode.WRN_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(14, 13),
                    // (20,35): warning CS9078: A result of a stackalloc expression of type 'Span<int>' in this context may be exposed outside of the containing method
                    //         ReturnsSpan(out var _ ) = stackalloc int[1]; // 2
                    Diagnostic(ErrorCode.WRN_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(20, 35),
                    // (26,20): warning CS9085: This returns a parameter by reference 'x' but it is scoped to the current method
                    //         return ref x; // 3
                    Diagnostic(ErrorCode.WRN_RefReturnScopedParameter, "x").WithArguments("x").WithLocation(26, 20)
                    );
            }
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped);
            verifier.VerifyIL("Program.Test2", @"
{
  // Code size       38 (0x26)
  .maxstack  2
  .locals init (System.Span<int>& V_0, //s
                System.Span<int> V_1,
                System.Span<int> V_2,
                System.Span<int> V_3)
  IL_0000:  nop
  IL_0001:  ldloca.s   V_1
  IL_0003:  call       ""ref System.Span<int> Program.ReturnsSpan(out System.Span<int>)""
  IL_0008:  stloc.0
  IL_0009:  ldc.i4.4
  IL_000a:  conv.u
  IL_000b:  localloc
  IL_000d:  ldc.i4.1
  IL_000e:  newobj     ""System.Span<int>..ctor(void*, int)""
  IL_0013:  stloc.2
  IL_0014:  ldloc.0
  IL_0015:  ldloc.2
  IL_0016:  stobj      ""System.Span<int>""
  IL_001b:  ldloc.0
  IL_001c:  ldobj      ""System.Span<int>""
  IL_0021:  stloc.3
  IL_0022:  br.s       IL_0024
  IL_0024:  ldloc.3
  IL_0025:  ret
}
");
            verifier.VerifyIL("Program.Test3", @"
{
  // Code size       28 (0x1c)
  .maxstack  2
  .locals init (System.Span<int> V_0,
                System.Span<int>& V_1,
                System.Span<int> V_2)
  IL_0000:  nop
  IL_0001:  ldloca.s   V_0
  IL_0003:  call       ""ref System.Span<int> Program.ReturnsSpan(out System.Span<int>)""
  IL_0008:  stloc.1
  IL_0009:  ldc.i4.4
  IL_000a:  conv.u
  IL_000b:  localloc
  IL_000d:  ldc.i4.1
  IL_000e:  newobj     ""System.Span<int>..ctor(void*, int)""
  IL_0013:  stloc.2
  IL_0014:  ldloc.1
  IL_0015:  ldloc.2
  IL_0016:  stobj      ""System.Span<int>""
  IL_001b:  ret
}
");
        }
 
        // As above with 'out _' instead of 'out var _'.
        [WorkItem(65651, "https://github.com/dotnet/roslyn/issues/65651")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DiscardExpressionSpan_02(LanguageVersion languageVersion)
        {
            string source = """
                using System;
                class Program
                {
                    static Span<int> Test2A()
                    {
                        ref var s2A = ref ReturnsSpan(out _);
                        s2A = stackalloc int[1]; // 1
                        return s2A;
                    }
                    static Span<int> Test2B()
                    {
                        Span<int> _;
                        ref var s2B = ref ReturnsSpan(out _);
                        s2B = stackalloc int[1]; // 2
                        return s2B;
                    }
                    static void Test3A()
                    {
                        ReturnsSpan(out _ ) = stackalloc int[1]; // 3
                    }
                    static void Test3B()
                    {
                        Span<int> _;
                        ReturnsSpan(out _ ) = stackalloc int[1]; // 4
                    }
                    static ref Span<int> ReturnsSpan(out Span<int> x)
                    {
                        throw null;
                    }
                }
                """;
            var comp = CreateCompilationWithMscorlibAndSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics(
                // (7,15): 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
                //         s2A = stackalloc int[1]; // 1
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(7, 15),
                // (14,15): 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
                //         s2B = stackalloc int[1]; // 2
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(14, 15),
                // (19,31): 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
                //         ReturnsSpan(out _ ) = stackalloc int[1]; // 3
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(19, 31),
                // (24,31): 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
                //         ReturnsSpan(out _ ) = stackalloc int[1]; // 4
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(24, 31));
        }
 
        // ReturnsSpan() returns ref Span<int>, callers return Span<int> by value.
        [WorkItem(65651, "https://github.com/dotnet/roslyn/issues/65651")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DiscardExpressionSpan_03(LanguageVersion languageVersion)
        {
            string source = """
                using System;
                class Program
                {
                    static Span<int> Test1()
                    {
                        var s1 = ReturnsSpan(out _);
                        return s1;
                    }
                    static Span<int> Test2()
                    {
                        var s2 = ReturnsSpan(out var _);
                        return s2;
                    }
                    static Span<int> Test3()
                    {
                        var s3 = ReturnsSpan(out Span<int> _);
                        return s3;
                    }
                    static Span<int> Test4()
                    {
                        var s4 = ReturnsSpan(out var unused);
                        return s4;
                    }
                    static Span<int> Test5()
                    {
                        Span<int> _;
                        var s5 = ReturnsSpan(out _);
                        return s5;
                    }
                    static Span<int> Test6(out Span<int> _)
                    {
                        var s6 = ReturnsSpan(out _);
                        return s6;
                    }
                    static ref Span<int> ReturnsSpan(out Span<int> x)
                    {
                        throw null;
                    }
                }
                """;
            var comp = CreateCompilationWithMscorlibAndSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics();
        }
 
        // ReturnsSpan() and callers return Span<int> by value.
        [WorkItem(65651, "https://github.com/dotnet/roslyn/issues/65651")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DiscardExpressionSpan_04(LanguageVersion languageVersion)
        {
            string source = """
                using System;
                class Program
                {
                    static Span<int> Test1()
                    {
                        var s1 = ReturnsSpan(out _);
                        return s1;
                    }
                    static Span<int> Test2()
                    {
                        var s2 = ReturnsSpan(out var _);
                        return s2;
                    }
                    static Span<int> Test3()
                    {
                        var s3 = ReturnsSpan(out Span<int> _);
                        return s3;
                    }
                    static Span<int> Test4()
                    {
                        var s4 = ReturnsSpan(out var unused);
                        return s4;
                    }
                    static Span<int> Test5()
                    {
                        Span<int> _;
                        var s5 = ReturnsSpan(out _);
                        return s5;
                    }
                    static Span<int> Test6(out Span<int> _)
                    {
                        var s6 = ReturnsSpan(out _);
                        return s6;
                    }
                    static Span<int> ReturnsSpan(out Span<int> x)
                    {
                        x = default;
                        return x;
                    }
                }
                """;
            var comp = CreateCompilationWithMscorlibAndSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics();
        }
 
        // ReturnsSpan() and callers return ref Span<int>.
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DiscardExpressionSpan_05(LanguageVersion languageVersion)
        {
            string source = """
                using System;
                class Program
                {
                    static ref Span<int> Test1()
                    {
                        var s1 = ReturnsSpan(out _);
                        return ref s1; // 1
                    }
                    static ref Span<int> Test2()
                    {
                        var s2 = ReturnsSpan(out var _);
                        return ref s2; // 2
                    }
                    static ref Span<int> Test3()
                    {
                        var s3 = ReturnsSpan(out Span<int> _);
                        return ref s3; // 3
                    }
                    static ref Span<int> Test4()
                    {
                        var s4 = ReturnsSpan(out var unused);
                        return ref s4; // 4
                    }
                    static ref Span<int> Test5()
                    {
                        Span<int> _;
                        var s5 = ReturnsSpan(out _);
                        return ref s5; // 5
                    }
                    static ref Span<int> Test6(out Span<int> _)
                    {
                        var s6 = ReturnsSpan(out _);
                        return ref s6; // 6
                    }
                    static ref Span<int> ReturnsSpan(out Span<int> x)
                    {
                        throw null;
                    }
                }
                """;
            var comp = CreateCompilationWithMscorlibAndSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics(
                // (7,20): error CS8168: Cannot return local 's1' by reference because it is not a ref local
                //         return ref s1; // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "s1").WithArguments("s1").WithLocation(7, 20),
                // (12,20): error CS8168: Cannot return local 's2' by reference because it is not a ref local
                //         return ref s2; // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "s2").WithArguments("s2").WithLocation(12, 20),
                // (17,20): error CS8168: Cannot return local 's3' by reference because it is not a ref local
                //         return ref s3; // 3
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "s3").WithArguments("s3").WithLocation(17, 20),
                // (22,20): error CS8168: Cannot return local 's4' by reference because it is not a ref local
                //         return ref s4; // 4
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "s4").WithArguments("s4").WithLocation(22, 20),
                // (28,20): error CS8168: Cannot return local 's5' by reference because it is not a ref local
                //         return ref s5; // 5
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "s5").WithArguments("s5").WithLocation(28, 20),
                // (33,20): error CS8168: Cannot return local 's6' by reference because it is not a ref local
                //         return ref s6; // 6
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "s6").WithArguments("s6").WithLocation(33, 20));
        }
 
        // ReturnsSpan() and callers return ref int.
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DiscardExpressionSpan_06(LanguageVersion languageVersion)
        {
            string source = """
                class Program
                {
                    static ref int Test1()
                    {
                        var s1 = ReturnsSpan(out _);
                        return ref s1; // 1
                    }
                    static ref int Test2()
                    {
                        var s2 = ReturnsSpan(out var _);
                        return ref s2; // 2
                    }
                    static ref int Test3()
                    {
                        var s3 = ReturnsSpan(out int _);
                        return ref s3; // 3
                    }
                    static ref int Test4()
                    {
                        var s4 = ReturnsSpan(out var unused);
                        return ref s4; // 4
                    }
                    static ref int Test5()
                    {
                        int _;
                        var s5 = ReturnsSpan(out _);
                        return ref s5; // 5
                    }
                    static ref int Test6(out int _)
                    {
                        var s6 = ReturnsSpan(out _);
                        return ref s6; // 6
                    }
                    static ref int ReturnsSpan(out int x)
                    {
                        throw null;
                    }
                }
                """;
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics(
                // (6,20): error CS8168: Cannot return local 's1' by reference because it is not a ref local
                //         return ref s1; // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "s1").WithArguments("s1").WithLocation(6, 20),
                // (11,20): error CS8168: Cannot return local 's2' by reference because it is not a ref local
                //         return ref s2; // 2
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "s2").WithArguments("s2").WithLocation(11, 20),
                // (16,20): error CS8168: Cannot return local 's3' by reference because it is not a ref local
                //         return ref s3; // 3
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "s3").WithArguments("s3").WithLocation(16, 20),
                // (21,20): error CS8168: Cannot return local 's4' by reference because it is not a ref local
                //         return ref s4; // 4
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "s4").WithArguments("s4").WithLocation(21, 20),
                // (27,20): error CS8168: Cannot return local 's5' by reference because it is not a ref local
                //         return ref s5; // 5
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "s5").WithArguments("s5").WithLocation(27, 20),
                // (32,20): error CS8168: Cannot return local 's6' by reference because it is not a ref local
                //         return ref s6; // 6
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "s6").WithArguments("s6").WithLocation(32, 20));
        }
 
        [Theory]
        [InlineData("out var _")]
        [InlineData("out _")]
        [InlineData("out Span<int> _")]
        [InlineData("out var unused")]
        [InlineData("out Span<int> unused")]
        public void DiscardExpressionSpan_07(string outVarDeclaration)
        {
            string source = $$"""
                using System;
                using System.Diagnostics.CodeAnalysis;
                class Program
                {
                    static Span<int> Test1()
                    {
                        var s1 = ReturnsSpan({{outVarDeclaration}});
                        return s1;
                    }
                    static Span<int> Test2()
                    {
                        ref var s2 = ref ReturnsSpan({{outVarDeclaration}});
                        s2 = stackalloc int[1]; // 1
                        return s2;
                    }
                    static void Test3()
                    {
                        ReturnsSpan({{outVarDeclaration}}) =
                            stackalloc int[1]; // 2
                    }
                    static ref Span<int> ReturnsSpan([UnscopedRef] out Span<int> x)
                    {
                        x = default;
                        return ref x;
                    }
                }
                """;
            var comp = CreateCompilationWithMscorlibAndSpan(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (13,14): 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
                //         s2 = stackalloc int[1]; // 1
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(13, 14),
                // (19,13): 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
                //             stackalloc int[1]; // 2
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(19, 13));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Discard_01(LanguageVersion languageVersion)
        {
            string source = """
                using System;
                class Program
                {
                    static void F1()
                    {
                        Span<int> s1 = stackalloc int[1];
                        _ = s1;
                    }
                    static void F2()
                    {
                        Span<int> s2 = stackalloc int[1];
                        Span<int> _;
                        _ = s2; // 1
                    }
                }
                """;
            var comp = CreateCompilationWithMscorlibAndSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics(
                // (13,13): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                //         _ = s2; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(13, 13));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Discard_02(LanguageVersion languageVersion)
        {
            string source = """
                class Program
                {
                    static void F1(ref int x1)
                    {
                        int y1 = 1;
                        _ = ref y1;
                        _ = ref x1;
                    }
                    static void F2(ref int x2)
                    {
                        int y2 = 2;
                        _ = ref x2;
                        _ = ref y2;
                    }
                    static void F3()
                    {
                        int y3 = 3;
                        ref int _ = ref y3;
                        _ = ref y3;
                    }
                    static void F4(ref int x4)
                    {
                        int y4 = 4;
                        ref int _ = ref x4;
                        _ = ref y4; // 1
                    }
                }
                """;
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics(
                // (25,9): error CS8374: Cannot ref-assign 'y4' to '_' because 'y4' has a narrower escape scope than '_'.
                //         _ = ref y4; // 1
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "_ = ref y4").WithArguments("_", "y4").WithLocation(25, 9));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Discard_03(LanguageVersion languageVersion)
        {
            var source =
@"class Program
{
    static void F1()
    {
        (var x1, _) = F();
        (var x2, var _) = F();
        (var x3, R _) = F();
        var (x4, _) = F();
    }
    static void F2()
    {
        R _;
        (var x5, _) = F();
    }
    static R F() => default;
}
ref struct R 
{
    public void Deconstruct(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 Discard_04(LanguageVersion languageVersion)
        {
            var source =
@"using System;
class Program
{
    static void F1()
    {
        Span<int> s1 = default;
        s1.Deconstruct(out s1, out _);
    }
    static void F2()
    {
        Span<int> s2 = default;
        (s2, _) = s2;
    }
    static void F3()
    {
        Span<int> s3 = default;
        s3.Deconstruct(out s3, out var _);
    }
    static void F4()
    {
        Span<int> s4 = default;
        (s4, var _) = s4;
    }
    static void F5()
    {
        Span<int> s5 = default;
        s5.Deconstruct(out s5, out Span<int> _);
    }
    static void F6()
    {
        Span<int> s6 = default;
        (s6, Span<int> _) = s6;
    }
    static void F7()
    {
        Span<int> s7 = default;
        s7.Deconstruct(out s7, out var unused);
    }
    static void F8()
    {
        Span<int> s8 = default;
        (s8, var unused) = s8;
    }
}
static class Extensions
{
    public static void Deconstruct(this Span<int> self, out Span<int> x, out Span<int> y)
    {
        throw null;
    }
}
";
            var comp = CreateCompilationWithMscorlibAndSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics();
        }
 
        [WorkItem(65522, "https://github.com/dotnet/roslyn/issues/65522")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void Discard_05(LanguageVersion languageVersion)
        {
            var source =
@"using System;
class Program
{
    static void F1()
    {
        Span<int> s1 = stackalloc int[10];
        s1.Deconstruct(out s1, out _);
    }
    static void F2()
    {
        Span<int> s2 = stackalloc int[10];
        (s2, _) = s2;
    }
    static void F3()
    {
        Span<int> s3 = stackalloc int[10];
        s3.Deconstruct(out s3, out var _);
    }
    static void F4()
    {
        Span<int> s4 = stackalloc int[10];
        (s4, var _) = s4;
    }
    static void F5()
    {
        Span<int> s5 = stackalloc int[10];
        s5.Deconstruct(out s5, out Span<int> _);
    }
    static void F6()
    {
        Span<int> s6 = stackalloc int[10];
        (s6, Span<int> _) = s6;
    }
    static void F7()
    {
        Span<int> s7 = stackalloc int[10];
        s7.Deconstruct(out s7, out var unused);
    }
    static void F8()
    {
        Span<int> s8 = stackalloc int[10];
        (s8, var unused) = s8;
    }
}
static class Extensions
{
    public static void Deconstruct(this Span<int> self, out Span<int> x, out Span<int> y)
    {
        throw null;
    }
}
";
            var comp = CreateCompilationWithMscorlibAndSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics();
        }
 
        [Fact()]
        public void OrdinaryLocalAndOutSpan()
        {
            var text = @"
using System;
class Program
{
    static void Main()
    {
 
    }
 
    static Span<int> Test1()
    {
        var s = ReturnsSpan(out var z);
 
        // ok
        return s;
    }
 
    static Span<int> Test2()
    {
        ref var r = ref ReturnsSpan(out var z);
 
        // error
        r = stackalloc int[1];
 
        // ok
        return r;
    }
 
    static void Test3()
    {
        ReturnsSpan(out var z) = stackalloc int[1];
    }
 
    static Span<int> Test4()
    {
        Span<int> s;
        var r = ReturnsSpan(out s);
 
        // ok
        return r;
    }
 
    static Span<int> Test5()
    {
        Span<int> s;
        ref var r = ref ReturnsSpan(out s);
 
        // error
        r = stackalloc int[1];
 
        // ok
        return r;
    }
 
    static void Test6()
    {
        Span<int> s;
 
        // error
        ReturnsSpan(out s) = stackalloc int[1];
    }
 
    static ref Span<int> ReturnsSpan(out Span<int> x)
    {
        x = default;
        return ref x;
    }
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular10).VerifyDiagnostics(
                // (23,13): 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
                //         r = stackalloc int[1];
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(23, 13),
                // (31,34): 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
                //         ReturnsSpan(out var z) = stackalloc int[1];
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(31, 34),
                // (49,13): 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
                //         r = stackalloc int[1];
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(49, 13),
                // (60,30): 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
                //         ReturnsSpan(out s) = stackalloc int[1];
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(60, 30)
                );
            CreateCompilationWithMscorlibAndSpan(text).VerifyDiagnostics(
                // (23,13): 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
                //         r = stackalloc int[1];
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(23, 13),
                // (31,34): 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
                //         ReturnsSpan(out var z) = stackalloc int[1];
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(31, 34),
                // (49,13): 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
                //         r = stackalloc int[1];
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(49, 13),
                // (60,30): 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
                //         ReturnsSpan(out s) = stackalloc int[1];
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[1]").WithArguments("System.Span<int>").WithLocation(60, 30),
                // (66,20): error CS9075: Cannot return a parameter by reference 'x' because it is scoped to the current method
                //         return ref x;
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "x").WithArguments("x").WithLocation(66, 20)
                );
        }
 
        [Fact]
        public void RefLikeScopeEscapeReturnable()
        {
            var text = @"
    using System;
    class Program
    {
        static void Main()
        {
            Span<int> outer = default;
 
            // make x returnable
            S1 x = default;
 
            {
                Span<int> inner = stackalloc int[0];
 
                // valid
                x = MayWrap(ref outer);
    
                // error
                x = MayWrap(ref inner);
            }
        }
 
        static S1 MayWrap(ref Span<int> arg)
        {
            return default;
        }
 
        ref struct S1
        {
        }
    }
";
            var comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(
                // (19,33): error CS8526: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //                 x = MayWrap(ref inner);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(19, 33),
                // (19,21): error CS8521: Cannot use a result of 'Program.MayWrap(ref Span<int>)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //                 x = MayWrap(ref inner);
                Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(ref inner)").WithArguments("Program.MayWrap(ref System.Span<int>)", "arg").WithLocation(19, 21)
            );
 
            comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular11);
            comp.VerifyDiagnostics(
                // (16,33): error CS8168: Cannot return local 'outer' by reference because it is not a ref local
                //                 x = MayWrap(ref outer);
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "outer").WithArguments("outer").WithLocation(16, 33),
                // (16,21): error CS8347: Cannot use a result of 'Program.MayWrap(ref Span<int>)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //                 x = MayWrap(ref outer);
                Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(ref outer)").WithArguments("Program.MayWrap(ref System.Span<int>)", "arg").WithLocation(16, 21),
                // (19,33): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //                 x = MayWrap(ref inner);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(19, 33),
                // (19,21): error CS8347: Cannot use a result of 'Program.MayWrap(ref Span<int>)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //                 x = MayWrap(ref inner);
                Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(ref inner)").WithArguments("Program.MayWrap(ref System.Span<int>)", "arg").WithLocation(19, 21)
            );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefLikeScopeEscapeThis(LanguageVersion languageVersion)
        {
            var text = @"
    using System;
    class Program
    {
        static void Main()
        {
            Span<int> outer = default;
 
            S1 x = MayWrap(ref outer);
 
            {
                Span<int> inner = stackalloc int[1];
 
                // valid
                x = S1.NotSlice(1);
 
                // valid
                x = MayWrap(ref outer).Slice(1);
    
                // error
                x = MayWrap(ref inner).Slice(1);
            }
        }
 
        static S1 MayWrap(ref Span<int> arg)
        {
            return default;
        }
 
        ref struct S1
        {
            public static S1 NotSlice(int x) => default;
 
            public S1 Slice(int x) => this;
        }
    }
";
            var comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics(
                // (21,33): error CS8526: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //                 x = MayWrap(ref inner).Slice(1);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(21, 33),
                // (21,21): error CS8521: Cannot use a result of 'Program.MayWrap(ref Span<int>)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //                 x = MayWrap(ref inner).Slice(1);
                Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(ref inner)").WithArguments("Program.MayWrap(ref System.Span<int>)", "arg").WithLocation(21, 21)
            );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefLikeScopeEscapeThisRef(LanguageVersion languageVersion)
        {
            var text = @"
using System;
class Program
{
    static void Main()
    {
        Span<int> outer = default;
 
        ref S1 x = ref MayWrap(ref outer)[0];
 
        {
            Span<int> inner = stackalloc int[1];
 
            // valid
            x[0] = MayWrap(ref outer).Slice(1)[0];
 
            // error, technically rules for this case can be relaxed, 
            // but ref-like typed ref-returning properties are nearly impossible to implement in a useful way
            //
            x[0] = MayWrap(ref inner).Slice(1)[0];
 
            // error, technically rules for this case can be relaxed, 
            // but ref-like typed ref-returning properties are nearly impossible to implement in a useful way
            //
            x[x] = MayWrap(ref inner).Slice(1)[0];
 
            // error
            x.ReturnsRefArg(ref x) = MayWrap(ref inner).Slice(1)[0];
        }
    }
 
    static S1 MayWrap(ref Span<int> arg)
    {
        return default;
    }
 
    ref struct S1
    {
        public ref S1 this[int i] => throw null;
 
        public ref S1 this[S1 i] => throw null;
 
        public ref S1 ReturnsRefArg(ref S1 arg) => throw null;
 
        public S1 Slice(int x) => this;
    }
}
";
            var comp = CreateCompilationWithMscorlibAndSpan(new[] { text, UnscopedRefAttributeDefinition }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics(
                // (20,32): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //             x[0] = MayWrap(ref inner).Slice(1)[0];
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(20, 32),
                // (20,20): error CS8347: Cannot use a result of 'Program.MayWrap(ref Span<int>)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //             x[0] = MayWrap(ref inner).Slice(1)[0];
                Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(ref inner)").WithArguments("Program.MayWrap(ref System.Span<int>)", "arg").WithLocation(20, 20),
                // (25,32): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //             x[x] = MayWrap(ref inner).Slice(1)[0];
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(25, 32),
                // (25,20): error CS8347: Cannot use a result of 'Program.MayWrap(ref Span<int>)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //             x[x] = MayWrap(ref inner).Slice(1)[0];
                Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(ref inner)").WithArguments("Program.MayWrap(ref System.Span<int>)", "arg").WithLocation(25, 20),
                // (28,50): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //             x.ReturnsRefArg(ref x) = MayWrap(ref inner).Slice(1)[0];
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(28, 50),
                // (28,38): error CS8347: Cannot use a result of 'Program.MayWrap(ref Span<int>)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //             x.ReturnsRefArg(ref x) = MayWrap(ref inner).Slice(1)[0];
                Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(ref inner)").WithArguments("Program.MayWrap(ref System.Span<int>)", "arg").WithLocation(28, 38));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefLikeScopeEscapeField(LanguageVersion languageVersion)
        {
            var text = @"
using System;
class Program
{
    static void Main()
    {
        Span<int> outer = default;
 
        S1 x = MayWrap(outer);
 
        {
            Span<int> inner = stackalloc int[1];
 
            // valid
            x.field = MayWrap(outer).Slice(1).field;
 
            // error
            x.field = MayWrap(inner).Slice(1).field;
        }
    }
 
    static S1 MayWrap(Span<int> arg)
    {
        return default;
    }
 
    ref struct S1
    {
        public S0 field;
 
        public S1 Slice(int x) => this;
    }
 
    ref struct S0
    {
    }
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (18,31): error CS8526: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //             x.field = MayWrap(inner).Slice(1).field;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(18, 31),
                // (18,23): error CS8521: Cannot use a result of 'Program.MayWrap(Span<int>)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //             x.field = MayWrap(inner).Slice(1).field;
                Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(inner)").WithArguments("Program.MayWrap(System.Span<int>)", "arg").WithLocation(18, 23)
            );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefLikeEscapeParamsAndTopLevel(LanguageVersion languageVersion)
        {
            var text = @"
    class Program
    {
        static void Main()
        {
        }
 
        void Test1(int x)
        {
            int y = 1;
 
            var rx = MayWrap(ref x);
            var ry = MayWrap(ref y);
 
            // valid. parameter scope and the top local scope are the same.
            rx = ry;
            
            bool condition = true;
            rx = condition ? rx: ry;
        }
 
        static S1 MayWrap(ref int arg)
        {
            return default;
        }
 
        ref struct S1
        {
        }
    }
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
            // no diagnostics expected
            );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefLikeEscapeMixingCallSameArgValue(LanguageVersion languageVersion)
        {
            var text = @"
    using System;
    public class Program
    {
        static void Main()
        {
        }
 
        void Test1()
        {
            S1 rOuter = default;
 
            Span<int> inner = stackalloc int[1];
            S1 rInner = MayWrap(inner);
 
            // valid
            MayAssign(ref rOuter);
 
            // valid
            MayAssign(ref rInner);
        }
 
        static void MayAssign(ref S1 arg1)
        {
            // valid
            arg1 = MayWrap(arg1.field);
        }
 
        static S1 MayWrap(Span<int> arg)
        {
            return default;
        }
 
        public ref struct S1
        {
            public Span<int> field;
        }
    }
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics();
        }
 
        [Fact]
        public void RefLikeEscapeMixingCall()
        {
            var text = @"
    using System;
    class Program
    {
        static void Main()
        {
        }
 
        void Test1()
        {
            S1 rOuter = default;
 
            Span<int> inner = stackalloc int[1];
            S1 rInner = MayWrap(ref inner);
 
            // valid
            MayAssign(ref rOuter, ref rOuter);
 
            // error
            MayAssign(ref rOuter, ref rInner);
 
            // error
            MayAssign(ref inner, ref rOuter);
        }
 
        static void MayAssign(ref Span<int> arg1, ref S1 arg2)
        {
            arg2 = MayWrap(ref arg1);
        }
 
        static void MayAssign(ref S1 arg1, ref S1 arg2)
        {
            arg1 = arg2;
        }
 
        static S1 MayWrap(ref Span<int> arg)
        {
            return default;
        }
 
        ref struct S1
        {
        }
    }
";
            var comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(
                // (20,39): error CS8352: Cannot use variable 'rInner' in this context because it may expose referenced variables outside of their declaration scope
                //             MayAssign(ref rOuter, ref rInner);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rInner").WithArguments("rInner").WithLocation(20, 39),
                // (20,13): error CS8350: This combination of arguments to 'Program.MayAssign(ref Program.S1, ref Program.S1)' is disallowed because it may expose variables referenced by parameter 'arg2' outside of their declaration scope
                //             MayAssign(ref rOuter, ref rInner);
                Diagnostic(ErrorCode.ERR_CallArgMixing, "MayAssign(ref rOuter, ref rInner)").WithArguments("Program.MayAssign(ref Program.S1, ref Program.S1)", "arg2").WithLocation(20, 13),
                // (23,27): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //             MayAssign(ref inner, ref rOuter);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(23, 27),
                // (23,13): error CS8350: This combination of arguments to 'Program.MayAssign(ref Span<int>, ref Program.S1)' is disallowed because it may expose variables referenced by parameter 'arg1' outside of their declaration scope
                //             MayAssign(ref inner, ref rOuter);
                Diagnostic(ErrorCode.ERR_CallArgMixing, "MayAssign(ref inner, ref rOuter)").WithArguments("Program.MayAssign(ref System.Span<int>, ref Program.S1)", "arg1").WithLocation(23, 13));
 
            comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular11);
            comp.VerifyDiagnostics(
                // (20,39): error CS8352: Cannot use variable 'rInner' in this context because it may expose referenced variables outside of their declaration scope
                //             MayAssign(ref rOuter, ref rInner);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rInner").WithArguments("rInner").WithLocation(20, 39),
                // (20,13): error CS8350: This combination of arguments to 'Program.MayAssign(ref Program.S1, ref Program.S1)' is disallowed because it may expose variables referenced by parameter 'arg2' outside of their declaration scope
                //             MayAssign(ref rOuter, ref rInner);
                Diagnostic(ErrorCode.ERR_CallArgMixing, "MayAssign(ref rOuter, ref rInner)").WithArguments("Program.MayAssign(ref Program.S1, ref Program.S1)", "arg2").WithLocation(20, 13),
                // (23,27): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //             MayAssign(ref inner, ref rOuter);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(23, 27),
                // (23,13): error CS8350: This combination of arguments to 'Program.MayAssign(ref Span<int>, ref Program.S1)' is disallowed because it may expose variables referenced by parameter 'arg1' outside of their declaration scope
                //             MayAssign(ref inner, ref rOuter);
                Diagnostic(ErrorCode.ERR_CallArgMixing, "MayAssign(ref inner, ref rOuter)").WithArguments("Program.MayAssign(ref System.Span<int>, ref Program.S1)", "arg1").WithLocation(23, 13),
                // (28,32): error CS9077: Cannot return a parameter by reference 'arg1' through a ref parameter; it can only be returned in a return statement
                //             arg2 = MayWrap(ref arg1);
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "arg1").WithArguments("arg1").WithLocation(28, 32),
                // (28,20): error CS8347: Cannot use a result of 'Program.MayWrap(ref Span<int>)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //             arg2 = MayWrap(ref arg1);
                Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(ref arg1)").WithArguments("Program.MayWrap(ref System.Span<int>)", "arg").WithLocation(28, 20)
            );
        }
 
        [Fact]
        public void RefLikeEscapeMixingCall_UnsafeContext()
        {
            var text = @"
using System;
class Program
{
    unsafe void Test1()
    {
        S1 rOuter = default;
 
        Span<int> inner = stackalloc int[1];
        S1 rInner = MayWrap(ref inner);
 
        // valid
        MayAssign(ref rOuter, ref rOuter);
 
        // warn
        MayAssign(ref rOuter, ref rInner);
 
        // warn
        MayAssign(ref inner, ref rOuter);
    }
 
    static unsafe void MayAssign(ref Span<int> arg1, ref S1 arg2)
    {
        arg2 = MayWrap(ref arg1);
    }
 
    static void MayAssign(ref S1 arg1, ref S1 arg2)
    {
        arg1 = arg2;
    }
 
    static S1 MayWrap(ref Span<int> arg)
    {
        return default;
    }
 
    ref struct S1
    {
    }
}
";
 
            var comp = CreateCompilationWithMscorlibAndSpan(text, options: TestOptions.UnsafeDebugDll, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(
                // (16,35): warning CS9080: Use of variable 'rInner' in this context may expose referenced variables outside of their declaration scope
                //         MayAssign(ref rOuter, ref rInner);
                Diagnostic(ErrorCode.WRN_EscapeVariable, "rInner").WithArguments("rInner").WithLocation(16, 35),
                // (19,23): warning CS9080: Use of variable 'inner' in this context may expose referenced variables outside of their declaration scope
                //         MayAssign(ref inner, ref rOuter);
                Diagnostic(ErrorCode.WRN_EscapeVariable, "inner").WithArguments("inner").WithLocation(19, 23)
                );
 
            comp = CreateCompilationWithMscorlibAndSpan(text, options: TestOptions.UnsafeDebugDll, parseOptions: TestOptions.Regular11);
            comp.VerifyDiagnostics(
                // (16,35): warning CS9080: Use of variable 'rInner' in this context may expose referenced variables outside of their declaration scope
                //         MayAssign(ref rOuter, ref rInner);
                Diagnostic(ErrorCode.WRN_EscapeVariable, "rInner").WithArguments("rInner").WithLocation(16, 35),
                // (19,23): warning CS9080: Use of variable 'inner' in this context may expose referenced variables outside of their declaration scope
                //         MayAssign(ref inner, ref rOuter);
                Diagnostic(ErrorCode.WRN_EscapeVariable, "inner").WithArguments("inner").WithLocation(19, 23),
                // (24,28): warning CS9094: This returns a parameter by reference 'arg1' through a ref parameter; but it can only safely be returned in a return statement
                //         arg2 = MayWrap(ref arg1);
                Diagnostic(ErrorCode.WRN_RefReturnOnlyParameter, "arg1").WithArguments("arg1").WithLocation(24, 28)
                );
        }
 
        [Fact]
        public void RefLikeEscapeMixingCallVararg()
        {
            var text = @"
using System;
class Program
{
    static void Main()
    {
    }
 
    void Test1()
    {
        S1 rOuter = default;
 
        Span<int> inner = stackalloc int[1];
        S1 rInner = MayWrap(ref inner);
 
        // valid
        MayAssign2(__arglist(ref rOuter, ref rOuter));
 
        // error
        MayAssign2(__arglist(ref rOuter, ref rInner));
 
        // error
        MayAssign1(__arglist(ref inner, ref rOuter));
    }
 
    static void MayAssign1(__arglist)
    {
        var ai = new ArgIterator(__arglist);
 
        ref var arg1 = ref __refvalue(ai.GetNextArg(), Span<int>);
        ref var arg2 = ref __refvalue(ai.GetNextArg(), S1);
 
        arg2 = MayWrap(ref arg1);
    }
 
    static void MayAssign2(__arglist)
    {
        var ai = new ArgIterator(__arglist);
 
        ref var arg1 = ref __refvalue(ai.GetNextArg(), S1);
        ref var arg2 = ref __refvalue(ai.GetNextArg(), S1);
 
        arg1 = arg2;
    }
 
    static S1 MayWrap(scoped ref Span<int> arg)
    {
        return default;
    }
 
    ref struct S1
    {
    }
}
";
 
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular10).VerifyDiagnostics(
                // (46,23): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     static S1 MayWrap(scoped ref Span<int> arg)
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(46, 23),
                // (20,46): error CS8352: Cannot use variable 'rInner' in this context because it may expose referenced variables outside of their declaration scope
                //         MayAssign2(__arglist(ref rOuter, ref rInner));
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rInner").WithArguments("rInner").WithLocation(20, 46),
                // (20,9): error CS8350: This combination of arguments to 'Program.MayAssign2(__arglist)' is disallowed because it may expose variables referenced by parameter '__arglist' outside of their declaration scope
                //         MayAssign2(__arglist(ref rOuter, ref rInner));
                Diagnostic(ErrorCode.ERR_CallArgMixing, "MayAssign2(__arglist(ref rOuter, ref rInner))").WithArguments("Program.MayAssign2(__arglist)", "__arglist").WithLocation(20, 9),
                // (23,34): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //         MayAssign1(__arglist(ref inner, ref rOuter));
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(23, 34),
                // (23,9): error CS8350: This combination of arguments to 'Program.MayAssign1(__arglist)' is disallowed because it may expose variables referenced by parameter '__arglist' outside of their declaration scope
                //         MayAssign1(__arglist(ref inner, ref rOuter));
                Diagnostic(ErrorCode.ERR_CallArgMixing, "MayAssign1(__arglist(ref inner, ref rOuter))").WithArguments("Program.MayAssign1(__arglist)", "__arglist").WithLocation(23, 9)
            );
 
            // Same errors modulo the scoped
            CreateCompilationWithMscorlibAndSpan(text).VerifyDiagnostics(
                // (20,46): error CS8352: Cannot use variable 'rInner' in this context because it may expose referenced variables outside of their declaration scope
                //         MayAssign2(__arglist(ref rOuter, ref rInner));
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rInner").WithArguments("rInner").WithLocation(20, 46),
                // (20,9): error CS8350: This combination of arguments to 'Program.MayAssign2(__arglist)' is disallowed because it may expose variables referenced by parameter '__arglist' outside of their declaration scope
                //         MayAssign2(__arglist(ref rOuter, ref rInner));
                Diagnostic(ErrorCode.ERR_CallArgMixing, "MayAssign2(__arglist(ref rOuter, ref rInner))").WithArguments("Program.MayAssign2(__arglist)", "__arglist").WithLocation(20, 9),
                // (23,34): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //         MayAssign1(__arglist(ref inner, ref rOuter));
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(23, 34),
                // (23,9): error CS8350: This combination of arguments to 'Program.MayAssign1(__arglist)' is disallowed because it may expose variables referenced by parameter '__arglist' outside of their declaration scope
                //         MayAssign1(__arglist(ref inner, ref rOuter));
                Diagnostic(ErrorCode.ERR_CallArgMixing, "MayAssign1(__arglist(ref inner, ref rOuter))").WithArguments("Program.MayAssign1(__arglist)", "__arglist").WithLocation(23, 9)
            );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefLikeEscapeMixingIndex(LanguageVersion languageVersion)
        {
            var text = @"
class Program
{
    static void Main()
    {
    }
 
    void Test1()
    {
        S1 rOuter = default;
 
        int inner = 1;
        S1 rInner = MayWrap(ref inner);
 
        // valid
        int dummy1 = this[rOuter, rOuter];
 
        // error
        int dummy2 = this[rOuter, rInner];
 
        // error
        int dummy3 = this[inner, rOuter];
    }
 
    int this[in int arg1, in S1 arg2]
    {
        get
        {
            // not possible
            // arg2 = MayWrap(ref arg1);
            return 0;
        }
    }
 
    int this[in S1 arg1, in S1 arg2]
    {
        get
        {
            // not possible
            // arg1 = arg2;
            return 0;
        }
    }
 
    static S1 MayWrap(ref int arg)
    {
        return default;
    }
 
    ref struct S1
    {
    }
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
            // no diagnostics
            );
        }
 
        [Fact]
        public void RefLikeEscapeMixingIndexOnRefLike()
        {
            var text = @"
using System;
class Program
{
    static void Main()
    {
    }
 
    void Test1()
    {
        S1 rOuter = default;
        rOuter.field = default;
 
        Span<int> inner = stackalloc int[1];
        S1 rInner = MayWrap(inner);
 
        // valid
        int dummy1 = rOuter[rOuter];
 
        // valid
        int dummy2 = rInner[rOuter];
 
        // error
        int dummy3 = rOuter[rInner];
 
        // error
        int dummy4 = rOuter[inner];
    }
 
    static S1 MayWrap(in Span<int> arg)
    {
        return default;
    }
 
    ref struct S1
    {
        public Span<int> field;
 
        public int this[in Span<int> arg1]
        {
            get
            {
                // error: ref-safe-to-escape of arg1 is return-only
                this = MayWrap(arg1);
                return 0;
            }
        }
 
        public int this[in S1 arg1]
        {
            get
            {
                // error: ref-safe-to-escape of arg1 is return-only
                this = MayWrap(arg1.field);
 
                // ok: safe-to-escape of arg1 is calling method
                this = arg1;
 
                return 0;
            }
        }
    }
}
";
            var comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(
                // (24,29): error CS8352: Cannot use variable 'rInner' in this context because it may expose referenced variables outside of their declaration scope
                //         int dummy3 = rOuter[rInner];
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rInner").WithArguments("rInner").WithLocation(24, 29),
                // (24,22): error CS8350: This combination of arguments to 'Program.S1.this[in Program.S1]' is disallowed because it may expose variables referenced by parameter 'arg1' outside of their declaration scope
                //         int dummy3 = rOuter[rInner];
                Diagnostic(ErrorCode.ERR_CallArgMixing, "rOuter[rInner]").WithArguments("Program.S1.this[in Program.S1]", "arg1").WithLocation(24, 22),
                // (27,29): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //         int dummy4 = rOuter[inner];
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(27, 29),
                // (27,22): error CS8350: This combination of arguments to 'Program.S1.this[in Span<int>]' is disallowed because it may expose variables referenced by parameter 'arg1' outside of their declaration scope
                //         int dummy4 = rOuter[inner];
                Diagnostic(ErrorCode.ERR_CallArgMixing, "rOuter[inner]").WithArguments("Program.S1.this[in System.Span<int>]", "arg1").WithLocation(27, 22)
            );
 
            comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular11);
            comp.VerifyDiagnostics(
                // (24,29): error CS8352: Cannot use variable 'rInner' in this context because it may expose referenced variables outside of their declaration scope
                //         int dummy3 = rOuter[rInner];
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rInner").WithArguments("rInner").WithLocation(24, 29),
                // (24,22): error CS8350: This combination of arguments to 'Program.S1.this[in Program.S1]' is disallowed because it may expose variables referenced by parameter 'arg1' outside of their declaration scope
                //         int dummy3 = rOuter[rInner];
                Diagnostic(ErrorCode.ERR_CallArgMixing, "rOuter[rInner]").WithArguments("Program.S1.this[in Program.S1]", "arg1").WithLocation(24, 22),
                // (27,29): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //         int dummy4 = rOuter[inner];
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(27, 29),
                // (27,22): error CS8350: This combination of arguments to 'Program.S1.this[in Span<int>]' is disallowed because it may expose variables referenced by parameter 'arg1' outside of their declaration scope
                //         int dummy4 = rOuter[inner];
                Diagnostic(ErrorCode.ERR_CallArgMixing, "rOuter[inner]").WithArguments("Program.S1.this[in System.Span<int>]", "arg1").WithLocation(27, 22),
                // (44,32): error CS9077: Cannot return a parameter by reference 'arg1' through a ref parameter; it can only be returned in a return statement
                //                 this = MayWrap(arg1);
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "arg1").WithArguments("arg1").WithLocation(44, 32),
                // (44,24): error CS8347: Cannot use a result of 'Program.MayWrap(in Span<int>)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //                 this = MayWrap(arg1);
                Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(arg1)").WithArguments("Program.MayWrap(in System.Span<int>)", "arg").WithLocation(44, 24),
                // (54,32): error CS9078: Cannot return by reference a member of parameter 'arg1' through a ref parameter; it can only be returned in a return statement
                //                 this = MayWrap(arg1.field);
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter2, "arg1").WithArguments("arg1").WithLocation(54, 32),
                // (54,24): error CS8347: Cannot use a result of 'Program.MayWrap(in Span<int>)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //                 this = MayWrap(arg1.field);
                Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(arg1.field)").WithArguments("Program.MayWrap(in System.Span<int>)", "arg").WithLocation(54, 24)
            );
        }
 
        [Fact]
        public void RefLikeEscapeMixingCtor()
        {
            var text = @"
    using System;
    class Program
    {
        static void Main()
        {
        }
 
        delegate void D1(ref S1 arg1, ref S1 arg2);
        delegate void D2(ref Span<int> arg1, ref S1 arg2);
 
        void Test1()
        {
            S1 rOuter = default;
 
            Span<int> inner = stackalloc int[1];
            S1 rInner = MayWrap(ref inner);
 
            D1 MayAssignDel1 = MayAssign;
            D2 MayAssignDel2 = MayAssign;
 
            // valid
            MayAssignDel1(ref rOuter, ref rOuter);
 
            // error
            MayAssignDel1(ref rOuter, ref rInner);
 
            // error
            MayAssignDel2(ref inner, ref rOuter);
        }
 
        static void MayAssign(ref Span<int> arg1, ref S1 arg2)
        {
            arg2 = MayWrap(ref arg1);
        }
 
        static void MayAssign(ref S1 arg1, ref S1 arg2)
        {
            arg1 = arg2;
        }
 
        static S1 MayWrap(ref Span<int> arg)
        {
            return default;
        }
 
        ref struct S1
        {
        }
    }
";
            var comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(
                // (26,43): error CS8352: Cannot use variable 'rInner' in this context because it may expose referenced variables outside of their declaration scope
                //             MayAssignDel1(ref rOuter, ref rInner);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rInner").WithArguments("rInner").WithLocation(26, 43),
                // (26,13): error CS8350: This combination of arguments to 'Program.D1.Invoke(ref Program.S1, ref Program.S1)' is disallowed because it may expose variables referenced by parameter 'arg2' outside of their declaration scope
                //             MayAssignDel1(ref rOuter, ref rInner);
                Diagnostic(ErrorCode.ERR_CallArgMixing, "MayAssignDel1(ref rOuter, ref rInner)").WithArguments("Program.D1.Invoke(ref Program.S1, ref Program.S1)", "arg2").WithLocation(26, 13),
                // (29,31): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //             MayAssignDel2(ref inner, ref rOuter);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(29, 31),
                // (29,13): error CS8350: This combination of arguments to 'Program.D2.Invoke(ref Span<int>, ref Program.S1)' is disallowed because it may expose variables referenced by parameter 'arg1' outside of their declaration scope
                //             MayAssignDel2(ref inner, ref rOuter);
                Diagnostic(ErrorCode.ERR_CallArgMixing, "MayAssignDel2(ref inner, ref rOuter)").WithArguments("Program.D2.Invoke(ref System.Span<int>, ref Program.S1)", "arg1").WithLocation(29, 13)
            );
 
            comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular11);
            comp.VerifyDiagnostics(
                // (26,43): error CS8352: Cannot use variable 'rInner' in this context because it may expose referenced variables outside of their declaration scope
                //             MayAssignDel1(ref rOuter, ref rInner);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rInner").WithArguments("rInner").WithLocation(26, 43),
                // (26,13): error CS8350: This combination of arguments to 'Program.D1.Invoke(ref Program.S1, ref Program.S1)' is disallowed because it may expose variables referenced by parameter 'arg2' outside of their declaration scope
                //             MayAssignDel1(ref rOuter, ref rInner);
                Diagnostic(ErrorCode.ERR_CallArgMixing, "MayAssignDel1(ref rOuter, ref rInner)").WithArguments("Program.D1.Invoke(ref Program.S1, ref Program.S1)", "arg2").WithLocation(26, 13),
                // (29,31): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //             MayAssignDel2(ref inner, ref rOuter);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(29, 31),
                // (29,13): error CS8350: This combination of arguments to 'Program.D2.Invoke(ref Span<int>, ref Program.S1)' is disallowed because it may expose variables referenced by parameter 'arg1' outside of their declaration scope
                //             MayAssignDel2(ref inner, ref rOuter);
                Diagnostic(ErrorCode.ERR_CallArgMixing, "MayAssignDel2(ref inner, ref rOuter)").WithArguments("Program.D2.Invoke(ref System.Span<int>, ref Program.S1)", "arg1").WithLocation(29, 13),
                // (34,32): error CS9077: Cannot return a parameter by reference 'arg1' through a ref parameter; it can only be returned in a return statement
                //             arg2 = MayWrap(ref arg1);
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "arg1").WithArguments("arg1").WithLocation(34, 32),
                // (34,20): error CS8347: Cannot use a result of 'Program.MayWrap(ref Span<int>)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //             arg2 = MayWrap(ref arg1);
                Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(ref arg1)").WithArguments("Program.MayWrap(ref System.Span<int>)", "arg").WithLocation(34, 20)
            );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefLikeObjInitializers(LanguageVersion languageVersion)
        {
            var text = @"
    using System;
 
    class Program
    {
        static void Main()
        {
        }
 
        static S2 Test1()
        {
            S1 outer = default;
            S1 inner = stackalloc int[1];
 
            // error
            return new S2() { Field1 = outer, Field2 = inner };
        }
 
        static S2 Test2()
        {
            S1 outer = default;
            S1 inner = stackalloc int[1];
 
            S2 result;
 
            // error
            result = new S2() { Field1 = inner, Field2 = outer };
 
            return result;
        }
 
        static S2 Test3()
        {
            S1 outer = default;
            S1 inner = stackalloc int[1];
 
            return new S2() { Field1 = outer, Field2 = outer };
        }
 
        public ref struct S1
        {
            public static implicit operator S1(Span<int> o) => default;
        }
 
        public ref struct S2
        {
            public S1 Field1;
            public S1 Field2;
        }
    }
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (16,47): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //             return new S2() { Field1 = outer, Field2 = inner };
                Diagnostic(ErrorCode.ERR_EscapeVariable, "Field2 = inner").WithArguments("inner").WithLocation(16, 47),
                // (27,33): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //             result = new S2() { Field1 = inner, Field2 = outer };
                Diagnostic(ErrorCode.ERR_EscapeVariable, "Field1 = inner").WithArguments("inner").WithLocation(27, 33)
            );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefLikeObjInitializers1(LanguageVersion languageVersion)
        {
            var text = @"
    using System;
 
    class Program
    {
        static void Main()
        {
        }
 
        static S2 Test1()
        {
            S1 outer = default;
            S1 inner = stackalloc int[1];
 
            var x1 = new S2() { Field1 = outer, Field2 = inner };
 
            // error
            return x1;
        }
 
        static S2 Test2()
        {
            S1 outer = default;
            S1 inner = stackalloc int[1];
 
            var x2 = new S2() { Field1 = inner, Field2 = outer };
 
            // error
            return x2;
        }
 
        static S2 Test3()
        {
            S1 outer = default;
            S1 inner = stackalloc int[1];
 
            var x3 = new S2() { Field1 = outer, Field2 = outer };
 
            // ok
            return x3;
        }
 
        public ref struct S1
        {
            public static implicit operator S1(Span<int> o) => default;
        }
 
        public ref struct S2
        {
            public S1 Field1;
            public S1 Field2;
        }
    }
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (18,20): error CS8352: Cannot use variable 'x1' in this context because it may expose referenced variables outside of their declaration scope
                //             return x1;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "x1").WithArguments("x1").WithLocation(18, 20),
                // (29,20): error CS8352: Cannot use variable 'x2' in this context because it may expose referenced variables outside of their declaration scope
                //             return x2;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "x2").WithArguments("x2").WithLocation(29, 20)
            );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefLikeObjInitializersIndexer(LanguageVersion languageVersion)
        {
            var text = @"
using System;
 
class Program
{
    static void Main()
    {
    }
 
    static S2 Test1()
    {
        S1 outer = default;
        S1 inner = stackalloc int[1];
 
        // error
        return new S2() { [inner] = outer, Field2 = outer };
    }
 
    static S2 Test2()
    {
        S1 outer = default;
        S1 inner = stackalloc int[1];
 
        // error
        return new S2() { [outer] = inner, Field2 = outer };
    }
 
    static S2 Test3()
    {
        S1 outer = default;
        S1 inner = stackalloc int[1];
 
        return new S2() { [outer] = outer, Field2 = outer };
    }
 
    public ref struct S1
    {
        public static implicit operator S1(Span<int> o) => default;
    }
 
    public ref struct S2
    {
        private S1 field;
 
        public S1 this[S1 i]
        {
            get
            {
                return i;
            }
            set
            {
                field = i;
            }
        }
 
        public S1 Field2;
    }
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (16,28): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //         return new S2() { [inner] = outer, Field2 = outer };
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(16, 28),
                // (25,27): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //         return new S2() { [outer] = inner, Field2 = outer };
                Diagnostic(ErrorCode.ERR_EscapeVariable, "[outer] = inner").WithArguments("inner").WithLocation(25, 27)
                );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefLikeObjInitializersIndexer1(LanguageVersion languageVersion)
        {
            var text = @"
using System;
 
class Program
{
    static void Main()
    {
    }
 
    static S2 Test1()
    {
        S1 outer = default;
        S1 inner = stackalloc int[1];
 
        var x1 =  new S2() { [inner] = outer, Field2 = outer };
 
        // error
        return x1;
    }
 
    static S2 Test2()
    {
        S1 outer = default;
        S1 inner = stackalloc int[1];
 
        S2 result;
 
        // error
        result = new S2() { [outer] = inner, Field2 = outer };
 
        return result;
    }
 
    static S2 Test3()
    {
        S1 outer = default;
        S1 inner = stackalloc int[1];
 
        var x3 = new S2() { [outer] = outer, Field2 = outer };
 
        // ok
        return x3;
    }
 
    public ref struct S1
    {
        public static implicit operator S1(Span<int> o) => default;
    }
 
    public ref struct S2
    {
        private S1 field;
 
        public S1 this[S1 i]
        {
            get
            {
                return i;
            }
            set
            {
                field = i;
            }
        }
 
        public S1 Field2;
    }
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (18,16): error CS8352: Cannot use variable 'x1' in this context because it may expose referenced variables outside of their declaration scope
                //         return x1;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "x1").WithArguments("x1").WithLocation(18, 16),
                // (29,29): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //         result = new S2() { [outer] = inner, Field2 = outer };
                Diagnostic(ErrorCode.ERR_EscapeVariable, "[outer] = inner").WithArguments("inner").WithLocation(29, 29)
                );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefLikeObjInitializersNested(LanguageVersion languageVersion)
        {
            var text = @"
using System;
 
class Program
{
    static void Main()
    {
    }
 
    static S2 Nested1()
    {
        S1 outer = default;
        S1 inner = stackalloc int[1];
 
        return new S2() { Field2 = {[inner] = outer} };
    }
 
    static S2 Nested2()
    {
        S1 outer = default;
        S1 inner = stackalloc int[1];
 
        var x = new S2() { Field2 = {[inner] = outer } };
 
        return x;
    }
 
    static S2 Nested3()
    {
        S1 outer = default;
        S1 inner = stackalloc int[1];
 
        return new S2() { Field2 = {[outer] = inner} };
    }
 
    static S2 Nested4()
    {
        S1 outer = default;
        S1 inner = stackalloc int[1];
 
        var x = new S2() { Field2 = {[outer] = outer } };
 
        return x;  //ok
    }
 
    public ref struct S2
    {
        public S3 Field2;
    }
 
    public ref struct S3
    {
        private S1 field;
 
        public S1 this[S1 i]
        {
            get
            {
                return i;
            }
            set
            {
                field = i;
            }
        }
 
        public S1 Field2;
    }
 
    public ref struct S1
    {
        public static implicit operator S1(Span<int> o) => default;
    }
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (15,38): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //         return new S2() { Field2 = {[inner] = outer} };
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(15, 38),
                // (25,16): error CS8352: Cannot use variable 'x' in this context because it may expose referenced variables outside of their declaration scope
                //         return x;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "x").WithArguments("x").WithLocation(25, 16),
                // (33,37): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //         return new S2() { Field2 = {[outer] = inner} };
                Diagnostic(ErrorCode.ERR_EscapeVariable, "[outer] = inner").WithArguments("inner").WithLocation(33, 37),
                // (67,19): warning CS0649: Field 'Program.S3.Field2' is never assigned to, and will always have its default value 
                //         public S1 Field2;
                Diagnostic(ErrorCode.WRN_UnassignedInternalField, "Field2").WithArguments("Program.S3.Field2", "").WithLocation(67, 19)
                );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefLikeColInitializer(LanguageVersion languageVersion)
        {
            var text = @"
using System;
using System.Collections.Generic;
 
// X cannot be a ref-like type since it must implement IEnumerable
// that significantly reduces the number of scenarios that could be applicable to ref-like types
class X : List<int>
{
    void Add(Span<int> x, int y) { }
 
    static void Main()
    {
        Span<int> inner = stackalloc int[1];
 
        var z = new X { { inner, 12 } };
    }
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics();
        }
 
        [Fact]
        public void RefLikeEscapeMixingDelegate()
        {
            var text = @"
    using System;
    class Program
    {
        static void Main()
        {
        }
 
        void Test1()
        {
            S1 rOuter = default;
 
            Span<int> inner = stackalloc int[2];
            S1 rInner = MayWrap(ref inner);
 
            // valid
            var dummy1 = new Program(ref rOuter, ref rOuter);
 
            // error
            var dummy2 = new Program(ref rOuter, ref rInner);
 
            // error
            var dummy3 = new Program(ref inner, ref rOuter);
        }
 
        Program(ref Span<int> arg1, ref S1 arg2)
        {
            arg2 = MayWrap(ref arg1);
        }
 
        Program(ref S1 arg1, ref S1 arg2)
        {
            arg1 = arg2;
        }
 
        static S1 MayWrap(ref Span<int> arg)
        {
            return default;
        }
 
        ref struct S1
        {
        }
    }
";
            var comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(
                // (20,54): error CS8526: Cannot use variable 'rInner' in this context because it may expose referenced variables outside of their declaration scope
                //             var dummy2 = new Program(ref rOuter, ref rInner);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rInner").WithArguments("rInner").WithLocation(20, 54),
                // (20,26): error CS8524: This combination of arguments to 'Program.Program(ref Program.S1, ref Program.S1)' is disallowed because it may expose variables referenced by parameter 'arg2' outside of their declaration scope
                //             var dummy2 = new Program(ref rOuter, ref rInner);
                Diagnostic(ErrorCode.ERR_CallArgMixing, "new Program(ref rOuter, ref rInner)").WithArguments("Program.Program(ref Program.S1, ref Program.S1)", "arg2").WithLocation(20, 26),
                // (23,42): error CS8526: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //             var dummy3 = new Program(ref inner, ref rOuter);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(23, 42),
                // (23,26): error CS8524: This combination of arguments to 'Program.Program(ref Span<int>, ref Program.S1)' is disallowed because it may expose variables referenced by parameter 'arg1' outside of their declaration scope
                //             var dummy3 = new Program(ref inner, ref rOuter);
                Diagnostic(ErrorCode.ERR_CallArgMixing, "new Program(ref inner, ref rOuter)").WithArguments("Program.Program(ref System.Span<int>, ref Program.S1)", "arg1").WithLocation(23, 26)
            );
 
            comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular11);
            comp.VerifyDiagnostics(
                // (20,54): error CS8352: Cannot use variable 'rInner' in this context because it may expose referenced variables outside of their declaration scope
                //             var dummy2 = new Program(ref rOuter, ref rInner);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rInner").WithArguments("rInner").WithLocation(20, 54),
                // (20,26): error CS8350: This combination of arguments to 'Program.Program(ref Program.S1, ref Program.S1)' is disallowed because it may expose variables referenced by parameter 'arg2' outside of their declaration scope
                //             var dummy2 = new Program(ref rOuter, ref rInner);
                Diagnostic(ErrorCode.ERR_CallArgMixing, "new Program(ref rOuter, ref rInner)").WithArguments("Program.Program(ref Program.S1, ref Program.S1)", "arg2").WithLocation(20, 26),
                // (23,42): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope
                //             var dummy3 = new Program(ref inner, ref rOuter);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(23, 42),
                // (23,26): error CS8350: This combination of arguments to 'Program.Program(ref Span<int>, ref Program.S1)' is disallowed because it may expose variables referenced by parameter 'arg1' outside of their declaration scope
                //             var dummy3 = new Program(ref inner, ref rOuter);
                Diagnostic(ErrorCode.ERR_CallArgMixing, "new Program(ref inner, ref rOuter)").WithArguments("Program.Program(ref System.Span<int>, ref Program.S1)", "arg1").WithLocation(23, 26),
                // (28,32): error CS9077: Cannot return a parameter by reference 'arg1' through a ref parameter; it can only be returned in a return statement
                //             arg2 = MayWrap(ref arg1);
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "arg1").WithArguments("arg1").WithLocation(28, 32),
                // (28,20): error CS8347: Cannot use a result of 'Program.MayWrap(ref Span<int>)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //             arg2 = MayWrap(ref arg1);
                Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(ref arg1)").WithArguments("Program.MayWrap(ref System.Span<int>)", "arg").WithLocation(28, 20)
            );
        }
 
        [Fact]
        public void RefLikeEscapeMixingCallOptionalIn()
        {
            var text = @"
    using System;
    class Program
    {
        static void Main()
        {
        }
 
        void Test1()
        {
            S1 rOuter = default;
 
            Span<int> inner = stackalloc int[1];
            S1 rInner = MayWrap(inner);
 
            // valid, optional arg is of the same escape level
            MayAssign(ref rOuter);
 
            // valid, optional arg is of wider escape level
            MayAssign(ref rInner);
        }
 
        static void MayAssign(ref S1 arg1, in Span<int> arg2 = default)
        {
            arg1 = MayWrap(arg2);
        }
 
        static S1 MayWrap(in Span<int> arg)
        {
            return default;
        }
 
        ref struct S1
        {
        }
    }
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular10).VerifyDiagnostics();
 
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
                // (25,20): error CS8347: Cannot use a result of 'Program.MayWrap(in Span<int>)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //             arg1 = MayWrap(arg2);
                Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(arg2)").WithArguments("Program.MayWrap(in System.Span<int>)", "arg").WithLocation(25, 20),
                // (25,28): error CS9077: Cannot return a parameter by reference 'arg2' through a ref parameter; it can only be returned in a return statement
                //             arg1 = MayWrap(arg2);
                Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "arg2").WithArguments("arg2").WithLocation(25, 28));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void MismatchedRefTernaryEscape(LanguageVersion languageVersion)
        {
            var text = @"
class Program
{
    static void Main()
    {
    }
 
    public static int field = 1;
 
    bool flag = true;
 
    ref int Test1()
    {
        var local = 42;
 
        if (flag) 
            return ref true ? ref field : ref local;
 
        ref var lr = ref local;
        ref var fr = ref field;
 
        ref var ternary1 = ref true ? ref lr : ref fr;
 
        if (flag) 
            return ref ternary1;
    }
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (17,47): error CS8168: Cannot return local 'local' by reference because it is not a ref local
                //             return ref true ? ref field : ref local;
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "local").WithArguments("local").WithLocation(17, 47),
                // (25,24): error CS8157: Cannot return 'ternary1' by reference because it was initialized to a value that cannot be returned by reference
                //             return ref ternary1;
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "ternary1").WithArguments("ternary1").WithLocation(25, 24),
                // (12,13): error CS0161: 'Program.Test1()': not all code paths return a value
                //     ref int Test1()
                Diagnostic(ErrorCode.ERR_ReturnExpected, "Test1").WithArguments("Program.Test1()").WithLocation(12, 13)
                );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void MismatchedRefTernaryEscapeBlock(LanguageVersion languageVersion)
        {
            var text = @"
using System;
class Program
{
    static void Main()
    {
    }
 
    public static int field = 1;
 
    void Test1()
    {
        Span<int> outer = default;
        var sOuter = MayWrap(ref outer);
 
        {
            Span<int> inner = stackalloc int[1];
            var sInner = MayWrap(ref inner);
 
            ref var ternarySame1 = ref true ? ref sInner : ref sInner;
            ref var ternarySame2 = ref true ? ref sOuter : ref sOuter;
 
            // ok
            ternarySame2 = true ? sOuter : sOuter;
 
            // error
            ternarySame2 = true ? sOuter : sInner;
 
            // error
            ternarySame2 = true ? sInner : sOuter;
 
            // error, mixing val escapes
            ref var ternary1 = ref true ? ref sOuter : ref sInner;
 
            // error, mixing val escapes
            ref var ternary2 = ref true ? ref sInner : ref sOuter;
 
            // error, mixing val escapes
            ref var ternary3 = ref true ? ref ternarySame1 : ref ternarySame2;
 
            ref var ir = ref sInner[1];
            ref var or = ref sOuter[1];
 
            // no error, indexer cannot ref-return the instance, so ir and or are both safe to return
            ref var ternary4 = ref true ? ref ir : ref or;
        }
    }
 
    static S1 MayWrap(ref Span<int> arg)
    {
        return default;
    }
 
    ref struct S1
    {
        public ref int this[int i] => throw null;
    }
}
";
            var comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics(
                // (27,44): error CS8526: Cannot use variable 'sInner' in this context because it may expose referenced variables outside of their declaration scope
                //             ternarySame2 = true ? sOuter : sInner;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "sInner").WithArguments("sInner").WithLocation(27, 44),
                // (30,35): error CS8526: Cannot use variable 'sInner' in this context because it may expose referenced variables outside of their declaration scope
                //             ternarySame2 = true ? sInner : sOuter;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "sInner").WithArguments("sInner").WithLocation(30, 35),
                // (33,60): error CS8526: Cannot use variable 'sInner' in this context because it may expose referenced variables outside of their declaration scope
                //             ref var ternary1 = ref true ? ref sOuter : ref sInner;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "sInner").WithArguments("sInner").WithLocation(33, 60),
                // (33,36): error CS8525: Branches of a ref ternary operator cannot refer to variables with incompatible declaration scopes
                //             ref var ternary1 = ref true ? ref sOuter : ref sInner;
                Diagnostic(ErrorCode.ERR_MismatchedRefEscapeInTernary, "true ? ref sOuter : ref sInner").WithLocation(33, 36),
                // (36,47): error CS8526: Cannot use variable 'sInner' in this context because it may expose referenced variables outside of their declaration scope
                //             ref var ternary2 = ref true ? ref sInner : ref sOuter;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "sInner").WithArguments("sInner").WithLocation(36, 47),
                // (36,36): error CS8525: Branches of a ref ternary operator cannot refer to variables with incompatible declaration scopes
                //             ref var ternary2 = ref true ? ref sInner : ref sOuter;
                Diagnostic(ErrorCode.ERR_MismatchedRefEscapeInTernary, "true ? ref sInner : ref sOuter").WithLocation(36, 36),
                // (39,47): error CS8526: Cannot use variable 'ternarySame1' in this context because it may expose referenced variables outside of their declaration scope
                //             ref var ternary3 = ref true ? ref ternarySame1 : ref ternarySame2;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "ternarySame1").WithArguments("ternarySame1").WithLocation(39, 47),
                // (39,36): error CS8525: Branches of a ref ternary operator cannot refer to variables with incompatible declaration scopes
                //             ref var ternary3 = ref true ? ref ternarySame1 : ref ternarySame2;
                Diagnostic(ErrorCode.ERR_MismatchedRefEscapeInTernary, "true ? ref ternarySame1 : ref ternarySame2").WithLocation(39, 36)
            );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void MismatchedRefTernaryEscapeBlock_UnsafeContext(LanguageVersion languageVersion)
        {
            var text = @"
using System;
unsafe class Program
{
    static void Main()
    {
    }
 
    public static int field = 1;
 
    void Test1()
    {
        Span<int> outer = default;
        var sOuter = MayWrap(ref outer);
 
        {
            Span<int> inner = stackalloc int[1];
            var sInner = MayWrap(ref inner);
 
            ref var ternarySame1 = ref true ? ref sInner : ref sInner;
            ref var ternarySame2 = ref true ? ref sOuter : ref sOuter;
 
            // ok
            ternarySame2 = true ? sOuter : sOuter;
 
            // error
            ternarySame2 = true ? sOuter : sInner;
 
            // error
            ternarySame2 = true ? sInner : sOuter;
 
            // error, mixing val escapes
            ref var ternary1 = ref true ? ref sOuter : ref sInner;
 
            // error, mixing val escapes
            ref var ternary2 = ref true ? ref sInner : ref sOuter;
 
            // error, mixing val escapes
            ref var ternary3 = ref true ? ref ternarySame1 : ref ternarySame2;
 
            ref var ir = ref sInner[1];
            ref var or = ref sOuter[1];
 
            // no error, indexer cannot ref-return the instance, so ir and or are both safe to return
            ref var ternary4 = ref true ? ref ir : ref or;
        }
    }
 
    static S1 MayWrap(ref Span<int> arg)
    {
        return default;
    }
 
    ref struct S1
    {
        public ref int this[int i] => throw null;
    }
}
";
            var comp = CreateCompilationWithMscorlibAndSpan(text, options: TestOptions.UnsafeDebugDll, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyEmitDiagnostics(
                // (27,44): warning CS9077: Use of variable 'sInner' in this context may expose referenced variables outside of their declaration scope
                //             ternarySame2 = true ? sOuter : sInner;
                Diagnostic(ErrorCode.WRN_EscapeVariable, "sInner").WithArguments("sInner").WithLocation(27, 44),
                // (30,35): warning CS9077: Use of variable 'sInner' in this context may expose referenced variables outside of their declaration scope
                //             ternarySame2 = true ? sInner : sOuter;
                Diagnostic(ErrorCode.WRN_EscapeVariable, "sInner").WithArguments("sInner").WithLocation(30, 35),
                // (33,60): warning CS9077: Use of variable 'sInner' in this context may expose referenced variables outside of their declaration scope
                //             ref var ternary1 = ref true ? ref sOuter : ref sInner;
                Diagnostic(ErrorCode.WRN_EscapeVariable, "sInner").WithArguments("sInner").WithLocation(33, 60),
                // (33,36): warning CS9083: The branches of the ref conditional operator refer to variables with incompatible declaration scopes
                //             ref var ternary1 = ref true ? ref sOuter : ref sInner;
                Diagnostic(ErrorCode.WRN_MismatchedRefEscapeInTernary, "true ? ref sOuter : ref sInner").WithLocation(33, 36),
                // (36,47): warning CS9077: Use of variable 'sInner' in this context may expose referenced variables outside of their declaration scope
                //             ref var ternary2 = ref true ? ref sInner : ref sOuter;
                Diagnostic(ErrorCode.WRN_EscapeVariable, "sInner").WithArguments("sInner").WithLocation(36, 47),
                // (36,36): warning CS9083: The branches of the ref conditional operator refer to variables with incompatible declaration scopes
                //             ref var ternary2 = ref true ? ref sInner : ref sOuter;
                Diagnostic(ErrorCode.WRN_MismatchedRefEscapeInTernary, "true ? ref sInner : ref sOuter").WithLocation(36, 36),
                // (39,47): warning CS9077: Use of variable 'ternarySame1' in this context may expose referenced variables outside of their declaration scope
                //             ref var ternary3 = ref true ? ref ternarySame1 : ref ternarySame2;
                Diagnostic(ErrorCode.WRN_EscapeVariable, "ternarySame1").WithArguments("ternarySame1").WithLocation(39, 47),
                // (39,36): warning CS9083: The branches of the ref conditional operator refer to variables with incompatible declaration scopes
                //             ref var ternary3 = ref true ? ref ternarySame1 : ref ternarySame2;
                Diagnostic(ErrorCode.WRN_MismatchedRefEscapeInTernary, "true ? ref ternarySame1 : ref ternarySame2").WithLocation(39, 36)
                );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void StackallocEscape(LanguageVersion languageVersion)
        {
            var text = @"
    using System;
    class Program
    {
        static void Main()
        {
 
        }
 
        Span<int> Test0()
        {
            // valid, baseline
            return default(Span<int>);
        }
 
        Span<int> Test3()
        {
            Span<int> local = stackalloc int[10];
            return true? local : default(Span<int>);
        }
      
        Span<int> Test4(Span<int> arg)
        {
            arg = stackalloc int[10];
            return arg;
        }
 
        Span<int> Test6()
        {
            Span<int> local = default;
            local = stackalloc int[10];
            return local;
        }
    }
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (19,26): error CS8352: Cannot use variable 'local' in this context because it may expose referenced variables outside of their declaration scope 
                //             return true? local : default(Span<int>);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "local").WithArguments("local").WithLocation(19, 26),
                // (24,19): 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
                //             arg = stackalloc int[10];
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[10]").WithArguments("System.Span<int>").WithLocation(24, 19),
                // (31,21): 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
                //             local = stackalloc int[10];
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[10]").WithArguments("System.Span<int>").WithLocation(31, 21)
                );
        }
 
        [WorkItem(21831, "https://github.com/dotnet/roslyn/issues/21831")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void LocalWithNoInitializerEscape(LanguageVersion languageVersion)
        {
            var text = @"using System;
 
    class Program
    {
        static void Main()
        {
            // uninitialized
            S1 sp;
 
            // ok
            sp = default;
            
            Span<int> local = stackalloc int[1];
 
            // error
            sp = MayWrap(ref local);
        }
 
        static S1 SefReferringTest()
        {
            S1 sp1 = sp1;
            return sp1;
        }
 
        static S1 MayWrap(ref Span<int> arg)
        {
            return default;
        }
 
        ref struct S1
        {
            public ref int this[int i] => throw null;
        }
    }
";
            var comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics(
                // (16,30): error CS8352: Cannot use variable 'local' in this context because it may expose referenced variables outside of their declaration scope
                //             sp = MayWrap(ref local);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "local").WithArguments("local").WithLocation(16, 30),
                // (16,18): error CS8347: Cannot use a result of 'Program.MayWrap(ref Span<int>)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope
                //             sp = MayWrap(ref local);
                Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(ref local)").WithArguments("Program.MayWrap(ref System.Span<int>)", "arg").WithLocation(16, 18),
                // (22,20): error CS8352: Cannot use variable 'sp1' in this context because it may expose referenced variables outside of their declaration scope
                //             return sp1;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "sp1").WithArguments("sp1").WithLocation(22, 20)
                );
        }
 
        [WorkItem(21858, "https://github.com/dotnet/roslyn/issues/21858")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void FieldOfRefLikeEscape(LanguageVersion languageVersion)
        {
            var text = @"
    class Program
    {
        static void Main()
        {
        }
 
        ref struct S1
        {
            private S2 x;
 
            public S1(S2 arg) => x = arg;
 
            public S2 M1()
            {
                // ok
                return x;
            }
 
            public S2 M2()
            {
                var toReturn = x;
 
                // ok
                return toReturn;
            }
 
            public ref S2 M3()
            {
                // not ok
                return ref x;
            }
        }
 
        ref struct S2{}
 
    }
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (31,28): error CS8170: Struct members cannot return 'this' or other instance members by reference
                //                 return ref x;
                Diagnostic(ErrorCode.ERR_RefReturnStructThis, "x").WithLocation(31, 28)
                );
        }
 
        [WorkItem(21880, "https://github.com/dotnet/roslyn/issues/21880")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void MemberOfReadonlyRefLikeEscape(LanguageVersion languageVersion)
        {
            var text = @"
    using System;
    using System.Diagnostics.CodeAnalysis;
    public static class Program
    {
        public static void Main()
        {
            // OK, SR is readonly
            Span<int> value1 = stackalloc int[1];
            new SR().TryGet(out value1);
 
            // Ok, the new value can be copied into SW but not the 
            // ref to the value
            new SW().TryGet(out value1);
 
            // Error as the ref of this can escape into value2
            Span<int> value2 = default;
            new SW().TryGet2(out value2);
        }
    }
 
    public readonly ref struct SR
    {
        public void TryGet(out Span<int> result)
        {
            result = default;
        }
    }
 
    public ref struct SW
    {
        public void TryGet(out Span<int> result)
        {
            result = default;
        }
 
        [UnscopedRef]
        public void TryGet2(out Span<int> result)
        {
            result = default;
        }
    }
";
            if (languageVersion == LanguageVersion.CSharp10)
            {
                CreateCompilationWithMscorlibAndSpan(new[] { text, UnscopedRefAttributeDefinition }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                    // (14,13): error CS8350: This combination of arguments to 'SW.TryGet(out Span<int>)' is disallowed because it may expose variables referenced by parameter 'result' outside of their declaration scope
                    //             new SW().TryGet(out value1);
                    Diagnostic(ErrorCode.ERR_CallArgMixing, "new SW().TryGet(out value1)").WithArguments("SW.TryGet(out System.Span<int>)", "result").WithLocation(14, 13),
                    // (14,33): error CS8352: Cannot use variable 'value1' in this context because it may expose referenced variables outside of their declaration scope
                    //             new SW().TryGet(out value1);
                    Diagnostic(ErrorCode.ERR_EscapeVariable, "value1").WithArguments("value1").WithLocation(14, 33)
                    );
 
            }
            else
            {
                CreateCompilationWithMscorlibAndSpan(new[] { text, UnscopedRefAttributeDefinition }, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                    // (18,13): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                    //             new SW().TryGet2(out value2);
                    Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "new SW()").WithLocation(18, 13),
                    // (18,13): error CS8350: This combination of arguments to 'SW.TryGet2(out Span<int>)' is disallowed because it may expose variables referenced by parameter 'this' outside of their declaration scope
                    //             new SW().TryGet2(out value2);
                    Diagnostic(ErrorCode.ERR_CallArgMixing, "new SW().TryGet2(out value2)").WithArguments("SW.TryGet2(out System.Span<int>)", "this").WithLocation(18, 13)
                    );
            }
        }
 
        [WorkItem(21911, "https://github.com/dotnet/roslyn/issues/21911")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void MemberOfReadonlyRefLikeEscapeSpans(LanguageVersion languageVersion)
        {
            var text = @"
    using System;
 
    public static class Program
    {
        public static void Main()
        {
            Span<int> stackAllocated = stackalloc int[100];
 
            // OK, Span is a readonly struct
            new Span<int>().CopyTo(stackAllocated);
 
            // OK, ReadOnlySpan is a readonly struct
            new ReadOnlySpan<int>().CopyTo(stackAllocated);
 
            // not OK, Span is writeable
            new NotReadOnly<int>().CopyTo(stackAllocated);
        }
    }
 
    public ref struct NotReadOnly<T>
    {
        private Span<T> wrapped;
 
        public void CopyTo(Span<T> other)
        {
            wrapped = other;
        }
    }
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (17,43): error CS8352: Cannot use variable 'stackAllocated' in this context because it may expose referenced variables outside of their declaration scope
                //             new NotReadOnly<int>().CopyTo(stackAllocated);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "stackAllocated").WithArguments("stackAllocated").WithLocation(17, 43),
                // (17,13): error CS8350: This combination of arguments to 'NotReadOnly<int>.CopyTo(Span<int>)' is disallowed because it may expose variables referenced by parameter 'other' outside of their declaration scope
                //             new NotReadOnly<int>().CopyTo(stackAllocated);
                Diagnostic(ErrorCode.ERR_CallArgMixing, "new NotReadOnly<int>().CopyTo(stackAllocated)").WithArguments("NotReadOnly<int>.CopyTo(System.Span<int>)", "other").WithLocation(17, 13)
                );
        }
 
        [WorkItem(35146, "https://github.com/dotnet/roslyn/issues/35146")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void ReadOnlyRefStruct_Method_RefLikeStructParameter(LanguageVersion languageVersion)
        {
            var csharp = @"
using System;
 
public readonly ref struct S<T>
{
    public void M(Span<T> x) { }
 
    public unsafe static void N(S<byte> b)
    {
        Span<byte> x = stackalloc byte[5];
        b.M(x);
    }
}
";
            var comp = CreateCompilationWithMscorlibAndSpan(csharp, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.UnsafeDebugDll);
            comp.VerifyDiagnostics();
        }
 
        [WorkItem(35146, "https://github.com/dotnet/roslyn/issues/35146")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void ReadOnlyMethod_RefLikeStructParameter(LanguageVersion languageVersion)
        {
            var csharp = @"
using System;
 
public ref struct S<T>
{
    public readonly void M(Span<T> x) { }
 
    public unsafe static void N(S<byte> b)
    {
        Span<byte> x = stackalloc byte[5];
        b.M(x);
    }
}
";
            var comp = CreateCompilationWithMscorlibAndSpan(csharp, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.UnsafeDebugDll);
            comp.VerifyDiagnostics();
        }
 
        [WorkItem(35146, "https://github.com/dotnet/roslyn/issues/35146")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void ReadOnlyRefStruct_RefLikeProperty(LanguageVersion languageVersion)
        {
            var csharp = @"
using System;
 
public readonly ref struct S<T>
{
    public Span<T> P { get => default; set {} }
 
    public unsafe static void N(S<byte> b)
    {
        Span<byte> x = stackalloc byte[5];
        b.P = x;
    }
}
";
            var comp = CreateCompilationWithMscorlibAndSpan(csharp, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.UnsafeDebugDll);
            comp.VerifyDiagnostics(
                // (11,15): warning CS9080: Use of variable 'x' in this context may expose referenced variables outside of their declaration scope
                //         b.P = x;
                Diagnostic(ErrorCode.WRN_EscapeVariable, "x").WithArguments("x").WithLocation(11, 15));
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped);
            verifier.VerifyIL("S<T>.N", @"
{
  // Code size       24 (0x18)
  .maxstack  2
  .locals init (System.Span<byte> V_0, //x
                System.Span<byte> V_1)
  IL_0000:  nop
  IL_0001:  ldc.i4.5
  IL_0002:  conv.u
  IL_0003:  localloc
  IL_0005:  ldc.i4.5
  IL_0006:  newobj     ""System.Span<byte>..ctor(void*, int)""
  IL_000b:  stloc.1
  IL_000c:  ldloc.1
  IL_000d:  stloc.0
  IL_000e:  ldarga.s   V_0
  IL_0010:  ldloc.0
  IL_0011:  call       ""void S<byte>.P.set""
  IL_0016:  nop
  IL_0017:  ret
}
");
        }
 
        [WorkItem(35146, "https://github.com/dotnet/roslyn/issues/35146")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void ReadOnlyRefLikeProperty_01(LanguageVersion languageVersion)
        {
            var csharp = @"
using System;
 
public ref struct S<T>
{
    public readonly Span<T> P { get => default; set {} }
 
    public unsafe static void N(S<byte> b)
    {
        Span<byte> x = stackalloc byte[5];
        b.P = x;
    }
}
";
            var comp = CreateCompilationWithMscorlibAndSpan(csharp, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.UnsafeDebugDll);
            comp.VerifyDiagnostics(
                // (11,15): warning CS9080: Use of variable 'x' in this context may expose referenced variables outside of their declaration scope
                //         b.P = x;
                Diagnostic(ErrorCode.WRN_EscapeVariable, "x").WithArguments("x").WithLocation(11, 15));
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped);
            verifier.VerifyIL("S<T>.N", @"
{
  // Code size       24 (0x18)
  .maxstack  2
  .locals init (System.Span<byte> V_0, //x
                System.Span<byte> V_1)
  IL_0000:  nop
  IL_0001:  ldc.i4.5
  IL_0002:  conv.u
  IL_0003:  localloc
  IL_0005:  ldc.i4.5
  IL_0006:  newobj     ""System.Span<byte>..ctor(void*, int)""
  IL_000b:  stloc.1
  IL_000c:  ldloc.1
  IL_000d:  stloc.0
  IL_000e:  ldarga.s   V_0
  IL_0010:  ldloc.0
  IL_0011:  call       ""readonly void S<byte>.P.set""
  IL_0016:  nop
  IL_0017:  ret
}
");
        }
 
        [WorkItem(35146, "https://github.com/dotnet/roslyn/issues/35146")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void ReadOnlyRefLikeProperty_02(LanguageVersion languageVersion)
        {
            var csharp = @"
using System;
 
public ref struct S<T>
{
    public Span<T> P { get => default; readonly set {} }
 
    public unsafe static void N(S<byte> b)
    {
        Span<byte> x = stackalloc byte[5];
        b.P = x;
    }
}
";
            var comp = CreateCompilationWithMscorlibAndSpan(csharp, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.UnsafeDebugDll);
            comp.VerifyDiagnostics(
                // (11,15): warning CS9080: Use of variable 'x' in this context may expose referenced variables outside of their declaration scope
                //         b.P = x;
                Diagnostic(ErrorCode.WRN_EscapeVariable, "x").WithArguments("x").WithLocation(11, 15));
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped);
            verifier.VerifyIL("S<T>.N", @"
{
  // Code size       24 (0x18)
  .maxstack  2
  .locals init (System.Span<byte> V_0, //x
                System.Span<byte> V_1)
  IL_0000:  nop
  IL_0001:  ldc.i4.5
  IL_0002:  conv.u
  IL_0003:  localloc
  IL_0005:  ldc.i4.5
  IL_0006:  newobj     ""System.Span<byte>..ctor(void*, int)""
  IL_000b:  stloc.1
  IL_000c:  ldloc.1
  IL_000d:  stloc.0
  IL_000e:  ldarga.s   V_0
  IL_0010:  ldloc.0
  IL_0011:  call       ""readonly void S<byte>.P.set""
  IL_0016:  nop
  IL_0017:  ret
}
");
        }
 
        [WorkItem(35146, "https://github.com/dotnet/roslyn/issues/35146")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void ReadOnlyIndexer_RefLikeStructParameter_01(LanguageVersion languageVersion)
        {
            var csharp = @"
using System;
 
public ref struct S<T>
{
    public readonly Span<T> this[Span<T> span] { get => default; set {} }
 
    public unsafe static Span<byte> N(S<byte> b)
    {
        Span<byte> x = stackalloc byte[5];
        _ = b[x];
        b[x] = x;
        return b[x];
    }
}
";
            var comp = CreateCompilationWithMscorlibAndSpan(csharp, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.UnsafeDebugDll);
            comp.VerifyDiagnostics(
                // (13,18): warning CS9080: Use of variable 'x' in this context may expose referenced variables outside of their declaration scope
                //         return b[x];
                Diagnostic(ErrorCode.WRN_EscapeVariable, "x").WithArguments("x").WithLocation(13, 18));
        }
 
        [WorkItem(35146, "https://github.com/dotnet/roslyn/issues/35146")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void ReadOnlyIndexer_RefLikeStructParameter_02(LanguageVersion languageVersion)
        {
            var csharp = @"
using System;
public ref struct S<T>
{
    public Span<T> this[Span<T> span] { get => default; readonly set {} }
 
    public unsafe static void N(S<byte> b)
    {
        Span<byte> x = stackalloc byte[5];
        _ = b[x];
        b[x] = x;
    }
}
";
            var comp = CreateCompilationWithMscorlibAndSpan(csharp, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.UnsafeDebugDll);
            comp.VerifyDiagnostics(
                // (10,15): warning CS9080: Use of variable 'x' in this context may expose referenced variables outside of their declaration scope
                //         _ = b[x];
                Diagnostic(ErrorCode.WRN_EscapeVariable, "x").WithArguments("x").WithLocation(10, 15),
                // (11,11): warning CS9080: Use of variable 'x' in this context may expose referenced variables outside of their declaration scope
                //         b[x] = x;
                Diagnostic(ErrorCode.WRN_EscapeVariable, "x").WithArguments("x").WithLocation(11, 11));
            var verifier = CompileAndVerify(comp, verify: Verification.Skipped);
            verifier.VerifyIL("S<T>.N", @"
{
  // Code size       34 (0x22)
  .maxstack  3
  .locals init (System.Span<byte> V_0, //x
                System.Span<byte> V_1)
  IL_0000:  nop
  IL_0001:  ldc.i4.5
  IL_0002:  conv.u
  IL_0003:  localloc
  IL_0005:  ldc.i4.5
  IL_0006:  newobj     ""System.Span<byte>..ctor(void*, int)""
  IL_000b:  stloc.1
  IL_000c:  ldloc.1
  IL_000d:  stloc.0
  IL_000e:  ldarga.s   V_0
  IL_0010:  ldloc.0
  IL_0011:  call       ""System.Span<byte> S<byte>.this[System.Span<byte>].get""
  IL_0016:  pop
  IL_0017:  ldarga.s   V_0
  IL_0019:  ldloc.0
  IL_001a:  ldloc.0
  IL_001b:  call       ""readonly void S<byte>.this[System.Span<byte>].set""
  IL_0020:  nop
  IL_0021:  ret
}
");
        }
 
        [WorkItem(22197, "https://github.com/dotnet/roslyn/issues/22197")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefTernaryMustMatchValEscapes(LanguageVersion languageVersion)
        {
            var text = @"
    using System;
 
    public class C
    {
        bool flag1 = true;
        bool flag2 = false;
 
        public void M(ref Span<int> global)
        {
            Span<int> local = stackalloc int[10];
 
            ref var r1 = ref (flag1 ? ref global : ref local);
            ref var r2 = ref (flag2 ? ref global : ref local);
 
	        // same as         global = local;   which would be an error.
            // but we can’t fail here, since r1 and r2 are basically the same, 
            // so should fail when making r1 and r2 above.
            r1 = r2;   
        }
 
        public static void Main()
        {
        }
    }
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (13,56): error CS8526: Cannot use variable 'local' in this context because it may expose referenced variables outside of their declaration scope
                //             ref var r1 = ref (flag1 ? ref global : ref local);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "local").WithArguments("local").WithLocation(13, 56),
                // (13,31): error CS8525: Branches of a ref ternary operator cannot refer to variables with incompatible declaration scopes
                //             ref var r1 = ref (flag1 ? ref global : ref local);
                Diagnostic(ErrorCode.ERR_MismatchedRefEscapeInTernary, "flag1 ? ref global : ref local").WithLocation(13, 31),
                // (14,56): error CS8526: Cannot use variable 'local' in this context because it may expose referenced variables outside of their declaration scope
                //             ref var r2 = ref (flag2 ? ref global : ref local);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "local").WithArguments("local").WithLocation(14, 56),
                // (14,31): error CS8525: Branches of a ref ternary operator cannot refer to variables with incompatible declaration scopes
                //             ref var r2 = ref (flag2 ? ref global : ref local);
                Diagnostic(ErrorCode.ERR_MismatchedRefEscapeInTernary, "flag2 ? ref global : ref local").WithLocation(14, 31)
            );
        }
 
        [WorkItem(22197, "https://github.com/dotnet/roslyn/issues/22197")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefTernaryMustMatchValEscapes1(LanguageVersion languageVersion)
        {
            var text = @"
    using System;
 
    public class C
    {
        public void M(ref Span<int> global)
        {
            Span<int> local = stackalloc int[0];
 
            // ok
            (true ? ref local : ref local) = (false ? ref global : ref global);
 
            // also OK
            (true ? ref local : ref local) = (false ? global : local);
        }
    }
";
            var comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics();
 
            var compiled = CompileAndVerify(comp, verify: Verification.Passes);
            compiled.VerifyIL("C.M(ref System.Span<int>)", @"
{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarg.1
  IL_0001:  ldobj      ""System.Span<int>""
  IL_0006:  pop
  IL_0007:  ret
}
");
        }
 
        [WorkItem(65522, "https://github.com/dotnet/roslyn/issues/65522")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DeconstructionAssignmentToGlobal(LanguageVersion languageVersion)
        {
            var text = @"
using System;
 
public class C
{
    public void M(ref Span<int> global)
    {
        Span<int> local = stackalloc int[10];
        (global, global) = global;
        (global, global) = local; // error 1
        (global, local) = local; // error 2
        (local, local) = local;
        (global, _) = local; // error 3
        (local, _) = local;
        (global, _) = global;
    }
    public static void Main()
    {
    }
}
public static class Extensions
{
    public static void Deconstruct(this Span<int> self, out Span<int> x, out Span<int> y)
    {
        throw null;
    }
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (10,9): error CS8352: Cannot use variable '(global, global) = local' in this context because it may expose referenced variables outside of their declaration scope
                //         (global, global) = local; // error 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "(global, global) = local").WithArguments("(global, global) = local").WithLocation(10, 9),
                // (10,28): error CS8350: This combination of arguments to 'Extensions.Deconstruct(Span<int>, out Span<int>, out Span<int>)' is disallowed because it may expose variables referenced by parameter 'self' outside of their declaration scope
                //         (global, global) = local; // error 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, "local").WithArguments("Extensions.Deconstruct(System.Span<int>, out System.Span<int>, out System.Span<int>)", "self").WithLocation(10, 28),
                // (11,9): error CS8352: Cannot use variable '(global, local) = local' in this context because it may expose referenced variables outside of their declaration scope
                //         (global, local) = local; // error 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "(global, local) = local").WithArguments("(global, local) = local").WithLocation(11, 9),
                // (11,27): error CS8350: This combination of arguments to 'Extensions.Deconstruct(Span<int>, out Span<int>, out Span<int>)' is disallowed because it may expose variables referenced by parameter 'self' outside of their declaration scope
                //         (global, local) = local; // error 2
                Diagnostic(ErrorCode.ERR_CallArgMixing, "local").WithArguments("Extensions.Deconstruct(System.Span<int>, out System.Span<int>, out System.Span<int>)", "self").WithLocation(11, 27),
                // (13,9): error CS8352: Cannot use variable '(global, _) = local' in this context because it may expose referenced variables outside of their declaration scope
                //         (global, _) = local; // error 3
                Diagnostic(ErrorCode.ERR_EscapeVariable, "(global, _) = local").WithArguments("(global, _) = local").WithLocation(13, 9),
                // (13,23): error CS8350: This combination of arguments to 'Extensions.Deconstruct(Span<int>, out Span<int>, out Span<int>)' is disallowed because it may expose variables referenced by parameter 'self' outside of their declaration scope
                //         (global, _) = local; // error 3
                Diagnostic(ErrorCode.ERR_CallArgMixing, "local").WithArguments("Extensions.Deconstruct(System.Span<int>, out System.Span<int>, out System.Span<int>)", "self").WithLocation(13, 23));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DeconstructionAssignmentToRefMethods(LanguageVersion languageVersion)
        {
            var text = @"
using System;
 
public class C
{
    public void M(ref Span<int> global)
    {
        Span<int> local = stackalloc int[10];
        (M(), M()) = local; // error
    }
    public static void Main() => throw null;
    public ref Span<int> M() => throw null;
}
public static class Extensions
{
    public static void Deconstruct(this Span<int> self, out Span<int> x, out Span<int> y) => throw null;
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (9,9): error CS8352: Cannot use variable '(M(), M()) = local' in this context because it may expose referenced variables outside of their declaration scope
                //         (M(), M()) = local; // error
                Diagnostic(ErrorCode.ERR_EscapeVariable, "(M(), M()) = local").WithArguments("(M(), M()) = local").WithLocation(9, 9),
                // (9,22): error CS8350: This combination of arguments to 'Extensions.Deconstruct(Span<int>, out Span<int>, out Span<int>)' is disallowed because it may expose variables referenced by parameter 'self' outside of their declaration scope
                //         (M(), M()) = local; // error
                Diagnostic(ErrorCode.ERR_CallArgMixing, "local").WithArguments("Extensions.Deconstruct(System.Span<int>, out System.Span<int>, out System.Span<int>)", "self").WithLocation(9, 22));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DeconstructionAssignmentWithRefExtension(LanguageVersion languageVersion)
        {
            var text = @"
using System;
 
public class C
{
    public void M(ref Span<int> global)
    {
        (global, global) = global;
    }
    public static void Main() => throw null;
}
public static class Extensions
{
    public static void Deconstruct(ref this Span<int> self, out Span<int> x, out Span<int> y) => throw null;
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (8,9): error CS1510: A ref or out value must be an assignable variable
                //         (global, global) = global;
                Diagnostic(ErrorCode.ERR_RefLvalueExpected, "(global, global) = global").WithLocation(8, 9)
            );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DeconstructionAssignmentWithRefExtension_UnsafeContext(LanguageVersion languageVersion)
        {
            var text = @"
using System;
 
public unsafe class C
{
    public void M(ref Span<int> global)
    {
        (global, global) = global;
    }
    public static void Main() => throw null;
}
public static class Extensions
{
    public static void Deconstruct(ref this Span<int> self, out Span<int> x, out Span<int> y) => throw null;
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.UnsafeDebugDll).VerifyDiagnostics(
                // (8,9): error CS1510: A ref or out value must be an assignable variable
                //         (global, global) = global;
                Diagnostic(ErrorCode.ERR_RefLvalueExpected, "(global, global) = global").WithLocation(8, 9)
                );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DeconstructionAssignmentWithRefReadonlyExtension(LanguageVersion languageVersion)
        {
            var text = @"
using System;
 
public class C
{
    public void M(ref Span<int> global)
    {
        Span<int> local = stackalloc int[10];
        (global, global) = global;
        (global, global) = local; // error
    }
    public static void Main() => throw null;
}
public static class Extensions
{
    public static void Deconstruct(in this Span<int> self, out Span<int> x, out Span<int> y) => throw null;
}
";
            var comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            if (languageVersion == LanguageVersion.CSharp10)
            {
                comp.VerifyDiagnostics(
                    // (10,9): error CS8352: Cannot use variable '(global, global) = local' in this context because it may expose referenced variables outside of their declaration scope
                    //         (global, global) = local; // error
                    Diagnostic(ErrorCode.ERR_EscapeVariable, "(global, global) = local").WithArguments("(global, global) = local").WithLocation(10, 9),
                    // (10,28): error CS8350: This combination of arguments to 'Extensions.Deconstruct(in Span<int>, out Span<int>, out Span<int>)' is disallowed because it may expose variables referenced by parameter 'self' outside of their declaration scope
                    //         (global, global) = local; // error
                    Diagnostic(ErrorCode.ERR_CallArgMixing, "local").WithArguments("Extensions.Deconstruct(in System.Span<int>, out System.Span<int>, out System.Span<int>)", "self").WithLocation(10, 28));
            }
            else
            {
                comp.VerifyDiagnostics(
                    // (9,9): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                    //         (global, global) = global;
                    Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "(global, global) = global").WithLocation(9, 9),
                    // (9,28): error CS8350: This combination of arguments to 'Extensions.Deconstruct(in Span<int>, out Span<int>, out Span<int>)' is disallowed because it may expose variables referenced by parameter 'self' outside of their declaration scope
                    //         (global, global) = global;
                    Diagnostic(ErrorCode.ERR_CallArgMixing, "global").WithArguments("Extensions.Deconstruct(in System.Span<int>, out System.Span<int>, out System.Span<int>)", "self").WithLocation(9, 28),
                    // (10,9): error CS8352: Cannot use variable '(global, global) = local' in this context because it may expose referenced variables outside of their declaration scope
                    //         (global, global) = local; // error
                    Diagnostic(ErrorCode.ERR_EscapeVariable, "(global, global) = local").WithArguments("(global, global) = local").WithLocation(10, 9),
                    // (10,28): error CS8350: This combination of arguments to 'Extensions.Deconstruct(in Span<int>, out Span<int>, out Span<int>)' is disallowed because it may expose variables referenced by parameter 'self' outside of their declaration scope
                    //         (global, global) = local; // error
                    Diagnostic(ErrorCode.ERR_CallArgMixing, "local").WithArguments("Extensions.Deconstruct(in System.Span<int>, out System.Span<int>, out System.Span<int>)", "self").WithLocation(10, 28));
            }
        }
 
        [ConditionalTheory(typeof(CoreClrOnly))]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DeconstructionAssignmentWithRefReadonlyExtension_02(LanguageVersion languageVersion)
        {
            var text = @"
using System;
 
public class C
{
    static void M()
    {
        Span<int> local = stackalloc int[10];
        Span<int> x1, y1;
        (x1, y1) = local; // 1
        var (x2, y2) = local;
        (var x3, var y3) = local;
        (Span<int> x4, Span<int> y4) = local;
    }
}
public static class Extensions
{
    public static void Deconstruct(in this Span<int> self, out Span<int> x, out Span<int> y) => throw null;
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), targetFramework: TargetFramework.NetCoreApp);
            comp.VerifyDiagnostics(
                // (10,9): error CS8352: Cannot use variable '(x1, y1) = local' in this context because it may expose referenced variables outside of their declaration scope
                //         (x1, y1) = local; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "(x1, y1) = local").WithArguments("(x1, y1) = local").WithLocation(10, 9),
                // (10,20): error CS8350: This combination of arguments to 'Extensions.Deconstruct(in Span<int>, out Span<int>, out Span<int>)' is disallowed because it may expose variables referenced by parameter 'self' outside of their declaration scope
                //         (x1, y1) = local; // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, "local").WithArguments("Extensions.Deconstruct(in System.Span<int>, out System.Span<int>, out System.Span<int>)", "self").WithLocation(10, 20));
        }
 
        [ConditionalTheory(typeof(CoreClrOnly))]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DeconstructionAssignmentWithRefReadonlyExtension_03(LanguageVersion languageVersion)
        {
            var text = @"
using System;
 
public class C
{
    static void M()
    {
        ReadOnlySpan<int> local = stackalloc int[10];
        ReadOnlySpan<int> x1, y1;
        (x1, y1) = local; // 1
        var (x2, y2) = local;
        (var x3, var y3) = local;
        (ReadOnlySpan<int> x4, ReadOnlySpan<int> y4) = local;
    }
}
public static class Extensions
{
    public static void Deconstruct(in this ReadOnlySpan<int> self, out ReadOnlySpan<int> x, out ReadOnlySpan<int> y) => throw null;
}
";
            var comp = CreateCompilation(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), targetFramework: TargetFramework.NetCoreApp);
            comp.VerifyDiagnostics(
                // (10,9): error CS8352: Cannot use variable '(x1, y1) = local' in this context because it may expose referenced variables outside of their declaration scope
                //         (x1, y1) = local; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "(x1, y1) = local").WithArguments("(x1, y1) = local").WithLocation(10, 9),
                // (10,20): error CS8350: This combination of arguments to 'Extensions.Deconstruct(in ReadOnlySpan<int>, out ReadOnlySpan<int>, out ReadOnlySpan<int>)' is disallowed because it may expose variables referenced by parameter 'self' outside of their declaration scope
                //         (x1, y1) = local; // 1
                Diagnostic(ErrorCode.ERR_CallArgMixing, "local").WithArguments("Extensions.Deconstruct(in System.ReadOnlySpan<int>, out System.ReadOnlySpan<int>, out System.ReadOnlySpan<int>)", "self").WithLocation(10, 20));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DeconstructionAssignmentWithReturnValue(LanguageVersion languageVersion)
        {
            var text = @"
using System;
 
public class C
{
    public void M(ref Span<int> global)
    {
        var t = ((global, global) = global); // error
    }
    public static void Main() => throw null;
}
public static class Extensions
{
    public static void Deconstruct(this Span<int> self, out Span<int> x, out Span<int> y) => throw null;
}
namespace System
{
    public struct ValueTuple<T1, T2>
    {
        public T1 Item1;
        public T2 Item2;
 
        public ValueTuple(T1 item1, T2 item2)
        {
            this.Item1 = item1;
            this.Item2 = item2;
        }
    }
}";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (8,19): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         var t = ((global, global) = global); // error
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "global").WithArguments("System.Span<int>").WithLocation(8, 19),
                // (8,27): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         var t = ((global, global) = global); // error
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "global").WithArguments("System.Span<int>").WithLocation(8, 27)
            );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DeconstructionAssignmentOfTuple(LanguageVersion languageVersion)
        {
            var text = @"
using System;
 
public class C
{
    public void M(ref Span<int> global)
    {
        Span<int> local = stackalloc int[10];
        string s;
        C c;
 
        (global, global) = (local, local); // error 1
 
        (global, s) = (local, """"); // error 2
        (global, s) = (local, null); // error 3
 
        (local, s) = (global, """"); // error 4
        (local, s) = (global, null); // error 5
 
        (c, s) = (local, """"); // error 6
        (c, s) = (local, null);
    }
    public static void Main() => throw null;
    public static implicit operator C(Span<int> s) => throw null;
}
namespace System
{
    public struct ValueTuple<T1, T2>
    {
        public T1 Item1;
        public T2 Item2;
 
        public ValueTuple(T1 item1, T2 item2)
        {
            this.Item1 = item1;
            this.Item2 = item2;
        }
    }
}
";
            var compilation = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            compilation.VerifyDiagnostics(
                // (12,29): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (global, global) = (local, local); // error 1
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span<int>").WithLocation(12, 29),
                // (12,36): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (global, global) = (local, local); // error 1
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span<int>").WithLocation(12, 36),
                // (14,24): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (global, s) = (local, ""); // error 2
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span<int>").WithLocation(14, 24),
                // (15,24): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (global, s) = (local, null); // error 3
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span<int>").WithLocation(15, 24),
                // (17,23): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (local, s) = (global, ""); // error 4
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "global").WithArguments("System.Span<int>").WithLocation(17, 23),
                // (18,23): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (local, s) = (global, null); // error 5
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "global").WithArguments("System.Span<int>").WithLocation(18, 23),
                // (20,19): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (c, s) = (local, ""); // error 6
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span<int>").WithLocation(20, 19)
            );
 
            // Check the Type and ConvertedType of tuples on the right-hand-side
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
 
            var tuple2 = tree.GetCompilationUnitRoot().DescendantNodes().OfType<TupleExpressionSyntax>().ElementAt(3);
            Assert.Equal(@"(local, """")", tuple2.ToString());
            Assert.Equal(@"(global, s) = (local, """")", tuple2.Parent.ToString());
            Assert.Equal("(System.Span<int> local, string)", model.GetTypeInfo(tuple2).Type.ToString());
            Assert.Equal("(System.Span<int>, string)", model.GetTypeInfo(tuple2).ConvertedType.ToString());
 
            var tuple3 = tree.GetCompilationUnitRoot().DescendantNodes().OfType<TupleExpressionSyntax>().ElementAt(5);
            Assert.Equal(@"(local, null)", tuple3.ToString());
            Assert.Equal(@"(global, s) = (local, null)", tuple3.Parent.ToString());
            Assert.Null(model.GetTypeInfo(tuple3).Type);
            Assert.Equal("(System.Span<int>, string)", model.GetTypeInfo(tuple3).ConvertedType.ToString());
 
            var tuple6 = tree.GetCompilationUnitRoot().DescendantNodes().OfType<TupleExpressionSyntax>().ElementAt(11);
            Assert.Equal(@"(local, """")", tuple6.ToString());
            Assert.Equal(@"(c, s) = (local, """")", tuple6.Parent.ToString());
            Assert.Equal("(System.Span<int> local, string)", model.GetTypeInfo(tuple6).Type.ToString());
            Assert.Equal("(C, string)", model.GetTypeInfo(tuple6).ConvertedType.ToString());
 
            var tuple7 = tree.GetCompilationUnitRoot().DescendantNodes().OfType<TupleExpressionSyntax>().ElementAt(13);
            Assert.Equal("(local, null)", tuple7.ToString());
            Assert.Equal("(c, s) = (local, null)", tuple7.Parent.ToString());
            Assert.Null(model.GetTypeInfo(tuple7).Type);
            Assert.Equal("(C, string)", model.GetTypeInfo(tuple7).ConvertedType.ToString());
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DeconstructionAssignmentOfTuple_WithoutValueTuple(LanguageVersion languageVersion)
        {
            var text = @"
using System;
 
public class C
{
    public void M(ref Span<int> global)
    {
        Span<int> local = stackalloc int[10];
        string s;
        C c;
 
        (global, global) = (local, local); // error 1
 
        (global, s) = (local, """"); // error 2
        (global, s) = (local, null); // error 3
 
        (local, s) = (global, """"); // error 4
        (local, s) = (global, null); // error 5
 
        (c, s) = (local, """"); // error 6
        (c, s) = (local, null); // error 7
    }
    public static void Main() => throw null;
    public static implicit operator C(Span<int> s) => throw null;
}
";
            var compilation = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            compilation.VerifyDiagnostics(
                // (12,28): error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported
                //         (global, global) = (local, local); // error 1
                Diagnostic(ErrorCode.ERR_PredefinedValueTupleTypeNotFound, "(local, local)").WithArguments("System.ValueTuple`2").WithLocation(12, 28),
                // (12,29): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (global, global) = (local, local); // error 1
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span<int>").WithLocation(12, 29),
                // (12,36): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (global, global) = (local, local); // error 1
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span<int>").WithLocation(12, 36),
                // (14,23): error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported
                //         (global, s) = (local, ""); // error 2
                Diagnostic(ErrorCode.ERR_PredefinedValueTupleTypeNotFound, @"(local, """")").WithArguments("System.ValueTuple`2").WithLocation(14, 23),
                // (14,24): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (global, s) = (local, ""); // error 2
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span<int>").WithLocation(14, 24),
                // (15,23): error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported
                //         (global, s) = (local, null); // error 3
                Diagnostic(ErrorCode.ERR_PredefinedValueTupleTypeNotFound, "(local, null)").WithArguments("System.ValueTuple`2").WithLocation(15, 23),
                // (17,22): error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported
                //         (local, s) = (global, ""); // error 4
                Diagnostic(ErrorCode.ERR_PredefinedValueTupleTypeNotFound, @"(global, """")").WithArguments("System.ValueTuple`2").WithLocation(17, 22),
                // (17,23): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (local, s) = (global, ""); // error 4
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "global").WithArguments("System.Span<int>").WithLocation(17, 23),
                // (18,22): error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported
                //         (local, s) = (global, null); // error 5
                Diagnostic(ErrorCode.ERR_PredefinedValueTupleTypeNotFound, "(global, null)").WithArguments("System.ValueTuple`2").WithLocation(18, 22),
                // (20,18): error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported
                //         (c, s) = (local, ""); // error 6
                Diagnostic(ErrorCode.ERR_PredefinedValueTupleTypeNotFound, @"(local, """")").WithArguments("System.ValueTuple`2").WithLocation(20, 18),
                // (20,19): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (c, s) = (local, ""); // error 6
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span<int>").WithLocation(20, 19),
                // (21,18): error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported
                //         (c, s) = (local, null); // error 7
                Diagnostic(ErrorCode.ERR_PredefinedValueTupleTypeNotFound, "(local, null)").WithArguments("System.ValueTuple`2").WithLocation(21, 18)
            );
 
            // Check the Type and ConvertedType of tuples on the right-hand-side
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
 
            var tuple2 = tree.GetCompilationUnitRoot().DescendantNodes().OfType<TupleExpressionSyntax>().ElementAt(3);
            Assert.Equal(@"(local, """")", tuple2.ToString());
            Assert.Equal(@"(global, s) = (local, """")", tuple2.Parent.ToString());
            Assert.Equal("(System.Span<int> local, string)", model.GetTypeInfo(tuple2).Type.ToString());
            Assert.Equal("(System.Span<int>, string)", model.GetTypeInfo(tuple2).ConvertedType.ToString());
 
            var tuple3 = tree.GetCompilationUnitRoot().DescendantNodes().OfType<TupleExpressionSyntax>().ElementAt(5);
            Assert.Equal(@"(local, null)", tuple3.ToString());
            Assert.Equal(@"(global, s) = (local, null)", tuple3.Parent.ToString());
            Assert.Null(model.GetTypeInfo(tuple3).Type);
            Assert.Equal("(System.Span<int>, string)", model.GetTypeInfo(tuple3).ConvertedType.ToString());
 
            var tuple6 = tree.GetCompilationUnitRoot().DescendantNodes().OfType<TupleExpressionSyntax>().ElementAt(11);
            Assert.Equal(@"(local, """")", tuple6.ToString());
            Assert.Equal(@"(c, s) = (local, """")", tuple6.Parent.ToString());
            Assert.Equal("(System.Span<int> local, string)", model.GetTypeInfo(tuple6).Type.ToString());
            Assert.Equal("(C, string)", model.GetTypeInfo(tuple6).ConvertedType.ToString());
 
            var tuple7 = tree.GetCompilationUnitRoot().DescendantNodes().OfType<TupleExpressionSyntax>().ElementAt(13);
            Assert.Equal("(local, null)", tuple7.ToString());
            Assert.Equal("(c, s) = (local, null)", tuple7.Parent.ToString());
            Assert.Null(model.GetTypeInfo(tuple7).Type);
            Assert.Equal("(C, string)", model.GetTypeInfo(tuple7).ConvertedType.ToString());
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DeconstructionAssignmentOfRefLikeTuple(LanguageVersion languageVersion)
        {
            var text = @"
using System;
 
public class C
{
    public void M(ref Span<int> global)
    {
        Span<int> local = stackalloc int[10];
        String s;
        C c;
 
        (global, global) = (local, local); // error 1
 
        (global, s) = (local, """"); // error 2
        (global, s) = (local, null); // error 3
 
        (local, s) = (global, """"); // error 4
        (local, s) = (global, null); // error 5
 
        (c, s) = (local, """"); // error 6
        (c, s) = (local, null);
    }
    public static void Main() => throw null;
    public static implicit operator C(Span<int> s) => throw null;
}
namespace System
{
    // Note: there is no way to make a ValueTuple type that will hold Spans and still be recognized as well-known type for tuples
    public ref struct ValueTuple<T1, T2>
    {
        public T1 Item1;
        public T2 Item2;
 
        public ValueTuple(T1 item1, T2 item2)
        {
            this.Item1 = item1;
            this.Item2 = item2;
        }
    }
}
";
            var compilation = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            compilation.VerifyDiagnostics(
                // (12,29): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (global, global) = (local, local); // error 1
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span<int>").WithLocation(12, 29),
                // (12,36): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (global, global) = (local, local); // error 1
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span<int>").WithLocation(12, 36),
                // (14,24): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (global, s) = (local, ""); // error 2
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span<int>").WithLocation(14, 24),
                // (15,24): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (global, s) = (local, null); // error 3
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span<int>").WithLocation(15, 24),
                // (17,23): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (local, s) = (global, ""); // error 4
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "global").WithArguments("System.Span<int>").WithLocation(17, 23),
                // (18,23): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (local, s) = (global, null); // error 5
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "global").WithArguments("System.Span<int>").WithLocation(18, 23),
                // (20,19): error CS0306: The type 'Span<int>' may not be used as a type argument
                //         (c, s) = (local, ""); // error 6
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span<int>").WithLocation(20, 19));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DeconstructionAssignmentToOuter(LanguageVersion languageVersion)
        {
            var text = @"
using System;
 
public class C
{
    public void M()
    {
        Span<int> outer = stackalloc int[10];
 
        {
            Span<int> local = stackalloc int[10]; // both stackallocs have the same escape scope
            (outer, outer) = outer;
            (outer, outer) = local;
            (outer, local) = local;
            (local, local) = local;
        }
    }
    public static void Main() => throw null;
}
public static class Extensions
{
    public static void Deconstruct(this Span<int> self, out Span<int> x, out Span<int> y) => throw null;
}
";
 
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics();
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void DeconstructionDeclaration(LanguageVersion languageVersion)
        {
            var text = @"
using System;
 
public class C
{
    public void M(ref Span<int> global)
    {
        Span<int> local = stackalloc int[10];
        var (local1, local2) = local;
        global = local1; // error 1
        global = local2; // error 2
 
        var (local3, local4) = global;
        global = local3;
        global = local4;
    }
    public static void Main() => throw null;
}
public static class Extensions
{
    public static void Deconstruct(this Span<int> self, out Span<int> x, out Span<int> y) => throw null;
}
";
            var comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics(
                // (10,18): error CS8352: Cannot use variable 'local1' in this context because it may expose referenced variables outside of their declaration scope
                //         global = local1; // error 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "local1").WithArguments("local1").WithLocation(10, 18),
                // (11,18): error CS8352: Cannot use variable 'local2' in this context because it may expose referenced variables outside of their declaration scope
                //         global = local2; // error 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "local2").WithArguments("local2").WithLocation(11, 18));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefLikeForeach(LanguageVersion languageVersion)
        {
            var text = @"
using System;
 
public class C
{
    public void M(ref S global)
    {
        S localCollection = stackalloc int[10];
        foreach (var local in localCollection)
        {
            global = local; // error
        }
    }
    public static void Main() => throw null;
}
 
public ref struct S
{
    public S GetEnumerator() => throw null;
    public bool MoveNext() => throw null;
    public S Current => throw null;
    public static implicit operator S(Span<int> s) => throw null;
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (11,22): error CS8352: Cannot use variable 'local' in this context because it may expose referenced variables outside of their declaration scope
                //             global = local; // error
                Diagnostic(ErrorCode.ERR_EscapeVariable, "local").WithArguments("local").WithLocation(11, 22)
                );
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefLikeDeconstructionForeach(LanguageVersion languageVersion)
        {
            var text = @"
using System;
 
public class C
{
    public void M(ref S global)
    {
        S localCollection = stackalloc int[10];
        foreach (var (local1, local2) in localCollection)
        {
            global = local1; // error 1
            global = local2; // error 2
        }
    }
    public static void Main() => throw null;
}
 
public ref struct S
{
    public S GetEnumerator() => throw null;
    public bool MoveNext() => throw null;
    public S Current => throw null;
    public static implicit operator S(Span<int> s) => throw null;
    public void Deconstruct(out S s1, out S s2) => throw null;
}
";
            var comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics(
                // (11,22): error CS8352: Cannot use variable 'local1' in this context because it may expose referenced variables outside of their declaration scope
                //             global = local1; // error 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "local1").WithArguments("local1").WithLocation(11, 22),
                // (12,22): error CS8352: Cannot use variable 'local2' in this context because it may expose referenced variables outside of their declaration scope
                //             global = local2; // error 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "local2").WithArguments("local2").WithLocation(12, 22));
        }
 
        [Theory]
        [CombinatorialData]
        public void RefLikeDeconstruction(
            [CombinatorialValues(LanguageVersion.CSharp10, LanguageVersion.CSharp11)] LanguageVersion languageVersion,
            bool useReadOnly)
        {
            string refModifier = useReadOnly ? "readonly" : "";
            var text = $@"
using System;
 
public class C
{{
    public void M(ref S global)
    {{
        S localCollection = stackalloc int[10];
        var (local1, local2) = localCollection;
        global = local1; // error 1
        global = local2; // error 2
    }}
}}
 
public {refModifier} ref struct S
{{
    public static implicit operator S(Span<int> s) => throw null;
    public void Deconstruct(out S s1, out S s2) => throw null;
}}
";
            var comp = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
            comp.VerifyDiagnostics(
                // (10,18): error CS8352: Cannot use variable 'local1' in this context because it may expose referenced variables outside of their declaration scope
                //         global = local1; // error 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "local1").WithArguments("local1").WithLocation(10, 18),
                // (11,18): error CS8352: Cannot use variable 'local2' in this context because it may expose referenced variables outside of their declaration scope
                //         global = local2; // error 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "local2").WithArguments("local2").WithLocation(11, 18));
        }
 
        [WorkItem(22361, "https://github.com/dotnet/roslyn/issues/22361")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefLikeOutVarFromLocal(LanguageVersion languageVersion)
        {
            var text = @"
using System;
 
public class C
{
    public void M(ref S global)
    {
        S local1 = stackalloc int[10];
        local1.M(out S local2);
        local1 = local2; // ok
        global = local2; // error
    }
    public static void Main() => throw null;
}
 
public ref struct S
{
    public static implicit operator S(Span<int> s) => throw null;
    public void M(out S s) => throw null;
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (11,18): error CS8352: Cannot use variable 'local2' in this context because it may expose referenced variables outside of their declaration scope
                //         global = local2; // error
                Diagnostic(ErrorCode.ERR_EscapeVariable, "local2").WithArguments("local2").WithLocation(11, 18));
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefLikeOutVarFromGlobal(LanguageVersion languageVersion)
        {
            var text = @"
using System;
 
public class C
{
    public void M(ref S global)
    {
        global.M(out S local2);
        global = local2;
    }
    public static void Main() => throw null;
}
 
public ref struct S
{
    public static implicit operator S(Span<int> s) => throw null;
    public void M(out S s) => throw null;
}
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics();
        }
 
        [WorkItem(22456, "https://github.com/dotnet/roslyn/issues/22456")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void InMatchesIn(LanguageVersion languageVersion)
        {
            var text = @"
public class C
{
    public static void Main() => throw null;
 
    static ref readonly int F1(in int x)
    {
        return ref x; 
    }
 
    static ref readonly int Test1(in int x)
    {
        return ref F1(in x);
    }
 
    static ref readonly int Test2(in int x)
    {
        ref readonly var t = ref F1(in x);
        return ref t;
    }
 
    static ref readonly int Test3()
    {
        return ref F1(in (new int[1])[0]);
    }
 
    static ref readonly int Test4()
    {
        ref readonly var t = ref F1(in (new int[1])[0]);
        return ref t;
    }
}
 
";
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics();
        }
 
        [WorkItem(24776, "https://github.com/dotnet/roslyn/issues/24776")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void PointerElementAccess_RefStructPointer(LanguageVersion languageVersion)
        {
            CreateCompilation(@"
public ref struct TestStruct
{
    public void M() { }
}
public class C
{
    public static unsafe void Test(TestStruct[] ar)
    {
        fixed (TestStruct* p = ar)
        {
            for (int i = 0; i < ar.Length; i++)
            {
                p[i].M();
            }
        }
    }
}", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(
                // (8,36): error CS0611: Array elements cannot be of type 'TestStruct'
                //     public static unsafe void Test(TestStruct[] ar)
                Diagnostic(ErrorCode.ERR_ArrayElementCantBeRefAny, "TestStruct").WithArguments("TestStruct").WithLocation(8, 36));
        }
 
        [WorkItem(24776, "https://github.com/dotnet/roslyn/issues/24776")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void PointerIndirectionOperator_RefStructPointer(LanguageVersion languageVersion)
        {
            CreateCompilation(@"
public ref struct TestStruct
{
    public void M() { }
}
public class C
{
    public static unsafe void Test(TestStruct[] ar)
    {
        fixed (TestStruct* p = ar)
        {
            var x = *p;
        }
    }
}", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(
                // (8,36): error CS0611: Array elements cannot be of type 'TestStruct'
                //     public static unsafe void Test(TestStruct[] ar)
                Diagnostic(ErrorCode.ERR_ArrayElementCantBeRefAny, "TestStruct").WithArguments("TestStruct").WithLocation(8, 36));
        }
 
        [WorkItem(25398, "https://github.com/dotnet/roslyn/issues/25398")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void AwaitRefStruct(LanguageVersion languageVersion)
        {
            CreateCompilation(@"
using System.Threading.Tasks;
 
ref struct S { }
 
class C
{
    async Task M(Task<S> t)
    {
        _ = await t;
 
        var a = await t;
 
        var r = t.Result;
        M(await t, ref r);
    }
 
    void M(S t, ref S t1)
    {
    }
}", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.ReleaseDll).VerifyDiagnostics(
                // (8,26): error CS0306: The type 'S' may not be used as a type argument
                //     async Task M(Task<S> t)
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "t").WithArguments("S").WithLocation(8, 26),
                // (12,9): error CS4012: Parameters or locals of type 'S' cannot be declared in async methods or async lambda expressions.
                //         var a = await t;
                Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "var").WithArguments("S").WithLocation(12, 9),
                // (14,9): error CS4012: Parameters or locals of type 'S' cannot be declared in async methods or async lambda expressions.
                //         var r = t.Result;
                Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "var").WithArguments("S").WithLocation(14, 9),
                // (15,9): error CS8350: This combination of arguments to 'C.M(S, ref S)' is disallowed because it may expose variables referenced by parameter 't' outside of their declaration scope
                //         M(await t, ref r);
                Diagnostic(ErrorCode.ERR_CallArgMixing, "M(await t, ref r)").WithArguments("C.M(S, ref S)", "t").WithLocation(15, 9)
                );
        }
 
        [WorkItem(25398, "https://github.com/dotnet/roslyn/issues/25398")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void CoalesceRefStruct(LanguageVersion languageVersion)
        {
            CreateCompilation(@"
ref struct S { }
 
class C
{
    void M()
    {       
        _ = (S?)null ?? default;
 
        var a = (S?)null ?? default;
    }
}", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.ReleaseDll).VerifyDiagnostics(
                // (8,14): error CS0306: The type 'S' may not be used as a type argument
                //         _ = (S?)null ?? default;
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "S?").WithArguments("S").WithLocation(8, 14),
                // (10,18): error CS0306: The type 'S' may not be used as a type argument
                //         var a = (S?)null ?? default;
                Diagnostic(ErrorCode.ERR_BadTypeArgument, "S?").WithArguments("S").WithLocation(10, 18)
                );
        }
 
        [WorkItem(25398, "https://github.com/dotnet/roslyn/issues/25398")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void ArrayAccessRefStruct(LanguageVersion languageVersion)
        {
            CreateCompilation(@"
ref struct S { }
 
class C
{
    void M()
    {       
        _ = ((S[])null)[0];
 
        var a = ((S[])null)[0];
    }
}", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.ReleaseDll).VerifyDiagnostics(
                // (8,15): error CS0611: Array elements cannot be of type 'S'
                //         _ = ((S[])null)[0];
                Diagnostic(ErrorCode.ERR_ArrayElementCantBeRefAny, "S").WithArguments("S").WithLocation(8, 15),
                // (10,19): error CS0611: Array elements cannot be of type 'S'
                //         var a = ((S[])null)[0];
                Diagnostic(ErrorCode.ERR_ArrayElementCantBeRefAny, "S").WithArguments("S").WithLocation(10, 19)
                );
        }
 
        [WorkItem(25398, "https://github.com/dotnet/roslyn/issues/25398")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void ConditionalRefStruct(LanguageVersion languageVersion)
        {
            CreateCompilation(@"
ref struct S { }
 
class C
{
    void M()
    {       
        _ = ((C)null)?.Test();
 
        var a = ((C)null)?.Test();
    }
    
    S Test() => default;        
}", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.ReleaseDll).VerifyDiagnostics(
                // (8,23): error CS8977: 'S' cannot be made nullable.
                //         _ = ((C)null)?.Test();
                Diagnostic(ErrorCode.ERR_CannotBeMadeNullable, ".Test()").WithArguments("S").WithLocation(8, 23),
                // (10,27): error CS8977: 'S' cannot be made nullable.
                //         var a = ((C)null)?.Test();
                Diagnostic(ErrorCode.ERR_CannotBeMadeNullable, ".Test()").WithArguments("S").WithLocation(10, 27)
                );
        }
 
        [WorkItem(25485, "https://github.com/dotnet/roslyn/issues/25485")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void ArrayAccess_CrashesEscapeRules(LanguageVersion languageVersion)
        {
            CreateCompilationWithMscorlibAndSpan(@"
using System;
public class Class1
{
    public void Foo(Span<Thing>[] first, Thing[] second)
    {
        var x = first[0];
    }
}
public struct Thing
{
}
", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (5,21): error CS0611: Array elements cannot be of type 'Span<Thing>'
                //     public void Foo(Span<Thing>[] first, Thing[] second)
                Diagnostic(ErrorCode.ERR_ArrayElementCantBeRefAny, "Span<Thing>").WithArguments("System.Span<Thing>").WithLocation(5, 21));
        }
 
        [WorkItem(26457, "https://github.com/dotnet/roslyn/issues/26457")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefThisAssignment_Class(LanguageVersion languageVersion)
        {
            CreateCompilation(@"
class Test
{
    public void M(ref Test obj)
    {
        this = ref this;
        obj = ref this;
        this = ref obj;
    }
}", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (6,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         this = ref this;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "this").WithLocation(6, 9),
                // (6,20): error CS1510: A ref or out value must be an assignable variable
                //         this = ref this;
                Diagnostic(ErrorCode.ERR_RefLvalueExpected, "this").WithLocation(6, 20),
                // (7,19): error CS1510: A ref or out value must be an assignable variable
                //         obj = ref this;
                Diagnostic(ErrorCode.ERR_RefLvalueExpected, "this").WithLocation(7, 19),
                // (8,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         this = ref obj;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "this").WithLocation(8, 9));
        }
 
        [WorkItem(26457, "https://github.com/dotnet/roslyn/issues/26457")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefThisAssignment_Struct(LanguageVersion languageVersion)
        {
            CreateCompilation(@"
struct Test
{
    public void M(ref Test obj)
    {
        this = ref this;
        obj = ref this;
        this = ref obj;
    }
}", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (6,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         this = ref this;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "this").WithLocation(6, 9),
                // (7,9): error CS8374: Cannot ref-assign 'this' to 'obj' because 'this' has a narrower escape scope than 'obj'.
                //         obj = ref this;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "obj = ref this").WithArguments("obj", "this").WithLocation(7, 9),
                // (8,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         this = ref obj;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "this").WithLocation(8, 9));
        }
 
        [WorkItem(26457, "https://github.com/dotnet/roslyn/issues/26457")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefThisAssignment_ReadOnlyStruct(LanguageVersion languageVersion)
        {
            CreateCompilation(@"
readonly struct Test
{
    public void M(ref Test obj)
    {
        this = ref this;
        obj = ref this;
        this = ref obj;
    }
}", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (6,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         this = ref this;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "this").WithLocation(6, 9),
                // (7,19): error CS1510: A ref or out value must be an assignable variable
                //         obj = ref this;
                Diagnostic(ErrorCode.ERR_RefLvalueExpected, "this").WithLocation(7, 19),
                // (8,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         this = ref obj;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "this").WithLocation(8, 9));
        }
 
        [WorkItem(26457, "https://github.com/dotnet/roslyn/issues/26457")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefThisAssignment_RefStruct(LanguageVersion languageVersion)
        {
            var source = @"
ref struct Test
{
    public void M(ref Test obj)
    {
        this = ref this;
        obj = ref this;
        this = ref obj;
    }
}";
 
            CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (6,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         this = ref this;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "this").WithLocation(6, 9),
                // (7,9): error CS8374: Cannot ref-assign 'this' to 'obj' because 'this' has a narrower escape scope than 'obj'.
                //         obj = ref this;
                Diagnostic(ErrorCode.ERR_RefAssignNarrower, "obj = ref this").WithArguments("obj", "this").WithLocation(7, 9),
                // (8,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         this = ref obj;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "this").WithLocation(8, 9));
        }
 
        [WorkItem(26457, "https://github.com/dotnet/roslyn/issues/26457")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void RefThisAssignment_ReadOnlyRefStruct(LanguageVersion languageVersion)
        {
            CreateCompilation(@"
readonly ref struct Test
{
    public void M(ref Test obj)
    {
        this = ref this;
        obj = ref this;
        this = ref obj;
    }
}", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics(
                // (6,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         this = ref this;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "this").WithLocation(6, 9),
                // (7,19): error CS1510: A ref or out value must be an assignable variable
                //         obj = ref this;
                Diagnostic(ErrorCode.ERR_RefLvalueExpected, "this").WithLocation(7, 19),
                // (8,9): error CS8373: The left-hand side of a ref assignment must be a ref variable.
                //         this = ref obj;
                Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "this").WithLocation(8, 9));
        }
 
        [WorkItem(29927, "https://github.com/dotnet/roslyn/issues/29927")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void CoalesceSpanReturn(LanguageVersion languageVersion)
        {
            CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    Span<byte> M()
    {       
        return null ?? new Span<byte>();
    }
}", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.ReleaseDll).VerifyDiagnostics();
        }
 
        [WorkItem(29927, "https://github.com/dotnet/roslyn/issues/29927")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void CoalesceAssignSpanReturn(LanguageVersion languageVersion)
        {
            CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    Span<byte> M()
    {       
        var x = null ?? new Span<byte>();
        return x;
    }
}", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.ReleaseDll).VerifyDiagnostics();
        }
 
        [WorkItem(29927, "https://github.com/dotnet/roslyn/issues/29927")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void CoalesceRefSpanReturn(LanguageVersion languageVersion)
        {
            CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    Span<byte> M()
    {       
        Span<byte> x = stackalloc byte[10];
        return null ?? x;
    }
}", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.ReleaseDll).VerifyDiagnostics(
                // (8,24): error CS8352: Cannot use variable 'x' in this context because it may expose referenced variables outside of their declaration scope
                //         return null ?? x;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "x").WithArguments("x").WithLocation(8, 24)
                );
        }
 
        [WorkItem(62973, "https://github.com/dotnet/roslyn/issues/62973")]
        [Fact]
        public void RegressionTest62973()
        {
            var compilation = CreateCompilation(
"""
#nullable enable
using System.Collections.Generic;
 
System.Console.WriteLine("");
 
public class ArrayPool<T> { }
public readonly ref struct PooledArrayHandle<T>
{
    public void Dispose() { }
}
 
public static class Test
{
    public static PooledArrayHandle<T> RentArray<T>(this int length, out T[] array, ArrayPool<T>? pool = null) {
        throw null!;
    }
 
    public static IEnumerable<int> Iterator() {
        // Verify that the ref struct is usable
        using var handle = RentArray<int>(200, out var array);
  
        for (int i = 0; i < array.Length; i++) {
            yield return i;
        }
    }
}
""");
            compilation.VerifyEmitDiagnostics(
                // (20,19): error CS4013: Instance of type 'PooledArrayHandle<int>' cannot be used inside a nested function, query expression, iterator block or async method
                //         using var handle = RentArray<int>(200, out var array);
                Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "handle = RentArray<int>(200, out var array)").WithArguments("PooledArrayHandle<int>").WithLocation(20, 19));
        }
 
        [Theory(Skip = "https://github.com/dotnet/roslyn/issues/40583")]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void ConvertedSpanReturn(LanguageVersion languageVersion)
        {
            CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    D M1() => stackalloc byte[10];
    D M2() { return stackalloc byte[10]; }
}
class D
{
    public static implicit operator D(Span<byte> span) => new D();
}
", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.ReleaseDll).VerifyDiagnostics();
        }
 
        [WorkItem(63384, "https://github.com/dotnet/roslyn/issues/63384")]
        [Theory]
        [InlineData("nuint")]
        [InlineData("nint")]
        public void NativeIntegerThis(string type)
        {
            var compilation = CreateCompilation(
    $$"""
        ref struct S
        {
            static int M({{type}} ptr) => ptr.GetHashCode();
        }
    """);
 
            compilation.VerifyDiagnostics();
        }
 
        [Fact]
        [WorkItem(63446, "https://github.com/dotnet/roslyn/issues/63446")]
        public void RefDiscardAssignment()
        {
            var source = @"
class Program
{
    static int dummy;
 
    static ref int F()
    {
        return ref dummy;
    }
 
    static void Main()
    {
        Test();
        System.Console.WriteLine(""Done"");
    }
 
    static void Test()
    {
        _ = ref F();
    }
}
";
 
            CompileAndVerify(source, expectedOutput: "Done").VerifyDiagnostics().
                VerifyIL("Program.Test",
@"
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  call       ""ref int Program.F()""
  IL_0005:  pop
  IL_0006:  ret
}
");
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_01()
        {
            var source =
@"
using System;
using System.Runtime.CompilerServices;
using System.Diagnostics.CodeAnalysis;
 
internal class Program
{
    private static readonly Vec4 ReadOnlyVec = new Vec4(1, 2, 3, 4);
 
    static void Main()
    {
        // This refers to stack memory that has already been left out.
        ref Vec4 local = ref Test1();
        Console.WriteLine(local);
    }
 
    private static ref Vec4 Test1()
    {
        // Defensive copy occurs and it is placed in stack memory implicitly.
        // The method returns a reference to the copy, which happens invalid memory access.
        ref Vec4 xyzw1 = ref ReadOnlyVec.Self;
        return ref xyzw1;
    }
 
    private static ref Vec4 Test2()
    {
        var copy = ReadOnlyVec;
        ref Vec4 xyzw2 = ref copy.Self;
        return ref xyzw2;
    }
 
    private static ref Vec4 Test3()
    {
        ref Vec4 xyzw3 = ref ReadOnlyVec.Self2();
        return ref xyzw3;
    }
 
    private static ref Vec4 Test4()
    {
        var copy = ReadOnlyVec;
        ref Vec4 xyzw4 = ref copy.Self2();
        return ref xyzw4;
    }
}
 
public struct Vec4
{
    public float X, Y, Z, W;
    public Vec4(float x, float y, float z, float w) => (X, Y, Z, W) = (x, y, z, w);
 
    [UnscopedRef]
    public ref Vec4 Self => ref this;
 
    [UnscopedRef]
    public ref Vec4 Self2() => ref this;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (22,20): error CS8157: Cannot return 'xyzw1' by reference because it was initialized to a value that cannot be returned by reference
                //         return ref xyzw1;
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "xyzw1").WithArguments("xyzw1").WithLocation(22, 20),
                // (29,20): error CS8157: Cannot return 'xyzw2' by reference because it was initialized to a value that cannot be returned by reference
                //         return ref xyzw2;
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "xyzw2").WithArguments("xyzw2").WithLocation(29, 20),
                // (35,20): error CS8157: Cannot return 'xyzw3' by reference because it was initialized to a value that cannot be returned by reference
                //         return ref xyzw3;
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "xyzw3").WithArguments("xyzw3").WithLocation(35, 20),
                // (42,20): error CS8157: Cannot return 'xyzw4' by reference because it was initialized to a value that cannot be returned by reference
                //         return ref xyzw4;
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "xyzw4").WithArguments("xyzw4").WithLocation(42, 20)
                );
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_02()
        {
            var source =
@"#pragma warning disable CS8321 // The local function is declared but never used
using System.Diagnostics.CodeAnalysis;
 
var x = new Wrap { X = 1 };
 
ref var r = ref m1(x);
System.Console.WriteLine(r.X); // undefined value
 
static ref Wrap m1(in Wrap i)
{
    ref Wrap r1 = ref i.Self; // defensive copy
    return ref r1; // ref to the local copy
}
 
static ref Wrap m2(in Wrap i)
{
    var copy = i;
    ref Wrap r2 = ref copy.Self;
    return ref r2; // ref to the local copy
}
 
static ref Wrap m3(in Wrap i)
{
    ref Wrap r3 = ref i.Self2();
    return ref r3;
}
 
static ref Wrap m4(in Wrap i)
{
    var copy = i;
    ref Wrap r4 = ref copy.Self2();
    return ref r4; // ref to the local copy
}
 
struct Wrap
{
    public float X;
 
    [UnscopedRef]
    public ref Wrap Self => ref this;
 
    [UnscopedRef]
    public ref Wrap Self2() => ref this;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (12,16): error CS8157: Cannot return 'r1' by reference because it was initialized to a value that cannot be returned by reference
                //     return ref r1; // ref to the local copy
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "r1").WithArguments("r1").WithLocation(12, 16),
                // (19,16): error CS8157: Cannot return 'r2' by reference because it was initialized to a value that cannot be returned by reference
                //     return ref r2; // ref to the local copy
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "r2").WithArguments("r2").WithLocation(19, 16),
                // (25,16): error CS8157: Cannot return 'r3' by reference because it was initialized to a value that cannot be returned by reference
                //     return ref r3;
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "r3").WithArguments("r3").WithLocation(25, 16),
                // (32,16): error CS8157: Cannot return 'r4' by reference because it was initialized to a value that cannot be returned by reference
                //     return ref r4; // ref to the local copy
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "r4").WithArguments("r4").WithLocation(32, 16)
                );
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_03()
        {
            var source =
@"
using System.Diagnostics.CodeAnalysis;
 
internal class Program
{
    private static readonly Vec4 ReadOnlyVec = new Vec4(1, 2, 3, 4);
 
    static void Main()
    {
    }
 
    private static ref Vec4 Test3()
    {
        ref Vec4 xyzw3 = ref ReadOnlyVec.Self2();
        return ref xyzw3;
    }
}
 
public struct Vec4
{
    public float X, Y, Z, W;
    public Vec4(float x, float y, float z, float w) => (X, Y, Z, W) = (x, y, z, w);
 
    [UnscopedRef]
    readonly public ref Vec4 Self2() => throw null;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, verify: Verification.Skipped).VerifyDiagnostics().VerifyIL("Program.Test3",
@"
{
  // Code size       11 (0xb)
  .maxstack  1
  IL_0000:  ldsflda    ""Vec4 Program.ReadOnlyVec""
  IL_0005:  call       ""readonly ref Vec4 Vec4.Self2()""
  IL_000a:  ret
}
");
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_04()
        {
            var source =
@"
using System.Diagnostics.CodeAnalysis;
 
internal class Program
{
    private static readonly Vec4 ReadOnlyVec = new Vec4(1, 2, 3, 4);
 
    static void Main()
    {
    }
 
    private static ref Vec4 Test1()
    {
        ref Vec4 xyzw1 = ref ReadOnlyVec.Self;
        return ref xyzw1;
    }
}
 
public struct Vec4
{
    public float X, Y, Z, W;
    public Vec4(float x, float y, float z, float w) => (X, Y, Z, W) = (x, y, z, w);
 
    [UnscopedRef]
    readonly public ref Vec4 Self => throw null;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, verify: Verification.Skipped).VerifyDiagnostics().VerifyIL("Program.Test1",
@"
{
  // Code size       11 (0xb)
  .maxstack  1
  IL_0000:  ldsflda    ""Vec4 Program.ReadOnlyVec""
  IL_0005:  call       ""readonly ref Vec4 Vec4.Self.get""
  IL_000a:  ret
}
");
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_05()
        {
            var source =
@"
using System;
using System.Diagnostics.CodeAnalysis;
 
internal class Program
{
    private static readonly Vec4 ReadOnlyVec = new Vec4(1, 2, 3, 4);
 
    static void Main()
    {
    }
 
    private static Span<float> Test1()
    {
        var xyzw1 = ReadOnlyVec.Self;
        return xyzw1;
    }
 
    private static Span<float> Test2()
    {
        var r2 = ReadOnlyVec;
        var xyzw2 = r2.Self;
        return xyzw2;
    }
}
 
public struct Vec4
{
    public float X, Y, Z, W;
    public Vec4(float x, float y, float z, float w) => (X, Y, Z, W) = (x, y, z, w);
 
    [UnscopedRef]
    public Span<float> Self
    {  get => throw null; set {}}
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (16,16): error CS8352: Cannot use variable 'xyzw1' in this context because it may expose referenced variables outside of their declaration scope
                //         return xyzw1;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "xyzw1").WithArguments("xyzw1").WithLocation(16, 16),
                // (23,16): error CS8352: Cannot use variable 'xyzw2' in this context because it may expose referenced variables outside of their declaration scope
                //         return xyzw2;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "xyzw2").WithArguments("xyzw2").WithLocation(23, 16)
                );
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_06()
        {
            var source =
@"
using System;
using System.Diagnostics.CodeAnalysis;
 
internal class Program
{
    private static readonly Vec4 ReadOnlyVec = new Vec4(1, 2, 3, 4);
 
    static void Main()
    {
    }
 
    private static Span<float> Test1()
    {
        var xyzw1 = ReadOnlyVec.Self;
        return xyzw1;
    }
}
 
public struct Vec4
{
    public float X, Y, Z, W;
    public Vec4(float x, float y, float z, float w) => (X, Y, Z, W) = (x, y, z, w);
 
    [UnscopedRef]
    readonly public Span<float> Self
    {  get => throw null; set {}}
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, verify: Verification.Skipped).VerifyDiagnostics().VerifyIL("Program.Test1",
@"
{
  // Code size       11 (0xb)
  .maxstack  1
  IL_0000:  ldsflda    ""Vec4 Program.ReadOnlyVec""
  IL_0005:  call       ""readonly System.Span<float> Vec4.Self.get""
  IL_000a:  ret
}
");
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_07()
        {
            var source =
@"
using System;
using System.Diagnostics.CodeAnalysis;
 
internal class Program
{
    private static readonly Vec4 ReadOnlyVec = new Vec4(1, 2, 3, 4);
 
    static void Main()
    {
    }
 
    private static Span<float> Test1()
    {
        var xyzw1 = ReadOnlyVec.Self;
        return xyzw1;
    }
}
 
public struct Vec4
{
    public float X, Y, Z, W;
    public Vec4(float x, float y, float z, float w) => (X, Y, Z, W) = (x, y, z, w);
 
    [UnscopedRef]
    public Span<float> Self
    { readonly get => throw null; set {}}
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, verify: Verification.Skipped).VerifyDiagnostics().VerifyIL("Program.Test1",
@"
{
  // Code size       11 (0xb)
  .maxstack  1
  IL_0000:  ldsflda    ""Vec4 Program.ReadOnlyVec""
  IL_0005:  call       ""readonly System.Span<float> Vec4.Self.get""
  IL_000a:  ret
}
");
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_08()
        {
            var source =
@"
using System;
using System.Diagnostics.CodeAnalysis;
 
internal class Program
{
    private static readonly Vec4 ReadOnlyVec = new Vec4(1, 2, 3, 4);
 
    static void Main()
    {
    }
 
    private static Span<float> Test1()
    {
        var xyzw1 = ReadOnlyVec.Self;
        return xyzw1;
    }
 
    private static Span<float> Test2()
    {
        var r2 = ReadOnlyVec;
        var xyzw2 = r2.Self;
        return xyzw2;
    }
}
 
public struct Vec4
{
    public float X, Y, Z, W;
    public Vec4(float x, float y, float z, float w) => (X, Y, Z, W) = (x, y, z, w);
 
    [UnscopedRef]
    public Span<float> Self
    {  get => throw null; readonly set {}}
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (16,16): error CS8352: Cannot use variable 'xyzw1' in this context because it may expose referenced variables outside of their declaration scope
                //         return xyzw1;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "xyzw1").WithArguments("xyzw1").WithLocation(16, 16),
                // (23,16): error CS8352: Cannot use variable 'xyzw2' in this context because it may expose referenced variables outside of their declaration scope
                //         return xyzw2;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "xyzw2").WithArguments("xyzw2").WithLocation(23, 16)
                );
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_09()
        {
            var source =
@"
using System;
using System.Diagnostics.CodeAnalysis;
 
internal class Program
{
    private static readonly Vec4 ReadOnlyVec = new Vec4(1, 2, 3, 4);
 
    static void Main()
    {
    }
 
    private static void Test1()
    {
        ReadOnlyVec.Self = default;
    }
}
 
public struct Vec4
{
    public float X, Y, Z, W;
    public Vec4(float x, float y, float z, float w) => (X, Y, Z, W) = (x, y, z, w);
 
    [UnscopedRef]
    public Span<float> Self
    {  readonly get => throw null; set {}}
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (15,9): error CS1650: Fields of static readonly field 'Program.ReadOnlyVec' cannot be assigned to (except in a static constructor or a variable initializer)
                //         ReadOnlyVec.Self = default;
                Diagnostic(ErrorCode.ERR_AssgReadonlyStatic2, "ReadOnlyVec.Self").WithArguments("Program.ReadOnlyVec").WithLocation(15, 9)
                );
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_10()
        {
            var source =
@"
using System;
using System.Diagnostics.CodeAnalysis;
 
internal class Program
{
    private static readonly Vec4 ReadOnlyVec = new Vec4(1, 2, 3, 4);
 
    static void Main()
    {
    }
 
    private static void Test1()
    {
        ReadOnlyVec.Self = default;
    }
}
 
public struct Vec4
{
    public float X, Y, Z, W;
    public Vec4(float x, float y, float z, float w) => (X, Y, Z, W) = (x, y, z, w);
 
    [UnscopedRef]
    public Span<float> Self
    {  get => throw null; readonly set {}}
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, verify: Verification.Skipped).VerifyDiagnostics().VerifyIL("Program.Test1",
@"
{
  // Code size       20 (0x14)
  .maxstack  2
  .locals init (System.Span<float> V_0)
  IL_0000:  ldsflda    ""Vec4 Program.ReadOnlyVec""
  IL_0005:  ldloca.s   V_0
  IL_0007:  initobj    ""System.Span<float>""
  IL_000d:  ldloc.0
  IL_000e:  call       ""readonly void Vec4.Self.set""
  IL_0013:  ret
}
");
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_11()
        {
            var source =
@"
 
using System.Diagnostics.CodeAnalysis;
 
public struct Vec4
{
    public float X, Y, Z, W;
    public Vec4(float x, float y, float z, float w) => (X, Y, Z, W) = (x, y, z, w);
 
    [UnscopedRef]
    public ref Vec4 Self2() => ref this;
 
    [UnscopedRef]
    readonly public ref Vec4 Test3()
    {
        ref Vec4 xyzw3 = ref this.Self2();
        return ref xyzw3;
    }
 
    [UnscopedRef]
    readonly public ref Vec4 Test4()
    {
        var r = this;
        ref Vec4 xyzw4 = ref r.Self2();
        return ref xyzw4;
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (16,30): warning CS8656: Call to non-readonly member 'Vec4.Self2()' from a 'readonly' member results in an implicit copy of 'this'.
                //         ref Vec4 xyzw3 = ref this.Self2();
                Diagnostic(ErrorCode.WRN_ImplicitCopyInReadOnlyMember, "this").WithArguments("Vec4.Self2()", "this").WithLocation(16, 30),
                // (17,20): error CS8157: Cannot return 'xyzw3' by reference because it was initialized to a value that cannot be returned by reference
                //         return ref xyzw3;
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "xyzw3").WithArguments("xyzw3").WithLocation(17, 20),
                // (25,20): error CS8157: Cannot return 'xyzw4' by reference because it was initialized to a value that cannot be returned by reference
                //         return ref xyzw4;
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "xyzw4").WithArguments("xyzw4").WithLocation(25, 20)
                );
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_12()
        {
            var source =
@"
using System.Diagnostics.CodeAnalysis;
 
public struct Vec4
{
    public float X, Y, Z, W;
    public Vec4(float x, float y, float z, float w) => (X, Y, Z, W) = (x, y, z, w);
 
    [UnscopedRef]
    public ref Vec4 Self2() => ref this;
 
    [UnscopedRef]
    public ref Vec4 Test3()
    {
        ref Vec4 xyzw3 = ref this.Self2();
        return ref xyzw3;
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, verify: Verification.Skipped).
                VerifyDiagnostics().
                VerifyIL("Vec4.Test3",
@"
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  call       ""ref Vec4 Vec4.Self2()""
  IL_0006:  ret
}
");
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_13()
        {
            var source =
@"
using System;
using System.Diagnostics.CodeAnalysis;
 
internal class Program
{
    private readonly Vec4 ReadOnlyVec = new Vec4(1, 2, 3, 4);
 
    private Program(out Span<float> x)
    {
        var xyzw3 = ReadOnlyVec.Self2();
        x = xyzw3;
    }
}
 
public struct Vec4
{
    public float X, Y, Z, W;
    public Vec4(float x, float y, float z, float w) => (X, Y, Z, W) = (x, y, z, w);
 
    [UnscopedRef]
    public Span<float> Self2() => throw null;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, verify: Verification.Skipped).
                VerifyDiagnostics().
                VerifyIL("Program..ctor",
@"
{
  // Code size       57 (0x39)
  .maxstack  5
  .locals init (System.Span<float> V_0) //xyzw3
  IL_0000:  ldarg.0
  IL_0001:  ldc.r4     1
  IL_0006:  ldc.r4     2
  IL_000b:  ldc.r4     3
  IL_0010:  ldc.r4     4
  IL_0015:  newobj     ""Vec4..ctor(float, float, float, float)""
  IL_001a:  stfld      ""Vec4 Program.ReadOnlyVec""
  IL_001f:  ldarg.0
  IL_0020:  call       ""object..ctor()""
  IL_0025:  ldarg.0
  IL_0026:  ldflda     ""Vec4 Program.ReadOnlyVec""
  IL_002b:  call       ""System.Span<float> Vec4.Self2()""
  IL_0030:  stloc.0
  IL_0031:  ldarg.1
  IL_0032:  ldloc.0
  IL_0033:  stobj      ""System.Span<float>""
  IL_0038:  ret
}
");
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_14()
        {
            var source =
@"
using System;
using System.Diagnostics.CodeAnalysis;
 
internal class Program
{
    private readonly Vec4 ReadOnlyVec = new Vec4(1, 2, 3, 4);
 
    private Program()
    {
        var d = (out Span<float> x) =>
                {
                    var xyzw1 = ReadOnlyVec.Self2();
                    x = xyzw1;
                };
 
        d = local;
 
        void local(out Span<float> x)
        {
            var xyzw2 = ReadOnlyVec.Self2();
            x = xyzw2;
        }
    }
 
    private void Test3(out Span<float> x)
    {
        var xyzw3 = ReadOnlyVec.Self2();
        x = xyzw3;
    }
}
 
public struct Vec4
{
    public float X, Y, Z, W;
    public Vec4(float x, float y, float z, float w) => (X, Y, Z, W) = (x, y, z, w);
 
    [UnscopedRef]
    public Span<float> Self2() => throw null;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (14,25): error CS8352: Cannot use variable 'xyzw1' in this context because it may expose referenced variables outside of their declaration scope
                //                     x = xyzw1;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "xyzw1").WithArguments("xyzw1").WithLocation(14, 25),
                // (22,17): error CS8352: Cannot use variable 'xyzw2' in this context because it may expose referenced variables outside of their declaration scope
                //             x = xyzw2;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "xyzw2").WithArguments("xyzw2").WithLocation(22, 17),
                // (29,13): error CS8352: Cannot use variable 'xyzw3' in this context because it may expose referenced variables outside of their declaration scope
                //         x = xyzw3;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "xyzw3").WithArguments("xyzw3").WithLocation(29, 13)
                );
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_15()
        {
            var source =
@"
using System;
using System.Diagnostics.CodeAnalysis;
 
internal class Program
{
    private readonly Vec4 ReadOnlyVec = new Vec4(1, 2, 3, 4);
    private static S s;
 
    int F1 = GetInt(s = new S(ReadOnlyVec.Self2()));
    int F2 = GetInt(() => s = new S(ReadOnlyVec.Self2()));
    static int F3 = GetInt(s = new S(ReadOnlyVec.Self2()));
 
    static int GetInt(S s) => 0;
    static int GetInt(System.Action a) => 0;
}
 
ref struct S
{
    public S (Span<float> x) {}
}
 
public struct Vec4
{
    public float X, Y, Z, W;
    public Vec4(float x, float y, float z, float w) => (X, Y, Z, W) = (x, y, z, w);
 
    [UnscopedRef]
    public Span<float> Self2() => throw null;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (8,20): error CS8345: Field or auto-implemented property cannot be of type 'S' unless it is an instance member of a ref struct.
                //     private static S s;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "S").WithArguments("S").WithLocation(8, 20),
                // (10,31): error CS0236: A field initializer cannot reference the non-static field, method, or property 'Program.ReadOnlyVec'
                //     int F1 = GetInt(s = new S(ReadOnlyVec.Self2()));
                Diagnostic(ErrorCode.ERR_FieldInitRefNonstatic, "ReadOnlyVec").WithArguments("Program.ReadOnlyVec").WithLocation(10, 31),
                // (11,37): error CS0236: A field initializer cannot reference the non-static field, method, or property 'Program.ReadOnlyVec'
                //     int F2 = GetInt(() => s = new S(ReadOnlyVec.Self2()));
                Diagnostic(ErrorCode.ERR_FieldInitRefNonstatic, "ReadOnlyVec").WithArguments("Program.ReadOnlyVec").WithLocation(11, 37),
                // (12,38): error CS0236: A field initializer cannot reference the non-static field, method, or property 'Program.ReadOnlyVec'
                //     static int F3 = GetInt(s = new S(ReadOnlyVec.Self2()));
                Diagnostic(ErrorCode.ERR_FieldInitRefNonstatic, "ReadOnlyVec").WithArguments("Program.ReadOnlyVec").WithLocation(12, 38)
                );
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_16()
        {
            var source =
@"
using System;
using System.Diagnostics.CodeAnalysis;
 
internal class Program
{
    private readonly Vec4 ReadOnlyVec = new Vec4(1, 2, 3, 4);
    private static S s;
 
    int P1 {get;} = GetInt(s = new S(ReadOnlyVec.Self2()));
    int P2 {get;} = GetInt(() => s = new S(ReadOnlyVec.Self2()));
    static int P3 {get;} = GetInt(s = new S(ReadOnlyVec.Self2()));
 
    static int GetInt(S s) => 0;
    static int GetInt(System.Action a) => 0;
}
 
ref struct S
{
    public S (Span<float> x) {}
}
 
public struct Vec4
{
    public float X, Y, Z, W;
    public Vec4(float x, float y, float z, float w) => (X, Y, Z, W) = (x, y, z, w);
 
    [UnscopedRef]
    public Span<float> Self2() => throw null;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (8,20): error CS8345: Field or auto-implemented property cannot be of type 'S' unless it is an instance member of a ref struct.
                //     private static S s;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "S").WithArguments("S").WithLocation(8, 20),
                // (10,38): error CS0236: A field initializer cannot reference the non-static field, method, or property 'Program.ReadOnlyVec'
                //     int P1 {get;} = GetInt(s = new S(ReadOnlyVec.Self2()));
                Diagnostic(ErrorCode.ERR_FieldInitRefNonstatic, "ReadOnlyVec").WithArguments("Program.ReadOnlyVec").WithLocation(10, 38),
                // (11,44): error CS0236: A field initializer cannot reference the non-static field, method, or property 'Program.ReadOnlyVec'
                //     int P2 {get;} = GetInt(() => s = new S(ReadOnlyVec.Self2()));
                Diagnostic(ErrorCode.ERR_FieldInitRefNonstatic, "ReadOnlyVec").WithArguments("Program.ReadOnlyVec").WithLocation(11, 44),
                // (12,45): error CS0236: A field initializer cannot reference the non-static field, method, or property 'Program.ReadOnlyVec'
                //     static int P3 {get;} = GetInt(s = new S(ReadOnlyVec.Self2()));
                Diagnostic(ErrorCode.ERR_FieldInitRefNonstatic, "ReadOnlyVec").WithArguments("Program.ReadOnlyVec").WithLocation(12, 45)
                );
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_17()
        {
            var source =
@"
using System;
using System.Diagnostics.CodeAnalysis;
 
internal class Program
{
    private static readonly Vec4 ReadOnlyVec = new Vec4(1, 2, 3, 4);
    private static S s;
 
    static Program()
    {
        var xyzw1 = ReadOnlyVec.Self2();
        s = new S(xyzw1);
 
        var d = static () =>
                {
                    var xyzw2 = ReadOnlyVec.Self2();
                    s = new S(xyzw2);
                };
 
        d = local;
 
        static void local()
        {
            var xyzw3 = ReadOnlyVec.Self2();
            s = new S(xyzw3);
        }
    }
 
    static void Test4()
    {
        var xyzw4 = ReadOnlyVec.Self2();
        s = new S(xyzw4);
    }
}
 
ref struct S
{
    public S (Span<float> x) {}
}
 
public struct Vec4
{
    public float X, Y, Z, W;
    public Vec4(float x, float y, float z, float w) => (X, Y, Z, W) = (x, y, z, w);
 
    [UnscopedRef]
    public Span<float> Self2() => throw null;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (8,20): error CS8345: Field or auto-implemented property cannot be of type 'S' unless it is an instance member of a ref struct.
                //     private static S s;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "S").WithArguments("S").WithLocation(8, 20),
                // (18,25): error CS8347: Cannot use a result of 'S.S(Span<float>)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //                     s = new S(xyzw2);
                Diagnostic(ErrorCode.ERR_EscapeCall, "new S(xyzw2)").WithArguments("S.S(System.Span<float>)", "x").WithLocation(18, 25),
                // (18,31): error CS8352: Cannot use variable 'xyzw2' in this context because it may expose referenced variables outside of their declaration scope
                //                     s = new S(xyzw2);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "xyzw2").WithArguments("xyzw2").WithLocation(18, 31),
                // (26,17): error CS8347: Cannot use a result of 'S.S(Span<float>)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //             s = new S(xyzw3);
                Diagnostic(ErrorCode.ERR_EscapeCall, "new S(xyzw3)").WithArguments("S.S(System.Span<float>)", "x").WithLocation(26, 17),
                // (26,23): error CS8352: Cannot use variable 'xyzw3' in this context because it may expose referenced variables outside of their declaration scope
                //             s = new S(xyzw3);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "xyzw3").WithArguments("xyzw3").WithLocation(26, 23),
                // (33,13): error CS8347: Cannot use a result of 'S.S(Span<float>)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //         s = new S(xyzw4);
                Diagnostic(ErrorCode.ERR_EscapeCall, "new S(xyzw4)").WithArguments("S.S(System.Span<float>)", "x").WithLocation(33, 13),
                // (33,19): error CS8352: Cannot use variable 'xyzw4' in this context because it may expose referenced variables outside of their declaration scope
                //         s = new S(xyzw4);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "xyzw4").WithArguments("xyzw4").WithLocation(33, 19)
                );
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_18()
        {
            var source =
@"
using System;
using System.Diagnostics.CodeAnalysis;
 
internal class Program
{
    private static readonly Vec4 ReadOnlyVec = new Vec4(1, 2, 3, 4);
    private static S s;
 
    static int F1 = GetInt(s = new S(ReadOnlyVec.Self2()));
    static int F2 = GetInt(static () => s = new S(ReadOnlyVec.Self2()));
    int F3 = GetInt(s = new S(ReadOnlyVec.Self2()));
 
    static int GetInt(S s) => 0;
    static int GetInt(System.Action a) => 0;
}
 
ref struct S
{
    public S (Span<float> x) {}
}
 
public struct Vec4
{
    public float X, Y, Z, W;
    public Vec4(float x, float y, float z, float w) => (X, Y, Z, W) = (x, y, z, w);
 
    [UnscopedRef]
    public Span<float> Self2() => throw null;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (8,20): error CS8345: Field or auto-implemented property cannot be of type 'S' unless it is an instance member of a ref struct.
                //     private static S s;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "S").WithArguments("S").WithLocation(8, 20),
                // (11,45): error CS8347: Cannot use a result of 'S.S(Span<float>)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //     static int F2 = GetInt(static () => s = new S(ReadOnlyVec.Self2()));
                Diagnostic(ErrorCode.ERR_EscapeCall, "new S(ReadOnlyVec.Self2())").WithArguments("S.S(System.Span<float>)", "x").WithLocation(11, 45),
                // (11,51): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                //     static int F2 = GetInt(static () => s = new S(ReadOnlyVec.Self2()));
                Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "ReadOnlyVec").WithLocation(11, 51),
                // (12,25): error CS8347: Cannot use a result of 'S.S(Span<float>)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //     int F3 = GetInt(s = new S(ReadOnlyVec.Self2()));
                Diagnostic(ErrorCode.ERR_EscapeCall, "new S(ReadOnlyVec.Self2())").WithArguments("S.S(System.Span<float>)", "x").WithLocation(12, 25),
                // (12,31): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                //     int F3 = GetInt(s = new S(ReadOnlyVec.Self2()));
                Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "ReadOnlyVec").WithLocation(12, 31)
                );
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_19()
        {
            var source =
@"
using System;
using System.Diagnostics.CodeAnalysis;
 
internal class Program
{
    private static readonly Vec4 ReadOnlyVec = new Vec4(1, 2, 3, 4);
    private static S s;
 
    static int P1 {get;} = GetInt(s = new S(ReadOnlyVec.Self2()));
    static int P2 {get;} = GetInt(static () => s = new S(ReadOnlyVec.Self2()));
    int P3 {get;} = GetInt(s = new S(ReadOnlyVec.Self2()));
 
    static int GetInt(S s) => 0;
    static int GetInt(System.Action a) => 0;
}
 
ref struct S
{
    public S (Span<float> x) {}
}
 
public struct Vec4
{
    public float X, Y, Z, W;
    public Vec4(float x, float y, float z, float w) => (X, Y, Z, W) = (x, y, z, w);
 
    [UnscopedRef]
    public Span<float> Self2() => throw null;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (8,20): error CS8345: Field or auto-implemented property cannot be of type 'S' unless it is an instance member of a ref struct.
                //     private static S s;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "S").WithArguments("S").WithLocation(8, 20),
                // (11,52): error CS8347: Cannot use a result of 'S.S(Span<float>)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //     static int P2 {get;} = GetInt(static () => s = new S(ReadOnlyVec.Self2()));
                Diagnostic(ErrorCode.ERR_EscapeCall, "new S(ReadOnlyVec.Self2())").WithArguments("S.S(System.Span<float>)", "x").WithLocation(11, 52),
                // (11,58): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                //     static int P2 {get;} = GetInt(static () => s = new S(ReadOnlyVec.Self2()));
                Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "ReadOnlyVec").WithLocation(11, 58),
                // (12,32): error CS8347: Cannot use a result of 'S.S(Span<float>)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //     int P3 {get;} = GetInt(s = new S(ReadOnlyVec.Self2()));
                Diagnostic(ErrorCode.ERR_EscapeCall, "new S(ReadOnlyVec.Self2())").WithArguments("S.S(System.Span<float>)", "x").WithLocation(12, 32),
                // (12,38): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                //     int P3 {get;} = GetInt(s = new S(ReadOnlyVec.Self2()));
                Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "ReadOnlyVec").WithLocation(12, 38)
                );
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_20()
        {
            var source =
@"
using System;
using System.Diagnostics.CodeAnalysis;
 
internal class Program
{
    private readonly Vec4 ReadOnlyVec = new Vec4(1, 2, 3, 4);
    private static S s;
 
    int P
    {
        get => 0;
        init
        {
            var xyz1 = ReadOnlyVec.Self2(); 
            s = new S(xyz1);
 
            var d = () =>
                    {
                        var xyz2 = ReadOnlyVec.Self2(); 
                        s = new S(xyz2);
                    };
 
            d = local;
 
            void local()
            {
                var xyz3 = ReadOnlyVec.Self2(); 
                s = new S(xyz3);
            }
        }
    }
}
 
ref struct S
{
    public S (Span<float> x) {}
}
 
public struct Vec4
{
    public float X, Y, Z, W;
    public Vec4(float x, float y, float z, float w) => (X, Y, Z, W) = (x, y, z, w);
 
    [UnscopedRef]
    public Span<float> Self2() => throw null;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (8,20): error CS8345: Field or auto-implemented property cannot be of type 'S' unless it is an instance member of a ref struct.
                //     private static S s;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "S").WithArguments("S").WithLocation(8, 20),
                // (21,29): error CS8347: Cannot use a result of 'S.S(Span<float>)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //                         s = new S(xyz2);
                Diagnostic(ErrorCode.ERR_EscapeCall, "new S(xyz2)").WithArguments("S.S(System.Span<float>)", "x").WithLocation(21, 29),
                // (21,35): error CS8352: Cannot use variable 'xyz2' in this context because it may expose referenced variables outside of their declaration scope
                //                         s = new S(xyz2);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "xyz2").WithArguments("xyz2").WithLocation(21, 35),
                // (29,21): error CS8347: Cannot use a result of 'S.S(Span<float>)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope
                //                 s = new S(xyz3);
                Diagnostic(ErrorCode.ERR_EscapeCall, "new S(xyz3)").WithArguments("S.S(System.Span<float>)", "x").WithLocation(29, 21),
                // (29,27): error CS8352: Cannot use variable 'xyz3' in this context because it may expose referenced variables outside of their declaration scope
                //                 s = new S(xyz3);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "xyz3").WithArguments("xyz3").WithLocation(29, 27)
                );
        }
 
        [Fact]
        [WorkItem(64776, "https://github.com/dotnet/roslyn/issues/64776")]
        public void DefensiveCopy_21()
        {
            var source =
@"
using System;
using System.Diagnostics.CodeAnalysis;
 
internal class Program
{
    private static readonly Vec4 ReadOnlyVec = new Vec4(1, 2, 3, 4);
 
    static void Main()
    {
    }
 
    private static Span<float> Test1()
    {
        var (xyzw1, _) = ReadOnlyVec;
        return xyzw1;
    }
 
    private static Span<float> Test2()
    {
        var r2 = ReadOnlyVec;
        var (xyzw2, _) = r2;
        return xyzw2;
    }
 
    private static Span<float> Test3()
    {
        ReadOnlyVec.Deconstruct(out var xyzw3, out _);
        return xyzw3;
    }
 
    private static Span<float> Test4()
    {
        var r4 = ReadOnlyVec;
        r4.Deconstruct(out var xyzw4, out _);
        return xyzw4;
    }
}
 
public struct Vec4
{
    public float X, Y, Z, W;
    public Vec4(float x, float y, float z, float w) => (X, Y, Z, W) = (x, y, z, w);
 
    [UnscopedRef]
    public void Deconstruct(out Span<float> x, out int i) => throw null;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (16,16): error CS8352: Cannot use variable 'xyzw1' in this context because it may expose referenced variables outside of their declaration scope
                //         return xyzw1;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "xyzw1").WithArguments("xyzw1").WithLocation(16, 16),
                // (23,16): error CS8352: Cannot use variable 'xyzw2' in this context because it may expose referenced variables outside of their declaration scope
                //         return xyzw2;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "xyzw2").WithArguments("xyzw2").WithLocation(23, 16),
                // (29,16): error CS8352: Cannot use variable 'xyzw3' in this context because it may expose referenced variables outside of their declaration scope
                //         return xyzw3;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "xyzw3").WithArguments("xyzw3").WithLocation(29, 16),
                // (36,16): error CS8352: Cannot use variable 'xyzw4' in this context because it may expose referenced variables outside of their declaration scope
                //         return xyzw4;
                Diagnostic(ErrorCode.ERR_EscapeVariable, "xyzw4").WithArguments("xyzw4").WithLocation(36, 16)
                );
        }
 
        [Fact]
        public void LocalScope_DeclarationExpression_01()
        {
            var source = """
                ref struct RS
                {
                    public RS(ref RS rs) => throw null!;
                }
 
                class Program
                {
                    static void M0(ref RS rs1, out RS rs2)
                    {
                        // ok. RSTE of rs1 is ReturnOnly. STE of rs2 is ReturnOnly.
                        rs2 = new RS(ref rs1);
                    }
 
                    static RS M1(scoped ref RS rs3)
                    {
                        // RSTE of rs3 is CurrentMethod
                        // STE of rs4 (local variable) is also CurrentMethod
                        M0(ref rs3, out var rs4);
                        return rs4; // 1
                    }
 
                    static RS M2(scoped ref RS rs3)
                    {
                        M0(ref rs3, out RS rs4);
                        return rs4; // 2
                    }
 
                    static RS M3(scoped ref RS rs3)
                    {
                        RS rs4;
                        M0(ref rs3, out rs4); // 3
                        return rs4;
                    }
                }
                """;
 
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (19,16): error CS8352: Cannot use variable 'rs4' in this context because it may expose referenced variables outside of their declaration scope
                //         return rs4; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rs4").WithArguments("rs4").WithLocation(19, 16),
                // (25,16): error CS8352: Cannot use variable 'rs4' in this context because it may expose referenced variables outside of their declaration scope
                //         return rs4; // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rs4").WithArguments("rs4").WithLocation(25, 16),
                // (31,9): error CS8350: This combination of arguments to 'Program.M0(ref RS, out RS)' is disallowed because it may expose variables referenced by parameter 'rs1' outside of their declaration scope
                //         M0(ref rs3, out rs4); // 3
                Diagnostic(ErrorCode.ERR_CallArgMixing, "M0(ref rs3, out rs4)").WithArguments("Program.M0(ref RS, out RS)", "rs1").WithLocation(31, 9),
                // (31,16): error CS9075: Cannot return a parameter by reference 'rs3' because it is scoped to the current method
                //         M0(ref rs3, out rs4); // 3
                Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "rs3").WithArguments("rs3").WithLocation(31, 16));
        }
 
        [Fact]
        public void LocalScope_DeclarationExpression_02()
        {
            var source = """
                ref struct RS { }
 
                class Program
                {
                    static void M0(RS rs1, out RS rs2)
                    {
                        // ok. STE of rs1 is CallingMethod. STE of rs2 is ReturnOnly.
                        rs2 = rs1;
                    }
 
                    static RS M1(scoped RS rs3)
                    {
                        // STE of rs3 is CurrentMethod
                        // STE of rs4 (local variable) is also CurrentMethod
                        M0(rs3, out var rs4);
                        return rs4; // 1
                    }
 
                    static RS M2(scoped RS rs3)
                    {
                        M0(rs3, out RS rs4);
                        return rs4; // 2
                    }
 
                    static RS M3(scoped RS rs3)
                    {
                        RS rs4;
                        M0(rs3, out rs4); // 3
                        return rs4;
                    }
                }
                """;
 
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (16,16): error CS8352: Cannot use variable 'rs4' in this context because it may expose referenced variables outside of their declaration scope
                //         return rs4; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rs4").WithArguments("rs4").WithLocation(16, 16),
                // (22,16): error CS8352: Cannot use variable 'rs4' in this context because it may expose referenced variables outside of their declaration scope
                //         return rs4; // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rs4").WithArguments("rs4").WithLocation(22, 16),
                // (28,9): error CS8350: This combination of arguments to 'Program.M0(RS, out RS)' is disallowed because it may expose variables referenced by parameter 'rs1' outside of their declaration scope
                //         M0(rs3, out rs4); // 3
                Diagnostic(ErrorCode.ERR_CallArgMixing, "M0(rs3, out rs4)").WithArguments("Program.M0(RS, out RS)", "rs1").WithLocation(28, 9),
                // (28,12): error CS8352: Cannot use variable 'scoped RS rs3' in this context because it may expose referenced variables outside of their declaration scope
                //         M0(rs3, out rs4); // 3
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rs3").WithArguments("scoped RS rs3").WithLocation(28, 12));
        }
 
        [Fact]
        public void LocalScope_DeclarationExpression_03()
        {
            var source = """
                ref struct RS { }
                struct S { }
 
                class Program
                {
                    static void M0(RS rs1, out S s1) => throw null!;
 
                    static S M1(scoped RS rs2)
                    {
                        // STE of s2 is CallingMethod because it is not ref struct
                        M0(rs2, out var s2);
                        return s2;
                    }
                }
                """;
 
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void LocalScope_DeclarationExpression_04()
        {
            var source0 = """
                public ref struct RS
                {
                    public RS(ref int i) => throw null!;
                }
 
                public class Util
                {
                    public static void M0(ref int i1, out RS rs1)
                    {
                        // RSTE of i1 is ReturnOnly. STE of rs1 is ReturnOnly in C# 11, but CallingMethod in C# 10.
                        rs1 = new RS(ref i1);
                    }
                }
                """;
 
            var source1 = """
                class Program
                {
                    static void M1(ref int i2, ref RS rs2)
                    {
                        // STE of rs3 (local variable) is ReturnOnly in C# 11, but CallingMethod in C# 10.
                        Util.M0(ref i2, out var rs3);
 
                        // STE of rs2 is CallingMethod. Therefore the assignment is permitted in C# 10 but not C# 11.
                        rs2 = rs3; // 1
                    }
                }
                """;
 
            var source1DiagnosticsWhenSource0IsCSharp11 = new[]
            {
                // (9,15): error CS8352: Cannot use variable 'rs3' in this context because it may expose referenced variables outside of their declaration scope
                //         rs2 = rs3; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rs3").WithArguments("rs3").WithLocation(9, 15)
            };
 
            var comp = CreateCompilation(new[] { source0, source1 }, parseOptions: TestOptions.Regular11);
            comp.VerifyDiagnostics(source1DiagnosticsWhenSource0IsCSharp11);
 
            comp = CreateCompilation(new[] { source0, source1 }, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics();
 
            // Reference C# 10, consume from 11
            var comp0 = CreateCompilation(source0, parseOptions: TestOptions.Regular10);
            comp0.VerifyDiagnostics();
 
            var comp1 = CreateCompilation(source1, references: new[] { comp0.ToMetadataReference() }, parseOptions: TestOptions.Regular11);
            comp1.VerifyDiagnostics();
 
            comp1 = CreateCompilation(source1, references: new[] { comp0.EmitToImageReference() }, parseOptions: TestOptions.Regular11);
            comp1.VerifyDiagnostics();
 
            // Reference C# 11, consume from 10
            comp0 = CreateCompilation(source0, parseOptions: TestOptions.Regular11);
            comp0.VerifyDiagnostics();
 
            comp1 = CreateCompilation(source1, references: new[] { comp0.ToMetadataReference() }, parseOptions: TestOptions.Regular10);
            comp1.VerifyDiagnostics(source1DiagnosticsWhenSource0IsCSharp11);
 
            comp1 = CreateCompilation(source1, references: new[] { comp0.EmitToImageReference() }, parseOptions: TestOptions.Regular10);
            comp1.VerifyDiagnostics(source1DiagnosticsWhenSource0IsCSharp11);
        }
 
        [Fact]
        public void LocalScope_DeclarationExpression_05()
        {
            var source = """
                using System;
 
                ref struct RS
                {
                    public RS(ref int i) => throw null!;
                }
 
                class Program
                {
                    static void M0(out RS rs1, __arglist)
                    {
                        // STE of __refvalue (i.e. values in __arglist) is CallingMethod.
                        // RSTE of __refvalue is CurrentMethod.
                        // STE of rs1 is ReturnOnly.
                        var ai = new ArgIterator(__arglist);
                        rs1 = __refvalue(ai.GetNextArg(), RS);
                        rs1 = new RS(ref __refvalue(ai.GetNextArg(), int)); // 1
                    }
 
                    static RS M1(scoped RS rs2)
                    {
                        M0(out var rs3, __arglist(rs2));
                        return rs3; // 2
                    }
 
                    static RS M2(scoped RS rs4)
                    {
                        M0(out var rs5, __arglist(ref rs4));
                        return rs5; // 3
                    }
 
                    static RS M3(ref int i1)
                    {
                        M0(out var rs5, __arglist(ref i1));
                        return rs5;
                    }
                }
                """;
 
            var comp = CreateCompilationWithMscorlibAndSpan(source);
            comp.VerifyDiagnostics(
                // (17,15): 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
                //         rs1 = new RS(ref __refvalue(ai.GetNextArg(), int)); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "new RS(ref __refvalue(ai.GetNextArg(), int))").WithArguments("RS.RS(ref int)", "i").WithLocation(17, 15),
                // (17,26): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
                //         rs1 = new RS(ref __refvalue(ai.GetNextArg(), int)); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "__refvalue(ai.GetNextArg(), int)").WithLocation(17, 26),
                // (23,16): error CS8352: Cannot use variable 'rs3' in this context because it may expose referenced variables outside of their declaration scope
                //         return rs3; // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rs3").WithArguments("rs3").WithLocation(23, 16),
                // (29,16): error CS8352: Cannot use variable 'rs5' in this context because it may expose referenced variables outside of their declaration scope
                //         return rs5; // 3
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rs5").WithArguments("rs5").WithLocation(29, 16));
        }
 
        [Fact]
        public void LocalScope_DeclarationExpression_06()
        {
            var source = """
                using System.Diagnostics.CodeAnalysis;
 
                ref struct RS
                {
                    public RS(ref RS rs) => throw null!;
 
                    [UnscopedRef]
                    void M0(out RS rs2)
                    {
                        // ok. RSTE of `this` is ReturnOnly. STE of rs2 is ReturnOnly.
                        rs2 = new RS(ref this);
                    }
 
                    RS M1()
                    {
                        // RSTE of `this` is CurrentMethod
                        // STE of rs4 (local variable) is also CurrentMethod
                        M0(out var rs4);
                        return rs4; // 1
                    }
 
                    [UnscopedRef]
                    RS M2()
                    {
                        M0(out var rs4);
                        return rs4;
                    }
                }
                """;
 
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (19,16): error CS8352: Cannot use variable 'rs4' in this context because it may expose referenced variables outside of their declaration scope
                //         return rs4; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rs4").WithArguments("rs4").WithLocation(19, 16));
        }
 
        [Fact]
        public void LocalScope_DeclarationExpression_07()
        {
            var source = """
                using System.Diagnostics.CodeAnalysis;
 
                class Program
                {
                    static ref int F1([UnscopedRef] out int i)
                    {
                        i = 0;
                        return ref i;
                    }
                    static ref int F2()
                    {
                        return ref F1(out int i); // 1
                    }
                }
                """;
 
            var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (12,20): error CS8347: Cannot use a result of 'Program.F1(out int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope
                //         return ref F1(out int i); // 1
                Diagnostic(ErrorCode.ERR_EscapeCall, "F1(out int i)").WithArguments("Program.F1(out int)", "i").WithLocation(12, 20),
                // (12,27): error CS8168: Cannot return local 'i' by reference because it is not a ref local
                //         return ref F1(out int i); // 1
                Diagnostic(ErrorCode.ERR_RefReturnLocal, "int i").WithArguments("i").WithLocation(12, 27));
        }
 
        [Fact]
        public void LocalScope_DeclarationExpression_08()
        {
            var source = """
                ref struct RS
                {
                    public RS(ref RS rs) => throw null!;
                }
 
                class Program
                {
                    static void M0(ref RS rs1, out RS rs2)
                    {
                        // ok. RSTE of rs1 is ReturnOnly. STE of rs2 is ReturnOnly.
                        rs2 = new RS(ref rs1);
                    }
 
                    static RS M1(ref RS rs3)
                    {
                        // RSTE of rs3 is ReturnOnly.
                        // However, since rs4 is 'scoped', its STE should be narrowed to CurrentMethod
                        M0(ref rs3, out scoped var rs4);
                        return rs4; // 1
                    }
 
                    static RS M2(ref RS rs5)
                    {
                        // RSTE of rs5 is ReturnOnly.
                        // However, since rs6 is 'scoped', its STE should be narrowed to CurrentMethod
                        M0(ref rs5, out scoped RS rs6);
                        return rs6; // 2
                    }
                
                    static RS M12(ref RS rs3)
                    {
                        // RSTE of rs3 is ReturnOnly.
                        // However, since rs4 is 'scoped', its STE should be narrowed to CurrentMethod
                        scoped RS rs4;
                        M0(ref rs3, out rs4);
                        return rs4; // 3
                    }
                
                    static RS M22(ref RS rs5)
                    {
                        // RSTE of rs5 is ReturnOnly.
                        // However, since rs6 is 'scoped', its STE should be narrowed to CurrentMethod
                        scoped RS rs6;
                        M0(ref rs5, out rs6);
                        return rs6; // 4
                    }
                }
                """;
 
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (19,16): error CS8352: Cannot use variable 'rs4' in this context because it may expose referenced variables outside of their declaration scope
                //         return rs4; // 1
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rs4").WithArguments("rs4").WithLocation(19, 16),
                // (27,16): error CS8352: Cannot use variable 'rs6' in this context because it may expose referenced variables outside of their declaration scope
                //         return rs6; // 2
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rs6").WithArguments("rs6").WithLocation(27, 16),
                // (36,16): error CS8352: Cannot use variable 'rs4' in this context because it may expose referenced variables outside of their declaration scope
                //         return rs4; // 3
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rs4").WithArguments("rs4").WithLocation(36, 16),
                // (45,16): error CS8352: Cannot use variable 'rs6' in this context because it may expose referenced variables outside of their declaration scope
                //         return rs6; // 4
                Diagnostic(ErrorCode.ERR_EscapeVariable, "rs6").WithArguments("rs6").WithLocation(45, 16)
                );
        }
 
        [Fact, WorkItem(64783, "https://github.com/dotnet/roslyn/issues/64783")]
        public void OutArgumentsDoNotContributeValEscape_01()
        {
            var source = """
                using System;
 
                class Program
                {
                    static Span<byte> M1()
                    {
                        Span<byte> a = stackalloc byte[42];
                        var ret = OneOutSpanReturnsSpan(out a);
                        return ret;
                    }
 
                    static Span<byte> M2()
                    {
                        Span<byte> a = stackalloc byte[42];
                        TwoOutSpans(out a, out Span<byte> b);
                        return b;
                    }
 
                    static Span<byte> OneOutSpanReturnsSpan(out Span<byte> a)
                    {
                        // 'return a' is illegal until it is overwritten
                        a = default;
                        return default;
                    }
 
                    static void TwoOutSpans(out Span<byte> a, out Span<byte> b)
                    {
                        // 'a = b' and 'b = a' are illegal until one has already been written
                        a = b = default;
                    }
                }
 
                """;
 
            var comp = CreateCompilationWithSpan(source);
            comp.VerifyDiagnostics();
        }
 
        [Fact, WorkItem(56587, "https://github.com/dotnet/roslyn/issues/56587")]
        public void OutArgumentsDoNotContributeValEscape_02()
        {
            // Test that out discard arguments are not treated as inputs.
            // This means we don't need to take special care to zero-out the variable used for a discard argument between uses.
            var source = """
                using System;
 
                class Program
                {
                    static Span<byte> M1()
                    {
                        Span<byte> a = stackalloc byte[42];
                        TwoOutSpans(out a, out _);
                        TwoOutSpans(out _, out Span<byte> c);
                        return c;
                    }
 
                    static void TwoOutSpans(out Span<byte> a, out Span<byte> b)
                    {
                        // 'a = b' and 'b = a' are illegal until one has already been written
                        a = b = default;
                    }
                }
                """;
 
            var comp = CreateCompilationWithSpan(source);
            comp.VerifyDiagnostics();
        }
    }
}