File: Semantics\SpanStackSafetyTests.cs
Web Access
Project: src\src\Compilers\CSharp\Test\Semantic\Microsoft.CodeAnalysis.CSharp.Semantic.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Semantic.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using System.Collections.Generic;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
    /// <summary>
    /// this place is dedicated to binding related error tests
    /// </summary>
    [CompilerTrait(CompilerFeature.ReadOnlyReferences)]
    public class SpanStackSafetyTests : CompilingTestBase
    {
        [Fact]
        public void SpanAssignmentExpression()
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    void M()
    {
        Span<int> s1 = stackalloc int[1];
        Span<int> s2 = new Span<int>();
 
        s2 = (s2 = new Span<int>());
        s2 = (s1 = s2);
    }
}");
            comp.VerifyDiagnostics(
                // (11,15): error CS8352: Cannot use variable 's1' in this context because it may expose referenced variables outside of their declaration scope
                //         s2 = (s1 = s2);
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s1 = s2").WithArguments("s1").WithLocation(11, 15));
        }
 
        [Fact]
        public void SpanToSpanSwitch()
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    void M(Span<string> s)
    {
        switch (s)
        {
            case Span<string> span:
                break;
        }
    }
}");
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void SpanToObjectPatternSwitch()
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
 
class C
{
    void M(object o)
    {
        switch (o)
        {
            case Span<int> span:
                break;
            default:
                break;
        }
    }
}");
            comp.VerifyDiagnostics(
                // (10,18): error CS8121: An expression of type 'object' cannot be handled by a pattern of type 'Span<int>'.
                //             case Span<int> span:
                Diagnostic(ErrorCode.ERR_PatternWrongType, "Span<int>").WithArguments("object", "System.Span<int>").WithLocation(10, 18)
                );
        }
 
        [Fact]
        public void SpanToGenericPatternSwitch()
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    void M<T>(T t)
    {
        switch (t)
        {
            case Span<int> span:
                break;
            default:
                break;
        }
    }
}");
            comp.VerifyDiagnostics(
                // (9,18): error CS8121: An expression of type 'T' cannot be handled by a pattern of type 'Span<int>'.
                //             case Span<int> span:
                Diagnostic(ErrorCode.ERR_PatternWrongType, "Span<int>").WithArguments("T", "System.Span<int>").WithLocation(9, 18)
                );
        }
 
        [Fact]
        public void SpanToGenericPatternSwitch2()
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    void M<T>(T t) where T : struct
    {
        switch (t)
        {
            case Span<int> span:
                break;
            default:
                break;
        }
    }
}");
            comp.VerifyDiagnostics(
                // (9,18): error CS8121: An expression of type 'T' cannot be handled by a pattern of type 'Span<int>'.
                //             case Span<int> span:
                Diagnostic(ErrorCode.ERR_PatternWrongType, "Span<int>").WithArguments("T", "System.Span<int>").WithLocation(9, 18)
                );
        }
 
        [Fact]
        public void ObjectToSpanPatternSwitch()
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    void M(Span<string> s)
    {
        switch (s)
        {
            case Span<object> span:
                break;
            case object o:
                break;
        }
    }
}");
            comp.VerifyDiagnostics(
                // (9,18): error CS8121: An expression of type 'Span<string>' cannot be handled by a pattern of type 'Span<object>'.
                //             case Span<object> span:
                Diagnostic(ErrorCode.ERR_PatternWrongType, "Span<object>").WithArguments("System.Span<string>", "System.Span<object>").WithLocation(9, 18),
                // (11,18): error CS8121: An expression of type 'Span<string>' cannot be handled by a pattern of type 'object'.
                //             case object o:
                Diagnostic(ErrorCode.ERR_PatternWrongType, "object").WithArguments("System.Span<string>", "object").WithLocation(11, 18)
                );
        }
 
        [Fact]
        public void GenericToSpanPatternSwitch()
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    void M<T>(Span<string> s)
    {
        switch (s)
        {
            case T t:
                break;
        }
    }
}");
            comp.VerifyDiagnostics(
                // (9,18): error CS8121: An expression of type 'Span<string>' cannot be handled by a pattern of type 'T'.
                //             case T t:
                Diagnostic(ErrorCode.ERR_PatternWrongType, "T").WithArguments("System.Span<string>", "T").WithLocation(9, 18)
                );
        }
 
        [Fact]
        public void GenericToSpanPatternSwitch2()
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    void M<T>(Span<string> s) where T : struct
    {
        switch (s)
        {
            case T t:
                break;
        }
    }
}");
            comp.VerifyDiagnostics(
                // (9,18): error CS8121: An expression of type 'Span<string>' cannot be handled by a pattern of type 'T'.
                //             case T t:
                Diagnostic(ErrorCode.ERR_PatternWrongType, "T").WithArguments("System.Span<string>", "T").WithLocation(9, 18)
                );
        }
 
        [Fact]
        public void SpanToSpanIsExpr()
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    bool M(Span<string> s) => s is Span<string> && s is Span<string> span;
}");
            comp.VerifyDiagnostics(
                // (5,31): warning CS0183: The given expression is always of the provided ('Span<string>') type
                //     bool M(Span<string> s) => s is Span<string> && s is Span<string> span;
                Diagnostic(ErrorCode.WRN_IsAlwaysTrue, "s is Span<string>").WithArguments("System.Span<string>").WithLocation(5, 31));
        }
 
        [Fact]
        public void ObjectToSpanIsExpr()
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    void M(object o)
    {
        if (o is Span<int>)
        { }
        if (o is Span<int> s)
        { }
    }
}");
            comp.VerifyDiagnostics(
                // (7,13): warning CS0184: The given expression is never of the provided ('Span<int>') type
                //         if (o is Span<int>)
                Diagnostic(ErrorCode.WRN_IsAlwaysFalse, "o is Span<int>").WithArguments("System.Span<int>").WithLocation(7, 13),
                // (9,18): error CS8121: An expression of type 'object' cannot be handled by a pattern of type 'Span<int>'.
                //         if (o is Span<int> s)
                Diagnostic(ErrorCode.ERR_PatternWrongType, "Span<int>").WithArguments("object", "System.Span<int>").WithLocation(9, 18));
        }
 
        [Fact]
        public void GenericToSpanIsExpr()
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    void M<T>(T t)
    {
        if (t is Span<int>)
        { }
        if (t is Span<int> s)
        { }
    }
}");
            comp.VerifyDiagnostics(
                // (7,13): warning CS0184: The given expression is never of the provided ('Span<int>') type
                //         if (t is Span<int>)
                Diagnostic(ErrorCode.WRN_IsAlwaysFalse, "t is Span<int>").WithArguments("System.Span<int>").WithLocation(7, 13),
                // (9,18): error CS8121: An expression of type 'T' cannot be handled by a pattern of type 'Span<int>'.
                //         if (t is Span<int> s)
                Diagnostic(ErrorCode.ERR_PatternWrongType, "Span<int>").WithArguments("T", "System.Span<int>").WithLocation(9, 18));
        }
 
        [Fact]
        public void SpanToObjectIsExpr()
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    void M(Span<int> s)
    {
        if (s is object) { }
        if (s is object o) { }
    }
}");
            comp.VerifyDiagnostics(
                // (7,13): warning CS0184: The given expression is never of the provided ('object') type
                //         if (s is object) { }
                Diagnostic(ErrorCode.WRN_IsAlwaysFalse, "s is object").WithArguments("object").WithLocation(7, 13),
                // (8,18): error CS8121: An expression of type 'Span<int>' cannot be handled by a pattern of type 'object'.
                //         if (s is object o) { }
                Diagnostic(ErrorCode.ERR_PatternWrongType, "object").WithArguments("System.Span<int>", "object").WithLocation(8, 18));
        }
 
        [Fact]
        public void SpanToGenericIsExpr()
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    void M<T>(Span<int> s)
    {
        if (s is T) { }
        if (s is T t) { }
    }
}");
            comp.VerifyDiagnostics(
                // (7,13): warning CS0184: The given expression is never of the provided ('T') type
                //         if (s is T) { }
                Diagnostic(ErrorCode.WRN_IsAlwaysFalse, "s is T").WithArguments("T").WithLocation(7, 13),
                // (8,18): error CS8121: An expression of type 'Span<int>' cannot be handled by a pattern of type 'T'.
                //         if (s is T t) { }
                Diagnostic(ErrorCode.ERR_PatternWrongType, "T").WithArguments("System.Span<int>", "T").WithLocation(8, 18));
        }
 
        [Fact]
        public void SpanToGenericIsExpr2()
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    void M<T>(Span<int> s) where T : struct
    {
        if (s is T) { }
        if (s is T t) { }
    }
}");
            comp.VerifyDiagnostics(
                // (7,13): warning CS0184: The given expression is never of the provided ('T') type
                //         if (s is T) { }
                Diagnostic(ErrorCode.WRN_IsAlwaysFalse, "s is T").WithArguments("T").WithLocation(7, 13),
                // (8,18): error CS8121: An expression of type 'Span<int>' cannot be handled by a pattern of type 'T'.
                //         if (s is T t) { }
                Diagnostic(ErrorCode.ERR_PatternWrongType, "T").WithArguments("System.Span<int>", "T").WithLocation(8, 18));
        }
 
        [Fact]
        public void TrivialBoxing()
        {
            var text = @"
using System;
 
class Program
{
    static void Main()
    {
        object x = new Span<int>();
        object y = new ReadOnlySpan<byte>();
        object z = new SpanLike<int>();
    }
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text);
 
            comp.VerifyDiagnostics(
                // (8,20): error CS0029: Cannot implicitly convert type 'System.Span<int>' to 'object'
                //         object x = new Span<int>();
                Diagnostic(ErrorCode.ERR_NoImplicitConv, "new Span<int>()").WithArguments("System.Span<int>", "object").WithLocation(8, 20),
                // (9,20): error CS0029: Cannot implicitly convert type 'System.ReadOnlySpan<byte>' to 'object'
                //         object y = new ReadOnlySpan<byte>();
                Diagnostic(ErrorCode.ERR_NoImplicitConv, "new ReadOnlySpan<byte>()").WithArguments("System.ReadOnlySpan<byte>", "object").WithLocation(9, 20),
                // (10,20): error CS0029: Cannot implicitly convert type 'System.SpanLike<int>' to 'object'
                //         object z = new SpanLike<int>();
                Diagnostic(ErrorCode.ERR_NoImplicitConv, "new SpanLike<int>()").WithArguments("System.SpanLike<int>", "object")
            );
 
            comp = CreateCompilationWithMscorlibAndSpanSrc(text);
 
            comp.VerifyDiagnostics(
                // (8,20): error CS0029: Cannot implicitly convert type 'System.Span<int>' to 'object'
                //         object x = new Span<int>();
                Diagnostic(ErrorCode.ERR_NoImplicitConv, "new Span<int>()").WithArguments("System.Span<int>", "object").WithLocation(8, 20),
                // (9,20): error CS0029: Cannot implicitly convert type 'System.ReadOnlySpan<byte>' to 'object'
                //         object y = new ReadOnlySpan<byte>();
                Diagnostic(ErrorCode.ERR_NoImplicitConv, "new ReadOnlySpan<byte>()").WithArguments("System.ReadOnlySpan<byte>", "object").WithLocation(9, 20),
                // (10,20): error CS0029: Cannot implicitly convert type 'System.SpanLike<int>' to 'object'
                //         object z = new SpanLike<int>();
                Diagnostic(ErrorCode.ERR_NoImplicitConv, "new SpanLike<int>()").WithArguments("System.SpanLike<int>", "object")
            );
        }
 
        [Fact]
        public void LambdaCapturing()
        {
            var text = @"
using System;
 
class Program
{
    // this should be ok
    public delegate Span<T> D1<T>(Span<T> arg);
 
    static void Main()
    {
        var x = new Span<int>();
 
        D1<int> d = (t)=>t;
        x = d(x);
        
        // error due to capture
        Func<int> f = () => x[1];
    }
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text);
 
            comp.VerifyDiagnostics(
                // (17,29): error CS8175: Cannot use ref local 'x' inside an anonymous method, lambda expression, or query expression
                //         Func<int> f = () => x[1];
                Diagnostic(ErrorCode.ERR_AnonDelegateCantUseLocal, "x").WithArguments("x").WithLocation(17, 29)
            );
        }
 
        [Fact]
        public void GenericArgsAndConstraints()
        {
            var text = @"
using System;
 
class Program
{
    static void Main()
    {
        var x = new Span<int>();
 
        Func<Span<int>> d = ()=>x;
    }
 
    class C1<T> where T: Span<int>
    {
    }
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text);
 
            comp.VerifyDiagnostics(
                // (13,26): error CS0701: 'Span<int>' is not a valid constraint. A type used as a constraint must be an interface, a non-sealed class or a type parameter.
                //     class C1<T> where T: Span<int>
                Diagnostic(ErrorCode.ERR_BadBoundType, "Span<int>").WithArguments("System.Span<int>").WithLocation(13, 26),
                // (10,14): error CS9244: The type 'Span<int>' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'TResult' in the generic type or method 'Func<TResult>'
                //         Func<Span<int>> d = ()=>x;
                Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "Span<int>").WithArguments("System.Func<TResult>", "TResult", "System.Span<int>").WithLocation(10, 14),
                // (10,33): error CS8175: Cannot use ref local 'x' inside an anonymous method, lambda expression, or query expression
                //         Func<Span<int>> d = ()=>x;
                Diagnostic(ErrorCode.ERR_AnonDelegateCantUseLocal, "x").WithArguments("x").WithLocation(10, 33)
            );
        }
 
        [Fact]
        public void Arrays()
        {
            var text = @"
using System;
 
class Program
{
    static void Main()
    {
        var x = new Span<int>[1];
 
        var y = new SpanLike<int>[1,2];
    }
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text);
 
            comp.VerifyDiagnostics(
                // (8,21): error CS0611: Array elements cannot be of type 'Span<int>'
                //         var x = new Span<int>[1];
                Diagnostic(ErrorCode.ERR_ArrayElementCantBeRefAny, "Span<int>").WithArguments("System.Span<int>"),
                // (10,21): error CS0611: Array elements cannot be of type 'SpanLike<int>'
                //         var y = new SpanLike<int>[1,2];
                Diagnostic(ErrorCode.ERR_ArrayElementCantBeRefAny, "SpanLike<int>").WithArguments("System.SpanLike<int>").WithLocation(10, 21)
            );
        }
 
        [Fact]
        public void ByrefParam()
        {
            var text = @"using System;
 
class Program
{
    static void Main()
    {
    }
 
    // OK
    static void M1(scoped ref Span<string> ss)
    {
    }
 
    // OK
    static void M2(out SpanLike<string> ss)
    {
        ss = default;
    }
 
    // OK
    static void M3(scoped in Span<string> ss)
    {
    }
 
    // OK
    static void M3l(scoped in SpanLike<string> ss)
    {
    }
 
    // OK
    static ref Span<string> M4(ref Span<string> ss) { return ref ss; }
 
    // OK
    static ref readonly Span<string> M5(ref Span<string> ss) => ref ss;
 
    // Not OK
    // TypedReference baseline
    static ref TypedReference M1(ref TypedReference ss) => ref ss;
}
";
 
            var comp = CreateCompilationWithMscorlibAndSpan(new[] { text, UnscopedRefAttributeDefinition }, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(
                // (10,20): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     static void M1(scoped ref Span<string> ss)
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(10, 20),
                // (38,34): error CS1601: Cannot make reference to variable of type 'TypedReference'
                //     static ref TypedReference M1(ref TypedReference ss) => ref ss;
                Diagnostic(ErrorCode.ERR_MethodArgCantBeRefAny, "ref TypedReference ss").WithArguments("System.TypedReference").WithLocation(38, 34),
                // (38,12): error CS1599: The return type of a method, delegate, or function pointer cannot be 'TypedReference'
                //     static ref TypedReference M1(ref TypedReference ss) => ref ss;
                Diagnostic(ErrorCode.ERR_MethodReturnCantBeRefAny, "ref TypedReference").WithArguments("System.TypedReference").WithLocation(38, 12),
                // (21,20): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     static void M3(scoped in Span<string> ss)
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(21, 20),
                // (26,21): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                //     static void M3l(scoped in SpanLike<string> ss)
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(26, 21)
            );
 
            comp = CreateCompilationWithMscorlibAndSpan(new[] { text, UnscopedRefAttributeDefinition });
            comp.VerifyDiagnostics(
                // (38,34): error CS1601: Cannot make reference to variable of type 'TypedReference'
                //     static ref TypedReference M1(ref TypedReference ss) => ref ss;
                Diagnostic(ErrorCode.ERR_MethodArgCantBeRefAny, "ref TypedReference ss").WithArguments("System.TypedReference").WithLocation(38, 34),
                // (38,12): error CS1599: The return type of a method, delegate, or function pointer cannot be 'TypedReference'
                //     static ref TypedReference M1(ref TypedReference ss) => ref ss;
                Diagnostic(ErrorCode.ERR_MethodReturnCantBeRefAny, "ref TypedReference").WithArguments("System.TypedReference").WithLocation(38, 12)
            );
        }
 
        [Fact]
        public void FieldsSpan()
        {
            var text = @"
using System;
 
public class Program
{
    static void Main()
    {
    }
 
    public static Span<byte> fs;
    public Span<int> fi; 
 
    public ref struct S1
    {
        public static Span<byte> fs1;
        public Span<int> fi1; 
    }
 
    public struct S2
    {
        public static Span<byte> fs2;
        public Span<int> fi2; 
    }
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text);
 
            comp.VerifyDiagnostics(
                // (22,16): error CS8345: Field or auto-implemented property cannot be of type 'Span<int>' unless it is an instance member of a ref struct.
                //         public Span<int> fi2; 
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "Span<int>").WithArguments("System.Span<int>").WithLocation(22, 16),
                // (21,23): error CS8345: Field or auto-implemented property cannot be of type 'Span<byte>' unless it is an instance member of a ref struct.
                //         public static Span<byte> fs2;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "Span<byte>").WithArguments("System.Span<byte>").WithLocation(21, 23),
                // (10,19): error CS8345: Field or auto-implemented property cannot be of type 'Span<byte>' unless it is an instance member of a ref struct.
                //     public static Span<byte> fs;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "Span<byte>").WithArguments("System.Span<byte>").WithLocation(10, 19),
                // (11,12): error CS8345: Field or auto-implemented property cannot be of type 'Span<int>' unless it is an instance member of a ref struct.
                //     public Span<int> fi; 
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "Span<int>").WithArguments("System.Span<int>").WithLocation(11, 12),
                // (15,23): error CS8345: Field or auto-implemented property cannot be of type 'Span<byte>' unless it is an instance member of a ref struct.
                //         public static Span<byte> fs1;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "Span<byte>").WithArguments("System.Span<byte>").WithLocation(15, 23)
            );
 
            comp = CreateCompilationWithMscorlibAndSpanSrc(text);
 
            comp.VerifyDiagnostics(
                // (22,16): error CS8345: Field or auto-implemented property cannot be of type 'Span<int>' unless it is an instance member of a ref struct.
                //         public Span<int> fi2; 
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "Span<int>").WithArguments("System.Span<int>").WithLocation(22, 16),
                // (21,23): error CS8345: Field or auto-implemented property cannot be of type 'Span<byte>' unless it is an instance member of a ref struct.
                //         public static Span<byte> fs2;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "Span<byte>").WithArguments("System.Span<byte>").WithLocation(21, 23),
                // (10,19): error CS8345: Field or auto-implemented property cannot be of type 'Span<byte>' unless it is an instance member of a ref struct.
                //     public static Span<byte> fs;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "Span<byte>").WithArguments("System.Span<byte>").WithLocation(10, 19),
                // (11,12): error CS8345: Field or auto-implemented property cannot be of type 'Span<int>' unless it is an instance member of a ref struct.
                //     public Span<int> fi; 
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "Span<int>").WithArguments("System.Span<int>").WithLocation(11, 12),
                // (15,23): error CS8345: Field or auto-implemented property cannot be of type 'Span<byte>' unless it is an instance member of a ref struct.
                //         public static Span<byte> fs1;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "Span<byte>").WithArguments("System.Span<byte>").WithLocation(15, 23)
            );
        }
 
        [Fact]
        public void FieldsSpanLike()
        {
            var text = @"
using System;
 
public class Program
{
    static void Main()
    {
    }
 
    public static SpanLike<byte> fs;
    public SpanLike<int> fi; 
 
    public ref struct S1
    {
        public static SpanLike<byte> fs1;
        public SpanLike<int> fi1; 
    }
 
    public struct S2
    {
        public static SpanLike<byte> fs2;
        public SpanLike<int> fi2; 
    }
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text);
 
            comp.VerifyDiagnostics(
                // (22,16): error CS8345: Field or auto-implemented property cannot be of type 'SpanLike<int>' unless it is an instance member of a ref struct.
                //         public SpanLike<int> fi2; 
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "SpanLike<int>").WithArguments("System.SpanLike<int>").WithLocation(22, 16),
                // (21,23): error CS8345: Field or auto-implemented property cannot be of type 'SpanLike<byte>' unless it is an instance member of a ref struct.
                //         public static SpanLike<byte> fs2;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "SpanLike<byte>").WithArguments("System.SpanLike<byte>").WithLocation(21, 23),
                // (10,19): error CS8345: Field or auto-implemented property cannot be of type 'SpanLike<byte>' unless it is an instance member of a ref struct.
                //     public static SpanLike<byte> fs;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "SpanLike<byte>").WithArguments("System.SpanLike<byte>").WithLocation(10, 19),
                // (11,12): error CS8345: Field or auto-implemented property cannot be of type 'SpanLike<int>' unless it is an instance member of a ref struct.
                //     public SpanLike<int> fi; 
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "SpanLike<int>").WithArguments("System.SpanLike<int>").WithLocation(11, 12),
                // (15,23): error CS8345: Field or auto-implemented property cannot be of type 'SpanLike<byte>' unless it is an instance member of a ref struct.
                //         public static SpanLike<byte> fs1;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "SpanLike<byte>").WithArguments("System.SpanLike<byte>").WithLocation(15, 23)
            );
 
            comp = CreateCompilationWithMscorlibAndSpanSrc(text);
 
            comp.VerifyDiagnostics(
                // (22,16): error CS8345: Field or auto-implemented property cannot be of type 'SpanLike<int>' unless it is an instance member of a ref struct.
                //         public SpanLike<int> fi2; 
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "SpanLike<int>").WithArguments("System.SpanLike<int>").WithLocation(22, 16),
                // (21,23): error CS8345: Field or auto-implemented property cannot be of type 'SpanLike<byte>' unless it is an instance member of a ref struct.
                //         public static SpanLike<byte> fs2;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "SpanLike<byte>").WithArguments("System.SpanLike<byte>").WithLocation(21, 23),
                // (10,19): error CS8345: Field or auto-implemented property cannot be of type 'SpanLike<byte>' unless it is an instance member of a ref struct.
                //     public static SpanLike<byte> fs;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "SpanLike<byte>").WithArguments("System.SpanLike<byte>").WithLocation(10, 19),
                // (11,12): error CS8345: Field or auto-implemented property cannot be of type 'SpanLike<int>' unless it is an instance member of a ref struct.
                //     public SpanLike<int> fi; 
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "SpanLike<int>").WithArguments("System.SpanLike<int>").WithLocation(11, 12),
                // (15,23): error CS8345: Field or auto-implemented property cannot be of type 'SpanLike<byte>' unless it is an instance member of a ref struct.
                //         public static SpanLike<byte> fs1;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "SpanLike<byte>").WithArguments("System.SpanLike<byte>").WithLocation(15, 23)
            );
        }
 
        [WorkItem(20226, "https://github.com/dotnet/roslyn/issues/20226")]
        [Fact]
        public void InterfaceImpl_01()
        {
            var text = @"
using System;
 
public class Program
{
    static void Main(string[] args)
    {
        using (new S1())
        {
            System.Console.Write(1);
        }
 
        System.Console.Write(3);    
    }
 
    public ref struct S1 : IDisposable
    {
        public void Dispose()
        {
            System.Console.Write(2);
        }
    }
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text, options: TestOptions.ReleaseExe);
 
            var verifier = CompileAndVerify(comp, expectedOutput: @"123").VerifyDiagnostics();
 
            verifier.VerifyIL("Program.Main",
@"
{
  // Code size       31 (0x1f)
  .maxstack  1
  .locals init (Program.S1 V_0)
  IL_0000:  ldloca.s   V_0
  IL_0002:  initobj    ""Program.S1""
  .try
  {
    IL_0008:  ldc.i4.1
    IL_0009:  call       ""void System.Console.Write(int)""
    IL_000e:  leave.s    IL_0018
  }
  finally
  {
    IL_0010:  ldloca.s   V_0
    IL_0012:  call       ""void Program.S1.Dispose()""
    IL_0017:  endfinally
  }
  IL_0018:  ldc.i4.3
  IL_0019:  call       ""void System.Console.Write(int)""
  IL_001e:  ret
}
");
        }
 
        [Fact]
        public void InterfaceImpl_02()
        {
            var text = @"
using System;
 
public class Program
{
    static void Main(string[] args)
    {
        using (new S1())
        {
            System.Console.Write(1);
        }
 
        System.Console.Write(3);    
    }
 
    public ref struct S1 : IDisposable
    {
        public void Dispose()
        {
            System.Console.Write(22);
        }
 
        void IDisposable.Dispose()
        {
            System.Console.Write(2);
        }
    }
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text, options: TestOptions.ReleaseExe);
 
            var verifier = CompileAndVerify(comp, expectedOutput: @"1223").VerifyDiagnostics();
 
            // We prioritize pattern over an interface according to https://github.com/dotnet/csharplang/blob/main/proposals/ref-struct-interfaces.md#using-statement 
 
            verifier.VerifyIL("Program.Main",
@"
{
  // Code size       31 (0x1f)
  .maxstack  1
  .locals init (Program.S1 V_0)
  IL_0000:  ldloca.s   V_0
  IL_0002:  initobj    ""Program.S1""
  .try
  {
    IL_0008:  ldc.i4.1
    IL_0009:  call       ""void System.Console.Write(int)""
    IL_000e:  leave.s    IL_0018
  }
  finally
  {
    IL_0010:  ldloca.s   V_0
    IL_0012:  call       ""void Program.S1.Dispose()""
    IL_0017:  endfinally
  }
  IL_0018:  ldc.i4.3
  IL_0019:  call       ""void System.Console.Write(int)""
  IL_001e:  ret
}
");
        }
 
        [Fact]
        public void InterfaceImpl_03()
        {
            var text = @"
using System;
 
public class Program
{
    static void Main(string[] args)
    {
        using (new S1())
        {
            System.Console.Write(1);
        }
 
        System.Console.Write(3);    
    }
 
    public ref struct S1 : IDisposable
    {
        void IDisposable.Dispose()
        {
            System.Console.Write(2);
        }
    }
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text, options: TestOptions.ReleaseExe);
 
            var verifier = CompileAndVerify(comp, expectedOutput: @"123").VerifyDiagnostics();
 
            verifier.VerifyIL("Program.Main",
@"
{
  // Code size       37 (0x25)
  .maxstack  1
  .locals init (Program.S1 V_0)
  IL_0000:  ldloca.s   V_0
  IL_0002:  initobj    ""Program.S1""
  .try
  {
    IL_0008:  ldc.i4.1
    IL_0009:  call       ""void System.Console.Write(int)""
    IL_000e:  leave.s    IL_001e
  }
  finally
  {
    IL_0010:  ldloca.s   V_0
    IL_0012:  constrained. ""Program.S1""
    IL_0018:  callvirt   ""void System.IDisposable.Dispose()""
    IL_001d:  endfinally
  }
  IL_001e:  ldc.i4.3
  IL_001f:  call       ""void System.Console.Write(int)""
  IL_0024:  ret
}
");
        }
 
        [Fact]
        public void NoInterfaceImp()
        {
            var text = @"
public class Program
{
    static void Main(string[] args)
    {
        using (new S1())
        {
            System.Console.Write(1);
        }
 
        System.Console.Write(3);
    }
 
    public ref struct S1
    {
        public void Dispose()
        {
            System.Console.Write(2);
        }
    }
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text, options: TestOptions.ReleaseExe);
 
            var verifier = CompileAndVerify(comp, expectedOutput: @"123").VerifyDiagnostics();
 
            verifier.VerifyIL("Program.Main",
@"
{
  // Code size       31 (0x1f)
  .maxstack  1
  .locals init (Program.S1 V_0)
  IL_0000:  ldloca.s   V_0
  IL_0002:  initobj    ""Program.S1""
  .try
  {
    IL_0008:  ldc.i4.1
    IL_0009:  call       ""void System.Console.Write(int)""
    IL_000e:  leave.s    IL_0018
  }
  finally
  {
    IL_0010:  ldloca.s   V_0
    IL_0012:  call       ""void Program.S1.Dispose()""
    IL_0017:  endfinally
  }
  IL_0018:  ldc.i4.3
  IL_0019:  call       ""void System.Console.Write(int)""
  IL_001e:  ret
}
");
        }
 
        [WorkItem(20226, "https://github.com/dotnet/roslyn/issues/20226")]
        [Fact]
        public void RefIteratorInAsync_01()
        {
            var text = @"
using System;
using System.Threading.Tasks;
 
class Program
{
    static void Main(string[] args)
    {
    }
 
    static async Task<int> Test()
    {
        var obj = new C1();
 
        foreach (var i in obj)
        {
            await Task.Yield();
            System.Console.WriteLine(i);
        }
 
        return 123;
    }
}
 
class C1
{
    public S1 GetEnumerator()
    {
        return new S1();
    }
 
    public ref struct S1
    {
        public int Current => throw new NotImplementedException();
 
        public bool MoveNext()
        {
            throw new NotImplementedException();
        }
    }
}
 
";
 
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular12).VerifyDiagnostics(
                // (15,9): error CS9202: Feature 'ref and unsafe in async and iterator methods' is not available in C# 12.0. Please use language version 13.0 or greater.
                //         foreach (var i in obj)
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion12, "foreach").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(15, 9));
 
            var expectedDiagnostics = new[]
            {
                // (15,9): error CS4007: Instance of type 'C1.S1' cannot be preserved across 'await' or 'yield' boundary.
                //         foreach (var i in obj)
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, @"foreach (var i in obj)
        {
            await Task.Yield();
            System.Console.WriteLine(i);
        }").WithArguments("C1.S1").WithLocation(15, 9)
            };
 
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular13).VerifyEmitDiagnostics(expectedDiagnostics);
            CreateCompilationWithMscorlibAndSpan(text).VerifyEmitDiagnostics(expectedDiagnostics);
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/74793")]
        public void RefIteratorInAsync_02()
        {
            var text = @"
using System.Threading.Tasks;
 
class Program
{
    static async Task Main()
    {
        var obj = new C1();
 
        foreach (var i in obj)
        {
            System.Console.Write(i);
        }
 
        await Task.Yield();
 
        System.Console.Write(-1);
    }
}
 
class C1
{
    public S1 GetEnumerator()
    {
        return new S1();
    }
 
    public ref struct S1
    {
        public int Current { get; private set; }
 
        public bool MoveNext()
        {
            Current++;
            return Current < 3;
        }
    }
}
 
";
 
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular12).VerifyDiagnostics(
                // (10,9): error CS9202: Feature 'ref and unsafe in async and iterator methods' is not available in C# 12.0. Please use language version 13.0 or greater.
                //         foreach (var i in obj)
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion12, "foreach").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(10, 9));
 
            var expectedOutput = "12-1";
 
            var comp = CreateCompilationWithMscorlibAndSpan(text, TestOptions.ReleaseExe, TestOptions.Regular13);
            CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify).VerifyDiagnostics();
 
            comp = CreateCompilationWithMscorlibAndSpan(text, TestOptions.ReleaseExe);
            CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify).VerifyDiagnostics();
        }
 
        [WorkItem(20226, "https://github.com/dotnet/roslyn/issues/20226")]
        [Fact]
        public void RefIteratorInIterator_01()
        {
            var text = @"
using System;
using System.Collections.Generic;
 
class Program
{
    static void Main(string[] args)
    {
        // this is valid
        Action a = () =>
        {
            foreach (var i in new C1())
            {
            }
        };
 
        a();
    }
 
    static IEnumerable<int> Test()
    {
        // this is valid
        Action a = () =>
        {
            foreach (var i in new C1())
            {
            }
        };
 
        a();
 
        // this is an error
        foreach (var i in new C1())
        {
            yield return 0;
        }
 
        yield return 1;
    }
}
 
class C1
{
    public S1 GetEnumerator()
    {
        return new S1();
    }
 
    public ref struct S1
    {
        public int Current => throw new NotImplementedException();
 
        public bool MoveNext()
        {
            throw new NotImplementedException();
        }
    }
}
";
 
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular12).VerifyDiagnostics(
                // (33,9): error CS9202: Feature 'ref and unsafe in async and iterator methods' is not available in C# 12.0. Please use language version 13.0 or greater.
                //         foreach (var i in new C1())
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion12, "foreach").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(33, 9));
 
            var expectedDiagnostics = new[]
            {
                // (33,9): error CS4007: Instance of type 'C1.S1' cannot be preserved across 'await' or 'yield' boundary.
                //         foreach (var i in new C1())
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, @"foreach (var i in new C1())
        {
            yield return 0;
        }").WithArguments("C1.S1").WithLocation(33, 9)
            };
 
            CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular13).VerifyEmitDiagnostics(expectedDiagnostics);
            CreateCompilationWithMscorlibAndSpan(text).VerifyEmitDiagnostics(expectedDiagnostics);
        }
 
        [Fact]
        public void RefIteratorInIterator_02()
        {
            var text = @"
using System;
using System.Collections.Generic;
 
class Program
{
    static void Main(string[] args)
    {
        foreach (var i in Test())
        {
            Console.Write(i);
        }
    }
 
    static IEnumerable<int> Test()
    {
        foreach (var i in new C1())
        {
            Console.Write(i);
        }
 
        yield return -1;
 
        Console.Write(-2);
    }
}
 
class C1
{
    public S1 GetEnumerator()
    {
        return new S1();
    }
 
    public ref struct S1
    {
        public int Current { get; private set; }
 
        public bool MoveNext()
        {
            Current++;
            return Current < 3;
        }
    }
}
";
 
            CreateCompilationWithMscorlibAndSpan(text, TestOptions.ReleaseExe, TestOptions.Regular12).VerifyDiagnostics(
                // (17,9): error CS9202: Feature 'ref and unsafe in async and iterator methods' is not available in C# 12.0. Please use language version 13.0 or greater.
                //         foreach (var i in new C1())
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion12, "foreach").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(17, 9));
 
            var expectedOutput = "12-1-2";
 
            var comp = CreateCompilationWithMscorlibAndSpan(text, TestOptions.ReleaseExe, TestOptions.Regular13);
            CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify).VerifyDiagnostics();
 
            comp = CreateCompilationWithMscorlibAndSpan(text, TestOptions.ReleaseExe);
            CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify).VerifyDiagnostics();
        }
 
        [Fact]
        public void Properties()
        {
            var text = @"
using System;
 
public class Program
{
    static void Main()
    {
    }
 
    // valid
    public static Span<byte> ps => default(Span<byte>);
    public Span<int> pi => default(Span<int>); 
 
    public Span<int> this[int i] => default(Span<int>); 
 
    // not valid
    public static Span<byte> aps {get;}
    public Span<int> api {get; set;} 
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text);
 
            comp.VerifyDiagnostics(
                // (17,19): error CS8345: Field or auto-implemented property cannot be of type 'Span<byte>' unless it is an instance member of a ref struct.
                //     public static Span<byte> aps {get;}
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "Span<byte>").WithArguments("System.Span<byte>").WithLocation(17, 19),
                // (18,12): error CS8345: Field or auto-implemented property cannot be of type 'Span<int>' unless it is an instance member of a ref struct.
                //     public Span<int> api {get; set;} 
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "Span<int>").WithArguments("System.Span<int>").WithLocation(18, 12)
            );
        }
 
        [Fact]
        public void Operators()
        {
            var text = @"
using System;
 
public class Program
{
    static void Main()
    {
    }
 
    // valid
    public static Span<byte> operator +(Span<byte> x, Program y) => default(Span<byte>);
 
    // invalid (baseline w/ TypedReference)
    public static TypedReference operator +(Span<int> x, Program y) => default(TypedReference);
 
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text);
 
            comp.VerifyDiagnostics(
                // (14,19): error CS1599: The return type of a method, delegate, or function pointer cannot be 'TypedReference'
                //     public static TypedReference operator +(Span<int> x, Program y) => default(TypedReference);
                Diagnostic(ErrorCode.ERR_MethodReturnCantBeRefAny, "TypedReference").WithArguments("System.TypedReference").WithLocation(14, 19)
            );
        }
 
        [Fact]
        public void AsyncParams()
        {
            var text = @"
using System;
using System.Threading.Tasks;
 
public class Program
{
    static void Main()
    {
    }
 
    public static async Task<int> M1(Span<int> arg)
    {
        await Task.Yield();
        return 42;
    }
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text);
 
            comp.VerifyDiagnostics(
                // (11,48): error CS4012: Parameters of type 'Span<int>' cannot be declared in async methods or async lambda expressions.
                //     public static async Task<int> M1(Span<int> arg)
                Diagnostic(ErrorCode.ERR_BadSpecialByRefParameter, "arg").WithArguments("System.Span<int>").WithLocation(11, 48)
            );
        }
 
        [Fact]
        public void AsyncLocals()
        {
            var text = @"
using System;
using System.Threading.Tasks;
 
public class Program
{
    static void Main()
    {
    }
 
    public static async Task<int> M1()
    {
        Span<int> local1 = default(Span<int>);
        var local2 = default(Span<int>);
 
        await Task.Yield();
        return 42;
    }
 
    public static async Task<int> M2()
    {
        Span<int> local1 = default(Span<int>);
        var local2 = default(Span<int>);
 
        await Task.Yield();
        return local1.Length; // 1
    }
 
    public static async Task<int> M3()
    {
        Span<int> local1 = default(Span<int>);
        var local2 = default(Span<int>);
 
        await Task.Yield();
        return local2.Length; // 2
    }
 
    public static async Task<int> M4()
    {
        Span<int> local1 = default(Span<int>);
        var local2 = default(Span<int>);
 
        await Task.Yield();
        return local1.Length + local2.Length; // 3, 4
    }
}
";
 
            var expectedDiagnostics = new[]
            {
                // (13,19): warning CS0219: The variable 'local1' is assigned but its value is never used
                //         Span<int> local1 = default(Span<int>);
                Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "local1").WithArguments("local1").WithLocation(13, 19),
                // (14,13): warning CS0219: The variable 'local2' is assigned but its value is never used
                //         var local2 = default(Span<int>);
                Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "local2").WithArguments("local2").WithLocation(14, 13),
                // (23,13): warning CS0219: The variable 'local2' is assigned but its value is never used
                //         var local2 = default(Span<int>);
                Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "local2").WithArguments("local2").WithLocation(23, 13),
                // (26,16): error CS4007: Instance of type 'System.Span<int>' cannot be preserved across 'await' or 'yield' boundary.
                //         return local1.Length; // 1
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "local1").WithArguments("System.Span<int>").WithLocation(26, 16),
                // (31,19): warning CS0219: The variable 'local1' is assigned but its value is never used
                //         Span<int> local1 = default(Span<int>);
                Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "local1").WithArguments("local1").WithLocation(31, 19),
                // (35,16): error CS4007: Instance of type 'System.Span<int>' cannot be preserved across 'await' or 'yield' boundary.
                //         return local2.Length; // 2
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "local2").WithArguments("System.Span<int>").WithLocation(35, 16),
                // (44,16): error CS4007: Instance of type 'System.Span<int>' cannot be preserved across 'await' or 'yield' boundary.
                //         return local1.Length + local2.Length; // 3, 4
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "local1").WithArguments("System.Span<int>").WithLocation(44, 16),
                // (44,32): error CS4007: Instance of type 'System.Span<int>' cannot be preserved across 'await' or 'yield' boundary.
                //         return local1.Length + local2.Length; // 3, 4
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "local2").WithArguments("System.Span<int>").WithLocation(44, 32)
            };
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text);
 
            comp.VerifyEmitDiagnostics(expectedDiagnostics);
 
            comp = CreateCompilationWithMscorlibAndSpan(text, TestOptions.DebugExe);
 
            comp.VerifyEmitDiagnostics(expectedDiagnostics);
        }
 
        [Fact]
        public void AsyncLocals_OutVar()
        {
            var text = @"
using System;
using System.Threading.Tasks;
 
public class Program
{
    public static async Task<int> M1()
    {
        M2(out var local1);
        M2(out Span<int> local2);
 
        await Task.Yield();
        return 42;
    }
 
    public static async Task<int> M3()
    {
        M2(out var local1);
        M2(out Span<int> local2);
 
        await Task.Yield();
        return local1.Length; // 1
    }
 
    public static async Task<int> M4()
    {
        M2(out var local1);
        M2(out Span<int> local2);
 
        await Task.Yield();
        return local2.Length; // 2
    }
 
    static void M2(out Span<int> s) => throw null;
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text);
 
            comp.VerifyEmitDiagnostics(
                // (22,16): error CS4007: Instance of type 'System.Span<int>' cannot be preserved across 'await' or 'yield' boundary.
                //         return local1.Length; // 1
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "local1").WithArguments("System.Span<int>").WithLocation(22, 16),
                // (31,16): error CS4007: Instance of type 'System.Span<int>' cannot be preserved across 'await' or 'yield' boundary.
                //         return local2.Length; // 2
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "local2").WithArguments("System.Span<int>").WithLocation(31, 16));
        }
 
        [Fact, WorkItem(62747, "https://github.com/dotnet/roslyn/issues/62747")]
        public void AsyncLocals_Foreach()
        {
            var src = @"
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
 
public class Program
{
    public async Task M(IReadOnlyList<string> o)
    {
        foreach (ReadOnlySpan<char> c1 in o) { }
 
        var enumerator = ((IEnumerable<string>)o).GetEnumerator();
        while (enumerator.MoveNext())
        {
            ReadOnlySpan<char> c2 = (ReadOnlySpan<char>)(string)enumerator.Current;
            _ = c2.Length;
        }
 
        await Task.Yield();
        return;
    }
 
    public async Task M2(IReadOnlyList<string> o)
    {
        foreach (ReadOnlySpan<char> c1 in o)
        {
            await Task.Yield();
            _ = c1.Length; // 1
        }
 
        var enumerator = ((IEnumerable<string>)o).GetEnumerator();
        while (enumerator.MoveNext())
        {
            ReadOnlySpan<char> c2 = (ReadOnlySpan<char>)(string)enumerator.Current;
            await Task.Yield();
            _ = c2.Length; // 2
        }
 
        await Task.Yield();
        return;
    }
}
";
 
            var comp = CreateCompilation(src, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (28,17): error CS4007: Instance of type 'System.ReadOnlySpan<char>' cannot be preserved across 'await' or 'yield' boundary.
                //             _ = c1.Length; // 1
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "c1").WithArguments("System.ReadOnlySpan<char>").WithLocation(28, 17),
                // (36,17): error CS4007: Instance of type 'System.ReadOnlySpan<char>' cannot be preserved across 'await' or 'yield' boundary.
                //             _ = c2.Length; // 2
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "c2").WithArguments("System.ReadOnlySpan<char>").WithLocation(36, 17));
        }
 
        [Fact, WorkItem(62747, "https://github.com/dotnet/roslyn/issues/62747")]
        public void AsyncLocals_Deconstruction()
        {
            var src = @"
using System;
using System.Threading.Tasks;
 
public class Program
{
    public async Task M()
    {
        (Span<int> s1, Span<int> s2) = new Program();
        var (s3, s4) = new Program();
        (var s5, var s6) = new Program();
 
        await Task.Yield();
        return;
    }
 
    public async Task M2()
    {
        (Span<int> s1, Span<int> s2) = new Program();
        var (s3, s4) = new Program();
        (var s5, var s6) = new Program();
 
        await Task.Yield();
 
        _ = s1.Length + s4.Length + s5.Length; // 1, 2, 3
        return;
    }
 
    void Deconstruct(out Span<int> s1, out Span<int> s2) => throw null;
}
";
            var comp = CreateCompilation(src, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (25,13): error CS4007: Instance of type 'System.Span<int>' cannot be preserved across 'await' or 'yield' boundary.
                //         _ = s1.Length + s4.Length + s5.Length; // 1, 2, 3
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s1").WithArguments("System.Span<int>").WithLocation(25, 13),
                // (25,25): error CS4007: Instance of type 'System.Span<int>' cannot be preserved across 'await' or 'yield' boundary.
                //         _ = s1.Length + s4.Length + s5.Length; // 1, 2, 3
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s4").WithArguments("System.Span<int>").WithLocation(25, 25),
                // (25,37): error CS4007: Instance of type 'System.Span<int>' cannot be preserved across 'await' or 'yield' boundary.
                //         _ = s1.Length + s4.Length + s5.Length; // 1, 2, 3
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s5").WithArguments("System.Span<int>").WithLocation(25, 37));
        }
 
        [Fact, WorkItem(62747, "https://github.com/dotnet/roslyn/issues/62747")]
        public void AsyncLocals_Using()
        {
            var src = @"
using System.Threading.Tasks;
 
public class Program
{
    public async Task M()
    {
        using (default(RS)) { }
        using (var s1 = default(RS)) { }
        using (RS s2 = default(RS)) { }
        using RS s3 = default(RS); // 1
        using var s4 = default(RS); // 2
 
        await Task.Yield();
        return;
    }
 
    public async Task M2()
    {
        using (default(RS)) { await Task.Yield(); } // 3
        using (var s1 = default(RS)) { await Task.Yield(); } // 4
        using (RS s2 = default(RS)) { await Task.Yield(); } // 5
        {
            using RS s3 = default(RS); // 6
            await Task.Yield();
            using var s4 = default(RS);
        }
 
        await Task.Yield();
        return;
    }
}
 
public ref struct RS
{
    public void Dispose() { }
}
";
            var comp = CreateCompilation(src, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (11,18): error CS4007: Instance of type 'RS' cannot be preserved across 'await' or 'yield' boundary.
                //         using RS s3 = default(RS); // 1
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s3 = default(RS)").WithArguments("RS").WithLocation(11, 18),
                // (12,19): error CS4007: Instance of type 'RS' cannot be preserved across 'await' or 'yield' boundary.
                //         using var s4 = default(RS); // 2
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s4 = default(RS)").WithArguments("RS").WithLocation(12, 19),
                // (20,16): error CS4007: Instance of type 'RS' cannot be preserved across 'await' or 'yield' boundary.
                //         using (default(RS)) { await Task.Yield(); } // 3
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "default(RS)").WithArguments("RS").WithLocation(20, 16),
                // (21,20): error CS4007: Instance of type 'RS' cannot be preserved across 'await' or 'yield' boundary.
                //         using (var s1 = default(RS)) { await Task.Yield(); } // 4
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s1 = default(RS)").WithArguments("RS").WithLocation(21, 20),
                // (22,19): error CS4007: Instance of type 'RS' cannot be preserved across 'await' or 'yield' boundary.
                //         using (RS s2 = default(RS)) { await Task.Yield(); } // 5
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s2 = default(RS)").WithArguments("RS").WithLocation(22, 19),
                // (24,22): error CS4007: Instance of type 'RS' cannot be preserved across 'await' or 'yield' boundary.
                //             using RS s3 = default(RS); // 6
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s3 = default(RS)").WithArguments("RS").WithLocation(24, 22));
        }
 
        [Fact]
        public void AsyncLocals_PatternDeclaration()
        {
            var src = @"
using System;
using System.Threading.Tasks;
 
public class Program
{
    public async Task M()
    {
        if (M2() is var s1) { }
        if (M2() is Span<int> s2) { }
        if (M2() is var s3) { await Task.Yield(); }
        if (M2() is Span<int> s4) { await Task.Yield(); }
 
        await Task.Yield();
        return;
    }
 
    public async Task M3()
    {
        if (M2() is var s1)
        {
            await Task.Yield();
            _ = s1.Length; // 1
        }
        if (M2() is Span<int> s2)
        {
            await Task.Yield();
            _ = s2.Length; // 2
        }
 
        await Task.Yield();
        return;
    }
 
    static Span<int> M2() => throw null;
}
";
            var comp = CreateCompilation(src, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics(
                // (23,17): error CS4007: Instance of type 'System.Span<int>' cannot be preserved across 'await' or 'yield' boundary.
                //             _ = s1.Length;
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s1").WithArguments("System.Span<int>").WithLocation(23, 17),
                // (28,17): error CS4007: Instance of type 'System.Span<int>' cannot be preserved across 'await' or 'yield' boundary.
                //             _ = s2.Length;
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s2").WithArguments("System.Span<int>").WithLocation(28, 17));
        }
 
        [Fact]
        public void AsyncLocals_Reassignment()
        {
            var code = """
                using System;
                using System.Threading.Tasks;
                class C
                {
                    async Task M1()
                    {
                        int x = 42;
                        Span<int> y = new(ref x);
                        y.ToString();
                        await Task.Yield();
                        y.ToString(); // 1
                    }
                    async Task M2()
                    {
                        int x = 42;
                        Span<int> y = new(ref x);
                        y.ToString();
                        await Task.Yield();
                        y = new(ref x);
                        y.ToString();
                    }
                }
                """;
            CreateCompilation(code, targetFramework: TargetFramework.Net70).VerifyEmitDiagnostics(
                // (11,9): error CS4007: Instance of type 'System.Span<int>' cannot be preserved across 'await' or 'yield' boundary.
                //         y.ToString(); // 1
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "y").WithArguments("System.Span<int>").WithLocation(11, 9));
        }
 
        [Fact]
        public void AsyncSpilling()
        {
            var text = @"
using System;
using System.Threading.Tasks;
 
public class Program
{
    static void Main()
    {
    }
 
    public static async Task<int> M1()
    {
        // this is ok
        TakesSpan(default(Span<int>), 123);
 
        // this is not ok
        TakesSpan(default(Span<int>), await I1());
 
        // this is ok
        TakesSpan(await I1(), default(Span<int>));
 
        return 42;
    }
 
    public static void TakesSpan(Span<int> s, int i)
    {
    }
 
    public static void TakesSpan(int i, Span<int> s)
    {
    }
 
    public static async Task<int> I1()
    {
        await Task.Yield();
        return 42;
    }
    
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text);
 
            var expectedDiagnostics = new[]
            {
                // (17,19): error CS4007: Instance of type 'System.Span<int>' cannot be preserved across 'await' or 'yield' boundary.
                //         TakesSpan(default(Span<int>), await I1());
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "default(Span<int>)").WithArguments("System.Span<int>").WithLocation(17, 19)
            };
 
            comp.VerifyEmitDiagnostics(expectedDiagnostics);
 
            comp = CreateCompilationWithMscorlibAndSpan(text, TestOptions.DebugExe);
 
            comp.VerifyEmitDiagnostics(expectedDiagnostics);
        }
 
        [Fact]
        public void AsyncSpillTemp()
        {
            var text = @"
using System;
using System.Threading.Tasks;
 
public class Program
{
    static void Main()
    {
    }
 
    public static async Task<int> M1()
    {
        // this is not ok
        TakesSpan(s: default(Span<int>), i: await I1());
 
        return 42;
    }
 
    public static void TakesSpan(int i, Span<int> s)
    {
    }
 
    public static async Task<int> I1()
    {
        await Task.Yield();
        return 42;
    }
    
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text);
 
            var expectedDiagnostics = new[]
            {
                // (14,22): error CS4007: Instance of type 'System.Span<int>' cannot be preserved across 'await' or 'yield' boundary.
                //         TakesSpan(s: default(Span<int>), i: await I1());
                Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "default(Span<int>)").WithArguments("System.Span<int>").WithLocation(14, 22)
            };
 
            comp.VerifyEmitDiagnostics(expectedDiagnostics);
 
            comp = CreateCompilationWithMscorlibAndSpan(text, TestOptions.DebugExe);
 
            comp.VerifyEmitDiagnostics(expectedDiagnostics);
        }
 
        [Fact]
        public void AwaitAssignSpan()
        {
            var source = """
                using System;
                using System.Threading.Tasks;
 
                ReadOnlySpan<int> r = await M();
                Console.Write(r[1]);
 
                async Task<int[]> M()
                {
                    await Task.Yield();
                    return new[] { 4, 5, 6 };
                }
                """;
 
            CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(
                // (4,1): error CS9202: Feature 'ref and unsafe in async and iterator methods' is not available in C# 12.0. Please use language version 13.0 or greater.
                // ReadOnlySpan<int> r = await M();
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion12, "ReadOnlySpan<int>").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(4, 1));
 
            var expectedOutput = "5";
 
            var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular13);
            CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
            comp = CreateCompilationWithSpan(source);
            CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        }
 
        [Fact]
        public void BaseMethods()
        {
            var text = @"
using System;
 
public class Program
{
    static void Main()
    {
        // this is ok  (overridden)
        default(Span<int>).GetHashCode();
 
        // this is ok  (implicit boxing)
        default(Span<int>).GetType();
 
        // this is not ok  (implicit boxing)
        default(Span<int>).ToString();
    }
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text);
 
            comp.VerifyDiagnostics(
                // (12,9): error CS0029: Cannot implicitly convert type 'System.Span<int>' to 'object'
                //         default(Span<int>).GetType();
                Diagnostic(ErrorCode.ERR_NoImplicitConv, "default(Span<int>)").WithArguments("System.Span<int>", "object").WithLocation(12, 9),
                // (15,9): error CS0029: Cannot implicitly convert type 'System.Span<int>' to 'System.ValueType'
                //         default(Span<int>).ToString();
                Diagnostic(ErrorCode.ERR_NoImplicitConv, "default(Span<int>)").WithArguments("System.Span<int>", "System.ValueType").WithLocation(15, 9)
            );
        }
 
        [WorkItem(21979, "https://github.com/dotnet/roslyn/issues/21979")]
        [Fact]
        public void MethodConversion()
        {
            var text = @"
using System;
 
public class Program
{
    static void Main()
    {
        // we no longer allow this.
        // see https://github.com/dotnet/roslyn/issues/21979
        Func<int> d0 = default(TypedReference).GetHashCode;
 
        // none of the following is ok, since we would need to capture the receiver.
        Func<int> d1 = default(Span<int>).GetHashCode;
 
        Func<Type> d2 = default(SpanLike<int>).GetType;
 
        Func<string> d3 = default(Span<int>).ToString;
    }
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text);
 
            comp.VerifyEmitDiagnostics(
                // (10,48): error CS0123: No overload for 'GetHashCode' matches delegate 'Func<int>'
                //         Func<int> d0 = default(TypedReference).GetHashCode;
                Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "GetHashCode").WithArguments("GetHashCode", "System.Func<int>").WithLocation(10, 48),
                // (13,43): error CS0123: No overload for 'GetHashCode' matches delegate 'Func<int>'
                //         Func<int> d1 = default(Span<int>).GetHashCode;
                Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "GetHashCode").WithArguments("GetHashCode", "System.Func<int>").WithLocation(13, 43),
                // (15,48): error CS0123: No overload for 'GetType' matches delegate 'Func<Type>'
                //         Func<Type> d2 = default(SpanLike<int>).GetType;
                Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "GetType").WithArguments("GetType", "System.Func<System.Type>").WithLocation(15, 48),
                // (17,46): error CS0123: No overload for 'ToString' matches delegate 'Func<string>'
                //         Func<string> d3 = default(Span<int>).ToString;
                Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "ToString").WithArguments("ToString", "System.Func<string>").WithLocation(17, 46)
            );
        }
 
        [Fact]
        public void RefSpanDetectBoxing_NoRef()
        {
            string spanSource = @"
namespace System
{
    public struct Span<T> { }
    public struct ReadOnlySpan<T> { }
}";
            var reference = CreateEmptyCompilation(
                spanSource,
                references: new List<MetadataReference>() { MscorlibRef_v4_0_30316_17626, SystemCoreRef, CSharpRef },
                options: TestOptions.ReleaseDll);
 
            reference.VerifyDiagnostics();
 
            var text = @"
class Program
{
    static void Main()
    {
        object x = new System.Span<int>();
        object y = new System.ReadOnlySpan<byte>();
    }
}
";
            var comp = CreateEmptyCompilation(
                text,
                references: new List<MetadataReference>() { MscorlibRef_v4_0_30316_17626, SystemCoreRef, CSharpRef, reference.EmitToImageReference() },
                options: TestOptions.ReleaseExe);
 
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void RefSpanDetectBoxing_Ref()
        {
            string spanSource = @"
namespace System
{
    public ref struct Span<T> { }
    public ref struct ReadOnlySpan<T> { }
}";
            var reference = CreateEmptyCompilation(
                spanSource,
                references: new List<MetadataReference>() { MscorlibRef_v4_0_30316_17626, SystemCoreRef, CSharpRef },
                options: TestOptions.ReleaseDll);
 
            reference.VerifyDiagnostics();
 
            var text = @"
class Program
{
    static void Main()
    {
        object x = new System.Span<int>();
        object y = new System.ReadOnlySpan<byte>();
    }
}
";
            var comp = CreateEmptyCompilation(
                text,
                references: new List<MetadataReference>() { MscorlibRef_v4_0_30316_17626, SystemCoreRef, CSharpRef, reference.EmitToImageReference() },
                options: TestOptions.ReleaseExe);
 
            comp.VerifyDiagnostics(
                // (6,20): error CS0029: Cannot implicitly convert type 'System.Span<int>' to 'object'
                //         object x = new System.Span<int>();
                Diagnostic(ErrorCode.ERR_NoImplicitConv, "new System.Span<int>()").WithArguments("System.Span<int>", "object").WithLocation(6, 20),
                // (7,20): error CS0029: Cannot implicitly convert type 'System.ReadOnlySpan<byte>' to 'object'
                //         object y = new System.ReadOnlySpan<byte>();
                Diagnostic(ErrorCode.ERR_NoImplicitConv, "new System.ReadOnlySpan<byte>()").WithArguments("System.ReadOnlySpan<byte>", "object").WithLocation(7, 20));
        }
 
        [Fact]
        public void CannotUseNonRefSpan()
        {
            string spanSource = @"
namespace System
{
    public struct Span<T> 
    {
        unsafe public Span(void* pointer, int length)
        {
        }
    }
}";
            var reference = CreateEmptyCompilation(
                spanSource,
                references: new List<MetadataReference>() { MscorlibRef_v4_0_30316_17626, SystemCoreRef, CSharpRef },
                options: TestOptions.UnsafeReleaseDll);
 
            reference.VerifyDiagnostics();
 
            var text = @"
using System;
class Program
{
    static void Main()
    {
        Span<int> x = stackalloc int [10];
    }
}
";
            var comp = CreateEmptyCompilation(
                text,
                references: new List<MetadataReference>() { MscorlibRef_v4_0_30316_17626, SystemCoreRef, CSharpRef, reference.EmitToImageReference() },
                options: TestOptions.ReleaseExe);
 
            comp.VerifyDiagnostics(
                // (7,23): error CS8346: Conversion of a stackalloc expression of type 'int' to type 'Span<int>' is not possible.
                //         Span<int> x = stackalloc int [10];
                Diagnostic(ErrorCode.ERR_StackAllocConversionNotPossible, "stackalloc int [10]").WithArguments("int", "System.Span<int>").WithLocation(7, 23));
        }
 
        [Fact]
        public void CannotUseNonStructSpan()
        {
            string spanSource = @"
namespace System
{
    public class Span<T> 
    {
        unsafe public Span(void* pointer, int length)
        {
        }
    }
}";
            var reference = CreateEmptyCompilation(
                spanSource,
                references: new List<MetadataReference>() { MscorlibRef_v4_0_30316_17626, SystemCoreRef, CSharpRef },
                options: TestOptions.UnsafeReleaseDll);
 
            reference.VerifyDiagnostics();
 
            var text = @"
using System;
class Program
{
    static void Main()
    {
        Span<int> x = stackalloc int [10];
    }
}
";
            var comp = CreateEmptyCompilation(
                text,
                references: new List<MetadataReference>() { MscorlibRef_v4_0_30316_17626, SystemCoreRef, CSharpRef, reference.EmitToImageReference() },
                options: TestOptions.ReleaseExe);
 
            comp.VerifyDiagnostics(
                // (7,23): error CS8346: Conversion of a stackalloc expression of type 'int' to type 'Span<int>' is not possible.
                //         Span<int> x = stackalloc int [10];
                Diagnostic(ErrorCode.ERR_StackAllocConversionNotPossible, "stackalloc int [10]").WithArguments("int", "System.Span<int>").WithLocation(7, 23));
        }
 
        [Fact]
        [WorkItem(23627, "https://github.com/dotnet/roslyn/issues/23627")]
        public void CreateVariableFromRefStructFieldInNonRefStruct()
        {
            var code = @"
public ref struct Point
{
}
class Program
{
    public Point field1 = new Point();
    public static Point field2 = new Point();
 
    void Check()
    {
        var temp1 = field1;
        var temp2 = field2;
    }
}";
 
            CreateCompilation(code).VerifyDiagnostics(
                // (8,19): error CS8345: Field or auto-implemented property cannot be of type 'Point' unless it is an instance member of a ref struct.
                //     public static Point field2 = new Point();
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "Point").WithArguments("Point").WithLocation(8, 19),
                // (7,12): error CS8345: Field or auto-implemented property cannot be of type 'Point' unless it is an instance member of a ref struct.
                //     public Point field1 = new Point();
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "Point").WithArguments("Point").WithLocation(7, 12));
        }
 
        [Fact]
        [WorkItem(23627, "https://github.com/dotnet/roslyn/issues/23627")]
        public void CreateVariableFromRefStructFieldInRefStruct()
        {
            var code = @"
public ref struct Point
{
}
ref struct Program
{
    public static Point field1;
    public static Point field2 = new Point();
 
    public Program(Point p)
    {
        field1 = p;
    }
 
    void Check()
    {
        var temp1 = field1;
        var temp2 = field2;
    }
}";
 
            CreateCompilation(code).VerifyDiagnostics(
                // (8,19): error CS8345: Field or auto-implemented property cannot be of type 'Point' unless it is an instance member of a ref struct.
                //     public static Point field2 = new Point();
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "Point").WithArguments("Point").WithLocation(8, 19),
                // (7,19): error CS8345: Field or auto-implemented property cannot be of type 'Point' unless it is an instance member of a ref struct.
                //     public static Point field1;
                Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "Point").WithArguments("Point").WithLocation(7, 19));
        }
 
        [Fact]
        [WorkItem(24627, "https://github.com/dotnet/roslyn/issues/24627")]
        public void ArgMixingBogusInstanceCall()
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
class Program
{
    ref struct S1
    {
        public void Test(int x) => throw null;       
        public int this[int x] => throw null;        
        public S1(S1 x, int y) => throw null;            
    }
    
