File: FirstClassSpanTests.cs
Web Access
Project: src\src\Compilers\CSharp\Test\Emit3\Microsoft.CodeAnalysis.CSharp.Emit3.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Emit3.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Symbols.Retargeting;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Operations;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.CSharp.UnitTests;
 
public class FirstClassSpanTests : CSharpTestBase
{
    public static TheoryData<LanguageVersion> LangVersions()
    {
        return new TheoryData<LanguageVersion>()
        {
            LanguageVersion.CSharp13,
            LanguageVersionFacts.CSharpNext,
            LanguageVersion.Preview,
        };
    }
 
    private sealed class CombinatorialLangVersions()
        : CombinatorialValuesAttribute(LangVersions().Select(d => d.Single()).ToArray());
 
    [Fact, WorkItem("https://github.com/dotnet/runtime/issues/101261")]
    public void Example_StringValuesAmbiguity()
    {
        var source = """
            using System;
 
            Console.Write(C.M(new StringValues()));
 
            static class C
            {
                public static string M(StringValues sv) => StringExtensions.Join(",", sv);
            }
 
            static class StringExtensions
            {
                public static string Join(string separator, params string[] values) => "array";
                public static string Join(string separator, params ReadOnlySpan<string> values) => "span";
            }
 
            readonly struct StringValues
            {
                public static implicit operator string(StringValues values) => null;
                public static implicit operator string[](StringValues value) => null;
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (7,65): error CS0121: The call is ambiguous between the following methods or properties: 'StringExtensions.Join(string, params string[])' and 'StringExtensions.Join(string, params ReadOnlySpan<string>)'
            //     public static string M(StringValues sv) => StringExtensions.Join(",", sv);
            Diagnostic(ErrorCode.ERR_AmbigCall, "Join").WithArguments("StringExtensions.Join(string, params string[])", "StringExtensions.Join(string, params System.ReadOnlySpan<string>)").WithLocation(7, 65));
 
        var expectedOutput = "array";
 
        var expectedIl = """
            {
              // Code size       17 (0x11)
              .maxstack  2
              IL_0000:  ldstr      ","
              IL_0005:  ldarg.0
              IL_0006:  call       "string[] StringValues.op_Implicit(StringValues)"
              IL_000b:  call       "string StringExtensions.Join(string, params string[])"
              IL_0010:  ret
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
    }
 
    [Fact]
    public void BreakingChange_Inheritance_UserDefinedConversion_ArrayToSpan()
    {
        var source = """
            using System;
 
            var a = new string[0];
            var d = new Derived();
            d.M(a);
 
            class Base
            {
                public void M(Span<string> s) => Console.Write("Base");
            }
 
            class Derived : Base
            {
                public static implicit operator Derived(Span<string> r) => new Derived();
 
                public void M(Derived s) => Console.WriteLine("Derived");
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: "Base").VerifyDiagnostics();
 
        var expectedOutput = "Derived";
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Fact]
    public void BreakingChange_ExtensionMethodLookup_ArrayToSpan()
    {
        var source = """
            using System;
 
            namespace N1
            {
                using N2;
 
                public class C
                {
                    public static void Main()
                    {
                        var a = new string[0];
                        a.Test();
                    }
                }
 
                public static class N1Ext
                {
                    public static void Test(this Span<string> x) => Console.WriteLine("N1");
                }
            }
 
            namespace N2
            {
                public static class N2Ext
                {
                    public static void Test(this string[] x) => Console.WriteLine("N2");
                }
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13, options: TestOptions.ReleaseExe);
        CompileAndVerify(comp, expectedOutput: "N2").VerifyDiagnostics();
 
        var expectedOutput = "N1";
 
        var expectedDiagnostics = new[]
        {
            // (5,5): hidden CS8019: Unnecessary using directive.
            //     using N2;
            Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using N2;").WithLocation(5, 5)
        };
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext, options: TestOptions.ReleaseExe);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(expectedDiagnostics);
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, TestOptions.ReleaseExe);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void BreakingChange_ExtensionMethodLookup_SpanVsIEnumerable()
    {
        var source = """
            using System;
            using System.Collections.Generic;
 
            var arr = new char[] { '/' };
            arr.M('/');
 
            static class E
            {
                public static void M<T>(this Span<T> s, T x) => Console.Write(1);
                public static void M<T>(this IEnumerable<T> e, T x) => Console.Write(2);
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: "2").VerifyDiagnostics();
 
        var expectedOutput = "1";
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void BreakingChange_ExtensionMethodLookup_SpanVsIEnumerable_Workaround(LanguageVersion langVersion)
    {
        var source = """
            using System;
            using System.Collections.Generic;
 
            var arr = new char[] { '/' };
            arr.M('/');
 
            static class E
            {
                public static void M<T>(this Span<T> s, T x) => Console.Write(1);
                public static void M<T>(this IEnumerable<T> e, T x) => Console.Write(2);
                public static void M<T>(this T[] a, T x) => Console.Write(3);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        var verifier = CompileAndVerify(comp, expectedOutput: "3").VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       19 (0x13)
              .maxstack  4
              IL_0000:  ldc.i4.1
              IL_0001:  newarr     "char"
              IL_0006:  dup
              IL_0007:  ldc.i4.0
              IL_0008:  ldc.i4.s   47
              IL_000a:  stelem.i2
              IL_000b:  ldc.i4.s   47
              IL_000d:  call       "void E.M<char>(char[], char)"
              IL_0012:  ret
            }
            """);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void BreakingChange_ExtensionMethodLookup_SpanVsIEnumerable_MethodConversion(LanguageVersion langVersion)
    {
        var source = """
            using System;
            using System.Collections.Generic;
 
            var arr = new int[] { 123 };
            E.R(arr.M);
 
            static class E
            {
                public static void R(Action<int> a) => a(-1);
                public static void M<T>(this Span<T> s, T x) => Console.Write(1);
                public static void M<T>(this IEnumerable<T> e, T x) => Console.Write(2);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "2").VerifyDiagnostics();
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void BreakingChange_ExtensionMethodLookup_SpanVsIEnumerable_MethodConversion_Workaround(LanguageVersion langVersion)
    {
        var source = """
            using System;
            using System.Collections.Generic;
            
            var arr = new int[] { 123 };
            E.R(arr.M);
            
            static class E
            {
                public static void R(Action<int> a) => a(-1);
                public static void M<T>(this Span<T> s, T x) => Console.Write(1);
                public static void M<T>(this IEnumerable<T> e, T x) => Console.Write(2);
                public static void M<T>(this T[] a, T x) => Console.Write(3);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "3").VerifyDiagnostics();
    }
 
    [Theory, CombinatorialData]
    public void BreakingChange_TypeInference_SpanVsIEnumerable_01(
        [CombinatorialValues("Span", "ReadOnlySpan")] string type)
    {
        var source = $$"""
            using System;
            using System.Collections.Generic;
 
            class C
            {
                void M(int[] a)
                {
                    foreach (var x in a.R()) { }
                }
            }
 
            static class E
            {
                public static void R<T>(this {{type}}<T> s) => throw null;
                public static IEnumerable<T> R<T>(this IEnumerable<T> e) => throw null;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics();
 
        var expectedDiagnostics = new[]
        {
            // (8,27): error CS1579: foreach statement cannot operate on variables of type 'void' because 'void' does not contain a public instance or extension definition for 'GetEnumerator'
            //         foreach (var x in a.R()) { }
            Diagnostic(ErrorCode.ERR_ForEachMissingMember, "a.R()").WithArguments("void", "GetEnumerator").WithLocation(8, 27)
        };
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Theory, CombinatorialData]
    public void BreakingChange_TypeInference_SpanVsIEnumerable_01_Workaround(
        [CombinatorialLangVersions] LanguageVersion langVersion,
        [CombinatorialValues("Span", "ReadOnlySpan")] string type)
    {
        var source = $$"""
            using System;
            using System.Collections.Generic;
 
            int[] a = new int[0];
            {{type}}<int> s = default;
            a.R();
            s.R();
 
            static class E
            {
                public static void R<T>(this {{type}}<T> s) => Console.Write(1);
                public static IEnumerable<T> R<T>(this IEnumerable<T> e) { Console.Write(2); return e; }
                public static IEnumerable<T> R<T>(this T[] a) { Console.Write(3); return a; }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "31").VerifyDiagnostics();
    }
 
    [Fact]
    public void BreakingChange_TypeInference_SpanVsIEnumerable_02()
    {
        var source = """
            using System;
            using System.Collections.Generic;
 
            string[] s = new[] { "a" };
            object[] o = s;
 
            try { C.R(o); } catch (Exception e) { Console.Write(e.GetType().Name); }
 
            static class C
            {
                public static void R<T>(IEnumerable<T> e) => Console.Write(1);
                public static void R<T>(Span<T> s) => Console.Write(2);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: "1").VerifyDiagnostics();
 
        var expectedOutput = ExecutionConditionUtil.IsCoreClr ? "ArrayTypeMismatchException" : "2";
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void BreakingChange_TypeInference_SpanVsIEnumerable_02_Workaround_AsEnumerable(LanguageVersion langVersion)
    {
        var source = """
            using System;
            using System.Collections.Generic;
            using System.Linq;
 
            string[] s = new[] { "a" };
            object[] o = s;
 
            C.R(o.AsEnumerable());
 
            static class C
            {
                public static void R<T>(IEnumerable<T> e) => Console.Write(1);
                public static void R<T>(Span<T> s) => Console.Write(2);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "1").VerifyDiagnostics();
    }
 
    [Fact]
    public void BreakingChange_TypeInference_SpanVsIEnumerable_02_Workaround_OverloadResolutionPriority()
    {
        var source = """
            using System;
            using System.Collections.Generic;
            using System.Runtime.CompilerServices;
 
            string[] s = new[] { "a" };
            object[] o = s;
 
            C.R(o);
 
            static class C
            {
                public static void R<T>(IEnumerable<T> e) => Console.Write(1);
                public static void R<T>(Span<T> s) => Console.Write(2);
                [OverloadResolutionPriority(1)]
                public static void R<T>(ReadOnlySpan<T> s) => Console.Write(3);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions([source, OverloadResolutionPriorityAttributeDefinition],
            parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: "1").VerifyDiagnostics();
 
        var expectedOutput = "3";
 
        comp = CreateCompilationWithSpanAndMemoryExtensions([source, OverloadResolutionPriorityAttributeDefinition],
            parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions([source, OverloadResolutionPriorityAttributeDefinition]);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Fact]
    public void BreakingChange_TypeInference_SpanVsIEnumerable_02_ReadOnlySpan()
    {
        var source = """
            using System;
            using System.Collections.Generic;
 
            string[] s = new[] { "a" };
            object[] o = s;
 
            C.R(o);
 
            static class C
            {
                public static void R<T>(IEnumerable<T> e) => Console.Write(1);
                public static void R<T>(ReadOnlySpan<T> s) => Console.Write(2);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: "1").VerifyDiagnostics();
 
        var expectedOutput = "2";
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Fact]
    public void BreakingChange_Conversion_SpanVsIEnumerable()
    {
        var source = """
            using System;
            using System.Collections.Generic;
 
            string[] s = new[] { "a" };
            object[] o = s;
 
            try { o.R<object>(); } catch (Exception e) { Console.Write(e.GetType().Name); }
 
            static class E
            {
                public static void R<T>(this IEnumerable<T> e) => Console.Write(1);
                public static void R<T>(this Span<T> s) => Console.Write(2);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: "1").VerifyDiagnostics();
 
        var expectedOutput = ExecutionConditionUtil.IsCoreClr ? "ArrayTypeMismatchException" : "2";
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Fact]
    public void BreakingChange_Conversion_SpanVsIEnumerable_ReadOnlySpan()
    {
        var source = """
            using System;
            using System.Collections.Generic;
 
            string[] s = new[] { "a" };
            object[] o = s;
 
            o.R<object>();
 
            static class E
            {
                public static void R<T>(this IEnumerable<T> e) => Console.Write(1);
                public static void R<T>(this ReadOnlySpan<T> s) => Console.Write(2);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: "1").VerifyDiagnostics();
 
        var expectedOutput = "2";
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Fact]
    public void BreakingChange_Conversion_SpanVsArray()
    {
        var source = """
            using System;
 
            var x = new long[] { 1 };
 
            C.M([2], x);
 
            static class C
            {
                public static void M<T>(T[] a, T[] b) => Console.Write("1 " + typeof(T).Name);
                public static void M<T>(ReadOnlySpan<T> a, Span<T> b) => Console.Write("2 " + typeof(T).Name);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: "1 Int64").VerifyDiagnostics();
 
        var expectedDiagnostics = new[]
        {
            // (5,3): error CS0121: The call is ambiguous between the following methods or properties: 'C.M<T>(T[], T[])' and 'C.M<T>(ReadOnlySpan<T>, Span<T>)'
            // C.M([2], x);
            Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("C.M<T>(T[], T[])", "C.M<T>(System.ReadOnlySpan<T>, System.Span<T>)").WithLocation(5, 3)
        };
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void BreakingChange_Conversion_SpanVsArray_Workaround_AsSpan(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            var x = new long[] { 1 };
 
            C.M([2], x.AsSpan());
 
            static class C
            {
                public static void M<T>(T[] a, T[] b) => Console.Write("1 " + typeof(T).Name);
                public static void M<T>(ReadOnlySpan<T> a, Span<T> b) => Console.Write("2 " + typeof(T).Name);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "2 Int64").VerifyDiagnostics();
    }
 
    [Fact]
    public void BreakingChange_Conversion_SpanVsArray_Workaround_OverloadResolutionPriority()
    {
        var source = """
            using System;
            using System.Runtime.CompilerServices;
 
            var x = new long[] { 1 };
 
            C.M([2], x);
 
            static class C
            {
                public static void M<T>(T[] a, T[] b) => Console.Write("1 " + typeof(T).Name);
                [OverloadResolutionPriority(1)]
                public static void M<T>(ReadOnlySpan<T> a, Span<T> b) => Console.Write("2 " + typeof(T).Name);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions([source, OverloadResolutionPriorityAttributeDefinition],
            parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: "1 Int64").VerifyDiagnostics();
 
        var expectedOutput = "2 Int64";
 
        comp = CreateCompilationWithSpanAndMemoryExtensions([source, OverloadResolutionPriorityAttributeDefinition],
            parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions([source, OverloadResolutionPriorityAttributeDefinition]);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [ConditionalFact(typeof(CoreClrOnly))]
    public void BreakingChange_Conversion_ArrayVsArraySegment()
    {
        var source = """
            using System;
 
            var x = new int[] { 1, 2 };
            var s = new ArraySegment<int>(x, 1, 1);
 
            C.M(x, s);
 
            static class C
            {
                public static void M<T>(T a, T b) => Console.Write("1 " + typeof(T));
                public static void M<T>(Span<T> a, Span<T> b) => Console.Write("2 " + typeof(T).Name);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: "1 System.ArraySegment`1[System.Int32]").VerifyDiagnostics();
 
        var expectedDiagnostics = new[]
        {
            // (6,3): error CS0121: The call is ambiguous between the following methods or properties: 'C.M<T>(T, T)' and 'C.M<T>(Span<T>, Span<T>)'
            // C.M(x, s);
            Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("C.M<T>(T, T)", "C.M<T>(System.Span<T>, System.Span<T>)").WithLocation(6, 3)
        };
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_Span_Implicit(
        [CombinatorialLangVersions] LanguageVersion langVersion,
        [CombinatorialValues("Span", "ReadOnlySpan")] string destination,
        bool cast)
    {
        var source = $$"""
            using System;
            {{destination}}<int> s = {{(cast ? $"({destination}<int>)" : "")}}arr();
            report(s);
            static int[] arr() => new int[] { 1, 2, 3 };
            static void report({{destination}}<int> s) { foreach (var x in s) { Console.Write(x); } }
            """;
 
        var expectedOutput = "123";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput);
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", $$"""
            {
              // Code size       16 (0x10)
              .maxstack  1
              IL_0000:  call       "int[] Program.<<Main>$>g__arr|0_0()"
              IL_0005:  call       "System.{{destination}}<int> System.{{destination}}<int>.op_Implicit(int[])"
              IL_000a:  call       "void Program.<<Main>$>g__report|0_1(System.{{destination}}<int>)"
              IL_000f:  ret
            }
            """);
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_Span_Explicit(
        [CombinatorialLangVersions] LanguageVersion langVersion,
        [CombinatorialValues("Span", "ReadOnlySpan")] string destination)
    {
        var source = $$"""
            using System;
            {{destination}}<string> s = ({{destination}}<string>)arr();
            report(s);
            static object[] arr() => new string[] { "a", "b" };
            static void report({{destination}}<string> s) { foreach (var x in s) { Console.Write(x); } }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        var verifier = CompileAndVerify(comp, expectedOutput: "ab");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", $$"""
            {
              // Code size       21 (0x15)
              .maxstack  1
              IL_0000:  call       "object[] Program.<<Main>$>g__arr|0_0()"
              IL_0005:  castclass  "string[]"
              IL_000a:  call       "System.{{destination}}<string> System.{{destination}}<string>.op_Implicit(string[])"
              IL_000f:  call       "void Program.<<Main>$>g__report|0_1(System.{{destination}}<string>)"
              IL_0014:  ret
            }
            """);
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_Span_Explicit_Invalid(
        [CombinatorialLangVersions] LanguageVersion langVersion,
        [CombinatorialValues("Span", "ReadOnlySpan")] string destination)
    {
        var source = $$"""
            using System;
            try
            {
                run();
            }
            catch (InvalidCastException)
            {
                Console.WriteLine("InvalidCastException");
            }
            static {{destination}}<string> run() => ({{destination}}<string>)arr();
            static object[] arr() => new object[] { "a", "b" };
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        var verifier = CompileAndVerify(comp, expectedOutput: "InvalidCastException", verify: Verification.FailsILVerify);
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("Program.<<Main>$>g__run|0_0", $$"""
            {
              // Code size       16 (0x10)
              .maxstack  1
              IL_0000:  call       "object[] Program.<<Main>$>g__arr|0_1()"
              IL_0005:  castclass  "string[]"
              IL_000a:  call       "System.{{destination}}<string> System.{{destination}}<string>.op_Implicit(string[])"
              IL_000f:  ret
            }
            """);
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Span_ReadOnlySpan_Implicit(
        [CombinatorialLangVersions] LanguageVersion langVersion,
        bool cast)
    {
        var source = $$"""
            using System;
            ReadOnlySpan<int> s = {{(cast ? "(ReadOnlySpan<int>)" : "")}}source();
            report(s);
            static Span<int> source() => new Span<int>(new int[] { 1, 2, 3 });
            static void report(ReadOnlySpan<int> s) { foreach (var x in s) { Console.Write(x); } }
            """;
 
        var expectedOutput = "123";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify);
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       16 (0x10)
              .maxstack  1
              IL_0000:  call       "System.Span<int> Program.<<Main>$>g__source|0_0()"
              IL_0005:  call       "System.ReadOnlySpan<int> System.Span<int>.op_Implicit(System.Span<int>)"
              IL_000a:  call       "void Program.<<Main>$>g__report|0_1(System.ReadOnlySpan<int>)"
              IL_000f:  ret
            }
            """);
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Span_ReadOnlySpan_CastUp_Implicit(bool cast)
    {
        var source = $$"""
            using System;
            ReadOnlySpan<object> s = {{(cast ? "(ReadOnlySpan<object>)" : "")}}source();
            report(s);
            static Span<string> source() => new Span<string>(new[] { "a", "b" });
            static void report(ReadOnlySpan<object> s) { foreach (var x in s) { Console.Write(x); } }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        if (!cast)
        {
            comp.VerifyDiagnostics(
                // (2,26): error CS0029: Cannot implicitly convert type 'System.Span<string>' to 'System.ReadOnlySpan<object>'
                // ReadOnlySpan<object> s = source();
                Diagnostic(ErrorCode.ERR_NoImplicitConv, "source()").WithArguments("System.Span<string>", "System.ReadOnlySpan<object>").WithLocation(2, 26));
        }
        else
        {
            comp.VerifyDiagnostics(
                // (2,26): error CS0030: Cannot convert type 'System.Span<string>' to 'System.ReadOnlySpan<object>'
                // ReadOnlySpan<object> s = (ReadOnlySpan<object>)source();
                Diagnostic(ErrorCode.ERR_NoExplicitConv, "(ReadOnlySpan<object>)source()").WithArguments("System.Span<string>", "System.ReadOnlySpan<object>").WithLocation(2, 26));
        }
 
        var expectedOutput = "ab";
 
        var expectedIL = """
            {
              // Code size       21 (0x15)
              .maxstack  1
              IL_0000:  call       "System.Span<string> Program.<<Main>$>g__source|0_0()"
              IL_0005:  call       "System.ReadOnlySpan<string> System.Span<string>.op_Implicit(System.Span<string>)"
              IL_000a:  call       "System.ReadOnlySpan<object> System.ReadOnlySpan<object>.CastUp<string>(System.ReadOnlySpan<string>)"
              IL_000f:  call       "void Program.<<Main>$>g__report|0_1(System.ReadOnlySpan<object>)"
              IL_0014:  ret
            }
            """;
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net90);
        var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify);
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", expectedIL);
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90);
        verifier = CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify);
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", expectedIL);
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Span_ReadOnlySpan_Implicit_IdentityInnerConversion(
        [CombinatorialLangVersions] LanguageVersion langVersion,
        bool cast)
    {
        var source = $$"""
            using System;
            ReadOnlySpan<object> s = {{(cast ? "(ReadOnlySpan<object>)" : "")}}source();
            report(s);
            static Span<dynamic> source() => new Span<dynamic>(new object[] { "a", "b" });
            static void report(ReadOnlySpan<object> s) { foreach (var x in s) { Console.Write(x); } }
            """;
 
        var expectedOutput = "ab";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify);
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       16 (0x10)
              .maxstack  1
              IL_0000:  call       "System.Span<dynamic> Program.<<Main>$>g__source|0_0()"
              IL_0005:  call       "System.ReadOnlySpan<dynamic> System.Span<dynamic>.op_Implicit(System.Span<dynamic>)"
              IL_000a:  call       "void Program.<<Main>$>g__report|0_1(System.ReadOnlySpan<object>)"
              IL_000f:  ret
            }
            """);
    }
 
    [Theory, CombinatorialData]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit(bool cast)
    {
        var source = $$"""
            using System;
            ReadOnlySpan<object> s = {{(cast ? "(ReadOnlySpan<object>)" : "")}}source();
            report(s);
            static ReadOnlySpan<string> source() => new ReadOnlySpan<string>(new[] { "a", "b" });
            static void report(ReadOnlySpan<object> s) { foreach (var x in s) { Console.Write(x); } }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        if (!cast)
        {
            comp.VerifyDiagnostics(
                // (2,26): error CS0029: Cannot implicitly convert type 'System.ReadOnlySpan<string>' to 'System.ReadOnlySpan<object>'
                // ReadOnlySpan<object> s = source();
                Diagnostic(ErrorCode.ERR_NoImplicitConv, "source()").WithArguments("System.ReadOnlySpan<string>", "System.ReadOnlySpan<object>").WithLocation(2, 26));
        }
        else
        {
            comp.VerifyDiagnostics(
                // (2,26): error CS0030: Cannot convert type 'System.ReadOnlySpan<string>' to 'System.ReadOnlySpan<object>'
                // ReadOnlySpan<object> s = (ReadOnlySpan<object>)source();
                Diagnostic(ErrorCode.ERR_NoExplicitConv, "(ReadOnlySpan<object>)source()").WithArguments("System.ReadOnlySpan<string>", "System.ReadOnlySpan<object>").WithLocation(2, 26));
        }
 
        var expectedOutput = "ab";
 
        var expectedIL = """
            {
              // Code size       16 (0x10)
              .maxstack  1
              IL_0000:  call       "System.ReadOnlySpan<string> Program.<<Main>$>g__source|0_0()"
              IL_0005:  call       "System.ReadOnlySpan<object> System.ReadOnlySpan<object>.CastUp<string>(System.ReadOnlySpan<string>)"
              IL_000a:  call       "void Program.<<Main>$>g__report|0_1(System.ReadOnlySpan<object>)"
              IL_000f:  ret
            }
            """;
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net90);
        var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify);
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", expectedIL);
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90);
        verifier = CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify);
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", expectedIL);
    }
 
    [Theory, CombinatorialData]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_IdentityInnerConversion(
        [CombinatorialLangVersions] LanguageVersion langVersion,
        bool cast)
    {
        var source = $$"""
            using System;
            ReadOnlySpan<object> s = {{(cast ? "(ReadOnlySpan<object>)" : "")}}source();
            report(s);
            static ReadOnlySpan<dynamic> source() => new ReadOnlySpan<dynamic>(new string[] { "a", "b" });
            static void report(ReadOnlySpan<object> s) { foreach (var x in s) { Console.Write(x); } }
            """;
 
        var expectedOutput = "ab";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify);
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       11 (0xb)
              .maxstack  1
              IL_0000:  call       "System.ReadOnlySpan<dynamic> Program.<<Main>$>g__source|0_0()"
              IL_0005:  call       "void Program.<<Main>$>g__report|0_1(System.ReadOnlySpan<object>)"
              IL_000a:  ret
            }
            """);
    }
 
    [Theory, CombinatorialData]
    public void Conversion_string_ReadOnlySpan_Implicit(bool cast)
    {
        var source = $$"""
            using System;
            ReadOnlySpan<char> s = {{(cast ? "(ReadOnlySpan<char>)" : "")}}source();
            report(s);
            static string source() => "abc";
            static void report(ReadOnlySpan<char> s) { foreach (var x in s) { Console.Write(x + " "); } }
            """;
 
        var expectedOutput = "a b c";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput);
        verifier.VerifyDiagnostics();
        var owner = ExecutionConditionUtil.IsCoreClr ? "string" : "System.ReadOnlySpan<char>";
        verifier.VerifyIL("<top-level-statements-entry-point>", $$"""
            {
              // Code size       16 (0x10)
              .maxstack  1
              IL_0000:  call       "string Program.<<Main>$>g__source|0_0()"
              IL_0005:  call       "System.ReadOnlySpan<char> {{owner}}.op_Implicit(string)"
              IL_000a:  call       "void Program.<<Main>$>g__report|0_1(System.ReadOnlySpan<char>)"
              IL_000f:  ret
            }
            """);
 
        var expectedIL = """
            {
              // Code size       16 (0x10)
              .maxstack  1
              IL_0000:  call       "string Program.<<Main>$>g__source|0_0()"
              IL_0005:  call       "System.ReadOnlySpan<char> System.MemoryExtensions.AsSpan(string)"
              IL_000a:  call       "void Program.<<Main>$>g__report|0_1(System.ReadOnlySpan<char>)"
              IL_000f:  ret
            }         
            """;
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        verifier = CompileAndVerify(comp, expectedOutput: expectedOutput);
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", expectedIL);
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        verifier = CompileAndVerify(comp, expectedOutput: expectedOutput);
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", expectedIL);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Implicit_IsOperator(LanguageVersion langVersion)
    {
        var source = """
            using System;
            Console.Write(arr() is Span<int>);
            static int[] arr() => new[] { 1, 2, 3 };
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        var verifier = CompileAndVerify(comp, expectedOutput: "False");
        verifier.VerifyDiagnostics(
            // (2,15): warning CS0184: The given expression is never of the provided ('Span<int>') type
            // Console.Write(arr() is Span<int>);
            Diagnostic(ErrorCode.WRN_IsAlwaysFalse, "arr() is Span<int>").WithArguments("System.Span<int>").WithLocation(2, 15));
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       13 (0xd)
              .maxstack  1
              IL_0000:  call       "int[] Program.<<Main>$>g__arr|0_0()"
              IL_0005:  pop
              IL_0006:  ldc.i4.0
              IL_0007:  call       "void System.Console.Write(bool)"
              IL_000c:  ret
            }
            """);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Implicit_IsPattern(LanguageVersion langVersion)
    {
        var source = """
            using System;
            if (arr() is Span<int> s)
            {
                Console.Write(s.Length);
            }
            static int[] arr() => throw null;
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (2,14): error CS8121: An expression of type 'int[]' cannot be handled by a pattern of type 'Span<int>'.
            // if (arr() is Span<int> s)
            Diagnostic(ErrorCode.ERR_PatternWrongType, "Span<int>").WithArguments("int[]", "System.Span<int>").WithLocation(2, 14));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Implicit_SwitchPattern(LanguageVersion langVersion)
    {
        var source = """
            using System;
            switch (arr())
            {
                case Span<int> s:
                    Console.Write(s.Length);
                    break;
            }
            static int[] arr() => throw null;
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,10): error CS8121: An expression of type 'int[]' cannot be handled by a pattern of type 'Span<int>'.
            //     case Span<int> s:
            Diagnostic(ErrorCode.ERR_PatternWrongType, "Span<int>").WithArguments("int[]", "System.Span<int>").WithLocation(4, 10));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Explicit_IsOperator(LanguageVersion langVersion)
    {
        var source = """
            using System;
            Console.Write(arr() is Span<string>);
            static object[] arr() => new[] { "a", "b" };
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        var verifier = CompileAndVerify(comp, expectedOutput: "False");
        verifier.VerifyDiagnostics(
            // (2,15): warning CS0184: The given expression is never of the provided ('Span<string>') type
            // Console.Write(arr() is Span<string>);
            Diagnostic(ErrorCode.WRN_IsAlwaysFalse, "arr() is Span<string>").WithArguments("System.Span<string>").WithLocation(2, 15));
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       13 (0xd)
              .maxstack  1
              IL_0000:  call       "object[] Program.<<Main>$>g__arr|0_0()"
              IL_0005:  pop
              IL_0006:  ldc.i4.0
              IL_0007:  call       "void System.Console.Write(bool)"
              IL_000c:  ret
            }
            """);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Explicit_IsPattern(LanguageVersion langVersion)
    {
        var source = """
            using System;
            if (arr() is Span<string> s)
            {
                Console.Write(s.Length);
            }
            static object[] arr() => throw null;
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (2,14): error CS8121: An expression of type 'object[]' cannot be handled by a pattern of type 'Span<string>'.
            // if (arr() is Span<string> s)
            Diagnostic(ErrorCode.ERR_PatternWrongType, "Span<string>").WithArguments("object[]", "System.Span<string>").WithLocation(2, 14));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Explicit_SwitchPattern(LanguageVersion langVersion)
    {
        var source = """
            using System;
            switch (arr())
            {
                case Span<string> s:
                    Console.Write(s.Length);
                    break;
            }
            static object[] arr() => throw null;
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,10): error CS8121: An expression of type 'object[]' cannot be handled by a pattern of type 'Span<string>'.
            //     case Span<string> s:
            Diagnostic(ErrorCode.ERR_PatternWrongType, "Span<string>").WithArguments("object[]", "System.Span<string>").WithLocation(4, 10));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_string_ReadOnlySpan_Implicit_IsOperator(LanguageVersion langVersion)
    {
        var source = """
            using System;
            Console.Write(str() is ReadOnlySpan<char>);
            static string str() => "abc";
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        var verifier = CompileAndVerify(comp, expectedOutput: "False");
        verifier.VerifyDiagnostics(
            // (2,15): warning CS0184: The given expression is never of the provided ('ReadOnlySpan<int>') type
            // Console.Write(str() is ReadOnlySpan<char>);
            Diagnostic(ErrorCode.WRN_IsAlwaysFalse, "str() is ReadOnlySpan<char>").WithArguments("System.ReadOnlySpan<char>").WithLocation(2, 15));
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       13 (0xd)
              .maxstack  1
              IL_0000:  call       "string Program.<<Main>$>g__str|0_0()"
              IL_0005:  pop
              IL_0006:  ldc.i4.0
              IL_0007:  call       "void System.Console.Write(bool)"
              IL_000c:  ret
            }
            """);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_string_ReadOnlySpan_Implicit_IsPattern(LanguageVersion langVersion)
    {
        var source = """
            using System;
            if (str() is ReadOnlySpan<char> s)
            {
                Console.Write(s.Length);
            }
            static string str() => throw null;
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (2,14): error CS8121: An expression of type 'string' cannot be handled by a pattern of type 'ReadOnlySpan<char>'.
            // if (str() is ReadOnlySpan<char> s)
            Diagnostic(ErrorCode.ERR_PatternWrongType, "ReadOnlySpan<char>").WithArguments("string", "System.ReadOnlySpan<char>").WithLocation(2, 14));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_string_ReadOnlySpan_Implicit_SwitchPattern(LanguageVersion langVersion)
    {
        var source = """
            using System;
            switch (str())
            {
                case ReadOnlySpan<char> s:
                    Console.Write(s.Length);
                    break;
            }
            static string str() => throw null;
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,10): error CS8121: An expression of type 'string' cannot be handled by a pattern of type 'ReadOnlySpan<char>'.
            //     case ReadOnlySpan<char> s:
            Diagnostic(ErrorCode.ERR_PatternWrongType, "ReadOnlySpan<char>").WithArguments("string", "System.ReadOnlySpan<char>").WithLocation(4, 10));
    }
 
    [Fact]
    public void Conversion_Array_Span_Implicit_MissingHelper()
    {
        var source = """
            using System;
            Span<int> s = arr();
            static int[] arr() => throw null;
 
            namespace System
            {
                public readonly ref struct Span<T>
                {
                }
            }
            """;
 
        CreateCompilation(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (2,15): error CS0029: Cannot implicitly convert type 'int[]' to 'System.Span<int>'
            // Span<int> s = arr();
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arr()").WithArguments("int[]", "System.Span<int>").WithLocation(2, 15));
 
        var expectedDiagnostics = new[]
        {
            // (2,15): error CS0656: Missing compiler required member 'System.Span<T>.op_Implicit'
            // Span<int> s = arr();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "arr()").WithArguments("System.Span<T>", "op_Implicit").WithLocation(2, 15)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Conversion_Span_ReadOnlySpan_Implicit_MissingHelper()
    {
        var source = """
            using System;
            ReadOnlySpan<int> s = source();
            static Span<int> source() => throw null;
 
            namespace System
            {
                public readonly ref struct Span<T> { }
                public readonly ref struct ReadOnlySpan<T> { }
            }
            """;
 
        CreateCompilation(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (2,23): error CS0029: Cannot implicitly convert type 'System.Span<int>' to 'System.ReadOnlySpan<int>'
            // ReadOnlySpan<int> s = source();
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "source()").WithArguments("System.Span<int>", "System.ReadOnlySpan<int>").WithLocation(2, 23));
 
        var expectedDiagnostics = new[]
        {
            // (2,23): error CS0656: Missing compiler required member 'Span<T>.op_Implicit'
            // ReadOnlySpan<int> s = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.Span<T>", "op_Implicit").WithLocation(2, 23)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Conversion_Span_ReadOnlySpan_CastUp_Implicit_MissingHelper_01()
    {
        var source = """
            using System;
            ReadOnlySpan<object> s = source();
            static Span<string> source() => throw null;
 
            namespace System
            {
                public readonly ref struct Span<T> { }
                public readonly ref struct ReadOnlySpan<T> { }
            }
            """;
 
        CreateCompilation(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (2,26): error CS0029: Cannot implicitly convert type 'System.Span<string>' to 'System.ReadOnlySpan<object>'
            // ReadOnlySpan<object> s = source();
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "source()").WithArguments("System.Span<string>", "System.ReadOnlySpan<object>").WithLocation(2, 26));
 
        var expectedDiagnostics = new[]
        {
            // (2,26): error CS0656: Missing compiler required member 'Span<T>.op_Implicit'
            // ReadOnlySpan<object> s = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.Span<T>", "op_Implicit").WithLocation(2, 26),
            // (2,26): error CS0656: Missing compiler required member 'ReadOnlySpan<T>.CastUp'
            // ReadOnlySpan<object> s = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.ReadOnlySpan<T>", "CastUp").WithLocation(2, 26)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Conversion_Span_ReadOnlySpan_CastUp_Implicit_MissingHelper_02()
    {
        var source = """
            using System;
            ReadOnlySpan<object> s = source();
            static Span<string> source() => throw null;
 
            namespace System
            {
                public readonly ref struct Span<T>
                {
                    public static implicit operator ReadOnlySpan<T>(Span<T> s) => throw null;
                }
                public readonly ref struct ReadOnlySpan<T> { }
            }
            """;
 
        CreateCompilation(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (2,26): error CS0029: Cannot implicitly convert type 'System.Span<string>' to 'System.ReadOnlySpan<object>'
            // ReadOnlySpan<object> s = source();
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "source()").WithArguments("System.Span<string>", "System.ReadOnlySpan<object>").WithLocation(2, 26));
 
        var expectedDiagnostics = new[]
        {
            // (2,26): error CS0656: Missing compiler required member 'ReadOnlySpan<T>.CastUp'
            // ReadOnlySpan<object> s = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.ReadOnlySpan<T>", "CastUp").WithLocation(2, 26)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Conversion_Span_ReadOnlySpan_CastUp_Implicit_MissingHelper_03()
    {
        var source = """
            using System;
            ReadOnlySpan<object> s = source();
            static Span<string> source() => throw null;
 
            namespace System
            {
                public readonly ref struct Span<T> { }
                public readonly ref struct ReadOnlySpan<T>
                {
                    public static ReadOnlySpan<T> CastUp<TDerived>(ReadOnlySpan<TDerived> s) where TDerived : class, T => throw null;
                }
            }
            """;
 
        CreateCompilation(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (2,26): error CS0029: Cannot implicitly convert type 'System.Span<string>' to 'System.ReadOnlySpan<object>'
            // ReadOnlySpan<object> s = source();
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "source()").WithArguments("System.Span<string>", "System.ReadOnlySpan<object>").WithLocation(2, 26));
 
        var expectedDiagnostics = new[]
        {
            // (2,26): error CS0656: Missing compiler required member 'Span<T>.op_Implicit'
            // ReadOnlySpan<object> s = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.Span<T>", "op_Implicit").WithLocation(2, 26)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_MissingHelper()
    {
        var source = """
            using System;
            ReadOnlySpan<object> s = source();
            static ReadOnlySpan<string> source() => throw null;
 
            namespace System
            {
                public readonly ref struct ReadOnlySpan<T> { }
            }
            """;
 
        CreateCompilation(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (2,26): error CS0029: Cannot implicitly convert type 'System.ReadOnlySpan<string>' to 'System.ReadOnlySpan<object>'
            // ReadOnlySpan<object> s = source();
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "source()").WithArguments("System.ReadOnlySpan<string>", "System.ReadOnlySpan<object>").WithLocation(2, 26));
 
        var expectedDiagnostics = new[]
        {
            // (2,26): error CS0656: Missing compiler required member 'ReadOnlySpan<T>.CastUp'
            // ReadOnlySpan<object> s = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.ReadOnlySpan<T>", "CastUp").WithLocation(2, 26)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Conversion_string_ReadOnlySpan_Implicit_MissingHelper()
    {
        var source = """
            using System;
            ReadOnlySpan<char> s = source();
            static string source() => throw null;
 
            namespace System
            {
                public readonly ref struct ReadOnlySpan<T> { }
            }
            """;
 
        CreateCompilation(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (2,24): error CS0029: Cannot implicitly convert type 'string' to 'System.ReadOnlySpan<char>'
            // ReadOnlySpan<char> s = source();
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "source()").WithArguments("string", "System.ReadOnlySpan<char>").WithLocation(2, 24));
 
        var expectedDiagnostics = new[]
        {
            // (2,24): error CS0656: Missing compiler required member 'System.MemoryExtensions.AsSpan'
            // ReadOnlySpan<char> s = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.MemoryExtensions", "AsSpan").WithLocation(2, 24)
        };
 
        CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_Span_Implicit_SpanNotRefStruct(
        [CombinatorialValues("class", "struct", "readonly struct", "record", "record struct", "readonly record struct")] string kind,
        [CombinatorialValues("Span", "ReadOnlySpan")] string type)
    {
        var source = $$"""
            using System;
            {{type}}<int> s =
                arr();
            static int[] arr() => new int[] { 1, 2, 3 };
 
            namespace System
            {
                public {{kind}} {{type}}<T>;
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (3,5): error CS0029: Cannot implicitly convert type 'int[]' to 'System.Span<int>'
            //     arr();
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arr()").WithArguments("int[]", $"System.{type}<int>").WithLocation(3, 5));
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_Span_Implicit_DifferentOperator(
        [CombinatorialValues("int[]", "T[][]")] string parameterType)
    {
        var source = $$"""
            using System;
            Span<int> s = arr();
            static int[] arr() => new int[] { 1, 2, 3 };
 
            namespace System
            {
                public readonly ref struct Span<T>
                {
                    public static implicit operator Span<T>({{parameterType}} array) => throw null;
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (2,15): error CS0656: Missing compiler required member 'System.Span<T>.op_Implicit'
            // Span<int> s = arr();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "arr()").WithArguments("System.Span<T>", "op_Implicit").WithLocation(2, 15));
    }
 
    [Theory]
    [InlineData("ReadOnlySpan<char> AsSpan(string s)", true)]
    [InlineData("ReadOnlySpan<int> AsSpan(string s)", false)]
    [InlineData("ReadOnlySpan<T> AsSpan<T>(string s)", false)]
    [InlineData("ReadOnlySpan<char> AsSpan(object o)", false)]
    [InlineData("Span<char> AsSpan(string s)", false)]
    public void Conversion_string_ReadOnlySpan_Implicit_DifferentHelper(string signature, bool works)
    {
        var source = $$"""
            using System;
            ReadOnlySpan<char> s = source();
            static string source() => "";
 
            namespace System
            {
                public readonly ref struct ReadOnlySpan<T> { }
                public readonly ref struct Span<T> { }
                public static class MemoryExtensions
                {
                    public static {{signature}} => default;
                }
            }
            """;
        var comp = CreateCompilation(source);
        if (works)
        {
            // Make sure the code above can work so we are testing something useful.
            comp.VerifyDiagnostics();
        }
        else
        {
            comp.VerifyDiagnostics(
                // (2,24): error CS0656: Missing compiler required member 'System.MemoryExtensions.AsSpan'
                // ReadOnlySpan<char> s = source();
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.MemoryExtensions", "AsSpan").WithLocation(2, 24));
        }
    }
 
    [Theory, CombinatorialData]
    public void Conversion_string_ReadOnlySpan_Implicit_HelperAccessibility_01(
        [CombinatorialValues("public", "internal")] string classModifier,
        [CombinatorialValues("public", "internal")] string methodModifier)
    {
        var source = $$"""
            using System;
            ReadOnlySpan<char> s = source();
            static string source() => "";
 
            namespace System
            {
                public readonly ref struct ReadOnlySpan<T> { }
                {{classModifier}} static class MemoryExtensions
                {
                    {{methodModifier}} static ReadOnlySpan<char> AsSpan(string s) => default;
                }
            }
            """;
        var comp = CreateCompilation(source);
        if (classModifier == "internal" || methodModifier == "internal")
        {
            comp.VerifyDiagnostics(
                // (2,24): error CS0656: Missing compiler required member 'System.MemoryExtensions.AsSpan'
                // ReadOnlySpan<char> s = source();
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.MemoryExtensions", "AsSpan").WithLocation(2, 24));
        }
        else
        {
            comp.VerifyDiagnostics();
        }
    }
 
    [Fact]
    public void Conversion_string_ReadOnlySpan_Implicit_HelperAccessibility_02()
    {
        var source1 = """
            namespace System;
            public readonly ref struct ReadOnlySpan<T>;
            internal static class MemoryExtensions
            {
                public static ReadOnlySpan<char> AsSpan(string s) => default;
            }
            """;
        var comp1 = CreateCompilation(source1).VerifyDiagnostics().EmitToImageReference();
 
        var source2 = """
            using System;
            ReadOnlySpan<char> s1 = source();
            ReadOnlySpan<char> s2 = MemoryExtensions.AsSpan(source());
            static string source() => "";
            """;
        CreateCompilation(source2, [comp1]).VerifyDiagnostics(
            // (2,25): error CS0656: Missing compiler required member 'System.MemoryExtensions.AsSpan'
            // ReadOnlySpan<char> s1 = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.MemoryExtensions", "AsSpan").WithLocation(2, 25),
            // (3,25): error CS0122: 'MemoryExtensions' is inaccessible due to its protection level
            // ReadOnlySpan<char> s2 = MemoryExtensions.AsSpan(source());
            Diagnostic(ErrorCode.ERR_BadAccess, "MemoryExtensions").WithArguments("System.MemoryExtensions").WithLocation(3, 25));
    }
 
    [Theory, CombinatorialData]
    public void Conversion_string_ReadOnlySpan_Implicit_RedefinedHelper(
        [CombinatorialValues("public", "internal")] string classModifier,
        [CombinatorialValues("public", "internal")] string methodModifier)
    {
        var source = $$"""
            using System;
            ReadOnlySpan<char> s = source();
            static string source() => "";
 
            namespace System
            {
                {{classModifier}} static class MemoryExtensions
                {
                    {{methodModifier}} static ReadOnlySpan<char> AsSpan(string s) => default;
                }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        if (classModifier == "public" && methodModifier == "public")
        {
            comp.VerifyDiagnostics(
                // (2,24): error CS0656: Missing compiler required member 'System.MemoryExtensions.AsSpan'
                // ReadOnlySpan<char> s = source();
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.MemoryExtensions", "AsSpan").WithLocation(2, 24));
        }
        else
        {
            comp.VerifyDiagnostics();
        }
    }
 
    [Fact]
    public void Conversion_Array_Span_Implicit_ExplicitOperator()
    {
        var source = """
            using System;
            Span<int> s = arr();
            static int[] arr() => new int[] { 1, 2, 3 };
 
            namespace System
            {
                public readonly ref struct Span<T>
                {
                    public static explicit operator Span<T>(T[] array) => throw null;
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (2,15): error CS0656: Missing compiler required member 'System.Span<T>.op_Implicit'
            // Span<int> s = arr();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "arr()").WithArguments("System.Span<T>", "op_Implicit").WithLocation(2, 15));
    }
 
    [Fact]
    public void Conversion_Array_Span_Explicit_ExplicitOperator()
    {
        var source = """
            using System;
            Span<int> s = (Span<int>)arr();
            static int[] arr() => new int[] { 1, 2, 3 };
 
            namespace System
            {
                public readonly ref struct Span<T>
                {
                    public static explicit operator Span<T>(T[] array) => throw null;
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (2,15): error CS0656: Missing compiler required member 'Span<T>.op_Implicit'
            // Span<int> s = (Span<int>)arr();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "(Span<int>)arr()").WithArguments("System.Span<T>", "op_Implicit").WithLocation(2, 15));
    }
 
    [Fact]
    public void Conversion_Array_Span_Implicit_UnrecognizedModreq()
    {
        /*
            public struct Span<T>
            {
                public static implicit operator modreq(A) Span<T>(T[] array) => throw null;
            }
            public class A { }
            public static class C
            {
                public static void M(Span<int> s) { }
            }
         */
        var ilSource = """
            .class public sequential ansi sealed beforefieldinit System.Span`1<T> extends System.ValueType
            {
                .pack 0
                .size 1
                .method public hidebysig specialname static valuetype System.Span`1<!T> modreq(A) op_Implicit(!T[] 'array') cil managed
                {
                    .maxstack 1
                    ret
                }
            }
            .class public auto ansi sealed beforefieldinit A extends System.Object
            {
            }
            .class public auto ansi abstract sealed beforefieldinit C extends System.Object
            {
                .method public hidebysig static void M(valuetype System.Span`1<int32> s) cil managed 
                {
                    .maxstack 1
                    ret
                }
            }
            """;
        var source = """
            C.M(new int[] { 1, 2, 3 });
            """;
        CreateCompilationWithIL(source, ilSource).VerifyDiagnostics(
            // (1,5): error CS0570: 'Span<T>.implicit operator Span<T>(T[])' is not supported by the language
            // C.M(new int[] { 1, 2, 3 });
            Diagnostic(ErrorCode.ERR_BindToBogus, "new int[] { 1, 2, 3 }").WithArguments("System.Span<T>.implicit operator System.Span<T>(T[])").WithLocation(1, 5));
    }
 
    [Fact]
    public void Conversion_Array_Span_Implicit_UnrecognizedModopt()
    {
        /*
            public struct Span<T>
            {
                public static implicit operator modopt(A) Span<T>(T[] array) => throw null;
            }
            public class A { }
            public static class C
            {
                public static void M(Span<int> s) { }
            }
         */
        var ilSource = """
            .class public sequential ansi sealed beforefieldinit System.Span`1<T> extends System.ValueType
            {
                .pack 0
                .size 1
                .method public hidebysig specialname static valuetype System.Span`1<!T> modopt(A) op_Implicit(!T[] 'array') cil managed
                {
                    .maxstack 1
                    ret
                }
            }
            .class public auto ansi sealed beforefieldinit A extends System.Object
            {
            }
            .class public auto ansi abstract sealed beforefieldinit C extends System.Object
            {
                .method public hidebysig static void M(valuetype System.Span`1<int32> s) cil managed 
                {
                    .maxstack 1
                    ret
                }
            }
            """;
        var source = """
            C.M(arr());
            static int[] arr() => new int[] { 1, 2, 3 };
            """;
        var comp = CreateCompilationWithIL(source, ilSource);
        var verifier = CompileAndVerify(comp).VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       16 (0x10)
              .maxstack  1
              IL_0000:  call       "int[] Program.<<Main>$>g__arr|0_0()"
              IL_0005:  call       "System.Span<int> System.Span<int>.op_Implicit(int[])"
              IL_000a:  call       "void C.M(System.Span<int>)"
              IL_000f:  ret
            }
            """);
    }
 
    [Theory]
    [InlineData("where TDerived : T")]
    [InlineData("")]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_MissingClassConstraint(string constraints)
    {
        var source = $$"""
            using System;
            ReadOnlySpan<object> s = source();
            static ReadOnlySpan<string> source() => throw null;
            
            namespace System
            {
                public readonly ref struct ReadOnlySpan<T>
                {
                    public static ReadOnlySpan<T> CastUp<TDerived>(ReadOnlySpan<TDerived> items) {{constraints}} => throw null;
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (2,26): error CS0656: Missing compiler required member 'ReadOnlySpan<T>.CastUp'
            // ReadOnlySpan<object> s = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.ReadOnlySpan<T>", "CastUp").WithLocation(2, 26));
    }
 
    [Fact]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_MissingInheritsConstraint()
    {
        var source = """
            using System;
            ReadOnlySpan<object> s = source();
            static ReadOnlySpan<string> source() => throw null;
            
            namespace System
            {
                public readonly ref struct ReadOnlySpan<T>
                {
                    public static ReadOnlySpan<T> CastUp<TDerived>(ReadOnlySpan<TDerived> items) where TDerived : class => throw null;
                }
            }
            """;
        var verifier = CompileAndVerify(source);
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  call       "System.ReadOnlySpan<string> Program.<<Main>$>g__source|0_0()"
              IL_0005:  call       "System.ReadOnlySpan<object> System.ReadOnlySpan<object>.CastUp<string>(System.ReadOnlySpan<string>)"
              IL_000a:  pop
              IL_000b:  ret
            }
            """);
    }
 
    [Fact]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_AdditionalConstraint()
    {
        var source = """
            using System;
            ReadOnlySpan<object> s = source();
            static ReadOnlySpan<string> source() => throw null;
 
            public class C { }
            namespace System
            {
                public readonly ref struct ReadOnlySpan<T>
                {
                    public static ReadOnlySpan<T> CastUp<TDerived>(ReadOnlySpan<TDerived> items) where TDerived : C => throw null;
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (2,26): error CS0311: The type 'string' cannot be used as type parameter 'TDerived' in the generic type or method 'ReadOnlySpan<object>.CastUp<TDerived>(ReadOnlySpan<TDerived>)'. There is no implicit reference conversion from 'string' to 'C'.
            // ReadOnlySpan<object> s = source();
            Diagnostic(ErrorCode.ERR_GenericConstraintNotSatisfiedRefType, "source()").WithArguments("System.ReadOnlySpan<object>.CastUp<TDerived>(System.ReadOnlySpan<TDerived>)", "C", "TDerived", "string").WithLocation(2, 26));
    }
 
    [Theory]
    [InlineData("T", "T", false)]
    [InlineData("T", "TDerived", false)]
    [InlineData("TDerived", "TDerived", false)]
    [InlineData("TDerived", "T", true)]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_WrongTypeArgument(string arg, string result, bool works)
    {
        var source = $$"""
            using System;
            ReadOnlySpan<object> s = source();
            static ReadOnlySpan<string> source() => throw null;
 
            public class C { }
            namespace System
            {
                public readonly ref struct ReadOnlySpan<T>
                {
                    public static ReadOnlySpan<{{result}}> CastUp<TDerived>(ReadOnlySpan<{{arg}}> items) where TDerived : class, T => throw null;
                }
            }
            """;
        var comp = CreateCompilation(source);
        if (works)
        {
            // Make sure the code above can work so we are testing something useful.
            comp.VerifyDiagnostics();
        }
        else
        {
            comp.VerifyDiagnostics(
                // (2,26): error CS0656: Missing compiler required member 'ReadOnlySpan<T>.CastUp'
                // ReadOnlySpan<object> s = source();
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.ReadOnlySpan<T>", "CastUp").WithLocation(2, 26));
        }
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Implicit_ConstantData(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            C.M1(new[] { 1 });
            C.M2(new[] { 2 });
 
            static class C
            {
                public static void M1(Span<int> s) => Console.Write(s[0]);
                public static void M2(ReadOnlySpan<int> s) => Console.Write(s[0]);
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        var verifier = CompileAndVerify(comp, expectedOutput: "12").VerifyDiagnostics();
        if (ExecutionConditionUtil.IsCoreClr)
        {
            verifier.VerifyIL("<top-level-statements-entry-point>", """
                {
                  // Code size       36 (0x24)
                  .maxstack  4
                  IL_0000:  ldc.i4.1
                  IL_0001:  newarr     "int"
                  IL_0006:  dup
                  IL_0007:  ldc.i4.0
                  IL_0008:  ldc.i4.1
                  IL_0009:  stelem.i4
                  IL_000a:  call       "System.Span<int> System.Span<int>.op_Implicit(int[])"
                  IL_000f:  call       "void C.M1(System.Span<int>)"
                  IL_0014:  ldtoken    "<PrivateImplementationDetails>.__StaticArrayInitTypeSize=4_Align=4 <PrivateImplementationDetails>.26B25D457597A7B0463F9620F666DD10AA2C4373A505967C7C8D70922A2D6ECE4"
                  IL_0019:  call       "System.ReadOnlySpan<int> System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan<int>(System.RuntimeFieldHandle)"
                  IL_001e:  call       "void C.M2(System.ReadOnlySpan<int>)"
                  IL_0023:  ret
                }
                """);
        }
        else
        {
            verifier.VerifyIL("<top-level-statements-entry-point>", """
                {
                  // Code size       63 (0x3f)
                  .maxstack  4
                  IL_0000:  ldc.i4.1
                  IL_0001:  newarr     "int"
                  IL_0006:  dup
                  IL_0007:  ldc.i4.0
                  IL_0008:  ldc.i4.1
                  IL_0009:  stelem.i4
                  IL_000a:  call       "System.Span<int> System.Span<int>.op_Implicit(int[])"
                  IL_000f:  call       "void C.M1(System.Span<int>)"
                  IL_0014:  ldsfld     "int[] <PrivateImplementationDetails>.26B25D457597A7B0463F9620F666DD10AA2C4373A505967C7C8D70922A2D6ECE_A6"
                  IL_0019:  dup
                  IL_001a:  brtrue.s   IL_0034
                  IL_001c:  pop
                  IL_001d:  ldc.i4.1
                  IL_001e:  newarr     "int"
                  IL_0023:  dup
                  IL_0024:  ldtoken    "int <PrivateImplementationDetails>.26B25D457597A7B0463F9620F666DD10AA2C4373A505967C7C8D70922A2D6ECE"
                  IL_0029:  call       "void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"
                  IL_002e:  dup
                  IL_002f:  stsfld     "int[] <PrivateImplementationDetails>.26B25D457597A7B0463F9620F666DD10AA2C4373A505967C7C8D70922A2D6ECE_A6"
                  IL_0034:  newobj     "System.ReadOnlySpan<int>..ctor(int[])"
                  IL_0039:  call       "void C.M2(System.ReadOnlySpan<int>)"
                  IL_003e:  ret
                }
                """);
        }
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Implicit_ConstantData_NotWellKnownSpan(LanguageVersion langVersion)
    {
        var source = """
            extern alias span;
            C.M1(new[] { 1 });
            C.M2(new[] { 2 });
            static class C
            {
                public static void M1(span::System.Span<int> s) => System.Console.Write(s[0]);
                public static void M2(span::System.ReadOnlySpan<int> s) => System.Console.Write(s[0]);
            }
            """;
        var spanDll = CreateCompilation(TestSources.Span, options: TestOptions.UnsafeReleaseDll)
            .VerifyDiagnostics()
            .EmitToImageReference(aliases: ["span"]);
        var verifier = CompileAndVerify([source, TestSources.Span],
            references: [spanDll],
            expectedOutput: "12",
            verify: Verification.Fails,
            // warning CS0436: Type conflicts with imported type
            options: TestOptions.UnsafeReleaseExe.WithSpecificDiagnosticOptions("CS0436", ReportDiagnostic.Suppress),
            parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       41 (0x29)
              .maxstack  4
              IL_0000:  ldc.i4.1
              IL_0001:  newarr     "int"
              IL_0006:  dup
              IL_0007:  ldc.i4.0
              IL_0008:  ldc.i4.1
              IL_0009:  stelem.i4
              IL_000a:  call       "System.Span<int> System.Span<int>.op_Implicit(int[])"
              IL_000f:  call       "void C.M1(System.Span<int>)"
              IL_0014:  ldc.i4.1
              IL_0015:  newarr     "int"
              IL_001a:  dup
              IL_001b:  ldc.i4.0
              IL_001c:  ldc.i4.2
              IL_001d:  stelem.i4
              IL_001e:  call       "System.ReadOnlySpan<int> System.ReadOnlySpan<int>.op_Implicit(int[])"
              IL_0023:  call       "void C.M2(System.ReadOnlySpan<int>)"
              IL_0028:  ret
            }
            """);
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_Span_Implicit_MultipleSpans_01(
        [CombinatorialValues("Span", "ReadOnlySpan")] string type)
    {
        string getSpanSource(string output) => $$"""
            namespace System
            {
                public readonly ref struct {{type}}<T>
                {
                    public static implicit operator {{type}}<T>(T[] array)
                    {
                        Console.Write("{{output}}");
                        return default;
                    }
                }
            }
            """;
 
        var spanComp = CreateCompilation(getSpanSource("External"), assemblyName: "Span1")
            .VerifyDiagnostics()
            .EmitToImageReference();
 
        var source = $$"""
            using System;
            {{type}}<int> s = arr();
            use(s);
            static int[] arr() => new int[] { 1, 2, 3 };
            static void use({{type}}<int> s) { }
            """;
 
        var comp = CreateCompilation([source, getSpanSource("Internal")], [spanComp], assemblyName: "Consumer");
        var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify, expectedOutput: "Internal");
        verifier.VerifyDiagnostics(
            // (2,1): warning CS0436: The type 'Span<T>' in '' conflicts with the imported type 'Span<T>' in 'Span1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. Using the type defined in ''.
            // Span<int> s = arr();
            Diagnostic(ErrorCode.WRN_SameFullNameThisAggAgg, $"{type}<int>").WithArguments("", $"System.{type}<T>", "Span1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", $"System.{type}<T>").WithLocation(2, 1),
            // (5,17): warning CS0436: The type 'Span<T>' in '' conflicts with the imported type 'Span<T>' in 'Span1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. Using the type defined in ''.
            // static void use(Span<int> s) { }
            Diagnostic(ErrorCode.WRN_SameFullNameThisAggAgg, $"{type}<int>").WithArguments("", $"System.{type}<T>", "Span1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", $"System.{type}<T>").WithLocation(5, 17),
            // (5,41): warning CS0436: The type 'Span<T>' in '' conflicts with the imported type 'Span<T>' in 'Span1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. Using the type defined in ''.
            //         public static implicit operator Span<T>(T[] array)
            Diagnostic(ErrorCode.WRN_SameFullNameThisAggAgg, $"{type}<T>").WithArguments("", $"System.{type}<T>", "Span1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", $"System.{type}<T>").WithLocation(5, 41));
 
        verifier.VerifyIL("<top-level-statements-entry-point>", $$"""
            {
              // Code size       16 (0x10)
              .maxstack  1
              IL_0000:  call       "int[] Program.<<Main>$>g__arr|0_0()"
              IL_0005:  call       "System.{{type}}<int> System.{{type}}<int>.op_Implicit(int[])"
              IL_000a:  call       "void Program.<<Main>$>g__use|0_1(System.{{type}}<int>)"
              IL_000f:  ret
            }
            """);
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_Span_Implicit_MultipleSpans_02(
        [CombinatorialValues("Span", "ReadOnlySpan")] string type)
    {
        string getSpanSource(string output) => $$"""
            namespace System
            {
                public readonly ref struct {{type}}<T>
                {
                    public static implicit operator {{type}}<T>(T[] array)
                    {
                        Console.Write("{{output}}");
                        return default;
                    }
                }
            }
            """;
 
        var spanComp = CreateCompilation(getSpanSource("External"), assemblyName: "Span1")
            .VerifyDiagnostics()
            .EmitToImageReference(aliases: ["lib"]);
 
        var source = $$"""
            extern alias lib;
            lib::System.{{type}}<int> s = arr();
            static int[] arr() => new int[] { 1, 2, 3 };
            """;
 
        var comp = CreateCompilation([source, getSpanSource("Internal")], [spanComp], assemblyName: "Consumer");
        var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify, expectedOutput: "External");
        verifier.VerifyDiagnostics();
 
        verifier.VerifyIL("<top-level-statements-entry-point>", $$"""
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  call       "int[] Program.<<Main>$>g__arr|0_0()"
              IL_0005:  call       "System.{{type}}<int> System.{{type}}<int>.op_Implicit(int[])"
              IL_000a:  pop
              IL_000b:  ret
            }
            """);
    }
 
    [Fact]
    public void Conversion_Span_ReadOnlySpan_Implicit_MultipleSpans_01()
    {
        static string getSpanSource(string output) => $$"""
            namespace System
            {
                public readonly ref struct ReadOnlySpan<T>;
                public readonly ref struct Span<T>
                {
                    public static implicit operator ReadOnlySpan<T>(Span<T> span)
                    {
                        Console.Write("{{output}}");
                        return default;
                    }
                }
            }
            """;
 
        var spanComp = CreateCompilation(getSpanSource("External"), assemblyName: "Span1")
            .VerifyDiagnostics()
            .EmitToImageReference();
 
        var source = """
            using System;
            ReadOnlySpan<int> s = source();
            use(s);
            static Span<int> source() => default;
            static void use(ReadOnlySpan<int> s) { }
            """;
 
        var comp = CreateCompilation([source, getSpanSource("Internal")], [spanComp], assemblyName: "Consumer",
            // warning CS0436: Type conflicts with imported type
            options: TestOptions.UnsafeReleaseExe.WithSpecificDiagnosticOptions("CS0436", ReportDiagnostic.Suppress));
        var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify, expectedOutput: "Internal");
        verifier.VerifyDiagnostics();
 
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       16 (0x10)
              .maxstack  1
              IL_0000:  call       "System.Span<int> Program.<<Main>$>g__source|0_0()"
              IL_0005:  call       "System.ReadOnlySpan<int> System.Span<int>.op_Implicit(System.Span<int>)"
              IL_000a:  call       "void Program.<<Main>$>g__use|0_1(System.ReadOnlySpan<int>)"
              IL_000f:  ret
            }
            """);
    }
 
    [Fact]
    public void Conversion_Span_ReadOnlySpan_Implicit_MultipleSpans_02()
    {
        static string getSpanSource(string output) => $$"""
            namespace System
            {
                public readonly ref struct ReadOnlySpan<T>;
                public readonly ref struct Span<T>
                {
                    public static implicit operator ReadOnlySpan<T>(Span<T> span)
                    {
                        Console.Write("{{output}}");
                        return default;
                    }
                }
            }
            """;
 
        var spanComp = CreateCompilation(getSpanSource("External"), assemblyName: "Span1")
            .VerifyDiagnostics()
            .EmitToImageReference(aliases: ["lib"]);
 
        var source = """
            extern alias lib;
            lib::System.ReadOnlySpan<int> s = source();
            static lib::System.Span<int> source() => default;
            """;
 
        var comp = CreateCompilation([source, getSpanSource("Internal")], [spanComp], assemblyName: "Consumer");
        var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify, expectedOutput: "External");
        verifier.VerifyDiagnostics();
 
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  call       "System.Span<int> Program.<<Main>$>g__source|0_0()"
              IL_0005:  call       "System.ReadOnlySpan<int> System.Span<int>.op_Implicit(System.Span<int>)"
              IL_000a:  pop
              IL_000b:  ret
            }
            """);
 
        source = """
            extern alias lib;
            lib::System.ReadOnlySpan<int> s = source();
            static System.Span<int> source() => default;
            """;
        CreateCompilation([source, getSpanSource("Internal")], [spanComp], assemblyName: "Consumer").VerifyDiagnostics(
            // (2,35): error CS0656: Missing compiler required member 'Span<T>.op_Implicit'
            // lib::System.ReadOnlySpan<int> s = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.Span<T>", "op_Implicit").WithLocation(2, 35));
 
        source = """
            extern alias lib;
            System.ReadOnlySpan<int> s = source();
            static lib::System.Span<int> source() => default;
            """;
        CreateCompilation([source, getSpanSource("Internal")], [spanComp], assemblyName: "Consumer").VerifyDiagnostics(
            // (2,30): error CS0656: Missing compiler required member 'Span<T>.op_Implicit'
            // System.ReadOnlySpan<int> s = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.Span<T>", "op_Implicit").WithLocation(2, 30));
    }
 
    [Fact]
    public void Conversion_Span_ReadOnlySpan_Implicit_MultipleSpans_03()
    {
        var span1 = CreateCompilation("""
            namespace System;
            public readonly ref struct ReadOnlySpan<T>;
            public readonly ref struct Span<T>;
            """, assemblyName: "Span1")
            .VerifyDiagnostics()
            .EmitToImageReference(aliases: ["span1"]);
        var span2 = CreateCompilation("""
            extern alias span1;
            namespace System;
            public readonly ref struct ReadOnlySpan<T>;
            public readonly ref struct Span<T>
            {
                public static implicit operator span1::System.ReadOnlySpan<T>(Span<T> span)
                {
                    Console.Write("Span2");
                    return default;
                }
            }
            """, [span1], assemblyName: "Span2")
            .VerifyDiagnostics()
            .EmitToImageReference(aliases: ["span2"]);
 
        var source = """
            extern alias span1;
            extern alias span2;
            span1::System.ReadOnlySpan<int> s = source();
            static span2::System.Span<int> source() => default;
            """;
 
        var comp = CreateCompilation(source, [span1, span2], assemblyName: "Consumer");
        var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify, expectedOutput: "Span2");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  call       "System.Span<int> Program.<<Main>$>g__source|0_0()"
              IL_0005:  call       "System.ReadOnlySpan<int> System.Span<int>.op_Implicit(System.Span<int>)"
              IL_000a:  pop
              IL_000b:  ret
            }
            """);
 
        source = """
            extern alias span2;
            span2::System.ReadOnlySpan<int> s = source();
            static span2::System.Span<int> source() => default;
            """;
        CreateCompilation(source, [span2], assemblyName: "Consumer").VerifyDiagnostics(
            // (2,37): error CS0656: Missing compiler required member 'Span<T>.op_Implicit'
            // span2::System.ReadOnlySpan<int> s = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.Span<T>", "op_Implicit").WithLocation(2, 37));
 
        source = """
            extern alias span1;
            extern alias span2;
            span2::System.ReadOnlySpan<int> s = source();
            static span1::System.Span<int> source() => default;
            """;
        CreateCompilation(source, [span1, span2], assemblyName: "Consumer").VerifyDiagnostics(
            // (3,37): error CS0656: Missing compiler required member 'Span<T>.op_Implicit'
            // span2::System.ReadOnlySpan<int> s = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.Span<T>", "op_Implicit").WithLocation(3, 37));
    }
 
    [Fact]
    public void Conversion_Span_ReadOnlySpan_CastUp_Implicit_MultipleSpans()
    {
        var span1 = CreateCompilation("""
            namespace System;
            public readonly ref struct Span<T>;
            public readonly ref struct ReadOnlySpan<T>
            {
                public static ReadOnlySpan<T> CastUp<TDerived>(ReadOnlySpan<TDerived> span) where TDerived : class, T
                {
                    Console.WriteLine("CastUp");
                    return default;
                }
            }
            """, assemblyName: "Span1")
            .VerifyDiagnostics()
            .EmitToImageReference(aliases: ["span1"]);
        var span2 = CreateCompilation("""
            extern alias span1;
            namespace System;
            public readonly ref struct Span<T>
            {
                public static implicit operator span1::System.ReadOnlySpan<T>(Span<T> span)
                {
                    Console.WriteLine("Span2 to ReadOnlySpan1");
                    return default;
                }
            }
            """, [span1], assemblyName: "Span2")
            .VerifyDiagnostics()
            .EmitToImageReference(aliases: ["span2"]);
 
        var source = """
            extern alias span1;
            extern alias span2;
            span1::System.ReadOnlySpan<object> s = source();
            static span2::System.Span<string> source() => default;
            """;
 
        var comp = CreateCompilation(source, [span1, span2], assemblyName: "Consumer");
        var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify, expectedOutput: """
            Span2 to ReadOnlySpan1
            CastUp
            """);
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       17 (0x11)
              .maxstack  1
              IL_0000:  call       "System.Span<string> Program.<<Main>$>g__source|0_0()"
              IL_0005:  call       "System.ReadOnlySpan<string> System.Span<string>.op_Implicit(System.Span<string>)"
              IL_000a:  call       "System.ReadOnlySpan<object> System.ReadOnlySpan<object>.CastUp<string>(System.ReadOnlySpan<string>)"
              IL_000f:  pop
              IL_0010:  ret
            }
            """);
    }
 
    [Fact]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_MultipleSpans_01()
    {
        static string getSpanSource(string output) => $$"""
            namespace System
            {
                public readonly ref struct ReadOnlySpan<T>
                {
                    public static ReadOnlySpan<T> CastUp<TDerived>(ReadOnlySpan<TDerived> other) where TDerived : class, T
                    {
                        Console.Write("{{output}}");
                        return default;
                    }
                }
            }
            """;
 
        var spanComp = CreateCompilation(getSpanSource("External"), assemblyName: "Span1")
            .VerifyDiagnostics()
            .EmitToImageReference();
 
        var source = """
            using System;
            ReadOnlySpan<object> s = source();
            use(s);
            static ReadOnlySpan<string> source() => default;
            static void use(ReadOnlySpan<object> s) { }
            """;
 
        var comp = CreateCompilation([source, getSpanSource("Internal")], [spanComp], assemblyName: "Consumer",
            // warning CS0436: Type conflicts with imported type
            options: TestOptions.UnsafeReleaseExe.WithSpecificDiagnosticOptions("CS0436", ReportDiagnostic.Suppress));
        var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify, expectedOutput: "Internal");
        verifier.VerifyDiagnostics();
 
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       16 (0x10)
              .maxstack  1
              IL_0000:  call       "System.ReadOnlySpan<string> Program.<<Main>$>g__source|0_0()"
              IL_0005:  call       "System.ReadOnlySpan<object> System.ReadOnlySpan<object>.CastUp<string>(System.ReadOnlySpan<string>)"
              IL_000a:  call       "void Program.<<Main>$>g__use|0_1(System.ReadOnlySpan<object>)"
              IL_000f:  ret
            }
            """);
    }
 
    [Fact]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_MultipleSpans_02()
    {
        static string getSpanSource(string output) => $$"""
            namespace System
            {
                public readonly ref struct ReadOnlySpan<T>
                {
                    public static ReadOnlySpan<T> CastUp<TDerived>(ReadOnlySpan<TDerived> other) where TDerived : class, T
                    {
                        Console.Write("{{output}}");
                        return default;
                    }
                }
            }
            """;
 
        var spanComp = CreateCompilation(getSpanSource("External"), assemblyName: "Span1")
            .VerifyDiagnostics()
            .EmitToImageReference(aliases: ["lib"]);
 
        var source = """
            extern alias lib;
            lib::System.ReadOnlySpan<object> s = source();
            static lib::System.ReadOnlySpan<string> source() => default;
            """;
 
        var comp = CreateCompilation([source, getSpanSource("Internal")], [spanComp], assemblyName: "Consumer");
        var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify, expectedOutput: "External");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  call       "System.ReadOnlySpan<string> Program.<<Main>$>g__source|0_0()"
              IL_0005:  call       "System.ReadOnlySpan<object> System.ReadOnlySpan<object>.CastUp<string>(System.ReadOnlySpan<string>)"
              IL_000a:  pop
              IL_000b:  ret
            }
            """);
 
        source = """
            extern alias lib;
            lib::System.ReadOnlySpan<object> s = source();
            static System.ReadOnlySpan<string> source() => default;
            """;
        CreateCompilation([source, getSpanSource("Internal")], [spanComp], assemblyName: "Consumer").VerifyDiagnostics(
            // (2,38): error CS0656: Missing compiler required member 'ReadOnlySpan<T>.CastUp'
            // lib::System.ReadOnlySpan<object> s = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.ReadOnlySpan<T>", "CastUp").WithLocation(2, 38));
 
        source = """
            extern alias lib;
            System.ReadOnlySpan<object> s = source();
            static lib::System.ReadOnlySpan<string> source() => default;
            """;
        CreateCompilation([source, getSpanSource("Internal")], [spanComp], assemblyName: "Consumer").VerifyDiagnostics(
            // (2,33): error CS0656: Missing compiler required member 'ReadOnlySpan<T>.CastUp'
            // System.ReadOnlySpan<object> s = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.ReadOnlySpan<T>", "CastUp").WithLocation(2, 33));
    }
 
    [Fact]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_MultipleSpans_03()
    {
        var span1 = CreateCompilation("""
            namespace System;
            public readonly ref struct ReadOnlySpan<T>;
            """, assemblyName: "Span1")
            .VerifyDiagnostics()
            .EmitToImageReference(aliases: ["span1"]);
        var span2 = CreateCompilation("""
            extern alias span1;
            namespace System;
            public readonly ref struct ReadOnlySpan<T>
            {
                public static span1::System.ReadOnlySpan<T> CastUp<TDerived>(ReadOnlySpan<TDerived> other) where TDerived : class, T
                {
                    Console.Write("Span2");
                    return default;
                }
            }
            """, [span1], assemblyName: "Span2")
            .VerifyDiagnostics()
            .EmitToImageReference(aliases: ["span2"]);
 
        var source = """
            extern alias span1;
            extern alias span2;
            span1::System.ReadOnlySpan<object> s = source();
            static span2::System.ReadOnlySpan<string> source() => default;
            """;
        CreateCompilation(source, [span1, span2], assemblyName: "Consumer").VerifyDiagnostics(
            // (3,40): error CS0656: Missing compiler required member 'ReadOnlySpan<T>.CastUp'
            // span1::System.ReadOnlySpan<object> s = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.ReadOnlySpan<T>", "CastUp").WithLocation(3, 40));
 
        source = """
            extern alias span2;
            span2::System.ReadOnlySpan<object> s = source();
            static span2::System.ReadOnlySpan<string> source() => default;
            """;
        CreateCompilation(source, [span2], assemblyName: "Consumer").VerifyDiagnostics(
            // (2,40): error CS0656: Missing compiler required member 'ReadOnlySpan<T>.CastUp'
            // span2::System.ReadOnlySpan<object> s = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.ReadOnlySpan<T>", "CastUp").WithLocation(2, 40));
 
        source = """
            extern alias span1;
            extern alias span2;
            span2::System.ReadOnlySpan<object> s = source();
            static span1::System.ReadOnlySpan<string> source() => default;
            """;
        CreateCompilation(source, [span1, span2], assemblyName: "Consumer").VerifyDiagnostics(
            // (3,40): error CS0656: Missing compiler required member 'ReadOnlySpan<T>.CastUp'
            // span2::System.ReadOnlySpan<object> s = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.ReadOnlySpan<T>", "CastUp").WithLocation(3, 40));
    }
 
    [Fact]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_MultipleSpans_04()
    {
        var span1 = CreateCompilation("""
            namespace System;
            public readonly ref struct ReadOnlySpan<T>;
            """, assemblyName: "Span1")
            .VerifyDiagnostics()
            .EmitToImageReference(aliases: ["span1"]);
        var span2 = CreateCompilation("""
            extern alias span1;
            namespace System;
            public readonly ref struct ReadOnlySpan<T>
            {
                public static ReadOnlySpan<T> CastUp<TDerived>(span1::System.ReadOnlySpan<TDerived> other) where TDerived : class, T
                {
                    Console.Write("Span2");
                    return default;
                }
            }
            """, [span1], assemblyName: "Span2")
            .VerifyDiagnostics()
            .EmitToImageReference(aliases: ["span2"]);
 
        var source = """
            extern alias span1;
            extern alias span2;
            span1::System.ReadOnlySpan<object> s = source();
            static span2::System.ReadOnlySpan<string> source() => default;
            """;
        CreateCompilation(source, [span1, span2], assemblyName: "Consumer").VerifyDiagnostics(
            // (3,40): error CS0656: Missing compiler required member 'ReadOnlySpan<T>.CastUp'
            // span1::System.ReadOnlySpan<object> s = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.ReadOnlySpan<T>", "CastUp").WithLocation(3, 40));
 
        source = """
            extern alias span2;
            span2::System.ReadOnlySpan<object> s = source();
            static span2::System.ReadOnlySpan<string> source() => default;
            """;
        CreateCompilation(source, [span2], assemblyName: "Consumer").VerifyDiagnostics(
            // (2,40): error CS0656: Missing compiler required member 'ReadOnlySpan<T>.CastUp'
            // span2::System.ReadOnlySpan<object> s = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.ReadOnlySpan<T>", "CastUp").WithLocation(2, 40));
 
        source = """
            extern alias span1;
            extern alias span2;
            span2::System.ReadOnlySpan<object> s = source();
            static span1::System.ReadOnlySpan<string> source() => default;
            """;
        var comp = CreateCompilation(source, [span1, span2], assemblyName: "Consumer");
        var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify, expectedOutput: "Span2");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  call       "System.ReadOnlySpan<string> Program.<<Main>$>g__source|0_0()"
              IL_0005:  call       "System.ReadOnlySpan<object> System.ReadOnlySpan<object>.CastUp<string>(System.ReadOnlySpan<string>)"
              IL_000a:  pop
              IL_000b:  ret
            }
            """);
    }
 
    [Fact]
    public void Conversion_string_ReadOnlySpan_Implicit_MultipleSpans_01()
    {
        static string getSpanSource(string output) => $$"""
            namespace System
            {
                public readonly ref struct ReadOnlySpan<T>;
                public static class MemoryExtensions
                {
                    public static ReadOnlySpan<char> AsSpan(string s)
                    {
                        Console.Write("{{output}}");
                        return default;
                    }
                }
            }
            """;
 
        var spanComp = CreateCompilation(getSpanSource("External"), assemblyName: "Span1")
            .VerifyDiagnostics()
            .EmitToImageReference();
 
        var source = """
            using System;
            ReadOnlySpan<char> s = source();
            use(s);
            static string source() => "";
            static void use(ReadOnlySpan<char> s) { }
            """;
 
        var comp = CreateCompilation([source, getSpanSource("Internal")], [spanComp], assemblyName: "Consumer",
            // warning CS0436: Type conflicts with imported type
            options: TestOptions.UnsafeReleaseExe.WithSpecificDiagnosticOptions("CS0436", ReportDiagnostic.Suppress));
        var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify, expectedOutput: "Internal");
        verifier.VerifyDiagnostics();
 
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       16 (0x10)
              .maxstack  1
              IL_0000:  call       "string Program.<<Main>$>g__source|0_0()"
              IL_0005:  call       "System.ReadOnlySpan<char> System.MemoryExtensions.AsSpan(string)"
              IL_000a:  call       "void Program.<<Main>$>g__use|0_1(System.ReadOnlySpan<char>)"
              IL_000f:  ret
            }
            """);
    }
 
    [Fact]
    public void Conversion_string_ReadOnlySpan_Implicit_MultipleSpans_02()
    {
        static string getSpanSource(string output) => $$"""
            namespace System
            {
                public readonly ref struct ReadOnlySpan<T>;
                public static class MemoryExtensions
                {
                    public static ReadOnlySpan<char> AsSpan(string s)
                    {
                        Console.Write("{{output}}");
                        return default;
                    }
                }
            }
            """;
 
        var spanComp = CreateCompilation(getSpanSource("External"), assemblyName: "Span1")
            .VerifyDiagnostics()
            .EmitToImageReference(aliases: ["lib"]);
 
        var source = """
            extern alias lib;
            lib::System.ReadOnlySpan<char> s = source();
            static string source() => "";
            """;
 
        var comp = CreateCompilation([source, getSpanSource("Internal")], [spanComp], assemblyName: "Consumer");
        var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify, expectedOutput: "External");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  call       "string Program.<<Main>$>g__source|0_0()"
              IL_0005:  call       "System.ReadOnlySpan<char> System.MemoryExtensions.AsSpan(string)"
              IL_000a:  pop
              IL_000b:  ret
            }
            """);
 
        source = """
            System.ReadOnlySpan<char> s = source();
            static string source() => "";
            """;
 
        comp = CreateCompilation([source, getSpanSource("Internal")], [spanComp], assemblyName: "Consumer");
        verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify, expectedOutput: "Internal");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  call       "string Program.<<Main>$>g__source|0_0()"
              IL_0005:  call       "System.ReadOnlySpan<char> System.MemoryExtensions.AsSpan(string)"
              IL_000a:  pop
              IL_000b:  ret
            }
            """);
    }
 
    [Fact]
    public void Conversion_string_ReadOnlySpan_Implicit_MultipleSpans_03()
    {
        var span1 = CreateCompilation("""
            namespace System;
            public readonly ref struct ReadOnlySpan<T>;
            """, assemblyName: "Span1")
            .VerifyDiagnostics()
            .EmitToImageReference(aliases: ["span1"]);
        var span2 = CreateCompilation($$"""
            extern alias span1;
            namespace System;
            public readonly ref struct ReadOnlySpan<T>;
            public static class MemoryExtensions
            {
                public static span1::System.ReadOnlySpan<char> AsSpan(string s)
                {
                    Console.Write("Span2");
                    return default;
                }
            }
            """, [span1], assemblyName: "Span2")
            .VerifyDiagnostics()
            .EmitToImageReference(aliases: ["span2"]);
 
        var source = """
            extern alias span1;
            span1::System.ReadOnlySpan<char> s = source();
            static string source() => "";
            """;
        var comp = CreateCompilation(source, [span1, span2], assemblyName: "Consumer");
        var verifier = CompileAndVerify(comp, expectedOutput: "Span2");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  call       "string Program.<<Main>$>g__source|0_0()"
              IL_0005:  call       "System.ReadOnlySpan<char> System.MemoryExtensions.AsSpan(string)"
              IL_000a:  pop
              IL_000b:  ret
            }
            """);
 
        source = """
            extern alias span2;
            span2::System.ReadOnlySpan<char> s = source();
            static string source() => "";
            """;
        CreateCompilation(source, [span2], assemblyName: "Consumer").VerifyDiagnostics(
            // (2,38): error CS0656: Missing compiler required member 'System.MemoryExtensions.AsSpan'
            // span2::System.ReadOnlySpan<char> s = source();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "source()").WithArguments("System.MemoryExtensions", "AsSpan").WithLocation(2, 38));
    }
 
    [Fact]
    public void Conversion_Span_ReadOnlySpan_Retargeting()
    {
        var source1 = """
            namespace System;
            public readonly ref struct ReadOnlySpan<T>;
            public readonly ref struct Span<T>
            {
                public static implicit operator ReadOnlySpan<T>(Span<T> span) => default;
            }
            """;
        var comp1Ref = CreateCompilation(source1, targetFramework: TargetFramework.Mscorlib40)
            .VerifyDiagnostics()
            .ToMetadataReference();
 
        var source2 = """
            using System;
            class C
            {
                ReadOnlySpan<int> M(Span<int> s) => s;
            }
            """;
        var comp2 = CreateCompilation(source2, [comp1Ref], targetFramework: TargetFramework.NetStandard20);
 
        Assert.IsType<RetargetingNamedTypeSymbol>(comp2.GlobalNamespace.GetMember("System.Span"));
        Assert.IsType<RetargetingNamedTypeSymbol>(comp2.GlobalNamespace.GetMember("System.ReadOnlySpan"));
 
        CompileAndVerify(comp2, verify: Verification.FailsILVerify)
            .VerifyDiagnostics()
            .VerifyIL("C.M", """
                {
                  // Code size        7 (0x7)
                  .maxstack  1
                  IL_0000:  ldarg.1
                  IL_0001:  call       "System.ReadOnlySpan<int> System.Span<int>.op_Implicit(System.Span<int>)"
                  IL_0006:  ret
                }
                """);
    }
 
    [Theory]
    [InlineData("System.Int32[]", "System.Span<System.Int32>")]
    [InlineData("System.Int32[]", "System.ReadOnlySpan<System.Int32>")]
    [InlineData("System.Span<System.Int32>", "System.ReadOnlySpan<System.Int32>")]
    [InlineData("System.ReadOnlySpan<System.String>", "System.ReadOnlySpan<System.Object>")]
    [InlineData("System.String", "System.ReadOnlySpan<System.Char>")]
    public void Conversion_Span_Implicit_SemanticModel(string sourceType, string targetType)
    {
        var source = $$"""
            class C
            {
                {{targetType}} M({{sourceType}} arg) { return arg; }
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        var tree = comp.SyntaxTrees.Single();
        var model = comp.GetSemanticModel(tree);
 
        var arg = tree.GetRoot().DescendantNodes().OfType<ReturnStatementSyntax>().Single().Expression;
        Assert.Equal("arg", arg!.ToString());
 
        var argType = model.GetTypeInfo(arg);
        Assert.Equal(sourceType, argType.Type.ToTestDisplayString());
        Assert.Equal(targetType, argType.ConvertedType.ToTestDisplayString());
 
        var argConv = model.GetConversion(arg);
        Assert.Equal(ConversionKind.ImplicitSpan, argConv.Kind);
        Assert.True(argConv.IsSpan);
        Assert.True(argConv.IsImplicit);
        Assert.False(argConv.IsUserDefined);
        Assert.False(argConv.IsIdentity);
    }
 
    [Fact]
    public void Conversion_Array_Span_Explicit_SemanticModel()
    {
        var source = """
            using System;
            class C<T, U>
                where T : class
                where U : class, T
            {
                ReadOnlySpan<T> F1(T[] x) => (ReadOnlySpan<T>)x;
                ReadOnlySpan<U> F2(T[] x) => (ReadOnlySpan<U>)x;
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        var tree = comp.SyntaxTrees.Single();
        var model = comp.GetSemanticModel(tree);
 
        var casts = tree.GetRoot().DescendantNodes().OfType<CastExpressionSyntax>().ToImmutableArray();
        Assert.Equal(2, casts.Length);
 
        {
            var cast = casts[0];
            Assert.Equal("(ReadOnlySpan<T>)x", cast.ToString());
 
            var op = (IConversionOperation)model.GetOperation(cast)!;
            var conv = op.GetConversion();
            Assert.Equal(ConversionKind.ExplicitSpan, conv.Kind);
 
            model.VerifyOperationTree(cast, """
                IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.ReadOnlySpan<T>) (Syntax: '(ReadOnlySpan<T>)x')
                  Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
                  Operand:
                    IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: T[]) (Syntax: 'x')
                """);
        }
 
        {
            var cast = casts[1];
            Assert.Equal("(ReadOnlySpan<U>)x", cast.ToString());
 
            var op = (IConversionOperation)model.GetOperation(cast)!;
            var conv = op.GetConversion();
            Assert.Equal(ConversionKind.ExplicitSpan, conv.Kind);
 
            model.VerifyOperationTree(cast, """
                IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.ReadOnlySpan<U>) (Syntax: '(ReadOnlySpan<U>)x')
                  Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
                  Operand:
                    IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: T[]) (Syntax: 'x')
                """);
        }
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Implicit_UnrelatedElementType(LanguageVersion langVersion)
    {
        var source = """
            class C
            {
                System.Span<string> M(int[] arg) => arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (3,41): error CS0029: Cannot implicitly convert type 'int[]' to 'System.Span<string>'
            //     System.Span<string> M(int[] arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("int[]", "System.Span<string>").WithLocation(3, 41));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Explicit_UnrelatedElementType(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                Span<string> M(int[] arg) => (Span<string>)arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,34): error CS0030: Cannot convert type 'int[]' to 'System.Span<string>'
            //     Span<string> M(int[] arg) => (Span<string>)arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(Span<string>)arg").WithArguments("int[]", "System.Span<string>").WithLocation(4, 34));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_ReadOnlySpan_Implicit_UnrelatedElementType(LanguageVersion langVersion)
    {
        var source = """
            class C
            {
                System.ReadOnlySpan<string> M(int[] arg) => arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (3,49): error CS0029: Cannot implicitly convert type 'int[]' to 'System.ReadOnlySpan<string>'
            //     System.ReadOnlySpan<string> M(int[] arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("int[]", "System.ReadOnlySpan<string>").WithLocation(3, 49));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Span_Array_Implicit_UserDefined(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                string[] M(Span<string> arg) => arg;
            }
            namespace System
            {
                public readonly ref struct Span<T>
                {
                    public static implicit operator T[](Span<T> span) => default;
                }
            }
            """;
        CompileAndVerify(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion))
            .VerifyDiagnostics()
            .VerifyIL("C.M", """
            {
              // Code size        7 (0x7)
              .maxstack  1
              IL_0000:  ldarg.1
              IL_0001:  call       "string[] System.Span<string>.op_Implicit(System.Span<string>)"
              IL_0006:  ret
            }
            """);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_ReadOnlySpan_Explicit_UnrelatedElementType(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                ReadOnlySpan<string> M(int[] arg) => (ReadOnlySpan<string>)arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,42): error CS0030: Cannot convert type 'int[]' to 'System.ReadOnlySpan<string>'
            //     ReadOnlySpan<string> M(int[] arg) => (ReadOnlySpan<string>)arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(ReadOnlySpan<string>)arg").WithArguments("int[]", "System.ReadOnlySpan<string>").WithLocation(4, 42));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Span_ReadOnlySpan_Implicit_UnrelatedElementType(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                ReadOnlySpan<string> M(Span<int> arg) => arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,46): error CS0029: Cannot implicitly convert type 'System.Span<int>' to 'System.ReadOnlySpan<string>'
            //     ReadOnlySpan<string> M(Span<int> arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("System.Span<int>", "System.ReadOnlySpan<string>").WithLocation(4, 46));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Span_ReadOnlySpan_Explicit_UnrelatedElementType(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                ReadOnlySpan<string> M(Span<int> arg) => (ReadOnlySpan<string>)arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,46): error CS0030: Cannot convert type 'System.Span<int>' to 'System.ReadOnlySpan<string>'
            //     ReadOnlySpan<string> M(Span<int> arg) => (ReadOnlySpan<string>)arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(ReadOnlySpan<string>)arg").WithArguments("System.Span<int>", "System.ReadOnlySpan<string>").WithLocation(4, 46));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Span_ReadOnlySpan_Implicit_Struct(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                ReadOnlySpan<int> M(Span<int> arg) => arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics();
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Span_ReadOnlySpan_Implicit_Struct_Generic(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                ReadOnlySpan<S<object>> M(Span<S<string>> arg) => arg;
            }
            struct S<T>;
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,55): error CS0029: Cannot implicitly convert type 'System.Span<S<string>>' to 'System.ReadOnlySpan<S<object>>'
            //     ReadOnlySpan<S<object>> M(Span<S<string>> arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("System.Span<S<string>>", "System.ReadOnlySpan<S<object>>").WithLocation(4, 55));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Span_ReadOnlySpan_Implicit_Struct_Generic_NullabilityAnnotation(LanguageVersion langVersion)
    {
        var source = """
            #nullable enable
            using System;
            class C
            {
                ReadOnlySpan<S<string?>> M(Span<S<string>> arg) => arg;
            }
            struct S<T>;
            """;
        var targetType = langVersion > LanguageVersion.CSharp13 ? "System.Span<S<string>>" : "System.ReadOnlySpan<S<string>>";
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (5,56): warning CS8619: Nullability of reference types in value of type 'Span<S<string>>' doesn't match target type 'ReadOnlySpan<S<string?>>'.
            //     ReadOnlySpan<S<string?>> M(Span<S<string>> arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments(targetType, "System.ReadOnlySpan<S<string?>>").WithLocation(5, 56));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_UnrelatedElementType(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                ReadOnlySpan<string> M(ReadOnlySpan<int> arg) => arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,54): error CS0029: Cannot implicitly convert type 'System.ReadOnlySpan<int>' to 'System.ReadOnlySpan<string>'
            //     ReadOnlySpan<string> M(ReadOnlySpan<int> arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("System.ReadOnlySpan<int>", "System.ReadOnlySpan<string>").WithLocation(4, 54));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Explicit_UnrelatedElementType(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                ReadOnlySpan<string> M(ReadOnlySpan<int> arg) => (ReadOnlySpan<string>)arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,54): error CS0030: Cannot convert type 'System.ReadOnlySpan<int>' to 'System.ReadOnlySpan<string>'
            //     ReadOnlySpan<string> M(ReadOnlySpan<int> arg) => (ReadOnlySpan<string>)arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(ReadOnlySpan<string>)arg").WithArguments("System.ReadOnlySpan<int>", "System.ReadOnlySpan<string>").WithLocation(4, 54));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_Struct(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                ReadOnlySpan<int> M(ReadOnlySpan<int> arg) => arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics();
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_Struct_Generic(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                ReadOnlySpan<S<object>> M(ReadOnlySpan<S<string>> arg) => arg;
            }
            struct S<T>;
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,63): error CS0029: Cannot implicitly convert type 'System.ReadOnlySpan<S<string>>' to 'System.ReadOnlySpan<S<object>>'
            //     ReadOnlySpan<S<object>> M(ReadOnlySpan<S<string>> arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("System.ReadOnlySpan<S<string>>", "System.ReadOnlySpan<S<object>>").WithLocation(4, 63));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_Struct_Generic_NullabilityAnnotation(LanguageVersion langVersion)
    {
        var source = """
            #nullable enable
            using System;
            class C
            {
                ReadOnlySpan<S<string?>> M(ReadOnlySpan<S<string>> arg) => arg;
            }
            struct S<T>;
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (5,64): warning CS8619: Nullability of reference types in value of type 'ReadOnlySpan<S<string>>' doesn't match target type 'ReadOnlySpan<S<string?>>'.
            //     ReadOnlySpan<S<string?>> M(ReadOnlySpan<S<string>> arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("System.ReadOnlySpan<S<string>>", "System.ReadOnlySpan<S<string?>>").WithLocation(5, 64));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_UserDefined_01(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                ReadOnlySpan<string> M(ReadOnlySpan<object> arg) => arg;
            }
            namespace System
            {
                public readonly ref struct ReadOnlySpan<T>
                {
                    public static implicit operator ReadOnlySpan<string>(ReadOnlySpan<T> span) => default;
                }
            }
            """;
        CompileAndVerify(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion), verify: Verification.FailsILVerify)
            .VerifyDiagnostics()
            .VerifyIL("C.M", """
            {
              // Code size        7 (0x7)
              .maxstack  1
              IL_0000:  ldarg.1
              IL_0001:  call       "System.ReadOnlySpan<string> System.ReadOnlySpan<object>.op_Implicit(System.ReadOnlySpan<object>)"
              IL_0006:  ret
            }
            """);
    }
 
    [Fact]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_UserDefined_02()
    {
        var source = """
            using System;
            class C
            {
                ReadOnlySpan<object> M(ReadOnlySpan<string> arg) => arg;
            }
            namespace System
            {
                public readonly ref struct ReadOnlySpan<T>
                {
                    public static implicit operator ReadOnlySpan<object>(ReadOnlySpan<T> span) => default;
                    public static ReadOnlySpan<T> CastUp<TDerived>(ReadOnlySpan<TDerived> s) where TDerived : class, T => throw null;
                }
            }
            """;
 
        CompileAndVerify(source, parseOptions: TestOptions.Regular13, verify: Verification.FailsILVerify)
            .VerifyDiagnostics()
            .VerifyIL("C.M", """
            {
              // Code size        7 (0x7)
              .maxstack  1
              IL_0000:  ldarg.1
              IL_0001:  call       "System.ReadOnlySpan<object> System.ReadOnlySpan<string>.op_Implicit(System.ReadOnlySpan<string>)"
              IL_0006:  ret
            }
            """);
 
        var expectedIl = """
            {
              // Code size        7 (0x7)
              .maxstack  1
              IL_0000:  ldarg.1
              IL_0001:  call       "System.ReadOnlySpan<object> System.ReadOnlySpan<object>.CastUp<string>(System.ReadOnlySpan<string>)"
              IL_0006:  ret
            }
            """;
 
        CompileAndVerify(source, parseOptions: TestOptions.RegularNext, verify: Verification.FailsILVerify)
            .VerifyDiagnostics().VerifyIL("C.M", expectedIl);
        CompileAndVerify(source, verify: Verification.FailsILVerify)
            .VerifyDiagnostics().VerifyIL("C.M", expectedIl);
    }
 
    [Theory, CombinatorialData]
    public void Conversion_ReadOnlySpan_Span_Implicit(
        [CombinatorialLangVersions] LanguageVersion langVersion,
        [CombinatorialValues("string", "object")] string type)
    {
        var source = $$"""
            using System;
            class C
            {
                Span<{{type}}> M(ReadOnlySpan<string> arg) => arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,49): error CS0029: Cannot implicitly convert type 'System.ReadOnlySpan<string>' to 'System.Span<string>'
            //     Span<string> M(ReadOnlySpan<string> arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("System.ReadOnlySpan<string>", $"System.Span<{type}>").WithLocation(4, 49));
    }
 
    [Theory, CombinatorialData]
    public void Conversion_ReadOnlySpan_Span_Explicit(
        [CombinatorialLangVersions] LanguageVersion langVersion,
        [CombinatorialValues("string", "object")] string type)
    {
        var source = $$"""
            using System;
            class C
            {
                Span<{{type}}> M(ReadOnlySpan<string> arg) => (Span<{{type}}>)arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,49): error CS0030: Cannot convert type 'System.ReadOnlySpan<string>' to 'System.Span<string>'
            //     Span<string> M(ReadOnlySpan<string> arg) => (Span<string>)arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, $"(Span<{type}>)arg").WithArguments("System.ReadOnlySpan<string>", $"System.Span<{type}>").WithLocation(4, 49));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_ReadOnlySpan_Span_Implicit_UserDefined(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                Span<string> M(ReadOnlySpan<string> arg) => arg;
            }
            namespace System
            {
                public readonly ref struct Span<T>;
                public readonly ref struct ReadOnlySpan<T>
                {
                    public static implicit operator Span<T>(ReadOnlySpan<T> span) => default;
                }
            }
            """;
        CompileAndVerify(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion), verify: Verification.FailsILVerify)
            .VerifyDiagnostics()
            .VerifyIL("C.M", """
            {
              // Code size        7 (0x7)
              .maxstack  1
              IL_0000:  ldarg.1
              IL_0001:  call       "System.Span<string> System.ReadOnlySpan<string>.op_Implicit(System.ReadOnlySpan<string>)"
              IL_0006:  ret
            }
            """);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_ReadOnlySpan_Span_Explicit_UserDefined(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                Span<string> M(ReadOnlySpan<string> arg) => (Span<string>)arg;
            }
            namespace System
            {
                public readonly ref struct Span<T>;
                public readonly ref struct ReadOnlySpan<T>
                {
                    public static explicit operator Span<T>(ReadOnlySpan<T> span) => default;
                }
            }
            """;
        CompileAndVerify(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion), verify: Verification.FailsILVerify)
            .VerifyDiagnostics()
            .VerifyIL("C.M", """
            {
              // Code size        7 (0x7)
              .maxstack  1
              IL_0000:  ldarg.1
              IL_0001:  call       "System.Span<string> System.ReadOnlySpan<string>.op_Explicit(System.ReadOnlySpan<string>)"
              IL_0006:  ret
            }
            """);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_ReadOnlySpan_Span_Explicit_UserDefined_Covariant(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                Span<string> M(ReadOnlySpan<object> arg) => (Span<string>)arg;
            }
            namespace System
            {
                public readonly ref struct Span<T>;
                public readonly ref struct ReadOnlySpan<T>
                {
                    public static explicit operator Span<string>(ReadOnlySpan<T> span) => default;
                }
            }
            """;
        CompileAndVerify(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion), verify: Verification.FailsILVerify)
            .VerifyDiagnostics()
            .VerifyIL("C.M", """
            {
              // Code size        7 (0x7)
              .maxstack  1
              IL_0000:  ldarg.1
              IL_0001:  call       "System.Span<string> System.ReadOnlySpan<object>.op_Explicit(System.ReadOnlySpan<object>)"
              IL_0006:  ret
            }
            """);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_string_ReadOnlySpan_Implicit_UnrelatedElementType(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                ReadOnlySpan<short> M(string arg) => arg;
            }
 
            namespace System
            {
                public readonly ref struct ReadOnlySpan<T>;
            }
            """;
        CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,42): error CS0029: Cannot implicitly convert type 'string' to 'System.ReadOnlySpan<short>'
            //     ReadOnlySpan<short> M(string arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("string", "System.ReadOnlySpan<short>").WithLocation(4, 42));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_string_Span_Implicit(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                Span<char> M(string arg) => arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,33): error CS0029: Cannot implicitly convert type 'string' to 'System.Span<char>'
            //     Span<char> M(string arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("string", "System.Span<char>").WithLocation(4, 33));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_string_Span_Explicit(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                Span<char> M(string arg) => (Span<char>)arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,33): error CS0030: Cannot convert type 'string' to 'System.Span<char>'
            //     Span<char> M(string arg) => (Span<char>)arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(Span<char>)arg").WithArguments("string", "System.Span<char>").WithLocation(4, 33));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_string_Span_Implicit_UserDefined(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                Span<char> M(string arg) => arg;
            }
            namespace System
            {
                public readonly ref struct Span<T>
                {
                    public static implicit operator Span<T>(string s) => default;
                }
            }
            """;
        CompileAndVerify(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion), verify: Verification.FailsILVerify)
            .VerifyDiagnostics()
            .VerifyIL("C.M", """
            {
              // Code size        7 (0x7)
              .maxstack  1
              IL_0000:  ldarg.1
              IL_0001:  call       "System.Span<char> System.Span<char>.op_Implicit(string)"
              IL_0006:  ret
            }
            """);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_ReadOnlySpan_string_Implicit_UserDefined(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                string M(ReadOnlySpan<char> arg) => arg;
            }
            namespace System
            {
                public readonly ref struct ReadOnlySpan<T>
                {
                    public static implicit operator string(ReadOnlySpan<T> span) => default;
                }
            }
            """;
        CompileAndVerify(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion))
            .VerifyDiagnostics()
            .VerifyIL("C.M", """
            {
              // Code size        7 (0x7)
              .maxstack  1
              IL_0000:  ldarg.1
              IL_0001:  call       "string System.ReadOnlySpan<char>.op_Implicit(System.ReadOnlySpan<char>)"
              IL_0006:  ret
            }
            """);
    }
 
    [Fact]
    public void Conversion_Array_Span_Implicit_NullableAnalysis()
    {
        var source = """
            #nullable enable
            using System;
            class C
            {
                Span<string> M1(string[] arg) => arg;
                Span<string> M2(string?[] arg) => arg;
                Span<string?> M3(string[] arg) => arg;
                Span<string?> M4(string?[] arg) => arg;
 
                Span<string> M5(string?[] arg) => (Span<string>)arg;
                Span<string> M6(string?[] arg) => (Span<string?>)arg;
                Span<string?> M7(string[] arg) => (Span<string>)arg;
                Span<string?> M8(string[] arg) => (Span<string?>)arg;
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (6,39): warning CS8619: Nullability of reference types in value of type 'string?[]' doesn't match target type 'string[]'.
            //     Span<string> M2(string?[] arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[]", "string[]").WithLocation(6, 39),
            // (10,39): warning CS8619: Nullability of reference types in value of type 'string?[]' doesn't match target type 'string[]'.
            //     Span<string> M5(string?[] arg) => (Span<string>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(Span<string>)arg").WithArguments("string?[]", "string[]").WithLocation(10, 39),
            // (11,39): warning CS8619: Nullability of reference types in value of type 'Span<string?>' doesn't match target type 'Span<string>'.
            //     Span<string> M6(string?[] arg) => (Span<string?>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(Span<string?>)arg").WithArguments("System.Span<string?>", "System.Span<string>").WithLocation(11, 39),
            // (12,39): warning CS8619: Nullability of reference types in value of type 'Span<string>' doesn't match target type 'Span<string?>'.
            //     Span<string?> M7(string[] arg) => (Span<string>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(Span<string>)arg").WithArguments("System.Span<string>", "System.Span<string?>").WithLocation(12, 39));
 
        var expectedDiagnostics = new[]
        {
            // (6,39): warning CS8619: Nullability of reference types in value of type 'string?[]' doesn't match target type 'Span<string>'.
            //     Span<string> M2(string?[] arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[]", "System.Span<string>").WithLocation(6, 39),
            // (7,39): warning CS8619: Nullability of reference types in value of type 'string[]' doesn't match target type 'Span<string?>'.
            //     Span<string?> M3(string[] arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string[]", "System.Span<string?>").WithLocation(7, 39),
            // (10,39): warning CS8619: Nullability of reference types in value of type 'string?[]' doesn't match target type 'Span<string>'.
            //     Span<string> M5(string?[] arg) => (Span<string>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(Span<string>)arg").WithArguments("string?[]", "System.Span<string>").WithLocation(10, 39),
            // (11,39): warning CS8619: Nullability of reference types in value of type 'Span<string?>' doesn't match target type 'Span<string>'.
            //     Span<string> M6(string?[] arg) => (Span<string?>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(Span<string?>)arg").WithArguments("System.Span<string?>", "System.Span<string>").WithLocation(11, 39),
            // (12,39): warning CS8619: Nullability of reference types in value of type 'Span<string>' doesn't match target type 'Span<string?>'.
            //     Span<string?> M7(string[] arg) => (Span<string>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(Span<string>)arg").WithArguments("System.Span<string>", "System.Span<string?>").WithLocation(12, 39),
            // (13,39): warning CS8619: Nullability of reference types in value of type 'string[]' doesn't match target type 'Span<string?>'.
            //     Span<string?> M8(string[] arg) => (Span<string?>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(Span<string?>)arg").WithArguments("string[]", "System.Span<string?>").WithLocation(13, 39)
        };
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Conversion_Array_ReadOnlySpan_Implicit_NullableAnalysis()
    {
        var source = """
            #nullable enable
            using System;
            class C
            {
                ReadOnlySpan<string> M1(string[] arg) => arg;
                ReadOnlySpan<string> M2(string?[] arg) => arg;
                ReadOnlySpan<string?> M3(string[] arg) => arg;
                ReadOnlySpan<string?> M4(string?[] arg) => arg;
                ReadOnlySpan<object> M5(string?[] arg) => arg;
 
                ReadOnlySpan<string> M6(string?[] arg) => (ReadOnlySpan<string>)arg;
                ReadOnlySpan<string> M7(object?[] arg) => (ReadOnlySpan<string>)arg;
                ReadOnlySpan<object> M8(string?[] arg) => (ReadOnlySpan<object>)arg;
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (6,47): warning CS8619: Nullability of reference types in value of type 'string?[]' doesn't match target type 'string[]'.
            //     ReadOnlySpan<string> M2(string?[] arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[]", "string[]").WithLocation(6, 47),
            // (9,47): warning CS8619: Nullability of reference types in value of type 'string?[]' doesn't match target type 'object[]'.
            //     ReadOnlySpan<object> M5(string?[] arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[]", "object[]").WithLocation(9, 47),
            // (11,47): warning CS8619: Nullability of reference types in value of type 'string?[]' doesn't match target type 'string[]'.
            //     ReadOnlySpan<string> M6(string?[] arg) => (ReadOnlySpan<string>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan<string>)arg").WithArguments("string?[]", "string[]").WithLocation(11, 47),
            // (12,47): warning CS8619: Nullability of reference types in value of type 'object?[]' doesn't match target type 'string[]'.
            //     ReadOnlySpan<string> M7(object?[] arg) => (ReadOnlySpan<string>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan<string>)arg").WithArguments("object?[]", "string[]").WithLocation(12, 47),
            // (13,47): warning CS8619: Nullability of reference types in value of type 'string?[]' doesn't match target type 'object[]'.
            //     ReadOnlySpan<object> M8(string?[] arg) => (ReadOnlySpan<object>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan<object>)arg").WithArguments("string?[]", "object[]").WithLocation(13, 47));
 
        var expectedDiagnostics = new[]
        {
            // (6,47): warning CS8619: Nullability of reference types in value of type 'string?[]' doesn't match target type 'ReadOnlySpan<string>'.
            //     ReadOnlySpan<string> M2(string?[] arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[]", "System.ReadOnlySpan<string>").WithLocation(6, 47),
            // (9,47): warning CS8619: Nullability of reference types in value of type 'string?[]' doesn't match target type 'ReadOnlySpan<object>'.
            //     ReadOnlySpan<object> M5(string?[] arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[]", "System.ReadOnlySpan<object>").WithLocation(9, 47),
            // (11,47): warning CS8619: Nullability of reference types in value of type 'string?[]' doesn't match target type 'ReadOnlySpan<string>'.
            //     ReadOnlySpan<string> M6(string?[] arg) => (ReadOnlySpan<string>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan<string>)arg").WithArguments("string?[]", "System.ReadOnlySpan<string>").WithLocation(11, 47),
            // (12,47): warning CS8619: Nullability of reference types in value of type 'object?[]' doesn't match target type 'ReadOnlySpan<string>'.
            //     ReadOnlySpan<string> M7(object?[] arg) => (ReadOnlySpan<string>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan<string>)arg").WithArguments("object?[]", "System.ReadOnlySpan<string>").WithLocation(12, 47),
            // (13,47): warning CS8619: Nullability of reference types in value of type 'string?[]' doesn't match target type 'ReadOnlySpan<object>'.
            //     ReadOnlySpan<object> M8(string?[] arg) => (ReadOnlySpan<object>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan<object>)arg").WithArguments("string?[]", "System.ReadOnlySpan<object>").WithLocation(13, 47)
        };
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Conversion_Span_ReadOnlySpan_Implicit_NullableAnalysis()
    {
        var source = """
            #nullable enable
            using System;
            class C
            {
                ReadOnlySpan<string> M1(Span<string> arg) => arg;
                ReadOnlySpan<string> M2(Span<string?> arg) => arg;
                ReadOnlySpan<string?> M3(Span<string> arg) => arg;
                ReadOnlySpan<string?> M4(Span<string?> arg) => arg;
                ReadOnlySpan<object> M5(Span<string?> arg) => arg;
 
                ReadOnlySpan<string> M6(Span<string?> arg) => (ReadOnlySpan<string>)arg;
                ReadOnlySpan<string> M7(Span<object?> arg) => (ReadOnlySpan<string>)arg;
                ReadOnlySpan<object> M8(Span<string?> arg) => (ReadOnlySpan<object>)arg;
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (6,51): warning CS8619: Nullability of reference types in value of type 'ReadOnlySpan<string?>' doesn't match target type 'ReadOnlySpan<string>'.
            //     ReadOnlySpan<string> M2(Span<string?> arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("System.ReadOnlySpan<string?>", "System.ReadOnlySpan<string>").WithLocation(6, 51),
            // (7,51): warning CS8619: Nullability of reference types in value of type 'ReadOnlySpan<string>' doesn't match target type 'ReadOnlySpan<string?>'.
            //     ReadOnlySpan<string?> M3(Span<string> arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("System.ReadOnlySpan<string>", "System.ReadOnlySpan<string?>").WithLocation(7, 51),
            // (9,51): error CS0029: Cannot implicitly convert type 'System.Span<string?>' to 'System.ReadOnlySpan<object>'
            //     ReadOnlySpan<object> M5(Span<string?> arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("System.Span<string?>", "System.ReadOnlySpan<object>").WithLocation(9, 51),
            // (11,51): warning CS8619: Nullability of reference types in value of type 'ReadOnlySpan<string?>' doesn't match target type 'ReadOnlySpan<string>'.
            //     ReadOnlySpan<string> M6(Span<string?> arg) => (ReadOnlySpan<string>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan<string>)arg").WithArguments("System.ReadOnlySpan<string?>", "System.ReadOnlySpan<string>").WithLocation(11, 51),
            // (12,51): error CS0030: Cannot convert type 'System.Span<object?>' to 'System.ReadOnlySpan<string>'
            //     ReadOnlySpan<string> M7(Span<object?> arg) => (ReadOnlySpan<string>)arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(ReadOnlySpan<string>)arg").WithArguments("System.Span<object?>", "System.ReadOnlySpan<string>").WithLocation(12, 51),
            // (13,51): error CS0030: Cannot convert type 'System.Span<string?>' to 'System.ReadOnlySpan<object>'
            //     ReadOnlySpan<object> M8(Span<string?> arg) => (ReadOnlySpan<object>)arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(ReadOnlySpan<object>)arg").WithArguments("System.Span<string?>", "System.ReadOnlySpan<object>").WithLocation(13, 51));
 
        var expectedDiagnostics = new[]
        {
            // (6,51): warning CS8619: Nullability of reference types in value of type 'Span<string?>' doesn't match target type 'ReadOnlySpan<string>'.
            //     ReadOnlySpan<string> M2(Span<string?> arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("System.Span<string?>", "System.ReadOnlySpan<string>").WithLocation(6, 51),
            // (9,51): warning CS8619: Nullability of reference types in value of type 'Span<string?>' doesn't match target type 'ReadOnlySpan<object>'.
            //     ReadOnlySpan<object> M5(Span<string?> arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("System.Span<string?>", "System.ReadOnlySpan<object>").WithLocation(9, 51),
            // (11,51): warning CS8619: Nullability of reference types in value of type 'Span<string?>' doesn't match target type 'ReadOnlySpan<string>'.
            //     ReadOnlySpan<string> M6(Span<string?> arg) => (ReadOnlySpan<string>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan<string>)arg").WithArguments("System.Span<string?>", "System.ReadOnlySpan<string>").WithLocation(11, 51),
            // (12,51): error CS0030: Cannot convert type 'System.Span<object?>' to 'System.ReadOnlySpan<string>'
            //     ReadOnlySpan<string> M7(Span<object?> arg) => (ReadOnlySpan<string>)arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(ReadOnlySpan<string>)arg").WithArguments("System.Span<object?>", "System.ReadOnlySpan<string>").WithLocation(12, 51),
            // (13,51): warning CS8619: Nullability of reference types in value of type 'Span<string?>' doesn't match target type 'ReadOnlySpan<object>'.
            //     ReadOnlySpan<object> M8(Span<string?> arg) => (ReadOnlySpan<object>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan<object>)arg").WithArguments("System.Span<string?>", "System.ReadOnlySpan<object>").WithLocation(13, 51)
        };
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net90).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_NullableAnalysis()
    {
        var source = """
            #nullable enable
            using System;
            class C
            {
                ReadOnlySpan<string> M1(ReadOnlySpan<string> arg) => arg;
                ReadOnlySpan<string> M2(ReadOnlySpan<string?> arg) => arg;
                ReadOnlySpan<string?> M3(ReadOnlySpan<string> arg) => arg;
                ReadOnlySpan<string?> M4(ReadOnlySpan<string?> arg) => arg;
                ReadOnlySpan<object> M5(ReadOnlySpan<string?> arg) => arg;
 
                ReadOnlySpan<string> M6(ReadOnlySpan<string?> arg) => (ReadOnlySpan<string>)arg;
                ReadOnlySpan<string> M7(ReadOnlySpan<object?> arg) => (ReadOnlySpan<string>)arg;
                ReadOnlySpan<object> M8(ReadOnlySpan<string?> arg) => (ReadOnlySpan<object>)arg;
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (6,59): warning CS8619: Nullability of reference types in value of type 'ReadOnlySpan<string?>' doesn't match target type 'ReadOnlySpan<string>'.
            //     ReadOnlySpan<string> M2(ReadOnlySpan<string?> arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("System.ReadOnlySpan<string?>", "System.ReadOnlySpan<string>").WithLocation(6, 59),
            // (7,59): warning CS8619: Nullability of reference types in value of type 'ReadOnlySpan<string>' doesn't match target type 'ReadOnlySpan<string?>'.
            //     ReadOnlySpan<string?> M3(ReadOnlySpan<string> arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("System.ReadOnlySpan<string>", "System.ReadOnlySpan<string?>").WithLocation(7, 59),
            // (9,59): error CS0029: Cannot implicitly convert type 'System.ReadOnlySpan<string?>' to 'System.ReadOnlySpan<object>'
            //     ReadOnlySpan<object> M5(ReadOnlySpan<string?> arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("System.ReadOnlySpan<string?>", "System.ReadOnlySpan<object>").WithLocation(9, 59),
            // (11,59): warning CS8619: Nullability of reference types in value of type 'ReadOnlySpan<string?>' doesn't match target type 'ReadOnlySpan<string>'.
            //     ReadOnlySpan<string> M6(ReadOnlySpan<string?> arg) => (ReadOnlySpan<string>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan<string>)arg").WithArguments("System.ReadOnlySpan<string?>", "System.ReadOnlySpan<string>").WithLocation(11, 59),
            // (12,59): error CS0030: Cannot convert type 'System.ReadOnlySpan<object?>' to 'System.ReadOnlySpan<string>'
            //     ReadOnlySpan<string> M7(ReadOnlySpan<object?> arg) => (ReadOnlySpan<string>)arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(ReadOnlySpan<string>)arg").WithArguments("System.ReadOnlySpan<object?>", "System.ReadOnlySpan<string>").WithLocation(12, 59),
            // (13,59): error CS0030: Cannot convert type 'System.ReadOnlySpan<string?>' to 'System.ReadOnlySpan<object>'
            //     ReadOnlySpan<object> M8(ReadOnlySpan<string?> arg) => (ReadOnlySpan<object>)arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(ReadOnlySpan<object>)arg").WithArguments("System.ReadOnlySpan<string?>", "System.ReadOnlySpan<object>").WithLocation(13, 59));
 
        var expectedDiagnostics = new[]
        {
            // (6,59): warning CS8619: Nullability of reference types in value of type 'ReadOnlySpan<string?>' doesn't match target type 'ReadOnlySpan<string>'.
            //     ReadOnlySpan<string> M2(ReadOnlySpan<string?> arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("System.ReadOnlySpan<string?>", "System.ReadOnlySpan<string>").WithLocation(6, 59),
            // (9,59): warning CS8619: Nullability of reference types in value of type 'ReadOnlySpan<string?>' doesn't match target type 'ReadOnlySpan<object>'.
            //     ReadOnlySpan<object> M5(ReadOnlySpan<string?> arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("System.ReadOnlySpan<string?>", "System.ReadOnlySpan<object>").WithLocation(9, 59),
            // (11,59): warning CS8619: Nullability of reference types in value of type 'ReadOnlySpan<string?>' doesn't match target type 'ReadOnlySpan<string>'.
            //     ReadOnlySpan<string> M6(ReadOnlySpan<string?> arg) => (ReadOnlySpan<string>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan<string>)arg").WithArguments("System.ReadOnlySpan<string?>", "System.ReadOnlySpan<string>").WithLocation(11, 59),
            // (12,59): error CS0030: Cannot convert type 'System.ReadOnlySpan<object?>' to 'System.ReadOnlySpan<string>'
            //     ReadOnlySpan<string> M7(ReadOnlySpan<object?> arg) => (ReadOnlySpan<string>)arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(ReadOnlySpan<string>)arg").WithArguments("System.ReadOnlySpan<object?>", "System.ReadOnlySpan<string>").WithLocation(12, 59),
            // (13,59): warning CS8619: Nullability of reference types in value of type 'ReadOnlySpan<string?>' doesn't match target type 'ReadOnlySpan<object>'.
            //     ReadOnlySpan<object> M8(ReadOnlySpan<string?> arg) => (ReadOnlySpan<object>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan<object>)arg").WithArguments("System.ReadOnlySpan<string?>", "System.ReadOnlySpan<object>").WithLocation(13, 59)
        };
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net90).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_string_ReadOnlySpan_Implicit_NullableAnalysis(LanguageVersion langVersion)
    {
        var source = """
            #nullable enable
            using System;
            class C
            {
                ReadOnlySpan<char> M1(string arg) => arg;
                ReadOnlySpan<char> M2(string? arg) => arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics();
    }
 
    [Fact]
    public void Conversion_Array_Span_Implicit_NullableAnalysis_NestedArrays()
    {
        var source = """
            #nullable enable
            using System;
            class C
            {
                Span<string[]> M1(string[][] arg) => arg;
                Span<string[]> M2(string?[][] arg) => arg;
                Span<string?[]> M3(string[][] arg) => arg;
                Span<string?[]> M4(string?[][] arg) => arg;
 
                Span<string[]> M5(string?[][] arg) => (Span<string[]>)arg;
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (6,43): warning CS8619: Nullability of reference types in value of type 'string?[][]' doesn't match target type 'string[][]'.
            //     Span<string[]> M2(string?[][] arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[][]", "string[][]").WithLocation(6, 43),
            // (10,43): warning CS8619: Nullability of reference types in value of type 'string?[][]' doesn't match target type 'string[][]'.
            //     Span<string[]> M5(string?[][] arg) => (Span<string[]>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(Span<string[]>)arg").WithArguments("string?[][]", "string[][]").WithLocation(10, 43));
 
        var expectedDiagnostics = new[]
        {
            // (6,43): warning CS8619: Nullability of reference types in value of type 'string?[][]' doesn't match target type 'Span<string[]>'.
            //     Span<string[]> M2(string?[][] arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[][]", "System.Span<string[]>").WithLocation(6, 43),
            // (7,43): warning CS8619: Nullability of reference types in value of type 'string[][]' doesn't match target type 'Span<string?[]>'.
            //     Span<string?[]> M3(string[][] arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string[][]", "System.Span<string?[]>").WithLocation(7, 43),
            // (10,43): warning CS8619: Nullability of reference types in value of type 'string?[][]' doesn't match target type 'Span<string[]>'.
            //     Span<string[]> M5(string?[][] arg) => (Span<string[]>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(Span<string[]>)arg").WithArguments("string?[][]", "System.Span<string[]>").WithLocation(10, 43)
        };
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Conversion_Array_ReadOnlySpan_Implicit_NullableAnalysis_NestedArrays()
    {
        var source = """
            #nullable enable
            using System;
            class C
            {
                ReadOnlySpan<string[]> M1(string[][] arg) => arg;
                ReadOnlySpan<string[]> M2(string?[][] arg) => arg;
                ReadOnlySpan<string?[]> M3(string[][] arg) => arg;
                ReadOnlySpan<string?[]> M4(string?[][] arg) => arg;
                ReadOnlySpan<object[]> M5(string?[][] arg) => arg;
 
                ReadOnlySpan<string[]> M6(string?[][] arg) => (ReadOnlySpan<string[]>)arg;
                ReadOnlySpan<string[]> M7(object?[][] arg) => (ReadOnlySpan<string[]>)arg;
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (6,51): warning CS8619: Nullability of reference types in value of type 'string?[][]' doesn't match target type 'string[][]'.
            //     ReadOnlySpan<string[]> M2(string?[][] arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[][]", "string[][]").WithLocation(6, 51),
            // (9,51): warning CS8619: Nullability of reference types in value of type 'string?[][]' doesn't match target type 'object[][]'.
            //     ReadOnlySpan<object[]> M5(string?[][] arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[][]", "object[][]").WithLocation(9, 51),
            // (11,51): warning CS8619: Nullability of reference types in value of type 'string?[][]' doesn't match target type 'string[][]'.
            //     ReadOnlySpan<string[]> M6(string?[][] arg) => (ReadOnlySpan<string[]>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan<string[]>)arg").WithArguments("string?[][]", "string[][]").WithLocation(11, 51),
            // (12,51): warning CS8619: Nullability of reference types in value of type 'object?[][]' doesn't match target type 'string[][]'.
            //     ReadOnlySpan<string[]> M7(object?[][] arg) => (ReadOnlySpan<string[]>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan<string[]>)arg").WithArguments("object?[][]", "string[][]").WithLocation(12, 51));
 
        var expectedDiagnostics = new[]
        {
            // (6,51): warning CS8619: Nullability of reference types in value of type 'string?[][]' doesn't match target type 'ReadOnlySpan<string[]>'.
            //     ReadOnlySpan<string[]> M2(string?[][] arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[][]", "System.ReadOnlySpan<string[]>").WithLocation(6, 51),
            // (9,51): warning CS8619: Nullability of reference types in value of type 'string?[][]' doesn't match target type 'ReadOnlySpan<object[]>'.
            //     ReadOnlySpan<object[]> M5(string?[][] arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[][]", "System.ReadOnlySpan<object[]>").WithLocation(9, 51),
            // (11,51): warning CS8619: Nullability of reference types in value of type 'string?[][]' doesn't match target type 'ReadOnlySpan<string[]>'.
            //     ReadOnlySpan<string[]> M6(string?[][] arg) => (ReadOnlySpan<string[]>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan<string[]>)arg").WithArguments("string?[][]", "System.ReadOnlySpan<string[]>").WithLocation(11, 51)
        };
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Implicit_NullableAnalysis_NestedNullability(LanguageVersion langVersion)
    {
        var source = """
            #nullable enable
            using System;
            class C
            {
                Span<S<string>> M1(S<string>[] arg) => arg;
                Span<S<string>> M2(S<string?>[] arg) => arg;
                Span<S<string?>> M3(S<string>[] arg) => arg;
                Span<S<string?>> M4(S<string?>[] arg) => arg;
 
                Span<S<string>> M5(S<string?>[] arg) => (Span<S<string>>)arg;
            }
            struct S<T> { }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (6,45): warning CS8619: Nullability of reference types in value of type 'S<string?>[]' doesn't match target type 'S<string>[]'.
            //     Span<S<string>> M2(S<string?>[] arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("S<string?>[]", targetType("string")).WithLocation(6, 45),
            // (7,45): warning CS8619: Nullability of reference types in value of type 'S<string>[]' doesn't match target type 'S<string?>[]'.
            //     Span<S<string?>> M3(S<string>[] arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("S<string>[]", targetType("string?")).WithLocation(7, 45),
            // (10,45): warning CS8619: Nullability of reference types in value of type 'S<string?>[]' doesn't match target type 'S<string>[]'.
            //     Span<S<string>> M5(S<string?>[] arg) => (Span<S<string>>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(Span<S<string>>)arg").WithArguments("S<string?>[]", targetType("string")).WithLocation(10, 45));
 
        string targetType(string inner)
            => langVersion > LanguageVersion.CSharp13 ? $"System.Span<S<{inner}>>" : $"S<{inner}>[]";
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_ReadOnlySpan_Implicit_NullableAnalysis_NestedNullability(LanguageVersion langVersion)
    {
        var source = """
            #nullable enable
            using System;
            class C
            {
                ReadOnlySpan<S<string>> M1(S<string>[] arg) => arg;
                ReadOnlySpan<S<string>> M2(S<string?>[] arg) => arg;
                ReadOnlySpan<S<string?>> M3(S<string>[] arg) => arg;
                ReadOnlySpan<S<string?>> M4(S<string?>[] arg) => arg;
                ReadOnlySpan<S<object>> M5(S<string?>[] arg) => arg;
 
                ReadOnlySpan<S<string>> M6(S<string?>[] arg) => (ReadOnlySpan<S<string>>)arg;
                ReadOnlySpan<S<string>> M7(S<object?>[] arg) => (ReadOnlySpan<S<string>>)arg;
            }
            struct S<T> { }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (6,53): warning CS8619: Nullability of reference types in value of type 'S<string?>[]' doesn't match target type 'S<string>[]'.
            //     ReadOnlySpan<S<string>> M2(S<string?>[] arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("S<string?>[]", targetType("string")).WithLocation(6, 53),
            // (7,53): warning CS8619: Nullability of reference types in value of type 'S<string>[]' doesn't match target type 'S<string?>[]'.
            //     ReadOnlySpan<S<string?>> M3(S<string>[] arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("S<string>[]", targetType("string?")).WithLocation(7, 53),
            // (9,53): error CS0029: Cannot implicitly convert type 'S<string?>[]' to 'System.ReadOnlySpan<S<object>>'
            //     ReadOnlySpan<S<object>> M5(S<string?>[] arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("S<string?>[]", "System.ReadOnlySpan<S<object>>").WithLocation(9, 53),
            // (11,53): warning CS8619: Nullability of reference types in value of type 'S<string?>[]' doesn't match target type 'S<string>[]'.
            //     ReadOnlySpan<S<string>> M6(S<string?>[] arg) => (ReadOnlySpan<S<string>>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan<S<string>>)arg").WithArguments("S<string?>[]", targetType("string")).WithLocation(11, 53),
            // (12,53): error CS0030: Cannot convert type 'S<object?>[]' to 'System.ReadOnlySpan<S<string>>'
            //     ReadOnlySpan<S<string>> M7(S<object?>[] arg) => (ReadOnlySpan<S<string>>)arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(ReadOnlySpan<S<string>>)arg").WithArguments("S<object?>[]", "System.ReadOnlySpan<S<string>>").WithLocation(12, 53));
 
        string targetType(string inner)
            => langVersion > LanguageVersion.CSharp13 ? $"System.ReadOnlySpan<S<{inner}>>" : $"S<{inner}>[]";
    }
 
    [Fact]
    public void Conversion_Span_ReadOnlySpan_Implicit_NullableAnalysis_NestedNullability()
    {
        var source = """
            #nullable enable
            using System;
            class C
            {
                ReadOnlySpan<I<string>> M1(Span<I<string>> arg) => arg;
                ReadOnlySpan<I<string>> M2(Span<I<string?>> arg) => arg;
                ReadOnlySpan<I<string?>> M3(Span<I<string>> arg) => arg;
                ReadOnlySpan<I<string?>> M4(Span<I<string?>> arg) => arg;
                ReadOnlySpan<I<object>> M5(Span<I<string?>> arg) => arg;
 
                ReadOnlySpan<I<string>> M6(Span<I<string?>> arg) => (ReadOnlySpan<I<string>>)arg;
                ReadOnlySpan<I<string>> M7(Span<I<object?>> arg) => (ReadOnlySpan<I<string>>)arg;
            }
            interface I<out T> { }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (6,57): warning CS8619: Nullability of reference types in value of type 'ReadOnlySpan<I<string?>>' doesn't match target type 'ReadOnlySpan<I<string>>'.
            //     ReadOnlySpan<I<string>> M2(Span<I<string?>> arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("System.ReadOnlySpan<I<string?>>", "System.ReadOnlySpan<I<string>>").WithLocation(6, 57),
            // (7,57): warning CS8619: Nullability of reference types in value of type 'ReadOnlySpan<I<string>>' doesn't match target type 'ReadOnlySpan<I<string?>>'.
            //     ReadOnlySpan<I<string?>> M3(Span<I<string>> arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("System.ReadOnlySpan<I<string>>", "System.ReadOnlySpan<I<string?>>").WithLocation(7, 57),
            // (9,57): error CS0029: Cannot implicitly convert type 'System.Span<I<string?>>' to 'System.ReadOnlySpan<I<object>>'
            //     ReadOnlySpan<I<object>> M5(Span<I<string?>> arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("System.Span<I<string?>>", "System.ReadOnlySpan<I<object>>").WithLocation(9, 57),
            // (11,57): warning CS8619: Nullability of reference types in value of type 'ReadOnlySpan<I<string?>>' doesn't match target type 'ReadOnlySpan<I<string>>'.
            //     ReadOnlySpan<I<string>> M6(Span<I<string?>> arg) => (ReadOnlySpan<I<string>>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan<I<string>>)arg").WithArguments("System.ReadOnlySpan<I<string?>>", "System.ReadOnlySpan<I<string>>").WithLocation(11, 57),
            // (12,57): error CS0030: Cannot convert type 'System.Span<I<object?>>' to 'System.ReadOnlySpan<I<string>>'
            //     ReadOnlySpan<I<string>> M7(Span<I<object?>> arg) => (ReadOnlySpan<I<string>>)arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(ReadOnlySpan<I<string>>)arg").WithArguments("System.Span<I<object?>>", "System.ReadOnlySpan<I<string>>").WithLocation(12, 57));
 
        var expectedDiagnostics = new[]
        {
            // (6,57): warning CS8619: Nullability of reference types in value of type 'Span<I<string?>>' doesn't match target type 'ReadOnlySpan<I<string>>'.
            //     ReadOnlySpan<I<string>> M2(Span<I<string?>> arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("System.Span<I<string?>>", "System.ReadOnlySpan<I<string>>").WithLocation(6, 57),
            // (9,57): warning CS8619: Nullability of reference types in value of type 'Span<I<string?>>' doesn't match target type 'ReadOnlySpan<I<object>>'.
            //     ReadOnlySpan<I<object>> M5(Span<I<string?>> arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("System.Span<I<string?>>", "System.ReadOnlySpan<I<object>>").WithLocation(9, 57),
            // (11,57): warning CS8619: Nullability of reference types in value of type 'Span<I<string?>>' doesn't match target type 'ReadOnlySpan<I<string>>'.
            //     ReadOnlySpan<I<string>> M6(Span<I<string?>> arg) => (ReadOnlySpan<I<string>>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan<I<string>>)arg").WithArguments("System.Span<I<string?>>", "System.ReadOnlySpan<I<string>>").WithLocation(11, 57),
            // (12,57): error CS0030: Cannot convert type 'System.Span<I<object?>>' to 'System.ReadOnlySpan<I<string>>'
            //     ReadOnlySpan<I<string>> M7(Span<I<object?>> arg) => (ReadOnlySpan<I<string>>)arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(ReadOnlySpan<I<string>>)arg").WithArguments("System.Span<I<object?>>", "System.ReadOnlySpan<I<string>>").WithLocation(12, 57)
        };
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net90).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_NullableAnalysis_NestedNullability(LanguageVersion langVersion)
    {
        var source = """
            #nullable enable
            using System;
            class C
            {
                ReadOnlySpan<S<string>> M1(ReadOnlySpan<S<string>> arg) => arg;
                ReadOnlySpan<S<string>> M2(ReadOnlySpan<S<string?>> arg) => arg;
                ReadOnlySpan<S<string?>> M3(ReadOnlySpan<S<string>> arg) => arg;
                ReadOnlySpan<S<string?>> M4(ReadOnlySpan<S<string?>> arg) => arg;
                ReadOnlySpan<S<object>> M5(ReadOnlySpan<S<string?>> arg) => arg;
 
                ReadOnlySpan<S<string>> M6(ReadOnlySpan<S<string?>> arg) => (ReadOnlySpan<S<string>>)arg;
                ReadOnlySpan<S<string>> M7(ReadOnlySpan<S<object?>> arg) => (ReadOnlySpan<S<string>>)arg;
            }
            struct S<T> { }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion), targetFramework: TargetFramework.Net90).VerifyDiagnostics(
            // (6,65): warning CS8619: Nullability of reference types in value of type 'ReadOnlySpan<S<string?>>' doesn't match target type 'ReadOnlySpan<S<string>>'.
            //     ReadOnlySpan<S<string>> M2(ReadOnlySpan<S<string?>> arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("System.ReadOnlySpan<S<string?>>", "System.ReadOnlySpan<S<string>>").WithLocation(6, 65),
            // (7,65): warning CS8619: Nullability of reference types in value of type 'ReadOnlySpan<S<string>>' doesn't match target type 'ReadOnlySpan<S<string?>>'.
            //     ReadOnlySpan<S<string?>> M3(ReadOnlySpan<S<string>> arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("System.ReadOnlySpan<S<string>>", "System.ReadOnlySpan<S<string?>>").WithLocation(7, 65),
            // (9,65): error CS0029: Cannot implicitly convert type 'System.ReadOnlySpan<S<string?>>' to 'System.ReadOnlySpan<S<object>>'
            //     ReadOnlySpan<S<object>> M5(ReadOnlySpan<S<string?>> arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("System.ReadOnlySpan<S<string?>>", "System.ReadOnlySpan<S<object>>").WithLocation(9, 65),
            // (11,65): warning CS8619: Nullability of reference types in value of type 'ReadOnlySpan<S<string?>>' doesn't match target type 'ReadOnlySpan<S<string>>'.
            //     ReadOnlySpan<S<string>> M6(ReadOnlySpan<S<string?>> arg) => (ReadOnlySpan<S<string>>)arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan<S<string>>)arg").WithArguments("System.ReadOnlySpan<S<string?>>", "System.ReadOnlySpan<S<string>>").WithLocation(11, 65),
            // (12,65): error CS0030: Cannot convert type 'System.ReadOnlySpan<S<object?>>' to 'System.ReadOnlySpan<S<string>>'
            //     ReadOnlySpan<S<string>> M7(ReadOnlySpan<S<object?>> arg) => (ReadOnlySpan<S<string>>)arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(ReadOnlySpan<S<string>>)arg").WithArguments("System.ReadOnlySpan<S<object?>>", "System.ReadOnlySpan<S<string>>").WithLocation(12, 65));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_ReadOnlySpan_Implicit_NullableAnalysis_NestedNullability_Covariant(LanguageVersion langVersion)
    {
        var source = """
            #nullable enable
            using System;
            class C
            {
                ReadOnlySpan<I<object>> M(I<string?>[] arg) => arg;
            }
            interface I<out T> { }
            """;
        var targetType = langVersion > LanguageVersion.CSharp13 ? "System.ReadOnlySpan<I<object>>" : "I<object>[]";
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (5,52): warning CS8619: Nullability of reference types in value of type 'I<string?>[]' doesn't match target type 'I<object>[]'.
            //     ReadOnlySpan<I<object>> M(I<string?>[] arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("I<string?>[]", targetType).WithLocation(5, 52));
    }
 
    [Fact]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_NullableAnalysis_NestedNullability_Covariant()
    {
        var source = """
            #nullable enable
            using System;
            class C
            {
                ReadOnlySpan<I<object>> M(ReadOnlySpan<I<string?>> arg) => arg;
            }
            interface I<out T> { }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (5,64): error CS0029: Cannot implicitly convert type 'System.ReadOnlySpan<I<string?>>' to 'System.ReadOnlySpan<I<object>>'
            //     ReadOnlySpan<I<object>> M(ReadOnlySpan<I<string?>> arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("System.ReadOnlySpan<I<string?>>", "System.ReadOnlySpan<I<object>>").WithLocation(5, 64));
 
        var expectedDiagnostics = new[]
        {
            // (5,64): warning CS8619: Nullability of reference types in value of type 'ReadOnlySpan<I<string?>>' doesn't match target type 'ReadOnlySpan<I<object>>'.
            //     ReadOnlySpan<I<object>> M(ReadOnlySpan<I<string?>> arg) => arg;
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("System.ReadOnlySpan<I<string?>>", "System.ReadOnlySpan<I<object>>").WithLocation(5, 64)
        };
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net90).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Implicit_NullableAnalysis_Outer(LanguageVersion langVersion)
    {
        var source = """
            #nullable enable
            using System;
            class C
            {
                Span<string>? M1(string[] arg) => arg;
                ReadOnlySpan<string>? M2(string[] arg) => arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (5,19): error CS9244: The type 'Span<string>' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Nullable<T>'
            //     Span<string>? M1(string[] arg) => arg;
            Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "M1").WithArguments("System.Nullable<T>", "T", "System.Span<string>").WithLocation(5, 19),
            // (6,27): error CS9244: The type 'ReadOnlySpan<string>' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Nullable<T>'
            //     ReadOnlySpan<string>? M2(string[] arg) => arg;
            Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "M2").WithArguments("System.Nullable<T>", "T", "System.ReadOnlySpan<string>").WithLocation(6, 27));
    }
 
    [Fact]
    public void Conversion_Array_Span_Implicit_NullableAnalysis_ExtensionMethodReceiver()
    {
        var source = """
            #nullable enable
            using System;
            static class C
            {
                static void MS(string[] a, string?[] b)
                {
                    a.M1(); b.M1();
                    a.M2(); b.M2();
                    a.M3(); b.M3();
                    a.M4(); b.M4();
                }
                static void M1(this Span<string> arg) { }
                static void M2(this Span<string?> arg) { }
                static void M3(this ReadOnlySpan<string> arg) { }
                static void M4(this ReadOnlySpan<string?> arg) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(
            // (7,17): warning CS8620: Argument of type 'string?[]' cannot be used for parameter 'arg' of type 'Span<string>' in 'void C.M1(Span<string> arg)' due to differences in the nullability of reference types.
            //         a.M1(); b.M1();
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInArgument, "b").WithArguments("string?[]", "System.Span<string>", "arg", "void C.M1(Span<string> arg)").WithLocation(7, 17),
            // (8,9): warning CS8620: Argument of type 'string[]' cannot be used for parameter 'arg' of type 'Span<string?>' in 'void C.M2(Span<string?> arg)' due to differences in the nullability of reference types.
            //         a.M2(); b.M2();
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInArgument, "a").WithArguments("string[]", "System.Span<string?>", "arg", "void C.M2(Span<string?> arg)").WithLocation(8, 9),
            // (9,17): warning CS8620: Argument of type 'string?[]' cannot be used for parameter 'arg' of type 'ReadOnlySpan<string>' in 'void C.M3(ReadOnlySpan<string> arg)' due to differences in the nullability of reference types.
            //         a.M3(); b.M3();
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInArgument, "b").WithArguments("string?[]", "System.ReadOnlySpan<string>", "arg", "void C.M3(ReadOnlySpan<string> arg)").WithLocation(9, 17));
    }
 
    [Fact]
    public void Conversion_Span_ReadOnlySpan_Implicit_NullableAnalysis_ExtensionMethodReceiver()
    {
        var source = """
            #nullable enable
            using System;
            static class C
            {
                static void MS(Span<string> a, Span<string?> b)
                {
                    a.M1(); b.M1();
                    a.M2(); b.M2();
                }
                static void M1(this ReadOnlySpan<string> arg) { }
                static void M2(this ReadOnlySpan<string?> arg) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(
            // (7,17): warning CS8620: Argument of type 'Span<string?>' cannot be used for parameter 'arg' of type 'ReadOnlySpan<string>' in 'void C.M1(ReadOnlySpan<string> arg)' due to differences in the nullability of reference types.
            //         a.M1(); b.M1();
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInArgument, "b").WithArguments("System.Span<string?>", "System.ReadOnlySpan<string>", "arg", "void C.M1(ReadOnlySpan<string> arg)").WithLocation(7, 17));
    }
 
    [Fact]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_NullableAnalysis_ExtensionMethodReceiver()
    {
        var source = """
            #nullable enable
            using System;
            static class C
            {
                static void MS(ReadOnlySpan<string> a, ReadOnlySpan<string?> b)
                {
                    a.M1(); b.M1();
                    a.M2(); b.M2();
                }
                static void M1(this ReadOnlySpan<object> arg) { }
                static void M2(this ReadOnlySpan<object?> arg) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics(
            // (7,17): warning CS8620: Argument of type 'ReadOnlySpan<string?>' cannot be used for parameter 'arg' of type 'ReadOnlySpan<object>' in 'void C.M1(ReadOnlySpan<object> arg)' due to differences in the nullability of reference types.
            //         a.M1(); b.M1();
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInArgument, "b").WithArguments("System.ReadOnlySpan<string?>", "System.ReadOnlySpan<object>", "arg", "void C.M1(ReadOnlySpan<object> arg)").WithLocation(7, 17));
    }
 
    [Fact]
    public void Conversion_string_ReadOnlySpan_Implicit_NullableAnalysis_ExtensionMethodReceiver()
    {
        var source = """
            #nullable enable
            using System;
            static class C
            {
                static void MS(string a, string? b)
                {
                    a.M();
                    b.M();
                }
                static void M(this ReadOnlySpan<char> arg) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics();
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_Span_Implicit_Ref_01(
        [CombinatorialValues("ref", "ref readonly", "in")] string modifier)
    {
        var source = $$"""
            class C
            {
                System.Span<string> M1({{modifier}} string[] arg) => arg;
                System.ReadOnlySpan<string> M2({{modifier}} string[] arg) => arg;
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics();
        verifier.VerifyIL("C.M1", """
            {
              // Code size        8 (0x8)
              .maxstack  1
              IL_0000:  ldarg.1
              IL_0001:  ldind.ref
              IL_0002:  call       "System.Span<string> System.Span<string>.op_Implicit(string[])"
              IL_0007:  ret
            }
            """);
        verifier.VerifyIL("C.M2", """
            {
              // Code size        8 (0x8)
              .maxstack  1
              IL_0000:  ldarg.1
              IL_0001:  ldind.ref
              IL_0002:  call       "System.ReadOnlySpan<string> System.ReadOnlySpan<string>.op_Implicit(string[])"
              IL_0007:  ret
            }
            """);
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_Span_Implicit_Ref_02(
        [CombinatorialLangVersions] LanguageVersion langVersion,
        [CombinatorialValues("ref", "ref readonly", "in")] string modifier)
    {
        var source = $$"""
            using System;
 
            class C
            {
                Span<string> M1(string[] arg) => M2({{argModifier(modifier)}}
                    arg); // 1
                Span<string> M2({{modifier}} Span<string> arg) => arg;
 
                ReadOnlySpan<string> M3(string[] arg) => M4({{argModifier(modifier)}}
                    arg); // 2
                ReadOnlySpan<string> M4({{modifier}} ReadOnlySpan<string> arg) => arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (6,9): error CS1503: Argument 1: cannot convert from 'ref string[]' to 'ref System.Span<string>'
            //         arg); // 1
            Diagnostic(ErrorCode.ERR_BadArgType, "arg").WithArguments("1", $"{argModifier(modifier)} string[]", $"{modifier} System.Span<string>").WithLocation(6, 9),
            // (10,9): error CS1503: Argument 1: cannot convert from 'ref string[]' to 'ref System.ReadOnlySpan<string>'
            //         arg); // 2
            Diagnostic(ErrorCode.ERR_BadArgType, "arg").WithArguments("1", $"{argModifier(modifier)} string[]", $"{modifier} System.ReadOnlySpan<string>").WithLocation(10, 9));
 
        static string argModifier(string paramModifier)
            => paramModifier == "ref readonly" ? "in" : paramModifier;
    }
 
    [Fact]
    public void Conversion_Array_Span_Implicit_Out()
    {
        var source = """
            class C
            {
                System.Span<string> M1(out string[] arg) => arg = null;
                System.ReadOnlySpan<string> M2(out string[] arg) => arg = null;
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics();
        verifier.VerifyIL("C.M1", """
            {
              // Code size       12 (0xc)
              .maxstack  3
              .locals init (string[] V_0)
              IL_0000:  ldarg.1
              IL_0001:  ldnull
              IL_0002:  dup
              IL_0003:  stloc.0
              IL_0004:  stind.ref
              IL_0005:  ldloc.0
              IL_0006:  call       "System.Span<string> System.Span<string>.op_Implicit(string[])"
              IL_000b:  ret
            }
            """);
        verifier.VerifyIL("C.M2", """
            {
              // Code size       12 (0xc)
              .maxstack  3
              .locals init (string[] V_0)
              IL_0000:  ldarg.1
              IL_0001:  ldnull
              IL_0002:  dup
              IL_0003:  stloc.0
              IL_0004:  stind.ref
              IL_0005:  ldloc.0
              IL_0006:  call       "System.ReadOnlySpan<string> System.ReadOnlySpan<string>.op_Implicit(string[])"
              IL_000b:  ret
            }
            """);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Implicit_RefReturn(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                ref Span<string> M1(ref string[] arg) => ref arg;
                ref ReadOnlySpan<string> M2(ref string[] arg) => ref arg;
                ref ReadOnlySpan<object> M3(ref string[] arg) => ref arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,50): error CS8151: The return expression must be of type 'Span<string>' because this method returns by reference
            //     ref Span<string> M1(ref string[] arg) => ref arg;
            Diagnostic(ErrorCode.ERR_RefReturnMustHaveIdentityConversion, "arg").WithArguments("System.Span<string>").WithLocation(4, 50),
            // (5,58): error CS8151: The return expression must be of type 'ReadOnlySpan<string>' because this method returns by reference
            //     ref ReadOnlySpan<string> M2(ref string[] arg) => ref arg;
            Diagnostic(ErrorCode.ERR_RefReturnMustHaveIdentityConversion, "arg").WithArguments("System.ReadOnlySpan<string>").WithLocation(5, 58),
            // (6,58): error CS8151: The return expression must be of type 'ReadOnlySpan<object>' because this method returns by reference
            //     ref ReadOnlySpan<object> M3(ref string[] arg) => ref arg;
            Diagnostic(ErrorCode.ERR_RefReturnMustHaveIdentityConversion, "arg").WithArguments("System.ReadOnlySpan<object>").WithLocation(6, 58));
    }
 
    [Fact]
    public void Conversion_Array_Span_Implicit_Value()
    {
        var source = """
            class C
            {
                void M()
                {
                    System.Span<string> s = A();
                    System.ReadOnlySpan<string> r = A();
                }
                string[] A() => null;
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, TestOptions.DebugDll);
        var verifier = CompileAndVerify(comp).VerifyDiagnostics();
        verifier.VerifyIL("C.M", """
            {
              // Code size       26 (0x1a)
              .maxstack  1
              .locals init (System.Span<string> V_0, //s
                            System.ReadOnlySpan<string> V_1) //r
              IL_0000:  nop
              IL_0001:  ldarg.0
              IL_0002:  call       "string[] C.A()"
              IL_0007:  call       "System.Span<string> System.Span<string>.op_Implicit(string[])"
              IL_000c:  stloc.0
              IL_000d:  ldarg.0
              IL_000e:  call       "string[] C.A()"
              IL_0013:  call       "System.ReadOnlySpan<string> System.ReadOnlySpan<string>.op_Implicit(string[])"
              IL_0018:  stloc.1
              IL_0019:  ret
            }
            """);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Opposite_Implicit(LanguageVersion langVersion)
    {
        var source = """
            class C
            {
                 int[] M1(System.Span<int> arg) => arg;
                 int[] M2(System.ReadOnlySpan<int> arg) => arg;
                 object[] M3(System.ReadOnlySpan<string> arg) => arg;
                 string[] M4(System.ReadOnlySpan<object> arg) => arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (3,40): error CS0029: Cannot implicitly convert type 'System.Span<int>' to 'int[]'
            //      int[] M1(System.Span<int> arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("System.Span<int>", "int[]").WithLocation(3, 40),
            // (4,48): error CS0029: Cannot implicitly convert type 'System.ReadOnlySpan<int>' to 'int[]'
            //      int[] M2(System.ReadOnlySpan<int> arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("System.ReadOnlySpan<int>", "int[]").WithLocation(4, 48),
            // (5,54): error CS0029: Cannot implicitly convert type 'System.ReadOnlySpan<string>' to 'object[]'
            //      object[] M3(System.ReadOnlySpan<string> arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("System.ReadOnlySpan<string>", "object[]").WithLocation(5, 54),
            // (6,54): error CS0029: Cannot implicitly convert type 'System.ReadOnlySpan<object>' to 'string[]'
            //      string[] M4(System.ReadOnlySpan<object> arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("System.ReadOnlySpan<object>", "string[]").WithLocation(6, 54));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Span_ReadOnlySpan_Opposite_Implicit(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                 Span<int> M1(ReadOnlySpan<int> arg) => arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,45): error CS0029: Cannot implicitly convert type 'System.ReadOnlySpan<int>' to 'System.Span<int>'
            //      Span<int> M1(ReadOnlySpan<int> arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("System.ReadOnlySpan<int>", "System.Span<int>").WithLocation(4, 45));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Opposite_Implicit(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                 ReadOnlySpan<string> M1(ReadOnlySpan<object> arg) => arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,59): error CS0029: Cannot implicitly convert type 'System.ReadOnlySpan<object>' to 'System.ReadOnlySpan<string>'
            //      ReadOnlySpan<string> M1(ReadOnlySpan<object> arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("System.ReadOnlySpan<object>", "System.ReadOnlySpan<string>").WithLocation(4, 59));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_string_ReadOnlySpan_Opposite_Implicit(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                 string M1(ReadOnlySpan<char> arg) => arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,43): error CS0029: Cannot implicitly convert type 'System.ReadOnlySpan<char>' to 'string'
            //      string M1(ReadOnlySpan<char> arg) => arg;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("System.ReadOnlySpan<char>", "string").WithLocation(4, 43));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Opposite_Explicit(LanguageVersion langVersion)
    {
        var source = """
            class C
            {
                 int[] M1(System.Span<int> arg) => (int[])arg;
                 int[] M2(System.ReadOnlySpan<int> arg) => (int[])arg;
                 object[] M3(System.ReadOnlySpan<string> arg) => (object[])arg;
                 string[] M4(System.ReadOnlySpan<object> arg) => (string[])arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (3,40): error CS0030: Cannot convert type 'System.Span<int>' to 'int[]'
            //      int[] M1(System.Span<int> arg) => (int[])arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(int[])arg").WithArguments("System.Span<int>", "int[]").WithLocation(3, 40),
            // (4,48): error CS0030: Cannot convert type 'System.ReadOnlySpan<int>' to 'int[]'
            //      int[] M2(System.ReadOnlySpan<int> arg) => (int[])arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(int[])arg").WithArguments("System.ReadOnlySpan<int>", "int[]").WithLocation(4, 48),
            // (5,54): error CS0030: Cannot convert type 'System.ReadOnlySpan<string>' to 'object[]'
            //      object[] M3(System.ReadOnlySpan<string> arg) => (object[])arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(object[])arg").WithArguments("System.ReadOnlySpan<string>", "object[]").WithLocation(5, 54),
            // (6,54): error CS0030: Cannot convert type 'System.ReadOnlySpan<object>' to 'string[]'
            //      string[] M4(System.ReadOnlySpan<object> arg) => (string[])arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(string[])arg").WithArguments("System.ReadOnlySpan<object>", "string[]").WithLocation(6, 54));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Span_ReadOnlySpan_Opposite_Explicit(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                 Span<int> M1(ReadOnlySpan<int> arg) => (Span<int>)arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,45): error CS0030: Cannot convert type 'System.ReadOnlySpan<int>' to 'System.Span<int>'
            //      Span<int> M1(ReadOnlySpan<int> arg) => (Span<int>)arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(Span<int>)arg").WithArguments("System.ReadOnlySpan<int>", "System.Span<int>").WithLocation(4, 45));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Opposite_Explicit(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                 ReadOnlySpan<string> M1(ReadOnlySpan<object> arg) => (ReadOnlySpan<string>)arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,59): error CS0030: Cannot convert type 'System.ReadOnlySpan<object>' to 'System.ReadOnlySpan<string>'
            //      ReadOnlySpan<string> M1(ReadOnlySpan<object> arg) => (ReadOnlySpan<string>)arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(ReadOnlySpan<string>)arg").WithArguments("System.ReadOnlySpan<object>", "System.ReadOnlySpan<string>").WithLocation(4, 59));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_string_ReadOnlySpan_Opposite_Explicit(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                 string M1(ReadOnlySpan<char> arg) => (string)arg;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,43): error CS0030: Cannot convert type 'System.ReadOnlySpan<char>' to 'string'
            //      string M1(ReadOnlySpan<char> arg) => (string)arg;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(string)arg").WithArguments("System.ReadOnlySpan<char>", "string").WithLocation(4, 43));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Opposite_Explicit_UserDefined(LanguageVersion langVersion)
    {
        var source = """
            class C
            {
                 int[] M(System.Span<int> arg) => (int[])arg;
            }
 
            namespace System
            {
                readonly ref struct Span<T>
                {
                    public static explicit operator T[](Span<T> span) => throw null;
                }
            }
            """;
        var verifier = CompileAndVerify(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.M", """
            {
              // Code size        7 (0x7)
              .maxstack  1
              IL_0000:  ldarg.1
              IL_0001:  call       "int[] System.Span<int>.op_Explicit(System.Span<int>)"
              IL_0006:  ret
            }
            """);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Span_ReadOnlySpan_Opposite_Explicit_UserDefined(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                 Span<int> M(ReadOnlySpan<int> arg) => (Span<int>)arg;
            }
 
            namespace System
            {
                readonly ref struct Span<T>;
                readonly ref struct ReadOnlySpan<T>
                {
                    public static explicit operator Span<T>(ReadOnlySpan<T> span) => throw null;
                }
            }
            """;
        var verifier = CompileAndVerify(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion), verify: Verification.FailsILVerify);
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.M", """
            {
              // Code size        7 (0x7)
              .maxstack  1
              IL_0000:  ldarg.1
              IL_0001:  call       "System.Span<int> System.ReadOnlySpan<int>.op_Explicit(System.ReadOnlySpan<int>)"
              IL_0006:  ret
            }
            """);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_string_ReadOnlySpan_Opposite_Explicit_UserDefined(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                 string M(ReadOnlySpan<char> arg) => (string)arg;
            }
 
            namespace System
            {
                readonly ref struct ReadOnlySpan<T>
                {
                    public static explicit operator string(ReadOnlySpan<T> span) => throw null;
                }
            }
            """;
        var verifier = CompileAndVerify(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.M", """
            {
              // Code size        7 (0x7)
              .maxstack  1
              IL_0000:  ldarg.1
              IL_0001:  call       "string System.ReadOnlySpan<char>.op_Explicit(System.ReadOnlySpan<char>)"
              IL_0006:  ret
            }
            """);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Implicit_Params(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            class C
            {
                void M(string[] a)
                {
                    M1(a);
                    M2(a);
                    M3(a);
                }
                void M1(params Span<string> s) { }
                void M2(params ReadOnlySpan<string> s) { }
                void M3(params string[] s) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        var verifier = CompileAndVerify(comp).VerifyDiagnostics();
        verifier.VerifyIL("C.M", """
            {
              // Code size       32 (0x20)
              .maxstack  2
              IL_0000:  ldarg.0
              IL_0001:  ldarg.1
              IL_0002:  call       "System.Span<string> System.Span<string>.op_Implicit(string[])"
              IL_0007:  call       "void C.M1(params System.Span<string>)"
              IL_000c:  ldarg.0
              IL_000d:  ldarg.1
              IL_000e:  call       "System.ReadOnlySpan<string> System.ReadOnlySpan<string>.op_Implicit(string[])"
              IL_0013:  call       "void C.M2(params System.ReadOnlySpan<string>)"
              IL_0018:  ldarg.0
              IL_0019:  ldarg.1
              IL_001a:  call       "void C.M3(params string[])"
              IL_001f:  ret
            }
            """);
    }
 
    [Fact]
    public void Conversion_Array_ReadOnlySpan_Implicit_Params_Covariant()
    {
        var source = """
            using System;
 
            class C
            {
                void M(string[] a)
                {
                    M1(a);
                    M2(a);
                    M3(a);
                }
                void M1(params Span<object> s) { }
                void M2(params ReadOnlySpan<object> s) { }
                void M3(params object[] p) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        var verifier = CompileAndVerify(comp).VerifyDiagnostics();
        verifier.VerifyIL("C.M", """
            {
              // Code size       38 (0x26)
              .maxstack  2
              .locals init (object[] V_0)
              IL_0000:  ldarg.0
              IL_0001:  ldarg.1
              IL_0002:  stloc.0
              IL_0003:  ldloc.0
              IL_0004:  call       "System.Span<object> System.Span<object>.op_Implicit(object[])"
              IL_0009:  call       "void C.M1(params System.Span<object>)"
              IL_000e:  ldarg.0
              IL_000f:  ldarg.1
              IL_0010:  stloc.0
              IL_0011:  ldloc.0
              IL_0012:  call       "System.ReadOnlySpan<object> System.ReadOnlySpan<object>.op_Implicit(object[])"
              IL_0017:  call       "void C.M2(params System.ReadOnlySpan<object>)"
              IL_001c:  ldarg.0
              IL_001d:  ldarg.1
              IL_001e:  stloc.0
              IL_001f:  ldloc.0
              IL_0020:  call       "void C.M3(params object[])"
              IL_0025:  ret
            }
            """);
 
        var expectedIl = """
            {
              // Code size       45 (0x2d)
              .maxstack  5
              .locals init (object[] V_0)
              IL_0000:  ldarg.0
              IL_0001:  ldc.i4.1
              IL_0002:  newarr     "object"
              IL_0007:  dup
              IL_0008:  ldc.i4.0
              IL_0009:  ldarg.1
              IL_000a:  stelem.ref
              IL_000b:  newobj     "System.Span<object>..ctor(object[])"
              IL_0010:  call       "void C.M1(params System.Span<object>)"
              IL_0015:  ldarg.0
              IL_0016:  ldarg.1
              IL_0017:  stloc.0
              IL_0018:  ldloc.0
              IL_0019:  call       "System.ReadOnlySpan<object> System.ReadOnlySpan<object>.op_Implicit(object[])"
              IL_001e:  call       "void C.M2(params System.ReadOnlySpan<object>)"
              IL_0023:  ldarg.0
              IL_0024:  ldarg.1
              IL_0025:  stloc.0
              IL_0026:  ldloc.0
              IL_0027:  call       "void C.M3(params object[])"
              IL_002c:  ret
            }
            """;
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        verifier = CompileAndVerify(comp).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        verifier = CompileAndVerify(comp).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Span_ReadOnlySpan_Implicit_Params(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                void M(Span<string> a)
                {
                    M1(a);
                }
                void M1(params ReadOnlySpan<string> s) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        var verifier = CompileAndVerify(comp).VerifyDiagnostics();
        verifier.VerifyIL("C.M", """
            {
              // Code size       13 (0xd)
              .maxstack  2
              IL_0000:  ldarg.0
              IL_0001:  ldarg.1
              IL_0002:  call       "System.ReadOnlySpan<string> System.Span<string>.op_Implicit(System.Span<string>)"
              IL_0007:  call       "void C.M1(params System.ReadOnlySpan<string>)"
              IL_000c:  ret
            }
            """);
    }
 
    [Fact]
    public void Conversion_Span_ReadOnlySpan_CastUp_Implicit_Params()
    {
        var source = """
            using System;
            class C
            {
                void M(Span<string> a)
                {
                    M1(a);
                }
                void M1(params ReadOnlySpan<object> s) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (6,12): error CS1503: Argument 1: cannot convert from 'System.Span<string>' to 'object'
            //         M1(a);
            Diagnostic(ErrorCode.ERR_BadArgType, "a").WithArguments("1", "System.Span<string>", "object").WithLocation(6, 12));
 
        var expectedIl = """
            {
              // Code size       18 (0x12)
              .maxstack  2
              IL_0000:  ldarg.0
              IL_0001:  ldarg.1
              IL_0002:  call       "System.ReadOnlySpan<string> System.Span<string>.op_Implicit(System.Span<string>)"
              IL_0007:  call       "System.ReadOnlySpan<object> System.ReadOnlySpan<object>.CastUp<string>(System.ReadOnlySpan<string>)"
              IL_000c:  call       "void C.M1(params System.ReadOnlySpan<object>)"
              IL_0011:  ret
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net90);
        var verifier = CompileAndVerify(comp).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90);
        verifier = CompileAndVerify(comp).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
    }
 
    [Fact]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_CastUp_Implicit_Params()
    {
        var source = """
            using System;
            class C
            {
                void M(ReadOnlySpan<string> a)
                {
                    M1(a);
                }
                void M1(params ReadOnlySpan<object> s) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (6,12): error CS1503: Argument 1: cannot convert from 'System.ReadOnlySpan<string>' to 'object'
            //         M1(a);
            Diagnostic(ErrorCode.ERR_BadArgType, "a").WithArguments("1", "System.ReadOnlySpan<string>", "object").WithLocation(6, 12));
 
        var expectedIl = """
            {
              // Code size       13 (0xd)
              .maxstack  2
              IL_0000:  ldarg.0
              IL_0001:  ldarg.1
              IL_0002:  call       "System.ReadOnlySpan<object> System.ReadOnlySpan<object>.CastUp<string>(System.ReadOnlySpan<string>)"
              IL_0007:  call       "void C.M1(params System.ReadOnlySpan<object>)"
              IL_000c:  ret
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net90);
        var verifier = CompileAndVerify(comp).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90);
        verifier = CompileAndVerify(comp).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
    }
 
    [Fact]
    public void Conversion_string_ReadOnlySpan_CastUp_Implicit_Params()
    {
        var source = """
            using System;
            class C
            {
                void M(ReadOnlySpan<string> a)
                {
                    M1(a);
                }
                void M1(params ReadOnlySpan<object> s) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (6,12): error CS1503: Argument 1: cannot convert from 'System.ReadOnlySpan<string>' to 'object'
            //         M1(a);
            Diagnostic(ErrorCode.ERR_BadArgType, "a").WithArguments("1", "System.ReadOnlySpan<string>", "object").WithLocation(6, 12));
 
        var expectedIl = """
            {
              // Code size       13 (0xd)
              .maxstack  2
              IL_0000:  ldarg.0
              IL_0001:  ldarg.1
              IL_0002:  call       "System.ReadOnlySpan<object> System.ReadOnlySpan<object>.CastUp<string>(System.ReadOnlySpan<string>)"
              IL_0007:  call       "void C.M1(params System.ReadOnlySpan<object>)"
              IL_000c:  ret
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net90);
        var verifier = CompileAndVerify(comp).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90);
        verifier = CompileAndVerify(comp).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Implicit_Multidimensional(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            class C
            {
                Span<string> M1(string[,] a) => a;
                Span<string> M2(string[][] a) => a;
                Span<string[]> M3(string[,] a) => a;
                Span<string[]> M4(string[][] a) => a;
                Span<string[][]> M5(string[,][] a) => a;
                Span<string[][]> M6(string[][][] a) => a;
                Span<string[,]> M7(string[][][] a) => a;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (5,37): error CS0029: Cannot implicitly convert type 'string[*,*]' to 'System.Span<string>'
            //     Span<string> M1(string[,] a) => a;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "a").WithArguments("string[*,*]", "System.Span<string>").WithLocation(5, 37),
            // (6,38): error CS0029: Cannot implicitly convert type 'string[][]' to 'System.Span<string>'
            //     Span<string> M2(string[][] a) => a;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "a").WithArguments("string[][]", "System.Span<string>").WithLocation(6, 38),
            // (7,39): error CS0029: Cannot implicitly convert type 'string[*,*]' to 'System.Span<string[]>'
            //     Span<string[]> M3(string[,] a) => a;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "a").WithArguments("string[*,*]", "System.Span<string[]>").WithLocation(7, 39),
            // (9,43): error CS0029: Cannot implicitly convert type 'string[*,*][]' to 'System.Span<string[][]>'
            //     Span<string[][]> M5(string[,][] a) => a;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "a").WithArguments("string[*,*][]", "System.Span<string[][]>").WithLocation(9, 43),
            // (11,43): error CS0029: Cannot implicitly convert type 'string[][][]' to 'System.Span<string[*,*]>'
            //     Span<string[,]> M7(string[][][] a) => a;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "a").WithArguments("string[][][]", "System.Span<string[*,*]>").WithLocation(11, 43));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Implicit_MethodGroup_ReturnType(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            C.R(C.M);
            C.R(() => C.M());
 
            static class C
            {
                public static int[] M() => new int[] { 1, 2, 3 };
                public static void R(D f) => Console.Write(f()[1]);
            }
 
            delegate Span<int> D();
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (3,5): error CS0407: 'int[] C.M()' has the wrong return type
            // C.R(C.M);
            Diagnostic(ErrorCode.ERR_BadRetType, "C.M").WithArguments("C.M()", "int[]").WithLocation(3, 5));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Implicit_MethodGroup_ParameterType(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            C.R(C.M);
            C.R(x => C.M(x));
 
            static class C
            {
                public static void M(Span<int> x) => Console.Write(x[1]);
                public static void R(D a) => a(new int[] { 1, 2, 3 });
            }
 
            delegate void D(int[] x);
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (3,5): error CS0123: No overload for 'C.M(Span<int>)' matches delegate 'D'
            // C.R(C.M);
            Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "C.M").WithArguments("C.M(System.Span<int>)", "D").WithLocation(3, 5));
    }
 
    [Fact]
    public void Conversion_Array_Span_Implicit_MethodGroup_ExtensionMethodReceiver()
    {
        var source = """
            using System;
 
            var a = new[] { 1, 2, 3 };
            C.R(a.M);
            C.R(x => a.M(x));
 
            static class C
            {
                public static int M(this Span<int> x, int y) => x[y];
                public static void R(Func<int, int> f) => Console.Write(f(1));
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (4,5): error CS1503: Argument 1: cannot convert from 'method group' to 'System.Func<int, int>'
            // C.R(a.M);
            Diagnostic(ErrorCode.ERR_BadArgType, "a.M").WithArguments("1", "method group", "System.Func<int, int>").WithLocation(4, 5),
            // (5,10): error CS1929: 'int[]' does not contain a definition for 'M' and the best extension method overload 'C.M(Span<int>, int)' requires a receiver of type 'System.Span<int>'
            // C.R(x => a.M(x));
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "a").WithArguments("int[]", "M", "C.M(System.Span<int>, int)", "System.Span<int>").WithLocation(5, 10));
 
        var expectedDiagnostics = new[]
        {
            // (4,5): error CS1503: Argument 1: cannot convert from 'method group' to 'System.Func<int, int>'
            // C.R(a.M);
            Diagnostic(ErrorCode.ERR_BadArgType, "a.M").WithArguments("1", "method group", "System.Func<int, int>").WithLocation(4, 5)
        };
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Conversion_Array_Span_Implicit_MethodGroup_ExtensionMethodReceiver_Inferred()
    {
        var source = """
            using System;
 
            var a = new[] { 1, 2, 3 };
            var d1 = a.M;
            var d2 = x => a.M(x);
            var d3 = (int x) => a.M(x);
 
            static class C
            {
                public static int M(this Span<int> x, int y) => x[y];
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (4,10): error CS8917: The delegate type could not be inferred.
            // var d1 = a.M;
            Diagnostic(ErrorCode.ERR_CannotInferDelegateType, "a.M").WithLocation(4, 10),
            // (5,10): error CS8917: The delegate type could not be inferred.
            // var d2 = x => a.M(x);
            Diagnostic(ErrorCode.ERR_CannotInferDelegateType, "x => a.M(x)").WithLocation(5, 10),
            // (6,21): error CS1929: 'int[]' does not contain a definition for 'M' and the best extension method overload 'C.M(Span<int>, int)' requires a receiver of type 'System.Span<int>'
            // var d3 = (int x) => a.M(x);
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "a").WithArguments("int[]", "M", "C.M(System.Span<int>, int)", "System.Span<int>").WithLocation(6, 21));
 
        var expectedDiagnostics = new[]
        {
            // (4,12): error CS0123: No overload for 'M' matches delegate 'Func<int, int>'
            // var d1 = a.M;
            Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "M").WithArguments("M", "System.Func<int, int>").WithLocation(4, 12),
            // (5,10): error CS8917: The delegate type could not be inferred.
            // var d2 = x => a.M(x);
            Diagnostic(ErrorCode.ERR_CannotInferDelegateType, "x => a.M(x)").WithLocation(5, 10)
        };
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics);
 
        var tree = comp.SyntaxTrees.Single();
        var model = comp.GetSemanticModel(tree);
        var aVariable = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().First();
        var aSymbol = (ILocalSymbol)model.GetDeclaredSymbol(aVariable)!;
        AssertEx.Equal("System.Int32[]", aSymbol.Type.ToTestDisplayString());
        var d1Access = tree.GetRoot().DescendantNodes().OfType<MemberAccessExpressionSyntax>()
            .First(s => s.Expression.ToString() == "a");
        var lookupResult = model.LookupSymbols(d1Access.Name.SpanStart, aSymbol.Type, "M", includeReducedExtensionMethods: true);
        AssertEx.Equal("System.Int32 System.Span<System.Int32>.M(System.Int32 y)", lookupResult.Single().ToTestDisplayString());
    }
 
    [Fact]
    public void Conversion_Array_Span_Implicit_MethodGroup_ExtensionMethodReceiver_Generic()
    {
        var source = """
            using System;
 
            var a = new[] { 1, 2, 3 };
            C.R(a.M);
            C.R(a.M<int>);
            C.R(x => a.M(x));
            C.R(x => a.M<int>(x));
 
            static class C
            {
                public static T M<T>(this Span<T> x, int y) => x[y];
                public static void R(Func<int, int> f) => Console.Write(f(1));
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (4,5): error CS1061: 'int[]' does not contain a definition for 'M' and no accessible extension method 'M' accepting a first argument of type 'int[]' could be found (are you missing a using directive or an assembly reference?)
            // C.R(a.M);
            Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "a.M").WithArguments("int[]", "M").WithLocation(4, 5),
            // (5,5): error CS1503: Argument 1: cannot convert from 'method group' to 'System.Func<int, int>'
            // C.R(a.M<int>);
            Diagnostic(ErrorCode.ERR_BadArgType, "a.M<int>").WithArguments("1", "method group", "System.Func<int, int>").WithLocation(5, 5),
            // (6,12): error CS1061: 'int[]' does not contain a definition for 'M' and no accessible extension method 'M' accepting a first argument of type 'int[]' could be found (are you missing a using directive or an assembly reference?)
            // C.R(x => a.M(x));
            Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "M").WithArguments("int[]", "M").WithLocation(6, 12),
            // (7,10): error CS1929: 'int[]' does not contain a definition for 'M' and the best extension method overload 'C.M<int>(Span<int>, int)' requires a receiver of type 'System.Span<int>'
            // C.R(x => a.M<int>(x));
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "a").WithArguments("int[]", "M", "C.M<int>(System.Span<int>, int)", "System.Span<int>").WithLocation(7, 10));
 
        var expectedDiagnostics = new[]
        {
            // (4,5): error CS1503: Argument 1: cannot convert from 'method group' to 'System.Func<int, int>'
            // C.R(a.M);
            Diagnostic(ErrorCode.ERR_BadArgType, "a.M").WithArguments("1", "method group", "System.Func<int, int>").WithLocation(4, 5),
            // (5,5): error CS1503: Argument 1: cannot convert from 'method group' to 'System.Func<int, int>'
            // C.R(a.M<int>);
            Diagnostic(ErrorCode.ERR_BadArgType, "a.M<int>").WithArguments("1", "method group", "System.Func<int, int>").WithLocation(5, 5)
        };
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Conversion_Array_Span_Implicit_MethodGroup_ExtensionMethodReceiver_Generic_Inferred()
    {
        var source = """
            using System;
 
            var a = new[] { 1, 2, 3 };
            var d1 = a.M;
            var d2 = x => a.M(x);
            var d3 = (int x) => a.M(x);
            var d4 = a.M<int>;
            var d5 = x => a.M<int>(x);
            var d6 = (int x) => a.M<int>(x);
            Func<int, int> d7 = a.M;
            Func<int, int> d8 = x => a.M(x);
 
            static class C
            {
                public static T M<T>(this Span<T> x, int y) => x[y];
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (4,10): error CS8917: The delegate type could not be inferred.
            // var d1 = a.M;
            Diagnostic(ErrorCode.ERR_CannotInferDelegateType, "a.M").WithLocation(4, 10),
            // (5,10): error CS8917: The delegate type could not be inferred.
            // var d2 = x => a.M(x);
            Diagnostic(ErrorCode.ERR_CannotInferDelegateType, "x => a.M(x)").WithLocation(5, 10),
            // (6,23): error CS1061: 'int[]' does not contain a definition for 'M' and no accessible extension method 'M' accepting a first argument of type 'int[]' could be found (are you missing a using directive or an assembly reference?)
            // var d3 = (int x) => a.M(x);
            Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "M").WithArguments("int[]", "M").WithLocation(6, 23),
            // (7,10): error CS8917: The delegate type could not be inferred.
            // var d4 = a.M<int>;
            Diagnostic(ErrorCode.ERR_CannotInferDelegateType, "a.M<int>").WithLocation(7, 10),
            // (8,10): error CS8917: The delegate type could not be inferred.
            // var d5 = x => a.M<int>(x);
            Diagnostic(ErrorCode.ERR_CannotInferDelegateType, "x => a.M<int>(x)").WithLocation(8, 10),
            // (9,21): error CS1929: 'int[]' does not contain a definition for 'M' and the best extension method overload 'C.M<int>(Span<int>, int)' requires a receiver of type 'System.Span<int>'
            // var d6 = (int x) => a.M<int>(x);
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "a").WithArguments("int[]", "M", "C.M<int>(System.Span<int>, int)", "System.Span<int>").WithLocation(9, 21),
            // (10,21): error CS1061: 'int[]' does not contain a definition for 'M' and no accessible extension method 'M' accepting a first argument of type 'int[]' could be found (are you missing a using directive or an assembly reference?)
            // Func<int, int> d7 = a.M;
            Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "a.M").WithArguments("int[]", "M").WithLocation(10, 21),
            // (11,28): error CS1061: 'int[]' does not contain a definition for 'M' and no accessible extension method 'M' accepting a first argument of type 'int[]' could be found (are you missing a using directive or an assembly reference?)
            // Func<int, int> d8 = x => a.M(x);
            Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "M").WithArguments("int[]", "M").WithLocation(11, 28));
 
        var expectedDiagnostics = new[]
        {
            // (4,12): error CS0123: No overload for 'M' matches delegate 'Func<int, int>'
            // var d1 = a.M;
            Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "M").WithArguments("M", "System.Func<int, int>").WithLocation(4, 12),
            // (5,10): error CS8917: The delegate type could not be inferred.
            // var d2 = x => a.M(x);
            Diagnostic(ErrorCode.ERR_CannotInferDelegateType, "x => a.M(x)").WithLocation(5, 10),
            // (7,12): error CS0123: No overload for 'M' matches delegate 'Func<int, int>'
            // var d4 = a.M<int>;
            Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "M<int>").WithArguments("M", "System.Func<int, int>").WithLocation(7, 12),
            // (8,10): error CS8917: The delegate type could not be inferred.
            // var d5 = x => a.M<int>(x);
            Diagnostic(ErrorCode.ERR_CannotInferDelegateType, "x => a.M<int>(x)").WithLocation(8, 10),
            // (10,23): error CS0123: No overload for 'M' matches delegate 'Func<int, int>'
            // Func<int, int> d7 = a.M;
            Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "M").WithArguments("M", "System.Func<int, int>").WithLocation(10, 23)
        };
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Implicit_MethodGroup_FunctionPointer(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            unsafe
            {
                C.R(&C.M);
            }
 
            unsafe static class C
            {
                public static void M(Span<int> x) => Console.Write(x[1]);
                public static void R(delegate*<int[], void> a) => a(new int[] { 1, 2, 3 });
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, TestOptions.UnsafeReleaseExe, TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (5,9): error CS8757: No overload for 'C.M(Span<int>)' matches function pointer 'delegate*<int[], void>'
            //     C.R(&C.M);
            Diagnostic(ErrorCode.ERR_MethFuncPtrMismatch, "&C.M").WithArguments("C.M(System.Span<int>)", "delegate*<int[], void>").WithLocation(5, 9));
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_Span_Implicit_ExpressionTree_01(
        [CombinatorialValues("Span", "ReadOnlySpan")] string type)
    {
        var source = $$"""
            using System;
            using System.Linq.Expressions;
 
            C.R(a => C.M(a));
 
            static class C
            {
                public static void R(Expression<Action<string[]>> e) => e.Compile()(new string[] { "a" });
                public static void M({{type}}<string> x) => Console.Write(x.Length + " " + x[0]);
            }
            """;
 
        var expectedOutput = "1 a";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", $$"""
            {
              // Code size      108 (0x6c)
              .maxstack  9
              .locals init (System.Linq.Expressions.ParameterExpression V_0)
              IL_0000:  ldtoken    "string[]"
              IL_0005:  call       "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"
              IL_000a:  ldstr      "a"
              IL_000f:  call       "System.Linq.Expressions.ParameterExpression System.Linq.Expressions.Expression.Parameter(System.Type, string)"
              IL_0014:  stloc.0
              IL_0015:  ldnull
              IL_0016:  ldtoken    "void C.M(System.{{type}}<string>)"
              IL_001b:  call       "System.Reflection.MethodBase System.Reflection.MethodBase.GetMethodFromHandle(System.RuntimeMethodHandle)"
              IL_0020:  castclass  "System.Reflection.MethodInfo"
              IL_0025:  ldc.i4.1
              IL_0026:  newarr     "System.Linq.Expressions.Expression"
              IL_002b:  dup
              IL_002c:  ldc.i4.0
              IL_002d:  ldloc.0
              IL_002e:  ldtoken    "System.{{type}}<string>"
              IL_0033:  call       "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"
              IL_0038:  ldtoken    "System.{{type}}<string> System.{{type}}<string>.op_Implicit(string[])"
              IL_003d:  ldtoken    "System.{{type}}<string>"
              IL_0042:  call       "System.Reflection.MethodBase System.Reflection.MethodBase.GetMethodFromHandle(System.RuntimeMethodHandle, System.RuntimeTypeHandle)"
              IL_0047:  castclass  "System.Reflection.MethodInfo"
              IL_004c:  call       "System.Linq.Expressions.UnaryExpression System.Linq.Expressions.Expression.Convert(System.Linq.Expressions.Expression, System.Type, System.Reflection.MethodInfo)"
              IL_0051:  stelem.ref
              IL_0052:  call       "System.Linq.Expressions.MethodCallExpression System.Linq.Expressions.Expression.Call(System.Linq.Expressions.Expression, System.Reflection.MethodInfo, params System.Linq.Expressions.Expression[])"
              IL_0057:  ldc.i4.1
              IL_0058:  newarr     "System.Linq.Expressions.ParameterExpression"
              IL_005d:  dup
              IL_005e:  ldc.i4.0
              IL_005f:  ldloc.0
              IL_0060:  stelem.ref
              IL_0061:  call       "System.Linq.Expressions.Expression<System.Action<string[]>> System.Linq.Expressions.Expression.Lambda<System.Action<string[]>>(System.Linq.Expressions.Expression, params System.Linq.Expressions.ParameterExpression[])"
              IL_0066:  call       "void C.R(System.Linq.Expressions.Expression<System.Action<string[]>>)"
              IL_006b:  ret
            }
            """);
 
        var expectedIl = $$"""
            {
              // Code size      108 (0x6c)
              .maxstack  11
              .locals init (System.Linq.Expressions.ParameterExpression V_0)
              IL_0000:  ldtoken    "string[]"
              IL_0005:  call       "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"
              IL_000a:  ldstr      "a"
              IL_000f:  call       "System.Linq.Expressions.ParameterExpression System.Linq.Expressions.Expression.Parameter(System.Type, string)"
              IL_0014:  stloc.0
              IL_0015:  ldnull
              IL_0016:  ldtoken    "void C.M(System.{{type}}<string>)"
              IL_001b:  call       "System.Reflection.MethodBase System.Reflection.MethodBase.GetMethodFromHandle(System.RuntimeMethodHandle)"
              IL_0020:  castclass  "System.Reflection.MethodInfo"
              IL_0025:  ldc.i4.1
              IL_0026:  newarr     "System.Linq.Expressions.Expression"
              IL_002b:  dup
              IL_002c:  ldc.i4.0
              IL_002d:  ldnull
              IL_002e:  ldtoken    "System.{{type}}<string> System.{{type}}<string>.op_Implicit(string[])"
              IL_0033:  ldtoken    "System.{{type}}<string>"
              IL_0038:  call       "System.Reflection.MethodBase System.Reflection.MethodBase.GetMethodFromHandle(System.RuntimeMethodHandle, System.RuntimeTypeHandle)"
              IL_003d:  castclass  "System.Reflection.MethodInfo"
              IL_0042:  ldc.i4.1
              IL_0043:  newarr     "System.Linq.Expressions.Expression"
              IL_0048:  dup
              IL_0049:  ldc.i4.0
              IL_004a:  ldloc.0
              IL_004b:  stelem.ref
              IL_004c:  call       "System.Linq.Expressions.MethodCallExpression System.Linq.Expressions.Expression.Call(System.Linq.Expressions.Expression, System.Reflection.MethodInfo, params System.Linq.Expressions.Expression[])"
              IL_0051:  stelem.ref
              IL_0052:  call       "System.Linq.Expressions.MethodCallExpression System.Linq.Expressions.Expression.Call(System.Linq.Expressions.Expression, System.Reflection.MethodInfo, params System.Linq.Expressions.Expression[])"
              IL_0057:  ldc.i4.1
              IL_0058:  newarr     "System.Linq.Expressions.ParameterExpression"
              IL_005d:  dup
              IL_005e:  ldc.i4.0
              IL_005f:  ldloc.0
              IL_0060:  stelem.ref
              IL_0061:  call       "System.Linq.Expressions.Expression<System.Action<string[]>> System.Linq.Expressions.Expression.Lambda<System.Action<string[]>>(System.Linq.Expressions.Expression, params System.Linq.Expressions.ParameterExpression[])"
              IL_0066:  call       "void C.R(System.Linq.Expressions.Expression<System.Action<string[]>>)"
              IL_006b:  ret
            }
            """;
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", expectedIl);
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", expectedIl);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Implicit_ExpressionTree_02(LanguageVersion langVersion)
    {
        var source = """
            using System;
            using System.Linq.Expressions;
 
            C.R(() => C.M(null));
 
            static class C
            {
                public static void R(Expression<Action> e) { }
                public static void M(Span<string> x) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        var verifier = CompileAndVerify(comp).VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       97 (0x61)
              .maxstack  9
              IL_0000:  ldnull
              IL_0001:  ldtoken    "void C.M(System.Span<string>)"
              IL_0006:  call       "System.Reflection.MethodBase System.Reflection.MethodBase.GetMethodFromHandle(System.RuntimeMethodHandle)"
              IL_000b:  castclass  "System.Reflection.MethodInfo"
              IL_0010:  ldc.i4.1
              IL_0011:  newarr     "System.Linq.Expressions.Expression"
              IL_0016:  dup
              IL_0017:  ldc.i4.0
              IL_0018:  ldnull
              IL_0019:  ldtoken    "string[]"
              IL_001e:  call       "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"
              IL_0023:  call       "System.Linq.Expressions.ConstantExpression System.Linq.Expressions.Expression.Constant(object, System.Type)"
              IL_0028:  ldtoken    "System.Span<string>"
              IL_002d:  call       "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"
              IL_0032:  ldtoken    "System.Span<string> System.Span<string>.op_Implicit(string[])"
              IL_0037:  ldtoken    "System.Span<string>"
              IL_003c:  call       "System.Reflection.MethodBase System.Reflection.MethodBase.GetMethodFromHandle(System.RuntimeMethodHandle, System.RuntimeTypeHandle)"
              IL_0041:  castclass  "System.Reflection.MethodInfo"
              IL_0046:  call       "System.Linq.Expressions.UnaryExpression System.Linq.Expressions.Expression.Convert(System.Linq.Expressions.Expression, System.Type, System.Reflection.MethodInfo)"
              IL_004b:  stelem.ref
              IL_004c:  call       "System.Linq.Expressions.MethodCallExpression System.Linq.Expressions.Expression.Call(System.Linq.Expressions.Expression, System.Reflection.MethodInfo, params System.Linq.Expressions.Expression[])"
              IL_0051:  call       "System.Linq.Expressions.ParameterExpression[] System.Array.Empty<System.Linq.Expressions.ParameterExpression>()"
              IL_0056:  call       "System.Linq.Expressions.Expression<System.Action> System.Linq.Expressions.Expression.Lambda<System.Action>(System.Linq.Expressions.Expression, params System.Linq.Expressions.ParameterExpression[])"
              IL_005b:  call       "void C.R(System.Linq.Expressions.Expression<System.Action>)"
              IL_0060:  ret
            }
            """);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_ReadOnlySpan_Implicit_ExpressionTree_02(LanguageVersion langVersion)
    {
        var source = """
            using System;
            using System.Linq.Expressions;
 
            C.R(() => C.M(null));
 
            static class C
            {
                public static void R(Expression<Action> e) { }
                public static void M(ReadOnlySpan<string> x) { }
            }
            """;
 
        var expectedIl = """
            {
                // Code size       97 (0x61)
                .maxstack  9
                IL_0000:  ldnull
                IL_0001:  ldtoken    "void C.M(System.ReadOnlySpan<string>)"
                IL_0006:  call       "System.Reflection.MethodBase System.Reflection.MethodBase.GetMethodFromHandle(System.RuntimeMethodHandle)"
                IL_000b:  castclass  "System.Reflection.MethodInfo"
                IL_0010:  ldc.i4.1
                IL_0011:  newarr     "System.Linq.Expressions.Expression"
                IL_0016:  dup
                IL_0017:  ldc.i4.0
                IL_0018:  ldnull
                IL_0019:  ldtoken    "string[]"
                IL_001e:  call       "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"
                IL_0023:  call       "System.Linq.Expressions.ConstantExpression System.Linq.Expressions.Expression.Constant(object, System.Type)"
                IL_0028:  ldtoken    "System.ReadOnlySpan<string>"
                IL_002d:  call       "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"
                IL_0032:  ldtoken    "System.ReadOnlySpan<string> System.ReadOnlySpan<string>.op_Implicit(string[])"
                IL_0037:  ldtoken    "System.ReadOnlySpan<string>"
                IL_003c:  call       "System.Reflection.MethodBase System.Reflection.MethodBase.GetMethodFromHandle(System.RuntimeMethodHandle, System.RuntimeTypeHandle)"
                IL_0041:  castclass  "System.Reflection.MethodInfo"
                IL_0046:  call       "System.Linq.Expressions.UnaryExpression System.Linq.Expressions.Expression.Convert(System.Linq.Expressions.Expression, System.Type, System.Reflection.MethodInfo)"
                IL_004b:  stelem.ref
                IL_004c:  call       "System.Linq.Expressions.MethodCallExpression System.Linq.Expressions.Expression.Call(System.Linq.Expressions.Expression, System.Reflection.MethodInfo, params System.Linq.Expressions.Expression[])"
                IL_0051:  call       "System.Linq.Expressions.ParameterExpression[] System.Array.Empty<System.Linq.Expressions.ParameterExpression>()"
                IL_0056:  call       "System.Linq.Expressions.Expression<System.Action> System.Linq.Expressions.Expression.Lambda<System.Action>(System.Linq.Expressions.Expression, params System.Linq.Expressions.ParameterExpression[])"
                IL_005b:  call       "void C.R(System.Linq.Expressions.Expression<System.Action>)"
                IL_0060:  ret
            }
            """;
 
        if (ExecutionConditionUtil.IsCoreClr)
        {
            var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
            var verifier = CompileAndVerify(comp).VerifyDiagnostics();
            verifier.VerifyIL("<top-level-statements-entry-point>", expectedIl);
        }
        else
        {
            // The test ReadOnlySpan source contains a non-standard operator from `string` to `ReadOnlySpan<T>`
            // which is ambiguous with the one from `T[]` to `ReadOnlySpan<T>` resulting in this slightly misleading error.
            CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
                // (4,15): error CS0037: Cannot convert null to 'ReadOnlySpan<string>' because it is a non-nullable value type
                // C.R(() => C.M(null));
                Diagnostic(ErrorCode.ERR_ValueCantBeNull, "null").WithArguments("System.ReadOnlySpan<string>").WithLocation(4, 15));
 
            var source2 = """
                namespace System;
 
                public readonly ref struct ReadOnlySpan<T>
                {
                    public static implicit operator ReadOnlySpan<T>(T[] array) => throw null;
                }
                """;
 
            var comp = CreateCompilation([source, source2], parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
            var verifier = CompileAndVerify(comp).VerifyDiagnostics();
            verifier.VerifyIL("<top-level-statements-entry-point>", expectedIl);
        }
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_Span_Implicit_ExpressionTree_03(
        [CombinatorialLangVersions] LanguageVersion langVersion,
        [CombinatorialValues("Span", "ReadOnlySpan")] string type)
    {
        var source = $$"""
            using System;
            using System.Linq.Expressions;
 
            C.R(() => C.M(default));
 
            static class C
            {
                public static void R(Expression<Action> e) => e.Compile()();
                public static void M({{type}}<string> x) => Console.Write(x.Length);
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,15): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'Span'.
            // C.R(() => C.M(default));
            Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "default").WithArguments(type).WithLocation(4, 15));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Span_ReadOnlySpan_Implicit_ExpressionTree(LanguageVersion langVersion)
    {
        var source = """
            using System;
            using System.Linq.Expressions;
 
            C.R(x => C.M(x));
 
            delegate void D(Span<string> x);
 
            static class C
            {
                public static void R(Expression<D> e) { }
                public static void M(ReadOnlySpan<string> x) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,5): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'Span'.
            // C.R(x => C.M(x));
            Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "x").WithArguments("Span").WithLocation(4, 5),
            // (4,14): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'Span'.
            // C.R(x => C.M(x));
            Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "x").WithArguments("Span").WithLocation(4, 14));
    }
 
    [Fact]
    public void Conversion_Span_ReadOnlySpan_CastUp_Implicit_ExpressionTree()
    {
        var source = """
            using System;
            using System.Linq.Expressions;
 
            C.R(x => C.M(x));
 
            delegate void D(Span<string> x);
 
            static class C
            {
                public static void R(Expression<D> e) { }
                public static void M(ReadOnlySpan<object> x) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (4,14): error CS1503: Argument 1: cannot convert from 'System.Span<string>' to 'System.ReadOnlySpan<object>'
            // C.R(x => C.M(x));
            Diagnostic(ErrorCode.ERR_BadArgType, "x").WithArguments("1", "System.Span<string>", "System.ReadOnlySpan<object>").WithLocation(4, 14));
 
        var expectedDiagnostics = new[]
        {
            // (4,5): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'Span'.
            // C.R(x => C.M(x));
            Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "x").WithArguments("Span").WithLocation(4, 5),
            // (4,14): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'Span'.
            // C.R(x => C.M(x));
            Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "x").WithArguments("Span").WithLocation(4, 14)
        };
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net90).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Implicit_ExpressionTree()
    {
        var source = """
            using System;
            using System.Linq.Expressions;
 
            C.R(x => C.M(x));
 
            delegate void D(ReadOnlySpan<string> x);
 
            static class C
            {
                public static void R(Expression<D> e) { }
                public static void M(ReadOnlySpan<object> x) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (4,14): error CS1503: Argument 1: cannot convert from 'System.ReadOnlySpan<string>' to 'System.ReadOnlySpan<object>'
            // C.R(x => C.M(x));
            Diagnostic(ErrorCode.ERR_BadArgType, "x").WithArguments("1", "System.ReadOnlySpan<string>", "System.ReadOnlySpan<object>").WithLocation(4, 14));
 
        var expectedDiagnostics = new[]
        {
            // (4,5): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'ReadOnlySpan'.
            // C.R(x => C.M(x));
            Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "x").WithArguments("ReadOnlySpan").WithLocation(4, 5),
            // (4,14): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'ReadOnlySpan'.
            // C.R(x => C.M(x));
            Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "x").WithArguments("ReadOnlySpan").WithLocation(4, 14)
        };
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net90).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_string_ReadOnlySpan_Implicit_ExpressionTree(LanguageVersion langVersion)
    {
        var source = """
            using System;
            using System.Linq.Expressions;
 
            C.R(x => C.M(x));
 
            static class C
            {
                public static void R(Expression<Action<string>> e) => e.Compile()("s");
                public static void M(ReadOnlySpan<char> x) => Console.Write(x.Length + " " + x[0]);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "1 s").VerifyDiagnostics();
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_ReadOnlySpan_Covariant(
        [CombinatorialLangVersions] LanguageVersion langVersion,
        bool cast)
    {
        var source = $$"""
            using System;
 
            class C
            {
                ReadOnlySpan<object> M(string[] x) => {{(cast ? "(ReadOnlySpan<object>)" : "")}}x;
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics();
        verifier.VerifyIL("C.M", """
            {
              // Code size        9 (0x9)
              .maxstack  1
              .locals init (object[] V_0)
              IL_0000:  ldarg.1
              IL_0001:  stloc.0
              IL_0002:  ldloc.0
              IL_0003:  call       "System.ReadOnlySpan<object> System.ReadOnlySpan<object>.op_Implicit(object[])"
              IL_0008:  ret
            }
            """);
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_ReadOnlySpan_Interface_Covariant(
        [CombinatorialLangVersions] LanguageVersion langVersion,
        bool cast)
    {
        var source = $$"""
            using System;
 
            class C
            {
                ReadOnlySpan<I<object>> M(I<string>[] x) => {{(cast ? "(ReadOnlySpan<I<object>>)" : "")}}x;
            }
 
            interface I<out T> { }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics();
        verifier.VerifyIL("C.M", """
            {
              // Code size        9 (0x9)
              .maxstack  1
              .locals init (I<object>[] V_0)
              IL_0000:  ldarg.1
              IL_0001:  stloc.0
              IL_0002:  ldloc.0
              IL_0003:  call       "System.ReadOnlySpan<I<object>> System.ReadOnlySpan<I<object>>.op_Implicit(I<object>[])"
              IL_0008:  ret
            }
            """);
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_ReadOnlySpan_Interface_Outside(
        [CombinatorialLangVersions] LanguageVersion langVersion,
        [CombinatorialValues("", "in", "out")] string variance)
    {
        var source = $$"""
            using System;
 
            class C
            {
                I<ReadOnlySpan<object>> M(I<string[]> x) => x;
            }
 
            interface I<{{variance}} T> { }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (5,29): error CS9244: The type 'ReadOnlySpan<object>' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'I<T>'
            //     I<ReadOnlySpan<object>> M(I<string[]> x) => x;
            Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "M").WithArguments("I<T>", "T", "System.ReadOnlySpan<object>").WithLocation(5, 29),
            // (5,49): error CS0266: Cannot implicitly convert type 'I<string[]>' to 'I<System.ReadOnlySpan<object>>'. An explicit conversion exists (are you missing a cast?)
            //     I<ReadOnlySpan<object>> M(I<string[]> x) => x;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("I<string[]>", "I<System.ReadOnlySpan<object>>").WithLocation(5, 49));
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_ReadOnlySpan_Interface_Outside_AllowsRefStruct(
        [CombinatorialValues("", "in", "out")] string variance)
    {
        var source = $$"""
            using System;
 
            class C
            {
                I<ReadOnlySpan<object>> M(I<string[]> x) => x;
            }
 
            interface I<{{variance}} T> where T : allows ref struct { }
            """;
        CreateCompilation(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics(
            // (5,49): error CS0266: Cannot implicitly convert type 'I<string[]>' to 'I<System.ReadOnlySpan<object>>'. An explicit conversion exists (are you missing a cast?)
            //     I<ReadOnlySpan<object>> M(I<string[]> x) => x;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("I<string[]>", "I<System.ReadOnlySpan<object>>").WithLocation(5, 49));
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_Span_Interface_Invariant(
        [CombinatorialValues("Span", "ReadOnlySpan")] string type)
    {
        var source = $$"""
            using System;
 
            class C
            {
                {{type}}<I<object>> M(I<string>[] x)
                    => x;
            }
 
            interface I<T> { }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (6,12): error CS0029: Cannot implicitly convert type 'I<string>[]' to 'System.Span<I<object>>'
            //         => x;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("I<string>[]", $"System.{type}<I<object>>").WithLocation(6, 12));
 
        var expectedDiagnostics = new[]
        {
            // (6,12): error CS0266: Cannot implicitly convert type 'I<string>[]' to 'System.Span<I<object>>'. An explicit conversion exists (are you missing a cast?)
            //         => x;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("I<string>[]", $"System.{type}<I<object>>").WithLocation(6, 12)
        };
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_Span_Interface_Cast(
        [CombinatorialValues("Span", "ReadOnlySpan")] string type)
    {
        var source = $$"""
            using System;
 
            class C
            {
                {{type}}<I<object>> M(I<string>[] x)
                    => ({{type}}<I<object>>)x;
            }
 
            interface I<T> { }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (6,12): error CS0030: Cannot convert type 'I<string>[]' to 'System.Span<I<object>>'
            //         => (Span<I<object>>)x;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, $"({type}<I<object>>)x").WithArguments("I<string>[]", $"System.{type}<I<object>>").WithLocation(6, 12));
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics();
 
        verifier.VerifyIL("C.M", $$"""
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  ldarg.1
              IL_0001:  castclass  "I<object>[]"
              IL_0006:  call       "System.{{type}}<I<object>> System.{{type}}<I<object>>.op_Implicit(I<object>[])"
              IL_000b:  ret
            }
            """);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_ReadOnlySpan_Interface_Contravariant(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            class C
            {
                ReadOnlySpan<I<object>> M(I<string>[] x) => x;
            }
 
            interface I<in T> { }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (5,49): error CS0266: Cannot implicitly convert type 'I<string>[]' to 'System.ReadOnlySpan<I<object>>'. An explicit conversion exists (are you missing a cast?)
            //     ReadOnlySpan<I<object>> M(I<string>[] x) => x;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("I<string>[]", "System.ReadOnlySpan<I<object>>").WithLocation(5, 49));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_ReadOnlySpan_Interface_Contravariant_Cast(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            C.M(new[] { new C() })[0].Report();
 
            class C : I<object>
            {
                public void Report() => Console.Write("C");
                public static ReadOnlySpan<I<object>> M(I<string>[] x) => (ReadOnlySpan<I<object>>)x;
            }
 
            interface I<in T>
            {
                void Report();
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        var verifier = CompileAndVerify(comp, expectedOutput: "C", verify: Verification.FailsILVerify).VerifyDiagnostics();
        verifier.VerifyIL("C.M", """
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  ldarg.0
              IL_0001:  castclass  "I<object>[]"
              IL_0006:  call       "System.ReadOnlySpan<I<object>> System.ReadOnlySpan<I<object>>.op_Implicit(I<object>[])"
              IL_000b:  ret
            }
            """);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_ReadOnlySpan_Covariant_ValueType(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            class C
            {
                ReadOnlySpan<long> M(int[] x) => x;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (5,38): error CS0029: Cannot implicitly convert type 'int[]' to 'System.ReadOnlySpan<long>'
            //     ReadOnlySpan<long> M(int[] x) => x;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("int[]", "System.ReadOnlySpan<long>").WithLocation(5, 38));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_ReadOnlySpan_Covariant_TypeParameter(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            class C<T, U>
                where T : class, U
            {
                ReadOnlySpan<U> M(T[] x) => x;
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics();
        verifier.VerifyIL("C<T, U>.M", """
            {
              // Code size        9 (0x9)
              .maxstack  1
              .locals init (U[] V_0)
              IL_0000:  ldarg.1
              IL_0001:  stloc.0
              IL_0002:  ldloc.0
              IL_0003:  call       "System.ReadOnlySpan<U> System.ReadOnlySpan<U>.op_Implicit(U[])"
              IL_0008:  ret
            }
            """);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_ReadOnlySpan_TypeParameter_NullableValueType_01(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            class C<T> where T : struct
            {
                ReadOnlySpan<T> M(T?[] x) => x;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (5,34): error CS0029: Cannot implicitly convert type 'T?[]' to 'System.ReadOnlySpan<T>'
            //     ReadOnlySpan<T> M(T?[] x) => x;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("T?[]", "System.ReadOnlySpan<T>").WithLocation(5, 34));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_ReadOnlySpan_TypeParameter_NullableValueType_02(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            class C<T> where T : struct
            {
                ReadOnlySpan<T?> M(T[] x) => x;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (5,34): error CS0029: Cannot implicitly convert type 'T[]' to 'System.ReadOnlySpan<T?>'
            //     ReadOnlySpan<T?> M(T[] x) => x;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("T[]", "System.ReadOnlySpan<T?>").WithLocation(5, 34));
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_Span_Variance_01(
        [CombinatorialValues("", "where U : T")] string constraints,
        [CombinatorialLangVersions] LanguageVersion langVersion)
    {
        var source = $$"""
            using System;
            class C<T, U> {{constraints}}
            {
                ReadOnlySpan<U> F1(T[] x) => x;
                ReadOnlySpan<U> F2(T[] x) => (ReadOnlySpan<U>)x;
                Span<U> F3(T[] x) => x;
                Span<U> F4(T[] x) => (Span<U>)x;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (4,34): error CS0029: Cannot implicitly convert type 'T[]' to 'System.ReadOnlySpan<U>'
            //     ReadOnlySpan<U> F1(T[] x) => x;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("T[]", "System.ReadOnlySpan<U>").WithLocation(4, 34),
            // (5,34): error CS0030: Cannot convert type 'T[]' to 'System.ReadOnlySpan<U>'
            //     ReadOnlySpan<U> F2(T[] x) => (ReadOnlySpan<U>)x;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(ReadOnlySpan<U>)x").WithArguments("T[]", "System.ReadOnlySpan<U>").WithLocation(5, 34),
            // (6,26): error CS0029: Cannot implicitly convert type 'T[]' to 'System.Span<U>'
            //     Span<U> F3(T[] x) => x;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("T[]", "System.Span<U>").WithLocation(6, 26),
            // (7,26): error CS0030: Cannot convert type 'T[]' to 'System.Span<U>'
            //     Span<U> F4(T[] x) => (Span<U>)x;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(Span<U>)x").WithArguments("T[]", "System.Span<U>").WithLocation(7, 26));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Variance_02(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C<T, U>
                where T : class
                where U : class, T
            {
                ReadOnlySpan<U> F1(T[] x) => x;
                ReadOnlySpan<U> F2(T[] x) => (ReadOnlySpan<U>)x;
                Span<U> F3(T[] x) => x;
                Span<U> F4(T[] x) => (Span<U>)x;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (6,34): error CS0266: Cannot implicitly convert type 'T[]' to 'System.ReadOnlySpan<U>'. An explicit conversion exists (are you missing a cast?)
            //     ReadOnlySpan<U> F1(T[] x) => x;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("T[]", "System.ReadOnlySpan<U>").WithLocation(6, 34),
            // (8,26): error CS0266: Cannot implicitly convert type 'T[]' to 'System.Span<U>'. An explicit conversion exists (are you missing a cast?)
            //     Span<U> F3(T[] x) => x;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("T[]", "System.Span<U>").WithLocation(8, 26));
    }
 
    [Fact]
    public void Conversion_Array_Span_Variance_03()
    {
        var source = """
            using System;
            class C<T, U>
                where T : class, U
                where U : class
            {
                ReadOnlySpan<U> F1(T[] x) => x;
                ReadOnlySpan<U> F2(T[] x) => (ReadOnlySpan<U>)x;
                Span<U> F3(T[] x) => x;
                Span<U> F4(T[] x) => (Span<U>)x;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics();
 
        // Note: although a breaking change, the previous would fail with a runtime exception
        // (Span's constructor checks that the element types are identical).
 
        var expectedDiagnostics = new[]
        {
            // (8,26): error CS0266: Cannot implicitly convert type 'T[]' to 'System.Span<U>'. An explicit conversion exists (are you missing a cast?)
            //     Span<U> F3(T[] x) => x;
            Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("T[]", "System.Span<U>").WithLocation(8, 26)
        };
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Conversion_Span_ReadOnlySpan_Variance()
    {
        var source = """
            using System;
            class C<T, U>
                where T : class
                where U : class, T
            {
                ReadOnlySpan<U> F1(Span<T> x) => x;
                ReadOnlySpan<U> F2(Span<T> x) => (ReadOnlySpan<U>)x;
                ReadOnlySpan<T> F3(Span<U> x) => x;
                ReadOnlySpan<T> F4(Span<U> x) => (ReadOnlySpan<T>)x;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics(
            // (6,38): error CS0029: Cannot implicitly convert type 'System.Span<T>' to 'System.ReadOnlySpan<U>'
            //     ReadOnlySpan<U> F1(Span<T> x) => x;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("System.Span<T>", "System.ReadOnlySpan<U>").WithLocation(6, 38),
            // (7,38): error CS0030: Cannot convert type 'System.Span<T>' to 'System.ReadOnlySpan<U>'
            //     ReadOnlySpan<U> F2(Span<T> x) => (ReadOnlySpan<U>)x;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(ReadOnlySpan<U>)x").WithArguments("System.Span<T>", "System.ReadOnlySpan<U>").WithLocation(7, 38));
    }
 
    [Fact]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_Variance()
    {
        var source = """
            using System;
            class C<T, U>
                where T : class
                where U : class, T
            {
                ReadOnlySpan<U> F1(ReadOnlySpan<T> x) => x;
                ReadOnlySpan<U> F2(ReadOnlySpan<T> x) => (ReadOnlySpan<U>)x;
                ReadOnlySpan<T> F3(ReadOnlySpan<U> x) => x;
                ReadOnlySpan<T> F4(ReadOnlySpan<U> x) => (ReadOnlySpan<T>)x;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics(
            // (6,46): error CS0029: Cannot implicitly convert type 'System.ReadOnlySpan<T>' to 'System.ReadOnlySpan<U>'
            //     ReadOnlySpan<U> F1(ReadOnlySpan<T> x) => x;
            Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("System.ReadOnlySpan<T>", "System.ReadOnlySpan<U>").WithLocation(6, 46),
            // (7,46): error CS0030: Cannot convert type 'System.ReadOnlySpan<T>' to 'System.ReadOnlySpan<U>'
            //     ReadOnlySpan<U> F2(ReadOnlySpan<T> x) => (ReadOnlySpan<U>)x;
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(ReadOnlySpan<U>)x").WithArguments("System.ReadOnlySpan<T>", "System.ReadOnlySpan<U>").WithLocation(7, 46));
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_Span_ThroughUserImplicit(
        [CombinatorialValues("Span", "ReadOnlySpan")] string destination)
    {
        var source = $$"""
            using System;
 
            D.M(new C());
 
            class C
            {
                public static implicit operator int[](C c) => new int[] { 4, 5, 6 };
            }
 
            static class D
            {
                public static void M({{destination}}<int> xs)
                {
                    foreach (var x in xs)
                    {
                        Console.Write(x);
                    }
                }
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (3,5): error CS1503: Argument 1: cannot convert from 'C' to 'System.Span<int>'
            // D.M(new C());
            Diagnostic(ErrorCode.ERR_BadArgType, "new C()").WithArguments("1", "C", $"System.{destination}<int>").WithLocation(3, 5));
 
        var expectedOutput = "456";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Fact]
    public void Conversion_Span_ReadOnlySpan_ThroughUserImplicit()
    {
        var source = """
            using System;
 
            D.M(new C());
 
            class C
            {
                public static implicit operator Span<int>(C c) => new Span<int>(new int[] { 4, 5, 6 });
            }
 
            static class D
            {
                public static void M(ReadOnlySpan<int> xs) => Console.Write(xs.Length + " " + xs[0]);
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (3,5): error CS1503: Argument 1: cannot convert from 'C' to 'System.ReadOnlySpan<int>'
            // D.M(new C());
            Diagnostic(ErrorCode.ERR_BadArgType, "new C()").WithArguments("1", "C", "System.ReadOnlySpan<int>").WithLocation(3, 5));
 
        var expectedOutput = "3 4";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify).VerifyDiagnostics();
    }
 
    [Fact]
    public void Conversion_Span_ReadOnlySpan_CastUp_ThroughUserImplicit()
    {
        var source = """
            using System;
 
            D.M(new C());
 
            class C
            {
                public static implicit operator Span<string>(C c) => new Span<string>(new string[] { "x" });
            }
 
            static class D
            {
                public static void M(ReadOnlySpan<object> xs) => Console.Write(xs.Length + " " + xs[0]);
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (3,5): error CS1503: Argument 1: cannot convert from 'C' to 'System.ReadOnlySpan<object>'
            // D.M(new C());
            Diagnostic(ErrorCode.ERR_BadArgType, "new C()").WithArguments("1", "C", "System.ReadOnlySpan<object>").WithLocation(3, 5));
 
        var expectedOutput = "1 x";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net90);
        CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90);
        CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify).VerifyDiagnostics();
    }
 
    [Fact]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_ThroughUserImplicit()
    {
        var source = """
            using System;
 
            D.M(new C());
 
            class C
            {
                public static implicit operator ReadOnlySpan<string>(C c) => new ReadOnlySpan<string>(new string[] { "x" });
            }
 
            static class D
            {
                public static void M(ReadOnlySpan<object> xs) => Console.Write(xs.Length + " " + xs[0]);
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (3,5): error CS1503: Argument 1: cannot convert from 'C' to 'System.ReadOnlySpan<object>'
            // D.M(new C());
            Diagnostic(ErrorCode.ERR_BadArgType, "new C()").WithArguments("1", "C", "System.ReadOnlySpan<object>").WithLocation(3, 5));
 
        var expectedOutput = "1 x";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net90);
        CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90);
        CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify).VerifyDiagnostics();
    }
 
    [Fact]
    public void Conversion_string_ReadOnlySpan_ThroughUserImplicit()
    {
        var source = """
            using System;
 
            D.M(new C());
 
            class C
            {
                public static implicit operator string(C c) => "x";
            }
 
            static class D
            {
                public static void M(ReadOnlySpan<char> xs) => Console.Write(xs.Length + " " + xs[0]);
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (3,5): error CS1503: Argument 1: cannot convert from 'C' to 'System.ReadOnlySpan<char>'
            // D.M(new C());
            Diagnostic(ErrorCode.ERR_BadArgType, "new C()").WithArguments("1", "C", "System.ReadOnlySpan<char>").WithLocation(3, 5));
 
        var expectedOutput = "1 x";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_Span_ThroughUserImplicit_Cast_01(
        [CombinatorialValues("Span", "ReadOnlySpan")] string destination,
        [CombinatorialValues("implicit", "explicit")] string op)
    {
        var source = $$"""
            using System;
 
            D.M(({{destination}}<int>)new C());
 
            class C
            {
                public static {{op}} operator int[](C c) => new int[] { 4, 5, 6 };
            }
 
            static class D
            {
                public static void M({{destination}}<int> xs)
                {
                    foreach (var x in xs)
                    {
                        Console.Write(x);
                    }
                }
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (3,5): error CS0030: Cannot convert type 'C' to 'System.Span<int>'
            // D.M((Span<int>)new C());
            Diagnostic(ErrorCode.ERR_NoExplicitConv, $"({destination}<int>)new C()").WithArguments("C", $"System.{destination}<int>").WithLocation(3, 5));
 
        var expectedOutput = "456";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_Span_ThroughUserImplicit_Cast_02(
        [CombinatorialValues("Span", "ReadOnlySpan")] string destination,
        [CombinatorialValues("implicit", "explicit")] string op,
        [CombinatorialLangVersions] LanguageVersion langVersion)
    {
        var source = $$"""
            using System;
 
            D.M((int[])new C());
 
            class C
            {
                public static {{op}} operator int[](C c) => new int[] { 4, 5, 6 };
            }
 
            static class D
            {
                public static void M({{destination}}<int> xs)
                {
                    foreach (var x in xs)
                    {
                        Console.Write(x);
                    }
                }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "456").VerifyDiagnostics();
    }
 
    [Fact]
    public void Conversion_Array_Span_ThroughUserImplicit_MissingHelper()
    {
        var source = """
            using System;
 
            D.M(new C());
 
            class C
            {
                public static implicit operator int[](C c) => new int[] { 4, 5, 6 };
            }
 
            static class D
            {
                public static void M(Span<int> xs) { }
            }
            """;
 
        var missingRosHelper = """
            namespace System
            {
                public readonly ref struct Span<T>
                {
                    public static implicit operator Span<T>(T[] array) => throw null;
                }
                public readonly ref struct ReadOnlySpan<T>
                {
                }
            }
            """;
 
        var missingSpanHelper = """
            namespace System
            {
                public readonly ref struct Span<T>
                {
                }
                public readonly ref struct ReadOnlySpan<T>
                {
                    public static implicit operator ReadOnlySpan<T>(T[] array) => throw null;
                }
            }
            """;
 
        var expectedDiagnostics = new[]
        {
            // (3,5): error CS1503: Argument 1: cannot convert from 'C' to 'System.Span<int>'
            // D.M(new C());
            Diagnostic(ErrorCode.ERR_BadArgType, "new C()").WithArguments("1", "C", "System.Span<int>").WithLocation(3, 5)
        };
 
        verifyWithMissing(missingRosHelper, TestOptions.Regular13, expectedDiagnostics);
        verifyWithMissing(missingSpanHelper, TestOptions.Regular13, expectedDiagnostics);
 
        expectedDiagnostics = [
            // (3,5): error CS0656: Missing compiler required member 'System.Span<T>.op_Implicit'
            // D.M(new C());
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "new C()").WithArguments("System.Span<T>", "op_Implicit").WithLocation(3, 5)
        ];
 
        verifyWithMissing(missingRosHelper, TestOptions.RegularNext);
        verifyWithMissing(missingSpanHelper, TestOptions.RegularNext, expectedDiagnostics);
 
        verifyWithMissing(missingRosHelper, TestOptions.RegularPreview);
        verifyWithMissing(missingSpanHelper, TestOptions.RegularPreview, expectedDiagnostics);
 
        void verifyWithMissing(string source2, CSharpParseOptions parseOptions, params DiagnosticDescription[] expected)
        {
            CreateCompilation([source, source2], parseOptions: parseOptions).VerifyDiagnostics(expected);
        }
    }
 
    [Fact]
    public void Conversion_Array_ReadOnlySpan_ThroughUserImplicit_MissingHelper()
    {
        var source = """
            using System;
 
            D.M(new C());
 
            class C
            {
                public static implicit operator int[](C c) => new int[] { 4, 5, 6 };
            }
 
            static class D
            {
                public static void M(ReadOnlySpan<int> xs) { }
            }
            """;
 
        var missingRosHelper = """
            namespace System
            {
                public readonly ref struct Span<T>
                {
                    public static implicit operator Span<T>(T[] array) => throw null;
                }
                public readonly ref struct ReadOnlySpan<T>
                {
                }
            }
            """;
 
        var missingSpanHelper = """
            namespace System
            {
                public readonly ref struct Span<T>
                {
                }
                public readonly ref struct ReadOnlySpan<T>
                {
                    public static implicit operator ReadOnlySpan<T>(T[] array) => throw null;
                }
            }
            """;
 
        var expectedDiagnostics = new[]
        {
            // (3,5): error CS1503: Argument 1: cannot convert from 'C' to 'System.ReadOnlySpan<int>'
            // D.M(new C());
            Diagnostic(ErrorCode.ERR_BadArgType, "new C()").WithArguments("1", "C", "System.ReadOnlySpan<int>").WithLocation(3, 5)
        };
 
        verifyWithMissing(missingRosHelper, TestOptions.Regular13, expectedDiagnostics);
        verifyWithMissing(missingSpanHelper, TestOptions.Regular13, expectedDiagnostics);
 
        expectedDiagnostics = [
            // (3,5): error CS0656: Missing compiler required member 'System.ReadOnlySpan<T>.op_Implicit'
            // D.M(new C());
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "new C()").WithArguments("System.ReadOnlySpan<T>", "op_Implicit").WithLocation(3, 5)
        ];
 
        verifyWithMissing(missingRosHelper, TestOptions.RegularNext, expectedDiagnostics);
        verifyWithMissing(missingSpanHelper, TestOptions.RegularNext);
 
        verifyWithMissing(missingRosHelper, TestOptions.RegularPreview, expectedDiagnostics);
        verifyWithMissing(missingSpanHelper, TestOptions.RegularPreview);
 
        void verifyWithMissing(string source2, CSharpParseOptions parseOptions, params DiagnosticDescription[] expected)
        {
            CreateCompilation([source, source2], parseOptions: parseOptions).VerifyDiagnostics(expected);
        }
    }
 
    [Fact]
    public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit()
    {
        var source = """
            using System;
 
            C.M(new int[] { 7, 8, 9 });
 
            static class C
            {
                public static void M(int[] arg) => arg.E();
                public static void E(this Span<int> arg) => Console.Write(arg[1]);
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (7,40): error CS1929: 'int[]' does not contain a definition for 'E' and the best extension method overload 'C.E(Span<int>)' requires a receiver of type 'System.Span<int>'
            //     public static void M(int[] arg) => arg.E();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("int[]", "E", "C.E(System.Span<int>)", "System.Span<int>").WithLocation(7, 40));
 
        var expectedOutput = "8";
 
        var expectedIl = """
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  ldarg.0
              IL_0001:  call       "System.Span<int> System.Span<int>.op_Implicit(int[])"
              IL_0006:  call       "void C.E(System.Span<int>)"
              IL_000b:  ret
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
    }
 
    [Fact]
    public void Conversion_Span_ReadOnlySpan_ExtensionMethodReceiver_Implicit()
    {
        var source = """
            using System;
 
            C.M(new Span<int>(new int[] { 7, 8, 9 }));
 
            static class C
            {
                public static void M(Span<int> arg) => arg.E();
                public static void E(this ReadOnlySpan<int> arg) => Console.Write(arg[1]);
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (7,44): error CS1929: 'Span<int>' does not contain a definition for 'E' and the best extension method overload 'C.E(ReadOnlySpan<int>)' requires a receiver of type 'System.ReadOnlySpan<int>'
            //     public static void M(Span<int> arg) => arg.E();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("System.Span<int>", "E", "C.E(System.ReadOnlySpan<int>)", "System.ReadOnlySpan<int>").WithLocation(7, 44));
 
        var expectedOutput = "8";
 
        var expectedIl = """
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  ldarg.0
              IL_0001:  call       "System.ReadOnlySpan<int> System.Span<int>.op_Implicit(System.Span<int>)"
              IL_0006:  call       "void C.E(System.ReadOnlySpan<int>)"
              IL_000b:  ret
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
    }
 
    [Fact]
    public void Conversion_Span_ReadOnlySpan_CastUp_ExtensionMethodReceiver_Implicit()
    {
        var source = """
            using System;
 
            C.M(new Span<string>(new string[] { "x", "y" }));
 
            static class C
            {
                public static void M(Span<string> arg) => arg.E();
                public static void E(this ReadOnlySpan<object> arg) => Console.Write(arg[1]);
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (7,47): error CS1929: 'Span<string>' does not contain a definition for 'E' and the best extension method overload 'C.E(ReadOnlySpan<object>)' requires a receiver of type 'System.ReadOnlySpan<object>'
            //     public static void M(Span<string> arg) => arg.E();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("System.Span<string>", "E", "C.E(System.ReadOnlySpan<object>)", "System.ReadOnlySpan<object>").WithLocation(7, 47));
 
        var expectedOutput = "y";
 
        var expectedIl = """
            {
              // Code size       17 (0x11)
              .maxstack  1
              IL_0000:  ldarg.0
              IL_0001:  call       "System.ReadOnlySpan<string> System.Span<string>.op_Implicit(System.Span<string>)"
              IL_0006:  call       "System.ReadOnlySpan<object> System.ReadOnlySpan<object>.CastUp<string>(System.ReadOnlySpan<string>)"
              IL_000b:  call       "void C.E(System.ReadOnlySpan<object>)"
              IL_0010:  ret
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net90);
        var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90);
        verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
    }
 
    [Fact]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_ExtensionMethodReceiver_Implicit()
    {
        var source = """
            using System;
 
            C.M(new ReadOnlySpan<string>(new string[] { "x", "y" }));
 
            static class C
            {
                public static void M(ReadOnlySpan<string> arg) => arg.E();
                public static void E(this ReadOnlySpan<object> arg) => Console.Write(arg[1]);
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (7,55): error CS1929: 'ReadOnlySpan<string>' does not contain a definition for 'E' and the best extension method overload 'C.E(ReadOnlySpan<object>)' requires a receiver of type 'System.ReadOnlySpan<object>'
            //     public static void M(ReadOnlySpan<string> arg) => arg.E();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("System.ReadOnlySpan<string>", "E", "C.E(System.ReadOnlySpan<object>)", "System.ReadOnlySpan<object>").WithLocation(7, 55));
 
        var expectedOutput = "y";
 
        var expectedIl = """
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  ldarg.0
              IL_0001:  call       "System.ReadOnlySpan<object> System.ReadOnlySpan<object>.CastUp<string>(System.ReadOnlySpan<string>)"
              IL_0006:  call       "void C.E(System.ReadOnlySpan<object>)"
              IL_000b:  ret
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net90);
        var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90);
        verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
    }
 
    [Fact]
    public void Conversion_string_ReadOnlySpan_ExtensionMethodReceiver_Implicit()
    {
        var source = """
            using System;
 
            C.M("xyz");
 
            static class C
            {
                public static void M(string arg) => arg.E();
                public static void E(this ReadOnlySpan<char> arg) => Console.Write(arg[1]);
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (7,41): error CS1929: 'string' does not contain a definition for 'E' and the best extension method overload 'C.E(ReadOnlySpan<char>)' requires a receiver of type 'System.ReadOnlySpan<char>'
            //     public static void M(string arg) => arg.E();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("string", "E", "C.E(System.ReadOnlySpan<char>)", "System.ReadOnlySpan<char>").WithLocation(7, 41));
 
        var expectedOutput = "y";
 
        var expectedIl = """
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  ldarg.0
              IL_0001:  call       "System.ReadOnlySpan<char> System.MemoryExtensions.AsSpan(string)"
              IL_0006:  call       "void C.E(System.ReadOnlySpan<char>)"
              IL_000b:  ret
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit_Ref(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            C.M(new int[] { 7, 8, 9 });
 
            static class C
            {
                public static void M(int[] arg) => arg.E();
                public static void E(this ref Span<int> arg) => Console.Write(arg[1]);
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (7,40): error CS1929: 'int[]' does not contain a definition for 'E' and the best extension method overload 'C.E(ref Span<int>)' requires a receiver of type 'ref System.Span<int>'
            //     public static void M(int[] arg) => arg.E();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("int[]", "E", "C.E(ref System.Span<int>)", "ref System.Span<int>").WithLocation(7, 40));
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit_RefReadOnly(
        [CombinatorialValues("ref readonly", "in")] string modifier)
    {
        var source = $$"""
            using System;
 
            C.M(new int[] { 7, 8, 9 });
 
            static class C
            {
                public static void M(int[] arg) => arg.E();
                public static void E(this {{modifier}} Span<int> arg) => Console.Write(arg[1]);
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (7,40): error CS1929: 'int[]' does not contain a definition for 'E' and the best extension method overload 'C.E(ref Span<int>)' requires a receiver of type 'ref System.Span<int>'
            //     public static void M(int[] arg) => arg.E();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("int[]", "E", $"C.E({modifier} System.Span<int>)", $"{modifier} System.Span<int>").WithLocation(7, 40));
 
        var expectedOutput = "8";
 
        var expectedIl = $$"""
            {
              // Code size       15 (0xf)
              .maxstack  1
              .locals init (System.Span<int> V_0)
              IL_0000:  ldarg.0
              IL_0001:  call       "System.Span<int> System.Span<int>.op_Implicit(int[])"
              IL_0006:  stloc.0
              IL_0007:  ldloca.s   V_0
              IL_0009:  call       "void C.E({{modifier}} System.Span<int>)"
              IL_000e:  ret
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
    }
 
    [Fact]
    public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit_MissingHelper()
    {
        var source = """
            using System;
            
            C.M(new int[] { 7, 8, 9 });
            
            static class C
            {
                public static void M(int[] arg) => arg.E();
                public static void E(this Span<int> arg) { }
            }
            
            namespace System
            {
                public readonly ref struct Span<T>
                {
                }
            }
            """;
        CreateCompilation(source).VerifyDiagnostics(
            // (7,40): error CS0656: Missing compiler required member 'System.Span<T>.op_Implicit'
            //     public static void M(int[] arg) => arg.E();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "arg").WithArguments("System.Span<T>", "op_Implicit").WithLocation(7, 40));
    }
 
    [Fact]
    public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit_Generic_01()
    {
        var source = """
            using System;
            static class C
            {
                public static void M(int[] arg) => arg.E();
                public static void E<T>(this Span<T> arg) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (4,44): error CS1061: 'int[]' does not contain a definition for 'E' and no accessible extension method 'E' accepting a first argument of type 'int[]' could be found (are you missing a using directive or an assembly reference?)
            //     public static void M(int[] arg) => arg.E();
            Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "E").WithArguments("int[]", "E").WithLocation(4, 44));
 
        var expectedIl = """
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  ldarg.0
              IL_0001:  call       "System.Span<int> System.Span<int>.op_Implicit(int[])"
              IL_0006:  call       "void C.E<int>(System.Span<int>)"
              IL_000b:  ret
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp).VerifyDiagnostics().VerifyIL("C.M", expectedIl);
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp).VerifyDiagnostics().VerifyIL("C.M", expectedIl);
    }
 
    [Fact]
    public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit_Generic_02()
    {
        var source = """
            using System;
            static class C
            {
                public static void M(int[] arg) => arg.E<int>();
                public static void E<T>(this Span<T> arg) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        var verifier = CompileAndVerify(comp).VerifyDiagnostics();
        verifier.VerifyIL("C.M", """
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  ldarg.0
              IL_0001:  call       "System.Span<int> System.Span<int>.op_Implicit(int[])"
              IL_0006:  call       "void C.E<int>(System.Span<int>)"
              IL_000b:  ret
            }
            """);
 
        var tree = comp.SyntaxTrees.Single();
        var invocation = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
        Assert.Equal("arg.E<int>()", invocation.ToString());
 
        var model = comp.GetSemanticModel(tree);
        var info = model.GetSymbolInfo(invocation);
        Assert.Equal("void System.Span<System.Int32>.E<System.Int32>()", info.Symbol!.ToTestDisplayString());
 
        var methodSymbol = (IMethodSymbol)info.Symbol!;
        var spanType = methodSymbol.ReceiverType!;
        Assert.Equal("System.Span<System.Int32>", spanType.ToTestDisplayString());
 
        // Reduce the extension method with Span receiver.
        var unreducedSymbol = methodSymbol.ReducedFrom!;
        var reduced = unreducedSymbol.ReduceExtensionMethod(spanType);
        Assert.Equal(methodSymbol, reduced);
 
        var arrayType = comp.GetMember<MethodSymbol>("C.M").GetPublicSymbol().Parameters.Single().Type;
        Assert.Equal("System.Int32[]", arrayType.ToTestDisplayString());
 
        // Reduce the extension method with array receiver.
        reduced = unreducedSymbol.ReduceExtensionMethod(arrayType);
        Assert.Equal("void System.Span<System.Int32>.E<System.Int32>()", reduced.ToTestDisplayString());
    }
 
    [Fact]
    public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit_Generic_03()
    {
        var source = """
            using System;
            static class C
            {
                public static void M(int[] arg) => arg.E(42);
                public static void E<T>(this Span<T> arg, T x) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        var verifier = CompileAndVerify(comp).VerifyDiagnostics();
        verifier.VerifyIL("C.M", """
            {
              // Code size       14 (0xe)
              .maxstack  2
              IL_0000:  ldarg.0
              IL_0001:  call       "System.Span<int> System.Span<int>.op_Implicit(int[])"
              IL_0006:  ldc.i4.s   42
              IL_0008:  call       "void C.E<int>(System.Span<int>, int)"
              IL_000d:  ret
            }
            """);
 
        var tree = comp.SyntaxTrees.Single();
        var invocation = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
        Assert.Equal("arg.E(42)", invocation.ToString());
 
        var model = comp.GetSemanticModel(tree);
        var info = model.GetSymbolInfo(invocation);
        Assert.Equal("void System.Span<System.Int32>.E<System.Int32>(System.Int32 x)", info.Symbol!.ToTestDisplayString());
 
        var methodSymbol = (IMethodSymbol)info.Symbol!;
        var spanType = methodSymbol.ReceiverType!;
        Assert.Equal("System.Span<System.Int32>", spanType.ToTestDisplayString());
 
        // Reduce the extension method with Span receiver.
        var unreducedSymbol = methodSymbol.ReducedFrom!;
        var reduced = unreducedSymbol.ReduceExtensionMethod(spanType);
        Assert.Equal(methodSymbol, reduced);
 
        var arrayType = comp.GetMember<MethodSymbol>("C.M").GetPublicSymbol().Parameters.Single().Type;
        Assert.Equal("System.Int32[]", arrayType.ToTestDisplayString());
 
        // Reduce the extension method with array receiver.
        reduced = unreducedSymbol.ReduceExtensionMethod(arrayType);
        Assert.Equal("void System.Span<System.Int32>.E<System.Int32>(System.Int32 x)", reduced.ToTestDisplayString());
    }
 
    [Fact]
    public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit_Generic_04()
    {
        var source = """
            using System;
            static class C
            {
                public static void M(int[] arg) => arg.E<int>(42);
                public static void E<T>(this Span<T> arg, T x) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        var verifier = CompileAndVerify(comp).VerifyDiagnostics();
        verifier.VerifyIL("C.M", """
            {
              // Code size       14 (0xe)
              .maxstack  2
              IL_0000:  ldarg.0
              IL_0001:  call       "System.Span<int> System.Span<int>.op_Implicit(int[])"
              IL_0006:  ldc.i4.s   42
              IL_0008:  call       "void C.E<int>(System.Span<int>, int)"
              IL_000d:  ret
            }
            """);
 
        var tree = comp.SyntaxTrees.Single();
        var invocation = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
        Assert.Equal("arg.E<int>(42)", invocation.ToString());
 
        var model = comp.GetSemanticModel(tree);
        var info = model.GetSymbolInfo(invocation);
        Assert.Equal("void System.Span<System.Int32>.E<System.Int32>(System.Int32 x)", info.Symbol!.ToTestDisplayString());
 
        var methodSymbol = (IMethodSymbol)info.Symbol!;
        var spanType = methodSymbol.ReceiverType!;
        Assert.Equal("System.Span<System.Int32>", spanType.ToTestDisplayString());
 
        // Reduce the extension method with Span receiver.
        var unreducedSymbol = methodSymbol.ReducedFrom!;
        var reduced = unreducedSymbol.ReduceExtensionMethod(spanType);
        Assert.Equal(methodSymbol, reduced);
 
        var arrayType = comp.GetMember<MethodSymbol>("C.M").GetPublicSymbol().Parameters.Single().Type;
        Assert.Equal("System.Int32[]", arrayType.ToTestDisplayString());
 
        // Reduce the extension method with array receiver.
        reduced = unreducedSymbol.ReduceExtensionMethod(arrayType);
        Assert.Equal("void System.Span<System.Int32>.E<System.Int32>(System.Int32 x)", reduced.ToTestDisplayString());
    }
 
    [Fact]
    public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit_Generic_05()
    {
        var source = """
            using System;
            static class C
            {
                public static void M(int[] arg) => arg.E("abc");
                public static void E<T>(this Span<int> arg, T x) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        var verifier = CompileAndVerify(comp).VerifyDiagnostics();
        verifier.VerifyIL("C.M", """
            {
              // Code size       17 (0x11)
              .maxstack  2
              IL_0000:  ldarg.0
              IL_0001:  call       "System.Span<int> System.Span<int>.op_Implicit(int[])"
              IL_0006:  ldstr      "abc"
              IL_000b:  call       "void C.E<string>(System.Span<int>, string)"
              IL_0010:  ret
            }
            """);
 
        var tree = comp.SyntaxTrees.Single();
        var invocation = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
        Assert.Equal("""arg.E("abc")""", invocation.ToString());
 
        var model = comp.GetSemanticModel(tree);
        var info = model.GetSymbolInfo(invocation);
        Assert.Equal("void System.Span<System.Int32>.E<System.String>(System.String x)", info.Symbol!.ToTestDisplayString());
 
        var methodSymbol = (IMethodSymbol)info.Symbol!;
        var spanType = methodSymbol.ReceiverType!;
        Assert.Equal("System.Span<System.Int32>", spanType.ToTestDisplayString());
 
        // Reduce the extension method with Span receiver.
        var unreducedSymbol = methodSymbol.ReducedFrom!;
        var reduced = unreducedSymbol.ReduceExtensionMethod(spanType);
        Assert.Equal("void System.Span<System.Int32>.E<T>(T x)", reduced.ToTestDisplayString());
 
        var arrayType = comp.GetMember<MethodSymbol>("C.M").GetPublicSymbol().Parameters.Single().Type;
        Assert.Equal("System.Int32[]", arrayType.ToTestDisplayString());
 
        // Reduce the extension method with array receiver.
        reduced = unreducedSymbol.ReduceExtensionMethod(arrayType);
        Assert.Equal("void System.Span<System.Int32>.E<T>(T x)", reduced.ToTestDisplayString());
    }
 
    [Fact]
    public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit_Reduced_01()
    {
        var source = """
            using System;
            static class C
            {
                public static void M(int[] arg) => arg.E();
                public static void E(this Span<int> arg) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        var verifier = CompileAndVerify(comp).VerifyDiagnostics();
        verifier.VerifyIL("C.M", """
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  ldarg.0
              IL_0001:  call       "System.Span<int> System.Span<int>.op_Implicit(int[])"
              IL_0006:  call       "void C.E(System.Span<int>)"
              IL_000b:  ret
            }
            """);
 
        var tree = comp.SyntaxTrees.Single();
        var invocation = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
        Assert.Equal("arg.E()", invocation.ToString());
 
        var model = comp.GetSemanticModel(tree);
        var info = model.GetSymbolInfo(invocation);
        Assert.Equal("void System.Span<System.Int32>.E()", info.Symbol!.ToTestDisplayString());
 
        var methodSymbol = (IMethodSymbol)info.Symbol!;
        var spanType = methodSymbol.ReceiverType!;
        Assert.Equal("System.Span<System.Int32>", spanType.ToTestDisplayString());
 
        // Reduce the extension method with Span receiver.
        var unreducedSymbol = methodSymbol.ReducedFrom!;
        var reduced = unreducedSymbol.ReduceExtensionMethod(spanType);
        Assert.Equal("void System.Span<System.Int32>.E()", reduced.ToTestDisplayString());
 
        var arrayType = comp.GetMember<MethodSymbol>("C.M").GetPublicSymbol().Parameters.Single().Type;
        Assert.Equal("System.Int32[]", arrayType.ToTestDisplayString());
 
        // Reduce the extension method with array receiver.
        reduced = unreducedSymbol.ReduceExtensionMethod(arrayType);
        Assert.Equal("void System.Span<System.Int32>.E()", reduced.ToTestDisplayString());
    }
 
    [Fact]
    public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit_Reduced_01_CSharp13()
    {
        var source = """
            using System;
            static class C
            {
                public static void M(int[] arg) => arg.E();
                public static void E(this Span<int> arg) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (4,40): error CS1929: 'int[]' does not contain a definition for 'E' and the best extension method overload 'C.E(Span<int>)' requires a receiver of type 'System.Span<int>'
            //     public static void M(int[] arg) => arg.E();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("int[]", "E", "C.E(System.Span<int>)", "System.Span<int>").WithLocation(4, 40));
 
        var tree = comp.SyntaxTrees.Single();
        var invocation = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
        Assert.Equal("arg.E()", invocation.ToString());
 
        var model = comp.GetSemanticModel(tree);
        Assert.Null(model.GetSymbolInfo(invocation).Symbol);
 
        var methodSymbol = comp.GetMember<MethodSymbol>("C.E").GetPublicSymbol();
        var spanType = methodSymbol.Parameters.Single().Type;
        Assert.Equal("System.Span<System.Int32>", spanType.ToTestDisplayString());
 
        // Reduce the extension method with Span receiver.
        var reduced = methodSymbol.ReduceExtensionMethod(spanType);
        Assert.Equal("void System.Span<System.Int32>.E()", reduced.ToTestDisplayString());
 
        var arrayType = comp.GetMember<MethodSymbol>("C.M").GetPublicSymbol().Parameters.Single().Type;
        Assert.Equal("System.Int32[]", arrayType.ToTestDisplayString());
 
        // Reduce the extension method with array receiver.
        reduced = methodSymbol.ReduceExtensionMethod(arrayType);
        Assert.Equal("void System.Span<System.Int32>.E()", reduced.ToTestDisplayString());
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_ExtensionMethodReceiver_Explicit(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            C.M(new int[] { 7, 8, 9 });
 
            static class C
            {
                public static void M(int[] arg) => ((Span<int>)arg).E();
                public static void E(this Span<int> arg) => Console.Write(arg[1]);
            }
            """;
 
        var expectedOutput = "8";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        verifier.VerifyIL("C.M", """
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  ldarg.0
              IL_0001:  call       "System.Span<int> System.Span<int>.op_Implicit(int[])"
              IL_0006:  call       "void C.E(System.Span<int>)"
              IL_000b:  ret
            }
            """);
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_ExtensionMethodReceiver_Opposite_Implicit(LanguageVersion langVersion)
    {
        var source = """
            static class C
            {
                static void M1(System.Span<int> arg) => arg.E1();
                static void M2(System.ReadOnlySpan<int> arg) => arg.E1();
                static void M3(System.ReadOnlySpan<string> arg) => arg.E2();
                static void M4(System.ReadOnlySpan<object> arg) => arg.E3();
                static void E1(this int[] arg) { }
                static void E2(this object[] arg) { }
                static void E3(this string[] arg) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (3,45): error CS1929: 'Span<int>' does not contain a definition for 'E1' and the best extension method overload 'C.E1(int[])' requires a receiver of type 'int[]'
            //     static void M1(System.Span<int> arg) => arg.E1();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("System.Span<int>", "E1", "C.E1(int[])", "int[]").WithLocation(3, 45),
            // (4,53): error CS1929: 'ReadOnlySpan<int>' does not contain a definition for 'E1' and the best extension method overload 'C.E1(int[])' requires a receiver of type 'int[]'
            //     static void M2(System.ReadOnlySpan<int> arg) => arg.E1();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("System.ReadOnlySpan<int>", "E1", "C.E1(int[])", "int[]").WithLocation(4, 53),
            // (5,56): error CS1929: 'ReadOnlySpan<string>' does not contain a definition for 'E2' and the best extension method overload 'C.E2(object[])' requires a receiver of type 'object[]'
            //     static void M3(System.ReadOnlySpan<string> arg) => arg.E2();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("System.ReadOnlySpan<string>", "E2", "C.E2(object[])", "object[]").WithLocation(5, 56),
            // (6,56): error CS1929: 'ReadOnlySpan<object>' does not contain a definition for 'E3' and the best extension method overload 'C.E3(string[])' requires a receiver of type 'string[]'
            //     static void M4(System.ReadOnlySpan<object> arg) => arg.E3();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("System.ReadOnlySpan<object>", "E3", "C.E3(string[])", "string[]").WithLocation(6, 56));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_ExtensionMethodReceiver_Opposite_Explicit(LanguageVersion langVersion)
    {
        var source = """
            static class C
            {
                static void M1(System.Span<int> arg) => ((int[])arg).E1();
                static void M2(System.ReadOnlySpan<int> arg) => ((int[])arg).E1();
                static void M3(System.ReadOnlySpan<string> arg) => ((object[])arg).E2();
                static void M4(System.ReadOnlySpan<object> arg) => ((string[])arg).E3();
                static void E1(this int[] arg) { }
                static void E2(this object[] arg) { }
                static void E3(this string[] arg) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
            // (3,46): error CS0030: Cannot convert type 'System.Span<int>' to 'int[]'
            //     static void M1(System.Span<int> arg) => ((int[])arg).E1();
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(int[])arg").WithArguments("System.Span<int>", "int[]").WithLocation(3, 46),
            // (4,54): error CS0030: Cannot convert type 'System.ReadOnlySpan<int>' to 'int[]'
            //     static void M2(System.ReadOnlySpan<int> arg) => ((int[])arg).E1();
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(int[])arg").WithArguments("System.ReadOnlySpan<int>", "int[]").WithLocation(4, 54),
            // (5,57): error CS0030: Cannot convert type 'System.ReadOnlySpan<string>' to 'object[]'
            //     static void M3(System.ReadOnlySpan<string> arg) => ((object[])arg).E2();
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(object[])arg").WithArguments("System.ReadOnlySpan<string>", "object[]").WithLocation(5, 57),
            // (6,57): error CS0030: Cannot convert type 'System.ReadOnlySpan<object>' to 'string[]'
            //     static void M4(System.ReadOnlySpan<object> arg) => ((string[])arg).E3();
            Diagnostic(ErrorCode.ERR_NoExplicitConv, "(string[])arg").WithArguments("System.ReadOnlySpan<object>", "string[]").WithLocation(6, 57));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_ExtensionMethodReceiver_Opposite_Explicit_UserDefined(LanguageVersion langVersion)
    {
        var source = """
            static class C
            {
                static void M(System.Span<int> arg) => ((int[])arg).E();
                static void E(this int[] arg) { }
            }
 
            namespace System
            {
                readonly ref struct Span<T>
                {
                    public static explicit operator T[](Span<T> span) => throw null;
                }
            }
            """;
        var verifier = CompileAndVerify(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.M", """
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  ldarg.0
              IL_0001:  call       "int[] System.Span<int>.op_Explicit(System.Span<int>)"
              IL_0006:  call       "void C.E(int[])"
              IL_000b:  ret
            }
            """);
    }
 
    [Theory]
    [InlineData("")]
    [InlineData("where U : T")]
    [InlineData("where T : class  where U : class, T")]
    public void Conversion_Array_Span_ExtensionMethodReceiver_Variance_01(string constraints)
    {
        var source = $$"""
            using System;
            static class Extensions
            {
                public static void M1<T>(this Span<T> arg) { }
                public static void M2<T>(this ReadOnlySpan<T> arg) { }
            }
            class C<T, U> {{constraints}}
            {
                static void F1(T[] a)
                {
                    a.M1<U>();
                    a.M2<U>();
                }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(
            // (11,9): error CS1929: 'T[]' does not contain a definition for 'M1' and the best extension method overload 'Extensions.M1<U>(Span<U>)' requires a receiver of type 'System.Span<U>'
            //         a.M1<U>();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "a").WithArguments("T[]", "M1", "Extensions.M1<U>(System.Span<U>)", "System.Span<U>").WithLocation(11, 9),
            // (12,9): error CS1929: 'T[]' does not contain a definition for 'M2' and the best extension method overload 'Extensions.M2<U>(ReadOnlySpan<U>)' requires a receiver of type 'System.ReadOnlySpan<U>'
            //         a.M2<U>();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "a").WithArguments("T[]", "M2", "Extensions.M2<U>(System.ReadOnlySpan<U>)", "System.ReadOnlySpan<U>").WithLocation(12, 9));
    }
 
    [Fact]
    public void Conversion_Array_Span_ExtensionMethodReceiver_Variance_02()
    {
        var source = """
            using System;
            static class Extensions
            {
                public static void M1<T>(this Span<T> arg) { }
                public static void M2<T>(this ReadOnlySpan<T> arg) { }
            }
            class C<T, U>
                where T : class, U
                where U : class
            {
                static void F1(T[] a)
                {
                    a.M1<U>();
                    a.M2<U>();
                }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(
            // (13,9): error CS1929: 'T[]' does not contain a definition for 'M1' and the best extension method overload 'Extensions.M1<U>(Span<U>)' requires a receiver of type 'System.Span<U>'
            //         a.M1<U>();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "a").WithArguments("T[]", "M1", "Extensions.M1<U>(System.Span<U>)", "System.Span<U>").WithLocation(13, 9));
    }
 
    [Fact]
    public void Conversion_Array_ReadOnlySpan_ExtensionMethodReceiver_Covariance()
    {
        var source = """
            using System;
 
            C.M(new string[] { "a", "b", "c" });
 
            static class C
            {
                public static void M(string[] arg) => arg.E();
                public static void E(this ReadOnlySpan<object> arg) => Console.Write(arg[1]);
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (7,43): error CS1929: 'string[]' does not contain a definition for 'E' and the best extension method overload 'C.E(ReadOnlySpan<object>)' requires a receiver of type 'System.ReadOnlySpan<object>'
            //     public static void M(string[] arg) => arg.E();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("string[]", "E", "C.E(System.ReadOnlySpan<object>)", "System.ReadOnlySpan<object>").WithLocation(7, 43));
 
        var expectedOutput = "b";
 
        var expectedIl = """
            {
              // Code size       14 (0xe)
              .maxstack  1
              .locals init (object[] V_0)
              IL_0000:  ldarg.0
              IL_0001:  stloc.0
              IL_0002:  ldloc.0
              IL_0003:  call       "System.ReadOnlySpan<object> System.ReadOnlySpan<object>.op_Implicit(object[])"
              IL_0008:  call       "void C.E(System.ReadOnlySpan<object>)"
              IL_000d:  ret
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        verifier.VerifyIL("C.M", expectedIl);
    }
 
    [Theory, CombinatorialData]
    public void Conversion_Span_ReadOnlySpan_RefSafety(bool cast)
    {
        var source = $$"""
            using System;
            class C
            {
                ReadOnlySpan<string> M()
                {
                    Span<string> x = {{(cast ? "(Span<string>)" : "")}}["a"];
                    return x;
                }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics(
            // (7,16): error CS8352: Cannot use variable 'x' in this context because it may expose referenced variables outside of their declaration scope
            //         return x;
            Diagnostic(ErrorCode.ERR_EscapeVariable, "x").WithArguments("x").WithLocation(7, 16));
    }
 
    [Theory, CombinatorialData]
    public void Conversion_ReadOnlySpan_ReadOnlySpan_RefSafety(bool cast)
    {
        var source = $$"""
            using System;
            class C
            {
                ReadOnlySpan<object> M()
                {
                    ReadOnlySpan<string> x = {{(cast ? "(ReadOnlySpan<string>)" : "")}}["a"];
                    return x;
                }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics(
            // (7,16): error CS8352: Cannot use variable 'x' in this context because it may expose referenced variables outside of their declaration scope
            //         return x;
            Diagnostic(ErrorCode.ERR_EscapeVariable, "x").WithArguments("x").WithLocation(7, 16));
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void Conversion_Array_Span_Coalesce(LanguageVersion langVersion)
    {
        var source = """
            using System;
            class C
            {
                void M1(int[] a)
                {
                    M2(a ?? Span<int>.Empty);
                }
                void M2(Span<int> s) => throw null;
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source,
            parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        var verifier = CompileAndVerify(comp);
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.M1", """
            {
              // Code size       25 (0x19)
              .maxstack  2
              .locals init (int[] V_0)
              IL_0000:  ldarg.0
              IL_0001:  ldarg.1
              IL_0002:  stloc.0
              IL_0003:  ldloc.0
              IL_0004:  brtrue.s   IL_000d
              IL_0006:  call       "System.Span<int> System.Span<int>.Empty.get"
              IL_000b:  br.s       IL_0013
              IL_000d:  ldloc.0
              IL_000e:  call       "System.Span<int> System.Span<int>.op_Implicit(int[])"
              IL_0013:  call       "void C.M2(System.Span<int>)"
              IL_0018:  ret
            }
            """);
    }
 
    [Fact]
    public void Conversion_string_ReadOnlySpan_Coalesce()
    {
        var source = """
            using System;
            class C
            {
                void M1(string s)
                {
                    M2(s ?? ReadOnlySpan<char>.Empty);
                }
                void M2(ReadOnlySpan<char> s) => throw null;
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        var verifier = CompileAndVerify(comp);
        verifier.VerifyDiagnostics();
        var owner = ExecutionConditionUtil.IsCoreClr ? "string" : "System.ReadOnlySpan<char>";
        verifier.VerifyIL("C.M1", $$"""
            {
                // Code size       25 (0x19)
                .maxstack  2
                .locals init (string V_0)
                IL_0000:  ldarg.0
                IL_0001:  ldarg.1
                IL_0002:  stloc.0
                IL_0003:  ldloc.0
                IL_0004:  brtrue.s   IL_000d
                IL_0006:  call       "System.ReadOnlySpan<char> System.ReadOnlySpan<char>.Empty.get"
                IL_000b:  br.s       IL_0013
                IL_000d:  ldloc.0
                IL_000e:  call       "System.ReadOnlySpan<char> {{owner}}.op_Implicit(string)"
                IL_0013:  call       "void C.M2(System.ReadOnlySpan<char>)"
                IL_0018:  ret
            }
            """);
 
        var expectedIl = """
            {
              // Code size       25 (0x19)
              .maxstack  2
              .locals init (string V_0)
              IL_0000:  ldarg.0
              IL_0001:  ldarg.1
              IL_0002:  stloc.0
              IL_0003:  ldloc.0
              IL_0004:  brtrue.s   IL_000d
              IL_0006:  call       "System.ReadOnlySpan<char> System.ReadOnlySpan<char>.Empty.get"
              IL_000b:  br.s       IL_0013
              IL_000d:  ldloc.0
              IL_000e:  call       "System.ReadOnlySpan<char> System.MemoryExtensions.AsSpan(string)"
              IL_0013:  call       "void C.M2(System.ReadOnlySpan<char>)"
              IL_0018:  ret
            }
            """;
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp).VerifyDiagnostics().VerifyIL("C.M1", expectedIl);
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp).VerifyDiagnostics().VerifyIL("C.M1", expectedIl);
    }
 
    [Fact]
    public void OverloadResolution_SpanVsIEnumerable()
    {
        var source = """
            using System;
            using System.Collections.Generic;
 
            var a = new int[0];
            C.M(a);
 
            static class C
            {
                public static void M(Span<int> x) => Console.Write(1);
                public static void M(IEnumerable<int> x) => Console.Write(2);
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (5,3): error CS0121: The call is ambiguous between the following methods or properties: 'C.M(Span<int>)' and 'C.M(IEnumerable<int>)'
            // C.M(a);
            Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("C.M(System.Span<int>)", "C.M(System.Collections.Generic.IEnumerable<int>)").WithLocation(5, 3));
 
        var expectedOutput = "1";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void OverloadResolution_SpanVsIEnumerable_CollectionExpression(LanguageVersion langVersion)
    {
        var source = """
            using System;
            using System.Collections.Generic;
 
            C.M([]);
 
            static class C
            {
                public static void M(Span<int> x) => Console.Write(1);
                public static void M(IEnumerable<int> x) => Console.Write(2);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "1").VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_SpanVsIEnumerable_Ctor()
    {
        var source = """
            using System;
            using System.Collections.Generic;
 
            var a = new int[0];
            var c = new C(a);
 
            class C
            {
                public C(Span<int> x) => Console.Write(1);
                public C(IEnumerable<int> x) => Console.Write(2);
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (5,13): error CS0121: The call is ambiguous between the following methods or properties: 'C.C(Span<int>)' and 'C.C(IEnumerable<int>)'
            // var c = new C(a);
            Diagnostic(ErrorCode.ERR_AmbigCall, "C").WithArguments("C.C(System.Span<int>)", "C.C(System.Collections.Generic.IEnumerable<int>)").WithLocation(5, 13));
 
        var expectedOutput = "1";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void OverloadResolution_ReadOnlySpanVsArray_01(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            var a = new string[] { "a" };
            C.M(a);
            C.M([a]);
            C.M([..a, a]);
 
            static class C
            {
                public static void M(string[] x) => Console.Write(" s" + x[0]);
                public static void M(ReadOnlySpan<object> x) => Console.Write(" o" + x[0]);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "sa oSystem.String[] oa").VerifyDiagnostics();
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void OverloadResolution_ReadOnlySpanVsArray_02(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            var a = new string[] { "a" };
            C.M([..a]);
            C.M(["a"]);
 
            static class C
            {
                public static void M(string[] x) => Console.Write(" s" + x[0]);
                public static void M(ReadOnlySpan<object> x) => Console.Write(" o" + x[0]);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "sa sa").VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_ReadOnlySpanVsArray_03()
    {
        var source = """
            using System;
 
            var a = new string[] { "a" };
            C.M(a);
            C.M([a]);
            C.M([..a, a]);
            C.M([..a]);
            C.M(["a"]);
 
            static class C
            {
                public static void M(object[] x) => Console.Write(" a" + x[0]);
                public static void M(ReadOnlySpan<object> x) => Console.Write(" r" + x[0]);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: "aa rSystem.String[] ra ra ra").VerifyDiagnostics();
 
        var expectedOutput = "ra rSystem.String[] ra ra ra";
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void OverloadResolution_ReadOnlySpanVsArray_04(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            var a = new object[] { "a" };
            C.M(a);
            C.M([a]);
            C.M([..a, a]);
            C.M([..a]);
 
            static class C
            {
                public static void M(object[] x) => Console.Write(" a" + x[0]);
                public static void M(ReadOnlySpan<object> x) => Console.Write(" r" + x[0]);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "aa rSystem.Object[] ra ra").VerifyDiagnostics();
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void OverloadResolution_ReadOnlySpanVsArray_05(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            C.M(null);
            C.M(default);
            C.M(default(object[]));
 
            static class C
            {
                public static void M(object[] x) => Console.Write(1);
                public static void M(ReadOnlySpan<object> x) => Console.Write(2);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "111").VerifyDiagnostics();
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void OverloadResolution_ReadOnlySpanVsArray_ExpressionTree_01(LanguageVersion langVersion)
    {
        var source = """
            using System;
            using System.Linq.Expressions;
 
            var a = new string[] { "a" };
            C.R(() => C.M(a));
 
            static class C
            {
                public static void R(Expression<Action> e) => e.Compile()();
                public static void M(string[] x) => Console.Write(" s" + x[0]);
                public static void M(ReadOnlySpan<object> x) => Console.Write(" o" + x[0]);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "sa").VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_ReadOnlySpanVsArray_ExpressionTree_02()
    {
        var source = """
            using System;
            using System.Linq.Expressions;
 
            var a = new string[] { "a" };
            C.R(() => C.M(a));
 
            static class C
            {
                public static void R(Expression<Action> e) => e.Compile()();
                public static void M(object[] x) => Console.Write(" a" + x[0]);
                public static void M(ReadOnlySpan<object> x) => Console.Write(" r" + x[0]);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: "aa").VerifyDiagnostics();
 
        var expectedOutput = "ra";
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void OverloadResolution_ReadOnlySpanVsArray_ExpressionTree_03(LanguageVersion langVersion)
    {
        var source = """
            using System;
            using System.Linq.Expressions;
 
            var a = new object[] { "a" };
            C.R(() => C.M(a));
 
            static class C
            {
                public static void R(Expression<Action> e) => e.Compile()();
                public static void M(object[] x) => Console.Write(" a" + x[0]);
                public static void M(ReadOnlySpan<object> x) => Console.Write(" r" + x[0]);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "aa").VerifyDiagnostics();
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void OverloadResolution_ReadOnlySpanVsArray_ExpressionTree_04(LanguageVersion langVersion)
    {
        var source = """
            using System;
            using System.Linq.Expressions;
 
            C.R(() => C.M(null));
            C.R(() => C.M(default));
            C.R(() => C.M(default(object[])));
 
            static class C
            {
                public static void R(Expression<Action> e) => e.Compile()();
                public static void M(object[] x) => Console.Write(" 1" + (x?[0] ?? "null"));
                public static void M(ReadOnlySpan<object> x) => Console.Write(" 2" + x.Length);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "1null 1null 1null").VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_ReadOnlySpanVsArray_Params_01()
    {
        var source = """
            using System;
 
            var a = new string[] { "a" };
            C.M(a);
            C.M(a, a);
            C.M([a]);
            C.M([..a, a]);
            C.M("a");
 
            static class C
            {
                public static void M(params string[] x) => Console.Write(" s" + x[0]);
                public static void M(params ReadOnlySpan<object> x) => Console.Write(" o" + x[0]);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: "sa oSystem.String[] oSystem.String[] oa sa").VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_ReadOnlySpanVsArray_Params_02()
    {
        var source = """
            using System;
 
            var a = new string[] { "a" };
            C.M([..a]);
            C.M(["a"]);
 
            static class C
            {
                public static void M(params string[] x) => Console.Write(" s" + x[0]);
                public static void M(params ReadOnlySpan<object> x) => Console.Write(" o" + x[0]);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: "sa sa").VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_ReadOnlySpanVsArray_Params_03()
    {
        var source = """
            using System;
 
            var a = new string[] { "a" };
            C.M(a);
            C.M([a]);
            C.M([..a, a]);
            C.M([..a]);
            C.M(["a"]);
 
            static class C
            {
                public static void M(params object[] x) => Console.Write(" a" + x[0]);
                public static void M(params ReadOnlySpan<object> x) => Console.Write(" r" + x[0]);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: "ra rSystem.String[] ra ra ra").VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_ReadOnlySpanVsArray_Params_04()
    {
        var source = """
            using System;
 
            var a = new object[] { "a" };
            C.M(a);
            C.M([a]);
            C.M([..a, a]);
            C.M([..a]);
 
            static class C
            {
                public static void M(params object[] x) => Console.Write(" a" + x[0]);
                public static void M(params ReadOnlySpan<object> x) => Console.Write(" r" + x[0]);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: "aa rSystem.Object[] ra ra").VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_ReadOnlySpanVsArray_Params_05()
    {
        var source = """
            using System;
 
            C.M(null);
            C.M(default);
 
            static class C
            {
                public static void M(params object[] x) => Console.Write(1);
                public static void M(params ReadOnlySpan<object> x) => Console.Write(2);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: "11").VerifyDiagnostics();
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void OverloadResolution_ReadOnlySpanVsArray_ExtensionMethodReceiver_01(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            var a = new string[] { "a" };
            a.M();
 
            static class C
            {
                public static void M(this string[] x) => Console.Write(" s" + x[0]);
                public static void M(this ReadOnlySpan<object> x) => Console.Write(" o" + x[0]);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "sa").VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_ReadOnlySpanVsArray_ExtensionMethodReceiver_02()
    {
        var source = """
            using System;
 
            var a = new string[] { "a" };
            a.M();
 
            static class C
            {
                public static void M(this object[] x) => Console.Write(" o" + x[0]);
                public static void M(this ReadOnlySpan<string> x) => Console.Write(" s" + x[0]);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: "oa").VerifyDiagnostics();
 
        var expectedOutput = "sa";
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_ReadOnlySpanVsArray_ExtensionMethodReceiver_03()
    {
        var source = """
            using System;
 
            var a = new string[] { "a" };
            a.M();
 
            static class C
            {
                public static void M(this object[] x) => Console.Write(" a" + x[0]);
                public static void M(this ReadOnlySpan<object> x) => Console.Write(" r" + x[0]);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: "aa").VerifyDiagnostics();
 
        var expectedOutput = "ra";
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void OverloadResolution_ReadOnlySpanVsArray_ExtensionMethodReceiver_04(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            var a = new object[] { "a" };
            a.M();
 
            static class C
            {
                public static void M(this object[] x) => Console.Write(" a" + x[0]);
                public static void M(this ReadOnlySpan<object> x) => Console.Write(" r" + x[0]);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "aa").VerifyDiagnostics();
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void OverloadResolution_ReadOnlySpanVsArray_ExtensionMethodReceiver_05(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            ((object[])null).M();
            default(object[]).M();
 
            static class C
            {
                public static void M(this object[] x) => Console.Write(1);
                public static void M(this ReadOnlySpan<object> x) => Console.Write(2);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "11").VerifyDiagnostics();
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void OverloadResolution_SpanVsArray_ExtensionMethodReceiver_01(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            var a = new string[] { "a" };
            a.M();
 
            static class C
            {
                public static void M(this string[] x) => Console.Write(" a" + x[0]);
                public static void M(this Span<string> x) => Console.Write(" s" + x[0]);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "aa").VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_SpanVsArray_ExtensionMethodReceiver_02()
    {
        var source = """
            using System;
 
            var a = new string[] { "a" };
            a.M();
 
            static class C
            {
                public static void M(this object[] x) => Console.Write(" a" + x[0]);
                public static void M(this Span<string> x) => Console.Write(" s" + x[0]);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: "aa").VerifyDiagnostics();
 
        var expectedOutput = "sa";
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void OverloadResolution_SpanVsArray_ExtensionMethodReceiver_ExpressionTree_01(LanguageVersion langVersion)
    {
        var source = """
            using System;
            using System.Linq.Expressions;
 
            var a = new string[] { "a" };
            C.R(() => a.M());
 
            static class C
            {
                public static void R(Expression<Action> e) => e.Compile()();
                public static void M(this string[] x) => Console.Write(" a" + x[0]);
                public static void M(this Span<string> x) => Console.Write(" s" + x[0]);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "aa").VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_SpanVsArray_ExtensionMethodReceiver_ExpressionTree_02()
    {
        var source = """
            using System;
            using System.Linq.Expressions;
 
            var a = new string[] { "a" };
            C.R(() => a.M());
 
            static class C
            {
                public static void R(Expression<Action> e) => e.Compile()();
                public static void M(this object[] x) => Console.Write(" a" + x[0]);
                public static void M(this Span<string> x) => Console.Write(" s" + x[0]);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: "aa").VerifyDiagnostics();
 
        var expectedOutput = "sa";
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void OverloadResolution_SpanVsReadOnlySpan_01(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            C.M(new int[0]);
            C.M(default(Span<int>));
            C.M(default(ReadOnlySpan<int>));
 
            static class C
            {
                public static void M(Span<int> arg) => Console.Write(1);
                public static void M(ReadOnlySpan<int> arg) => Console.Write(2);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "112").VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_SpanVsReadOnlySpan_02()
    {
        var source = """
            using System;
 
            C.M(new object[0]);
            C.M(default(Span<object>));
            C.M(default(ReadOnlySpan<object>));
 
            try { C.M(new string[0]); } catch (ArrayTypeMismatchException) { Console.Write(3); }
 
            static class C
            {
                public static void M(Span<object> arg) => Console.Write(1);
                public static void M(ReadOnlySpan<object> arg) => Console.Write(2);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsCoreClr ? "1123" : "1121").VerifyDiagnostics();
 
        var expectedOutput = "1122";
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_SpanVsReadOnlySpan_03()
    {
        var source = """
            using System;
 
            C.M(default(Span<string>));
            C.M(default(ReadOnlySpan<string>));
 
            static class C
            {
                public static void M(Span<object> arg) => Console.Write(1);
                public static void M(ReadOnlySpan<object> arg) => Console.Write(2);
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (3,5): error CS1503: Argument 1: cannot convert from 'System.Span<string>' to 'System.Span<object>'
            // C.M(default(Span<string>));
            Diagnostic(ErrorCode.ERR_BadArgType, "default(Span<string>)").WithArguments("1", "System.Span<string>", "System.Span<object>").WithLocation(3, 5),
            // (4,5): error CS1503: Argument 1: cannot convert from 'System.ReadOnlySpan<string>' to 'System.Span<object>'
            // C.M(default(ReadOnlySpan<string>));
            Diagnostic(ErrorCode.ERR_BadArgType, "default(ReadOnlySpan<string>)").WithArguments("1", "System.ReadOnlySpan<string>", "System.Span<object>").WithLocation(4, 5));
 
        var expectedOutput = "22";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net90);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_SpanVsReadOnlySpan_ExtensionMethodReceiver_01()
    {
        var source = """
            using System;
 
            (new int[0]).E();
 
            static class C
            {
                public static void E(this Span<int> arg) => Console.Write(1);
                public static void E(this ReadOnlySpan<int> arg) => Console.Write(2);
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (3,2): error CS1929: 'int[]' does not contain a definition for 'E' and the best extension method overload 'C.E(Span<int>)' requires a receiver of type 'System.Span<int>'
            // (new int[0]).E();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "new int[0]").WithArguments("int[]", "E", "C.E(System.Span<int>)", "System.Span<int>").WithLocation(3, 2));
 
        var expectedOutput = "1";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Theory, MemberData(nameof(LangVersions))]
    public void OverloadResolution_SpanVsReadOnlySpan_ExtensionMethodReceiver_02(LanguageVersion langVersion)
    {
        var source = """
            using System;
 
            default(Span<int>).E();
            default(ReadOnlySpan<int>).E();
 
            static class C
            {
                public static void E(this Span<int> arg) => Console.Write(1);
                public static void E(this ReadOnlySpan<int> arg) => Console.Write(2);
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion));
        CompileAndVerify(comp, expectedOutput: "12").VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_SpanVsReadOnlySpan_ExtensionMethodReceiver_03()
    {
        var source = """
            using System;
 
            (new string[0]).E();
            (new object[0]).E();
 
            static class C
            {
                public static void E(this Span<object> arg) => Console.Write(1);
                public static void E(this ReadOnlySpan<object> arg) => Console.Write(2);
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (3,2): error CS1929: 'string[]' does not contain a definition for 'E' and the best extension method overload 'C.E(Span<object>)' requires a receiver of type 'System.Span<object>'
            // (new string[0]).E();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "new string[0]").WithArguments("string[]", "E", "C.E(System.Span<object>)", "System.Span<object>").WithLocation(3, 2),
            // (4,2): error CS1929: 'object[]' does not contain a definition for 'E' and the best extension method overload 'C.E(Span<object>)' requires a receiver of type 'System.Span<object>'
            // (new string[0]).E();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "new object[0]").WithArguments("object[]", "E", "C.E(System.Span<object>)", "System.Span<object>").WithLocation(4, 2));
 
        var expectedOutput = "21";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_SpanVsReadOnlySpan_ExtensionMethodReceiver_04()
    {
        var source = """
            using System;
 
            default(Span<string>).E();
            default(ReadOnlySpan<string>).E();
 
            static class C
            {
                public static void E(this Span<object> arg) => Console.Write(1);
                public static void E(this ReadOnlySpan<object> arg) => Console.Write(2);
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (3,1): error CS1929: 'Span<string>' does not contain a definition for 'E' and the best extension method overload 'C.E(Span<object>)' requires a receiver of type 'System.Span<object>'
            // default(Span<string>).E();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "default(Span<string>)").WithArguments("System.Span<string>", "E", "C.E(System.Span<object>)", "System.Span<object>").WithLocation(3, 1),
            // (4,1): error CS1929: 'ReadOnlySpan<string>' does not contain a definition for 'E' and the best extension method overload 'C.E(Span<object>)' requires a receiver of type 'System.Span<object>'
            // default(ReadOnlySpan<string>).E();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "default(ReadOnlySpan<string>)").WithArguments("System.ReadOnlySpan<string>", "E", "C.E(System.Span<object>)", "System.Span<object>").WithLocation(4, 1));
 
        var expectedOutput = "22";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net90);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_ReadOnlySpanVsReadOnlySpan()
    {
        var source1 = """
            using System;
            static class C
            {
                public static void M(ReadOnlySpan<string> arg) => Console.Write(1);
                public static void M(ReadOnlySpan<object> arg) => Console.Write(2);
            }
            """;
 
        var source2 = """
            C.M(new string[0]);
            """;
        CreateCompilationWithSpanAndMemoryExtensions([source1, source2], parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (1,3): error CS0121: The call is ambiguous between the following methods or properties: 'C.M(ReadOnlySpan<string>)' and 'C.M(ReadOnlySpan<object>)'
            // C.M(new string[0]);
            Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("C.M(System.ReadOnlySpan<string>)", "C.M(System.ReadOnlySpan<object>)").WithLocation(1, 3));
 
        var expectedOutput = "1";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions([source1, source2], parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions([source1, source2]);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        var source3 = """
            using System;
            C.M(new object[0]);
            C.M(default(Span<string>));
            C.M(default(Span<object>));
            C.M(default(ReadOnlySpan<string>));
            C.M(default(ReadOnlySpan<object>));
            """;
 
        expectedOutput = "21212";
 
        comp = CreateCompilationWithSpanAndMemoryExtensions([source1, source3], parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions([source1, source3], parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions([source1, source3]);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_ReadOnlySpanVsReadOnlySpan_ExtensionMethodReceiver()
    {
        var source = """
            using System;
 
            (new string[0]).M();
            (new object[0]).M();
            (default(Span<string>)).M();
            (default(Span<object>)).M();
            (default(ReadOnlySpan<string>)).M();
            (default(ReadOnlySpan<object>)).M();
 
            static class C
            {
                public static void M(this ReadOnlySpan<string> arg) => Console.Write(1);
                public static void M(this ReadOnlySpan<object> arg) => Console.Write(2);
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (3,2): error CS1929: 'string[]' does not contain a definition for 'M' and the best extension method overload 'C.M(ReadOnlySpan<string>)' requires a receiver of type 'System.ReadOnlySpan<string>'
            // (new string[0]).M();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "new string[0]").WithArguments("string[]", "M", "C.M(System.ReadOnlySpan<string>)", "System.ReadOnlySpan<string>").WithLocation(3, 2),
            // (4,2): error CS1929: 'object[]' does not contain a definition for 'M' and the best extension method overload 'C.M(ReadOnlySpan<string>)' requires a receiver of type 'System.ReadOnlySpan<string>'
            // (new object[0]).M();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "new object[0]").WithArguments("object[]", "M", "C.M(System.ReadOnlySpan<string>)", "System.ReadOnlySpan<string>").WithLocation(4, 2),
            // (5,2): error CS1929: 'Span<string>' does not contain a definition for 'M' and the best extension method overload 'C.M(ReadOnlySpan<string>)' requires a receiver of type 'System.ReadOnlySpan<string>'
            // (default(Span<string>)).M();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "default(Span<string>)").WithArguments("System.Span<string>", "M", "C.M(System.ReadOnlySpan<string>)", "System.ReadOnlySpan<string>").WithLocation(5, 2),
            // (6,2): error CS1929: 'Span<object>' does not contain a definition for 'M' and the best extension method overload 'C.M(ReadOnlySpan<string>)' requires a receiver of type 'System.ReadOnlySpan<string>'
            // (default(Span<object>)).M();
            Diagnostic(ErrorCode.ERR_BadInstanceArgType, "default(Span<object>)").WithArguments("System.Span<object>", "M", "C.M(System.ReadOnlySpan<string>)", "System.ReadOnlySpan<string>").WithLocation(6, 2));
 
        var expectedOutput = "121212";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [ConditionalFact(typeof(CoreClrOnly))]
    public void OverloadResolution_ReadOnlySpanVsReadOnlySpan_Params()
    {
        var source1 = """
            using System;
            static class C
            {
                public static void M(params ReadOnlySpan<string> arg) => Console.Write(1);
                public static void M(params ReadOnlySpan<object> arg) => Console.Write(2);
            }
            """;
 
        var source2 = """
            C.M(new string[0]);
            """;
        CreateCompilationWithSpanAndMemoryExtensions([source1, source2], parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (1,3): error CS0121: The call is ambiguous between the following methods or properties: 'C.M(params ReadOnlySpan<string>)' and 'C.M(params ReadOnlySpan<object>)'
            // C.M(new string[0]);
            Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("C.M(params System.ReadOnlySpan<string>)", "C.M(params System.ReadOnlySpan<object>)").WithLocation(1, 3));
 
        var expectedOutput = "1";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions([source1, source2], parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions([source1, source2]);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        var source3 = """
            using System;
            C.M("a");
            C.M(new object());
            C.M(new object[0]);
            C.M(default(Span<string>));
            C.M(default(Span<object>));
            C.M(default(ReadOnlySpan<string>));
            C.M(default(ReadOnlySpan<object>));
            """;
 
        expectedOutput = "1221212";
 
        comp = CreateCompilationWithSpanAndMemoryExtensions([source1, source3], parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions([source1, source3], parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions([source1, source3]);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_SpanVsUserDefined_01()
    {
        var source = """
            using System;
 
            C.M(new string[0]);
 
            class C
            {
                public static implicit operator C(string[] s) => new C();
                public static implicit operator C(Span<string> s) => new C();
                public static void M(C arg) => Console.Write(1);
                public static void M(ReadOnlySpan<object> arg) => Console.Write(2);
            }
            """;
 
        CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13).VerifyDiagnostics(
            // (3,3): error CS0121: The call is ambiguous between the following methods or properties: 'C.M(C)' and 'C.M(ReadOnlySpan<object>)'
            // C.M(new string[0]);
            Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("C.M(C)", "C.M(System.ReadOnlySpan<object>)").WithLocation(3, 3));
 
        var expectedOutput = "2";
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_SpanVsUserDefined_02()
    {
        var source = """
            using System;
 
            C.M(default(Span<string>));
 
            class C
            {
                public static implicit operator C(string[] s) => new C();
                public static implicit operator C(Span<string> s) => new C();
                public static void M(C arg) => Console.Write(1);
                public static void M(ReadOnlySpan<object> arg) => Console.Write(2);
            }
            """;
 
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: "1").VerifyDiagnostics();
 
        var expectedOutput = "2";
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_ReadOnlySpanVsArrayVsSpan()
    {
        var source = """
            using System;
            using System.Collections.Generic;
            using System.Linq;
 
            var a = new string[] { "a" };
            C.M(a);
            C.M([a]);
            C.M([..a, a]);
            C.M([..a]);
            C.M(["a"]);
 
            var b = new object[] { "b" };
            C.M(b);
            C.M([b]);
            C.M([..b, b]);
            C.M([..b]);
 
            static class C
            {
                public static void M(object[] x) => Console.Write(" a" + x[0]);
                public static void M(ReadOnlySpan<object> x) => Console.Write(" r" + x[0]);
                public static void M(Span<object> x) => Console.Write(" s" + x[0]);
                public static void M(IEnumerable<object> x) => Console.Write(" e" + x.First());
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: "aa rSystem.String[] ra ra ra ab rSystem.Object[] rb rb").VerifyDiagnostics();
 
        var expectedOutput = "ra rSystem.String[] ra ra ra ab rSystem.Object[] rb rb";
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_ReadOnlySpanVsArrayVsSpan_Params()
    {
        var source = """
            using System;
            using System.Collections.Generic;
            using System.Linq;
 
            var a = new string[] { "a" };
            C.M(a);
            C.M([a]);
            C.M([..a, a]);
            C.M([..a]);
            C.M(["a"]);
 
            var b = new object[] { "b" };
            C.M(b);
            C.M([b]);
            C.M([..b, b]);
            C.M([..b]);
 
            static class C
            {
                public static void M(params object[] x) => Console.Write(" a" + x[0]);
                public static void M(params ReadOnlySpan<object> x) => Console.Write(" r" + x[0]);
                public static void M(params Span<object> x) => Console.Write(" s" + x[0]);
                public static void M(params IEnumerable<object> x) => Console.Write(" e" + x.First());
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: "ra rSystem.String[] ra ra ra ab rSystem.Object[] rb rb").VerifyDiagnostics();
    }
 
    [Fact]
    public void OverloadResolution_ReadOnlySpanVsArrayVsSpan_ExtensionMethodReceiver()
    {
        var source = """
            using System;
            using System.Collections.Generic;
            using System.Linq;
 
            var a = new string[] { "a" };
            a.M();
 
            var b = new object[] { "b" };
            b.M();
 
            static class C
            {
                public static void M(this object[] x) => Console.Write(" a" + x[0]);
                public static void M(this ReadOnlySpan<object> x) => Console.Write(" r" + x[0]);
                public static void M(this Span<object> x) => Console.Write(" s" + x[0]);
                public static void M(this IEnumerable<object> x) => Console.Write(" e" + x.First());
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular13);
        CompileAndVerify(comp, expectedOutput: "aa ab").VerifyDiagnostics();
 
        var expectedOutput = "ra ab";
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
 
        comp = CreateCompilationWithSpanAndMemoryExtensions(source);
        CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
    }
 
    private static readonly SymbolDisplayFormat s_typeArgumentsDisplayFormat = SymbolDisplayFormat.TestFormat
        .RemoveMemberOptions(SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeType);
 
    private static string DisplayInvokedMethodTypeArguments(CSharpCompilation comp, CandidateReason failure = CandidateReason.None)
    {
        var invocation = comp.SyntaxTrees.Single().GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
        var model = comp.GetSemanticModel(invocation.SyntaxTree);
        var info = model.GetSymbolInfo(invocation);
        ISymbol symbol;
 
        if (failure != CandidateReason.None)
        {
            Assert.Null(info.Symbol);
            Assert.Equal(failure, info.CandidateReason);
            symbol = info.CandidateSymbols.Single();
        }
        else
        {
            symbol = info.Symbol!;
        }
 
        return symbol.GetSymbol<MethodSymbol>()!.ToDisplayString(s_typeArgumentsDisplayFormat);
    }
 
    [Fact]
    public void TypeInference_Span_Span_01()
    {
        var source = """
            using System;
            class C
            {
                void M(Span<int> a) => M1(a);
                void M1<T>(Span<T> x) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics();
        AssertEx.Equal("C.M1<System.Int32>", DisplayInvokedMethodTypeArguments(comp));
    }
 
    [Fact]
    public void TypeInference_Span_Span_02()
    {
        var source = """
            using System;
            class C
            {
                void M(Span<string> a, object b) => M1(a, b);
                void M1<T>(Span<T> x, T y) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(
            // (4,41): error CS0411: The type arguments for method 'C.M1<T>(Span<T>, T)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
            //     void M(Span<string> a, object b) => M1(a, b);
            Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "M1").WithArguments("C.M1<T>(System.Span<T>, T)").WithLocation(4, 41));
    }
 
    [Fact]
    public void TypeInference_Span_Span_03()
    {
        var source = """
            using System;
            class C
            {
                void M(Span<object> a, string b) => M1(a, b);
                void M1<T>(Span<T> x, T y) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics();
        AssertEx.Equal("C.M1<System.Object>", DisplayInvokedMethodTypeArguments(comp));
    }
 
    [Fact]
    public void TypeInference_Span_Span_04()
    {
        var source = """
            using System;
            class C
            {
                void M(Span<string[]> a, object b) => M1(a, b);
                void M1<T>(Span<T[]> x, T y) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(
            // (4,43): error CS0411: The type arguments for method 'C.M1<T>(Span<T[]>, T)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
            //     void M(Span<string[]> a, object b) => M1(a, b);
            Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "M1").WithArguments("C.M1<T>(System.Span<T[]>, T)").WithLocation(4, 43));
    }
 
    [Fact]
    public void TypeInference_Span_Span_05()
    {
        var source = """
            using System;
            class C
            {
                void M(Span<object[]> a, string b) => M1(a, b);
                void M1<T>(Span<T[]> x, T y) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics();
        AssertEx.Equal("C.M1<System.Object>", DisplayInvokedMethodTypeArguments(comp));
    }
 
    [Fact]
    public void TypeInference_Array_Span_01()
    {
        var source = """
            using System;
            class C
            {
                void M(int[] a) => M1(a);
                void M1<T>(Span<T> x) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics();
        AssertEx.Equal("C.M1<System.Int32>", DisplayInvokedMethodTypeArguments(comp));
    }
 
    [Fact]
    public void TypeInference_Array_Span_02()
    {
        var source = """
            using System;
            class C
            {
                void M(string[] a, object b) => M1(a, b);
                void M1<T>(Span<T> x, T y) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(
            // (4,37): error CS0411: The type arguments for method 'C.M1<T>(Span<T>, T)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
            //     void M(string[] a, object b) => M1(a, b);
            Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "M1").WithArguments("C.M1<T>(System.Span<T>, T)").WithLocation(4, 37));
    }
 
    [Fact]
    public void TypeInference_Array_Span_03()
    {
        var source = """
            using System;
            class C
            {
                void M(object[] a, string b) => M1(a, b);
                void M1<T>(Span<T> x, T y) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics();
        AssertEx.Equal("C.M1<System.Object>", DisplayInvokedMethodTypeArguments(comp));
    }
 
    [Fact]
    public void TypeInference_Span_Array()
    {
        var source = """
            using System;
            class C
            {
                void M(Span<int> a) => M1(a);
                void M1<T>(T[] x) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(
            // (4,28): error CS0411: The type arguments for method 'C.M1<T>(T[])' cannot be inferred from the usage. Try specifying the type arguments explicitly.
            //     void M(Span<int> a) => M1(a);
            Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "M1").WithArguments("C.M1<T>(T[])").WithLocation(4, 28));
    }
 
    [Fact]
    public void TypeInference_Array_ReadOnlySpan_01()
    {
        var source = """
            using System;
            class C
            {
                void M(int[] a) => M1(a);
                void M1<T>(ReadOnlySpan<T> x) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics();
        AssertEx.Equal("C.M1<System.Int32>", DisplayInvokedMethodTypeArguments(comp));
    }
 
    [Fact]
    public void TypeInference_Array_ReadOnlySpan_02()
    {
        var source = """
            using System;
            class C
            {
                void M(string[] a, object b) => M1(a, b);
                void M1<T>(ReadOnlySpan<T> x, T y) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics();
        AssertEx.Equal("C.M1<System.Object>", DisplayInvokedMethodTypeArguments(comp));
    }
 
    [Fact]
    public void TypeInference_Array_ReadOnlySpan_03()
    {
        var source = """
            using System;
            class C
            {
                void M(object[] a, string b) => M1(a, b);
                void M1<T>(ReadOnlySpan<T> x, T y) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics();
        AssertEx.Equal("C.M1<System.Object>", DisplayInvokedMethodTypeArguments(comp));
    }
 
    [Fact]
    public void TypeInference_Array_ReadOnlySpan_04()
    {
        var source = """
            using System;
            class C
            {
                void M(int[] a, object b) => M1(a, b);
                void M1<T>(ReadOnlySpan<T> x, T y) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(
            // (4,34): error CS0411: The type arguments for method 'C.M1<T>(ReadOnlySpan<T>, T)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
            //     void M(int[] a, object b) => M1(a, b);
            Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "M1").WithArguments("C.M1<T>(System.ReadOnlySpan<T>, T)").WithLocation(4, 34));
    }
 
    [Fact]
    public void TypeInference_Array_ReadOnlySpan_05()
    {
        var source = """
            using System;
            class C
            {
                void M(object[] a, int b) => M1(a, b);
                void M1<T>(ReadOnlySpan<T> x, T y) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics();
        AssertEx.Equal("C.M1<System.Object>", DisplayInvokedMethodTypeArguments(comp));
    }
 
    [Fact]
    public void TypeInference_Array_ReadOnlySpan_06()
    {
        var source = """
            using System;
            class C
            {
                void M(I<object[]> a) => M1(a);
                void M1<T>(I<ReadOnlySpan<T>> x) { }
            }
            interface I<T> where T : allows ref struct { }
            """;
        var comp = CreateCompilation(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics(
            // (4,33): error CS1503: Argument 1: cannot convert from 'I<object[]>' to 'I<System.ReadOnlySpan<object>>'
            //     void M(I<object[]> a) => M1(a);
            Diagnostic(ErrorCode.ERR_BadArgType, "a").WithArguments("1", "I<object[]>", "I<System.ReadOnlySpan<object>>").WithLocation(4, 33));
        AssertEx.Equal("C.M1<System.Object>", DisplayInvokedMethodTypeArguments(comp, CandidateReason.OverloadResolutionFailure));
    }
 
    [Fact]
    public void TypeInference_Array_ReadOnlySpan_07()
    {
        var source = """
            using System;
            class C
            {
                void M(I<object[]> a) => M1(a);
                void M1<T>(I<ReadOnlySpan<T>> x) { }
            }
            interface I<out T> where T : allows ref struct { }
            """;
        var comp = CreateCompilation(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics(
            // (4,33): error CS1503: Argument 1: cannot convert from 'I<object[]>' to 'I<System.ReadOnlySpan<object>>'
            //     void M(I<object[]> a) => M1(a);
            Diagnostic(ErrorCode.ERR_BadArgType, "a").WithArguments("1", "I<object[]>", "I<System.ReadOnlySpan<object>>").WithLocation(4, 33));
        AssertEx.Equal("C.M1<System.Object>", DisplayInvokedMethodTypeArguments(comp, CandidateReason.OverloadResolutionFailure));
    }
 
    [Fact]
    public void TypeInference_Array_ReadOnlySpan_08()
    {
        var source = """
            using System;
            class C
            {
                void M(I<object[]> a) => M1(a);
                void M1<T>(I<ReadOnlySpan<T>> x) { }
            }
            interface I<in T> where T : allows ref struct { }
            """;
        CreateCompilation(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics(
            // (4,30): error CS0411: The type arguments for method 'C.M1<T>(I<ReadOnlySpan<T>>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
            //     void M(I<object[]> a) => M1(a);
            Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "M1").WithArguments("C.M1<T>(I<System.ReadOnlySpan<T>>)").WithLocation(4, 30));
    }
 
    [Fact]
    public void TypeInference_ReadOnlySpan_ReadOnlySpan_01()
    {
        var source = """
            using System;
            class C
            {
                void M(ReadOnlySpan<int> a) => M1(a);
                void M1<T>(ReadOnlySpan<T> x) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics();
        AssertEx.Equal("C.M1<System.Int32>", DisplayInvokedMethodTypeArguments(comp));
    }
 
    [Fact]
    public void TypeInference_ReadOnlySpan_ReadOnlySpan_02()
    {
        var source = """
            using System;
            class C
            {
                void M(ReadOnlySpan<string> a, object b) => M1(a, b);
                void M1<T>(ReadOnlySpan<T> x, T y) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics();
        AssertEx.Equal("C.M1<System.Object>", DisplayInvokedMethodTypeArguments(comp));
    }
 
    [Fact]
    public void TypeInference_ReadOnlySpan_ReadOnlySpan_03()
    {
        var source = """
            using System;
            class C
            {
                void M(ReadOnlySpan<object> a, string b) => M1(a, b);
                void M1<T>(ReadOnlySpan<T> x, T y) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics();
        AssertEx.Equal("C.M1<System.Object>", DisplayInvokedMethodTypeArguments(comp));
    }
 
    [Fact]
    public void TypeInference_ReadOnlySpan_ReadOnlySpan_04()
    {
        var source = """
            using System;
            class C
            {
                void M(ReadOnlySpan<string[]> a, object b) => M1(a, b);
                void M1<T>(ReadOnlySpan<T[]> x, T y) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics();
        AssertEx.Equal("C.M1<System.Object>", DisplayInvokedMethodTypeArguments(comp));
    }
 
    [Fact]
    public void TypeInference_ReadOnlySpan_ReadOnlySpan_05()
    {
        var source = """
            using System;
            class C
            {
                void M(out ReadOnlySpan<string[]> a, object b) => M1(out a, b);
                void M1<T>(out ReadOnlySpan<T[]> x, T y) => throw null;
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(
            // (4,55): error CS0411: The type arguments for method 'C.M1<T>(out ReadOnlySpan<T[]>, T)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
            //     void M(out ReadOnlySpan<string[]> a, object b) => M1(out a, b);
            Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "M1").WithArguments("C.M1<T>(out System.ReadOnlySpan<T[]>, T)").WithLocation(4, 55));
    }
 
    [Fact]
    public void TypeInference_ReadOnlySpan_ReadOnlySpan_06()
    {
        var source = """
            using System;
            class C
            {
                void M(ReadOnlySpan<int> a, object b) => M1(a, b);
                void M1<T>(ReadOnlySpan<T> x, T y) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(
            // (4,46): error CS0411: The type arguments for method 'C.M1<T>(ReadOnlySpan<T>, T)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
            //     void M(ReadOnlySpan<int> a, object b) => M1(a, b);
            Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "M1").WithArguments("C.M1<T>(System.ReadOnlySpan<T>, T)").WithLocation(4, 46));
    }
 
    [Fact]
    public void TypeInference_ReadOnlySpan_ReadOnlySpan_07()
    {
        var source = """
            using System;
            class C
            {
                void M(ReadOnlySpan<object> a, int b) => M1(a, b);
                void M1<T>(ReadOnlySpan<T> x, T y) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics();
        AssertEx.Equal("C.M1<System.Object>", DisplayInvokedMethodTypeArguments(comp));
    }
 
    [Fact]
    public void TypeInference_ReadOnlySpan_Span()
    {
        var source = """
            using System;
            class C
            {
                void M(ReadOnlySpan<int> a) => M1(a);
                void M1<T>(Span<T> x) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(
            // (4,36): error CS0411: The type arguments for method 'C.M1<T>(Span<T>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
            //     void M(ReadOnlySpan<int> a) => M1(a);
            Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "M1").WithArguments("C.M1<T>(System.Span<T>)").WithLocation(4, 36));
    }
 
    [Fact]
    public void TypeInference_Span_ReadOnlySpan_01()
    {
        var source = """
            using System;
            class C
            {
                void M(Span<int> a) => M1(a);
                void M1<T>(ReadOnlySpan<T> x) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics();
        AssertEx.Equal("C.M1<System.Int32>", DisplayInvokedMethodTypeArguments(comp));
    }
 
    [Fact]
    public void TypeInference_Span_ReadOnlySpan_02()
    {
        var source = """
            using System;
            class C
            {
                void M(Span<string> a, object b) => M1(a, b);
                void M1<T>(ReadOnlySpan<T> x, T y) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics();
        AssertEx.Equal("C.M1<System.Object>", DisplayInvokedMethodTypeArguments(comp));
    }
 
    [Fact]
    public void TypeInference_Span_ReadOnlySpan_03()
    {
        var source = """
            using System;
            class C
            {
                void M(Span<object> a, string b) => M1(a, b);
                void M1<T>(ReadOnlySpan<T> x, T y) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics();
        AssertEx.Equal("C.M1<System.Object>", DisplayInvokedMethodTypeArguments(comp));
    }
 
    [Fact]
    public void TypeInference_Span_ReadOnlySpan_04()
    {
        var source = """
            using System;
            class C
            {
                void M(Span<int> a, object b) => M1(a, b);
                void M1<T>(ReadOnlySpan<T> x, T y) { }
            }
            """;
        CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(
            // (4,38): error CS0411: The type arguments for method 'C.M1<T>(ReadOnlySpan<T>, T)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
            //     void M(Span<int> a, object b) => M1(a, b);
            Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "M1").WithArguments("C.M1<T>(System.ReadOnlySpan<T>, T)").WithLocation(4, 38));
    }
 
    [Fact]
    public void TypeInference_Span_ReadOnlySpan_05()
    {
        var source = """
            using System;
            class C
            {
                void M(Span<object> a, int b) => M1(a, b);
                void M1<T>(ReadOnlySpan<T> x, T y) { }
            }
            """;
        var comp = CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics();
        AssertEx.Equal("C.M1<System.Object>", DisplayInvokedMethodTypeArguments(comp));
    }
}