    static void Main()
    {
        // these are all errors, we should not be doing escape analysis on them.
        S1.Test(1);
        var x = S1[1];       
        var y = new S1(S1, 1);
    }
}");
 
            comp.VerifyDiagnostics(
                // (14,9): error CS0120: An object reference is required for the non-static field, method, or property 'Program.S1.Test(int)'
                //         S1.Test(1);
                Diagnostic(ErrorCode.ERR_ObjectRequired, "S1.Test").WithArguments("Program.S1.Test(int)").WithLocation(14, 9),
                // (15,17): error CS0119: 'Program.S1' is a type, which is not valid in the given context
                //         var x = S1[1];       
                Diagnostic(ErrorCode.ERR_BadSKunknown, "S1").WithArguments("Program.S1", "type").WithLocation(15, 17),
                // (16,24): error CS0119: 'Program.S1' is a type, which is not valid in the given context
                //         var y = new S1(S1, 1);
                Diagnostic(ErrorCode.ERR_BadSKunknown, "S1").WithArguments("Program.S1", "type").WithLocation(16, 24)
                );
        }
 
        [WorkItem(27874, "https://github.com/dotnet/roslyn/issues/27874")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void PassingSpansToLocals_EscapeScope_01(LanguageVersion languageVersion)
        {
            var source = @"using System;
class C
{
    static void Main()
    {
        Span<int> x = stackalloc int [10];
        
        Console.WriteLine(M1(ref x).Length);
        Console.WriteLine(M2(ref x).Length);
    }
    
    static ref Span<int> M1(ref Span<int> x)
    {
        ref Span<int> q = ref x;
        return ref q;
    }
    
    static ref Span<int> M2(ref Span<int> x)
    {
        return ref x;
    }
}";
 
            var comp = CreateCompilationWithMscorlibAndSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.ReleaseExe);
            CompileAndVerify(comp, verify: Verification.Fails, expectedOutput: @"
10
10");
        }
 
        [WorkItem(27874, "https://github.com/dotnet/roslyn/issues/27874")]
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        public void PassingSpansToLocals_EscapeScope_02(LanguageVersion languageVersion)
        {
            var source = @"using System;
 
class C
{
    static void Main()
    {
        Span<int> x = stackalloc int [10];
        
        Console.WriteLine(M1(ref x).Length);
        Console.WriteLine(M2(ref x).Length);
    }
    
    static ref Span<int> M1(ref Span<int> x)
    {
        ref Span<int> q = ref x;
        return ref q;
    }
    
    static ref Span<int> M2(ref Span<int> x)
    {
        return ref x;
    }
}";
 
            var comp = CreateCompilationWithMscorlibAndSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.ReleaseExe);
            CompileAndVerify(comp, verify: Verification.Fails, expectedOutput: @"
10
10");
        }
 
        [Fact]
        [WorkItem(27357, "https://github.com/dotnet/roslyn/issues/27357")]
        public void PassingSpansToInParameters_Methods()
        {
            CompileAndVerify(CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    static void Main()
    {
        Span<int> s1 = stackalloc int[1];
        M1(s1);
    }
    
    static void M1(Span<int> s1)
    {
        Span<int> s2 = stackalloc int[2];
 
        M2(s1, s2);
        M2(s2, s1);
 
        M2(s1, in s2);
        M2(s2, in s1);
 
        M2(x: s1, y: in s2);
        M2(x: s2, y: in s1);
 
        M2(y: in s2, x: s1);
        M2(y: in s1, x: s2);
    }
 
    static void M2(Span<int> x, in Span<int> y)
    {
        Console.WriteLine(x.Length + "" - "" + y.Length);
    }
}", options: TestOptions.ReleaseExe), verify: Verification.Fails, expectedOutput: @"
1 - 2
2 - 1
1 - 2
2 - 1
1 - 2
2 - 1
1 - 2
2 - 1");
        }
 
        [Fact]
        [WorkItem(27357, "https://github.com/dotnet/roslyn/issues/27357")]
        public void PassingSpansToInParameters_Indexers()
        {
            CompileAndVerify(CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    static void Main()
    {
        Span<int> s1 = stackalloc int[1];
        M1(s1);
    }
    
    static void M1(Span<int> s1)
    {
        var obj = new C();
        Span<int> s2 = stackalloc int[2];
 
        Console.WriteLine(obj[s1, s2]);
        Console.WriteLine(obj[s2, s1]);
 
        Console.WriteLine(obj[s1, in s2]);
        Console.WriteLine(obj[s2, in s1]);
 
        Console.WriteLine(obj[x: s1, y: in s2]);
        Console.WriteLine(obj[x: s2, y: in s1]);
 
        Console.WriteLine(obj[y: in s2, x: s1]);
        Console.WriteLine(obj[y: in s1, x: s2]);
    }
 
    string this[Span<int> x, in Span<int> y] => x.Length + "" - "" + y.Length;
}", options: TestOptions.ReleaseExe), verify: Verification.Fails, expectedOutput: @"
1 - 2
2 - 1
1 - 2
2 - 1
1 - 2
2 - 1
1 - 2
2 - 1");
        }
 
        [Theory]
        [InlineData(LanguageVersion.CSharp10)]
        [InlineData(LanguageVersion.CSharp11)]
        [WorkItem(27357, "https://github.com/dotnet/roslyn/issues/27357")]
        public void PassingSpansToParameters_Errors(LanguageVersion languageVersion)
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    static void Main()
    {
        Span<int> s1 = stackalloc int[1];
        M1(s1);
    }
    
    static void M1(Span<int> s1)
    {
        var obj = new C();
        Span<int> s2 = stackalloc int[2];
 
        M2(ref s1, out s2);         // one
        M2(ref s2, out s1);         // two
 
        M2(ref s1, out s2);         // three
        M2(ref s2, out s1);         // four
 
        M2(y: out s2, x: ref s1);   // five
        M2(y: out s1, x: ref s2);   // six
 
        M2(ref s1, out s1);         // okay
        M2(ref s2, out s2);         // okay
    }
 
    static void M2(scoped ref Span<int> x, out Span<int> y)
    {
        y = default;
    }
}", parseOptions: TestOptions.RegularDefault.WithLanguageVersion(languageVersion));
 
            if (languageVersion == LanguageVersion.CSharp10)
            {
                // In C# 7.2 the input to an `out` parameter can escape which means several 
                // of the tests are errors due to stack copying to escape
                comp.VerifyDiagnostics(
                    // (16,9): error CS8350: This combination of arguments to 'C.M2(scoped ref Span<int>, out Span<int>)' is disallowed because it may expose variables referenced by parameter 'y' outside of their declaration scope
                    //         M2(ref s1, out s2);         // one
                    Diagnostic(ErrorCode.ERR_CallArgMixing, "M2(ref s1, out s2)").WithArguments("C.M2(scoped ref System.Span<int>, out System.Span<int>)", "y").WithLocation(16, 9),
                    // (16,24): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                    //         M2(ref s1, out s2);         // one
                    Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(16, 24),
                    // (17,9): error CS8350: This combination of arguments to 'C.M2(scoped ref Span<int>, out Span<int>)' is disallowed because it may expose variables referenced by parameter 'x' outside of their declaration scope
                    //         M2(ref s2, out s1);         // two
                    Diagnostic(ErrorCode.ERR_CallArgMixing, "M2(ref s2, out s1)").WithArguments("C.M2(scoped ref System.Span<int>, out System.Span<int>)", "x").WithLocation(17, 9),
                    // (17,16): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                    //         M2(ref s2, out s1);         // two
                    Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(17, 16),
                    // (19,9): error CS8350: This combination of arguments to 'C.M2(scoped ref Span<int>, out Span<int>)' is disallowed because it may expose variables referenced by parameter 'y' outside of their declaration scope
                    //         M2(ref s1, out s2);         // three
                    Diagnostic(ErrorCode.ERR_CallArgMixing, "M2(ref s1, out s2)").WithArguments("C.M2(scoped ref System.Span<int>, out System.Span<int>)", "y").WithLocation(19, 9),
                    // (19,24): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                    //         M2(ref s1, out s2);         // three
                    Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(19, 24),
                    // (20,9): error CS8350: This combination of arguments to 'C.M2(scoped ref Span<int>, out Span<int>)' is disallowed because it may expose variables referenced by parameter 'x' outside of their declaration scope
                    //         M2(ref s2, out s1);         // four
                    Diagnostic(ErrorCode.ERR_CallArgMixing, "M2(ref s2, out s1)").WithArguments("C.M2(scoped ref System.Span<int>, out System.Span<int>)", "x").WithLocation(20, 9),
                    // (20,16): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                    //         M2(ref s2, out s1);         // four
                    Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(20, 16),
                    // (22,9): error CS8350: This combination of arguments to 'C.M2(scoped ref Span<int>, out Span<int>)' is disallowed because it may expose variables referenced by parameter 'y' outside of their declaration scope
                    //         M2(y: out s2, x: ref s1);   // five
                    Diagnostic(ErrorCode.ERR_CallArgMixing, "M2(y: out s2, x: ref s1)").WithArguments("C.M2(scoped ref System.Span<int>, out System.Span<int>)", "y").WithLocation(22, 9),
                    // (22,19): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                    //         M2(y: out s2, x: ref s1);   // five
                    Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(22, 19),
                    // (23,9): error CS8350: This combination of arguments to 'C.M2(scoped ref Span<int>, out Span<int>)' is disallowed because it may expose variables referenced by parameter 'x' outside of their declaration scope
                    //         M2(y: out s1, x: ref s2);   // six
                    Diagnostic(ErrorCode.ERR_CallArgMixing, "M2(y: out s1, x: ref s2)").WithArguments("C.M2(scoped ref System.Span<int>, out System.Span<int>)", "x").WithLocation(23, 9),
                    // (23,30): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                    //         M2(y: out s1, x: ref s2);   // six
                    Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(23, 30),
                    // (29,20): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
                    //     static void M2(scoped ref Span<int> x, out Span<int> y)
                    Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(29, 20));
            }
            else
            {
                comp.VerifyDiagnostics(
                    // (17,9): error CS8350: This combination of arguments to 'C.M2(scoped ref Span<int>, out Span<int>)' is disallowed because it may expose variables referenced by parameter 'x' outside of their declaration scope
                    //         M2(ref s2, out s1);         // two
                    Diagnostic(ErrorCode.ERR_CallArgMixing, "M2(ref s2, out s1)").WithArguments("C.M2(scoped ref System.Span<int>, out System.Span<int>)", "x").WithLocation(17, 9),
                    // (17,16): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                    //         M2(ref s2, out s1);         // two
                    Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(17, 16),
                    // (20,9): error CS8350: This combination of arguments to 'C.M2(scoped ref Span<int>, out Span<int>)' is disallowed because it may expose variables referenced by parameter 'x' outside of their declaration scope
                    //         M2(ref s2, out s1);         // four
                    Diagnostic(ErrorCode.ERR_CallArgMixing, "M2(ref s2, out s1)").WithArguments("C.M2(scoped ref System.Span<int>, out System.Span<int>)", "x").WithLocation(20, 9),
                    // (20,16): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                    //         M2(ref s2, out s1);         // four
                    Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(20, 16),
                    // (23,9): error CS8350: This combination of arguments to 'C.M2(scoped ref Span<int>, out Span<int>)' is disallowed because it may expose variables referenced by parameter 'x' outside of their declaration scope
                    //         M2(y: out s1, x: ref s2);   // six
                    Diagnostic(ErrorCode.ERR_CallArgMixing, "M2(y: out s1, x: ref s2)").WithArguments("C.M2(scoped ref System.Span<int>, out System.Span<int>)", "x").WithLocation(23, 9),
                    // (23,30): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                    //         M2(y: out s1, x: ref s2);   // six
                    Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(23, 30));
            }
        }
 
        [Fact]
        [WorkItem(27357, "https://github.com/dotnet/roslyn/issues/27357")]
        public void PassingSpansToParameters_Errors_Arglist()
        {
            CreateCompilationWithMscorlibAndSpan(@"
using System;
class C
{
    static void Main()
    {
        Span<int> s1 = stackalloc int[1];
        M1(s1);
    }
    
    static void M1(Span<int> s1)
    {
        var obj = new C();
        Span<int> s2 = stackalloc int[2];
 
        M2(__arglist(ref s1, ref s2));  // one
        M2(__arglist(ref s2, ref s1));  // two
    }
 
    static void M2(__arglist)
    {
    }
}").VerifyDiagnostics(
                // (16,34): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                //         M2(__arglist(ref s1, ref s2));  // one
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(16, 34),
                // (16,9): error CS8350: This combination of arguments to 'C.M2(__arglist)' is disallowed because it may expose variables referenced by parameter '__arglist' outside of their declaration scope
                //         M2(__arglist(ref s1, ref s2));  // one
                Diagnostic(ErrorCode.ERR_CallArgMixing, "M2(__arglist(ref s1, ref s2))").WithArguments("C.M2(__arglist)", "__arglist").WithLocation(16, 9),
                // (17,26): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope
                //         M2(__arglist(ref s2, ref s1));  // two
                Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(17, 26),
                // (17,9): error CS8350: This combination of arguments to 'C.M2(__arglist)' is disallowed because it may expose variables referenced by parameter '__arglist' outside of their declaration scope
                //         M2(__arglist(ref s2, ref s1));  // two
                Diagnostic(ErrorCode.ERR_CallArgMixing, "M2(__arglist(ref s2, ref s1))").WithArguments("C.M2(__arglist)", "__arglist").WithLocation(17, 9));
        }
 
        [Fact]
        [WorkItem(44588, "https://github.com/dotnet/roslyn/issues/44588")]
        public void SwitchDefaultLocalInitialization_01()
        {
            var source = @"
using System;
 
struct Struct2
{
    public static ReadOnlySpan<T> GetSpan1<T>(int x)
    {
        return x switch
        {
            0 => default,
            _ => default,
        };
    }
 
    public static ReadOnlySpan<T> GetSpan2<T>(int x)
    {
        ReadOnlySpan<T> span;
 
        span = x switch
        {
            0 => default,
            _ => default,
        };
 
        return span;
    }
 
    public static ReadOnlySpan<T> GetSpan3<T>(int x)
    {
        ReadOnlySpan<T> span = x switch
        {
            0 => default,
            _ => default,
        };
 
        return span;
    }
 
    public static ReadOnlySpan<T> GetSpan4<T>(int x)
    {
        ReadOnlySpan<T> span = default;
 
        return span;
    }
}";
            CreateCompilationWithMscorlibAndSpan(source).VerifyDiagnostics(
                );
        }
 
        [Fact]
        [WorkItem(44588, "https://github.com/dotnet/roslyn/issues/44588")]
        public void SwitchDefaultLocalInitialization_02()
        {
            var source = @"
using System;
 
struct Struct2
{
    public static Span<byte> GetSpan1(int x)
    {
        return x switch
        {
            0 => stackalloc byte[10], // 1
            _ => default,
        };
    }
 
    public static Span<byte> GetSpan2(int x)
    {
        Span<byte> span;
 
        span = x switch
        {
            0 => stackalloc byte[10], // 2
            _ => default,
        };
 
        return span;
    }
 
    public static Span<byte> GetSpan3(int x)
    {
        Span<byte> span = x switch
        {
            0 => stackalloc byte[10],
            _ => default,
        };
 
        return span; // 3
    }
 
    public static Span<byte> GetSpan4(int x)
    {
        Span<byte> span = stackalloc byte[10];
 
        return span; // 4
    }
}";
            CreateCompilationWithMscorlibAndSpan(source).VerifyDiagnostics(
                // (10,18): error CS8353: A result of a stackalloc expression of type 'Span<byte>' cannot be used in this context because it may be exposed outside of the containing method
                //             0 => stackalloc byte[10], // 1
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc byte[10]").WithArguments("System.Span<byte>").WithLocation(10, 18),
                // (21,18): error CS8353: A result of a stackalloc expression of type 'Span<byte>' cannot be used in this context because it may be exposed outside of the containing method
                //             0 => stackalloc byte[10], // 2
                Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc byte[10]").WithArguments("System.Span<byte>").WithLocation(21, 18),
                // (36,16): error CS8352: Cannot use variable 'span' in this context because it may expose referenced variables outside of their declaration scope
                //         return span; // 3
                Diagnostic(ErrorCode.ERR_EscapeVariable, "span").WithArguments("span").WithLocation(36, 16),
                // (43,16): error CS8352: Cannot use variable 'span' in this context because it may expose referenced variables outside of their declaration scope
                //         return span; // 4
                Diagnostic(ErrorCode.ERR_EscapeVariable, "span").WithArguments("span").WithLocation(43, 16)
                );
        }
 
        [Fact]
        [WorkItem(39663, "https://github.com/dotnet/roslyn/issues/39663")]
        public void AssignToDiscard_01()
        {
            var text = @"
using System;
 
class Program
{
    static void Main()
    {
        _ = Test(stackalloc int[5]);
        System.Console.WriteLine(""Done"");
    }
 
    static Span<int> Test(Span<int> items) => items;
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text, options: TestOptions.DebugExe);
            CompileAndVerify(comp, verify: Verification.Fails, expectedOutput: "Done").VerifyDiagnostics();
        }
 
        [Fact]
        [WorkItem(39663, "https://github.com/dotnet/roslyn/issues/39663")]
        public void AssignToDiscard_02()
        {
            var text = @"
using System;
 
class Program
{
    static int[] _array = new int[] {};
 
    static void Main()
    {
        _ = Test;
        System.Console.WriteLine(""Done"");
    }
 
    static Span<int> Test => _array;
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text, options: TestOptions.DebugExe);
            // ILVerify: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
            CompileAndVerify(comp, expectedOutput: "Done", verify: Verification.FailsILVerify).VerifyDiagnostics();
        }
 
        [Fact]
        [WorkItem(39663, "https://github.com/dotnet/roslyn/issues/39663")]
        public void AssignToDiscard_03()
        {
            var text = @"
using System;
 
class Program
{
    static void Main()
    {
        var l = Test(stackalloc int[5]);
        _ = l;
        System.Console.WriteLine(""Done"");
    }
 
    static Span<int> Test(Span<int> items) => items;
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text, options: TestOptions.DebugExe);
            CompileAndVerify(comp, verify: Verification.Fails, expectedOutput: "Done").VerifyDiagnostics();
        }
 
        [Fact]
        [WorkItem(39663, "https://github.com/dotnet/roslyn/issues/39663")]
        public void AssignToDiscard_04()
        {
            var text = @"
using System;
 
class Program
{
    static void Main()
    {
        var l = Test(stackalloc int[5]);
 
        {
            int i = 0;
            _ = l;
            i++;
        }
 
        System.Console.WriteLine(""Done"");
    }
 
    static Span<int> Test(Span<int> items) => items;
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text, options: TestOptions.DebugExe);
            CompileAndVerify(comp, verify: Verification.Fails, expectedOutput: "Done").VerifyDiagnostics();
        }
 
        [Fact]
        [WorkItem(39663, "https://github.com/dotnet/roslyn/issues/39663")]
        public void AssignToDiscard_05()
        {
            var text = @"
using System;
 
class Program
{
    static void Main()
    {
        Test(stackalloc int[5]);
        System.Console.WriteLine(""Done"");
    }
 
    static Span<int> Test(Span<int> items) => items;
}
";
 
            CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text, options: TestOptions.DebugExe);
            CompileAndVerify(comp, verify: Verification.Fails, expectedOutput: "Done").VerifyDiagnostics();
        }
    }
}