From 18a55466436a794f0a6ce8a054e9d59695d93d1a Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Thu, 11 Jul 2024 15:19:51 +0200 Subject: [PATCH 1/7] Use CreateCompilationWithSpanAndMemoryExtensions --- .../CSharp/Test/Emit3/FirstClassSpanTests.cs | 360 +++++++++--------- 1 file changed, 180 insertions(+), 180 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs b/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs index 8d9b2f34bc062..25df33d6930c1 100644 --- a/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs +++ b/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs @@ -55,7 +55,7 @@ readonly struct StringValues } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).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)' // 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)").WithLocation(7, 65), @@ -77,11 +77,11 @@ .maxstack 2 } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); verifier.VerifyIL("C.M", expectedIl); - comp = CreateCompilationWithSpan(source); + comp = CreateCompilationWithSpanAndMemoryExtensions(source); verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); verifier.VerifyIL("C.M", expectedIl); } @@ -109,15 +109,15 @@ class Derived : Base } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12); CompileAndVerify(comp, expectedOutput: "Base").VerifyDiagnostics(); var expectedOutput = "Derived"; - comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); - comp = CreateCompilationWithSpan(source); + comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); } @@ -155,7 +155,7 @@ public static class N2Ext } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12, options: TestOptions.ReleaseExe); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12, options: TestOptions.ReleaseExe); CompileAndVerify(comp, expectedOutput: "N2").VerifyDiagnostics(); var expectedOutput = "N1"; @@ -167,10 +167,10 @@ public static class N2Ext Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using N2;").WithLocation(5, 5) }; - comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext, options: TestOptions.ReleaseExe); + comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext, options: TestOptions.ReleaseExe); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(expectedDiagnostics); - comp = CreateCompilationWithSpan(source, TestOptions.ReleaseExe); + comp = CreateCompilationWithSpanAndMemoryExtensions(source, TestOptions.ReleaseExe); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(expectedDiagnostics); } @@ -191,15 +191,15 @@ static class E } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12); CompileAndVerify(comp, expectedOutput: "2").VerifyDiagnostics(); var expectedOutput = "1"; - comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); - comp = CreateCompilationWithSpan(source); + comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); } @@ -220,7 +220,7 @@ static class E public static void M(this T[] a, T x) => Console.Write(3); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); var verifier = CompileAndVerify(comp, expectedOutput: "3").VerifyDiagnostics(); verifier.VerifyIL("", """ { @@ -257,7 +257,7 @@ static class E } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12); CompileAndVerify(comp, expectedOutput: "2").VerifyDiagnostics(); // PROTOTYPE: Can we avoid this break? @@ -269,8 +269,8 @@ static class E Diagnostic(ErrorCode.ERR_ValueTypeExtDelegate, "arr.M").WithArguments("E.M(System.Span, int)", "System.Span").WithLocation(5, 5) }; - CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); - CreateCompilationWithSpan(source).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics); } [Theory, MemberData(nameof(LangVersions))] @@ -291,7 +291,7 @@ static class E public static void M(this T[] a, T x) => Console.Write(3); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); CompileAndVerify(comp, expectedOutput: "3").VerifyDiagnostics(); } @@ -311,7 +311,7 @@ public void Conversion_Array_Span_Implicit( var expectedOutput = "123"; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput); verifier.VerifyDiagnostics(); verifier.VerifyIL("", $$""" @@ -531,7 +531,7 @@ static class C } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); var verifier = CompileAndVerify(comp, expectedOutput: "12").VerifyDiagnostics(); verifier.VerifyIL("", """ { @@ -722,7 +722,7 @@ class C } """; - var comp = CreateCompilationWithSpan(source); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); @@ -755,7 +755,7 @@ class C } """; - var comp = CreateCompilationWithSpan(source); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); @@ -804,7 +804,7 @@ class C System.Span M(int[] arg) => arg; } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (3,41): error CS0029: Cannot implicitly convert type 'int[]' to 'System.Span' // System.Span M(int[] arg) => arg; Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("int[]", "System.Span").WithLocation(3, 41)); @@ -830,7 +830,7 @@ class C } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( // (6,39): warning CS8619: Nullability of reference types in value of type 'string?[]' doesn't match target type 'string[]'. // Span M2(string?[] arg) => arg; Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[]", "string[]").WithLocation(6, 39), @@ -866,8 +866,8 @@ class C Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(Span)arg").WithArguments("string[]", "System.Span").WithLocation(13, 39) }; - CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); - CreateCompilationWithSpan(source).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics); } [Fact] @@ -889,7 +889,7 @@ class C } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( // (6,47): warning CS8619: Nullability of reference types in value of type 'string?[]' doesn't match target type 'string[]'. // ReadOnlySpan M2(string?[] arg) => arg; Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[]", "string[]").WithLocation(6, 47), @@ -919,8 +919,8 @@ class C Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan)arg").WithArguments("object?[]", "System.ReadOnlySpan").WithLocation(12, 47) }; - CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); - CreateCompilationWithSpan(source).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics); } [Fact] @@ -940,7 +940,7 @@ class C } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( // (6,43): warning CS8619: Nullability of reference types in value of type 'string?[][]' doesn't match target type 'string[][]'. // Span M2(string?[][] arg) => arg; Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[][]", "string[][]").WithLocation(6, 43), @@ -961,8 +961,8 @@ class C Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(Span)arg").WithArguments("string?[][]", "System.Span").WithLocation(10, 43) }; - CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); - CreateCompilationWithSpan(source).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics); } [Fact] @@ -984,7 +984,7 @@ class C } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( // (6,51): warning CS8619: Nullability of reference types in value of type 'string?[][]' doesn't match target type 'string[][]'. // ReadOnlySpan M2(string?[][] arg) => arg; Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[][]", "string[][]").WithLocation(6, 51), @@ -1011,8 +1011,8 @@ class C Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(ReadOnlySpan)arg").WithArguments("string?[][]", "System.ReadOnlySpan").WithLocation(11, 51) }; - CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); - CreateCompilationWithSpan(source).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics); } [Theory, MemberData(nameof(LangVersions))] @@ -1032,7 +1032,7 @@ class C } struct S { } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (6,45): warning CS8619: Nullability of reference types in value of type 'S[]' doesn't match target type 'S[]'. // Span> M2(S[] arg) => arg; Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("S[]", targetType("string")).WithLocation(6, 45), @@ -1066,7 +1066,7 @@ class C } struct S { } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (6,53): warning CS8619: Nullability of reference types in value of type 'S[]' doesn't match target type 'S[]'. // ReadOnlySpan> M2(S[] arg) => arg; Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("S[]", targetType("string")).WithLocation(6, 53), @@ -1100,7 +1100,7 @@ class C interface I { } """; var targetType = langVersion > LanguageVersion.CSharp12 ? "System.ReadOnlySpan>" : "I[]"; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (5,52): warning CS8619: Nullability of reference types in value of type 'I[]' doesn't match target type 'I[]'. // ReadOnlySpan> M(I[] arg) => arg; Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("I[]", targetType).WithLocation(5, 52)); @@ -1118,7 +1118,7 @@ class C ReadOnlySpan? M2(string[] arg) => arg; } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (5,19): error CS9244: The type 'Span' 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' // Span? M1(string[] arg) => arg; Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "M1").WithArguments("System.Nullable", "T", "System.Span").WithLocation(5, 19), @@ -1148,7 +1148,7 @@ static void M3(this ReadOnlySpan arg) { } static void M4(this ReadOnlySpan arg) { } } """; - CreateCompilationWithSpan(source).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics( // (7,17): warning CS8620: Argument of type 'string?[]' cannot be used for parameter 'arg' of type 'Span' in 'void C.M1(Span arg)' due to differences in the nullability of reference types. // a.M1(); b.M1(); Diagnostic(ErrorCode.WRN_NullabilityMismatchInArgument, "b").WithArguments("string?[]", "System.Span", "arg", "void C.M1(Span arg)").WithLocation(7, 17), @@ -1171,7 +1171,7 @@ class C System.ReadOnlySpan M2({{modifier}} string[] arg) => arg; } """; - var comp = CreateCompilationWithSpan(source); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source); var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics(); verifier.VerifyIL("C.M1", """ { @@ -1214,7 +1214,7 @@ ReadOnlySpan M3(string[] arg) => M4({{argModifier(modifier)}} ReadOnlySpan M4({{modifier}} ReadOnlySpan arg) => arg; } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (6,9): error CS1503: Argument 1: cannot convert from 'ref string[]' to 'ref System.Span' // arg); // 1 Diagnostic(ErrorCode.ERR_BadArgType, "arg").WithArguments("1", $"{argModifier(modifier)} string[]", $"{modifier} System.Span").WithLocation(6, 9), @@ -1236,7 +1236,7 @@ class C System.ReadOnlySpan M2(out string[] arg) => arg = null; } """; - var comp = CreateCompilationWithSpan(source); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source); var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics(); verifier.VerifyIL("C.M1", """ { @@ -1282,7 +1282,7 @@ class C ref ReadOnlySpan M3(ref string[] arg) => ref arg; } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (4,50): error CS8151: The return expression must be of type 'Span' because this method returns by reference // ref Span M1(ref string[] arg) => ref arg; Diagnostic(ErrorCode.ERR_RefReturnMustHaveIdentityConversion, "arg").WithArguments("System.Span").WithLocation(4, 50), @@ -1308,7 +1308,7 @@ void M() string[] A() => null; } """; - var comp = CreateCompilationWithSpan(source, TestOptions.DebugDll); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, TestOptions.DebugDll); var verifier = CompileAndVerify(comp).VerifyDiagnostics(); verifier.VerifyIL("C.M", """ { @@ -1342,7 +1342,7 @@ class C string[] M4(System.ReadOnlySpan arg) => arg; } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (3,40): error CS0029: Cannot implicitly convert type 'System.Span' to 'int[]' // int[] M1(System.Span arg) => arg; Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("System.Span", "int[]").WithLocation(3, 40), @@ -1369,7 +1369,7 @@ class C string[] M4(System.ReadOnlySpan arg) => (string[])arg; } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (3,40): error CS0030: Cannot convert type 'System.Span' to 'int[]' // int[] M1(System.Span arg) => (int[])arg; Diagnostic(ErrorCode.ERR_NoExplicitConv, "(int[])arg").WithArguments("System.Span", "int[]").WithLocation(3, 40), @@ -1443,7 +1443,7 @@ void M2(params ReadOnlySpan s) { } void M3(params string[] s) { } } """; - var comp = CreateCompilationWithSpan(source); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source); var verifier = CompileAndVerify(comp).VerifyDiagnostics(); verifier.VerifyIL("C.M", """ { @@ -1484,7 +1484,7 @@ void M2(params ReadOnlySpan s) { } void M3(params object[] p) { } } """; - var comp = CreateCompilationWithSpan(source); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source); var verifier = CompileAndVerify(comp).VerifyDiagnostics(); verifier.VerifyIL("C.M", """ { @@ -1533,7 +1533,7 @@ class C Span M7(string[][][] a) => a; } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (5,37): error CS0029: Cannot implicitly convert type 'string[*,*]' to 'System.Span' // Span M1(string[,] a) => a; Diagnostic(ErrorCode.ERR_NoImplicitConv, "a").WithArguments("string[*,*]", "System.Span").WithLocation(5, 37), @@ -1569,7 +1569,7 @@ static class C delegate Span D(); """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + 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)); @@ -1593,7 +1593,7 @@ static class C delegate void D(int[] x); """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (3,5): error CS0123: No overload for 'C.M(Span)' matches delegate 'D' // C.R(C.M); Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "C.M").WithArguments("C.M(System.Span)", "D").WithLocation(3, 5)); @@ -1616,7 +1616,7 @@ static class C } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( // (4,5): error CS1503: Argument 1: cannot convert from 'method group' to 'System.Func' // C.R(a.M); Diagnostic(ErrorCode.ERR_BadArgType, "a.M").WithArguments("1", "method group", "System.Func").WithLocation(4, 5), @@ -1631,8 +1631,8 @@ static class C Diagnostic(ErrorCode.ERR_ValueTypeExtDelegate, "a.M").WithArguments("C.M(System.Span, int)", "System.Span").WithLocation(4, 5) }; - CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); - CreateCompilationWithSpan(source).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics); } [Fact] @@ -1652,7 +1652,7 @@ static class C } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).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), @@ -1673,8 +1673,8 @@ static class C Diagnostic(ErrorCode.ERR_CannotInferDelegateType, "x => a.M(x)").WithLocation(5, 10) }; - CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); - var comp = CreateCompilationWithSpan(source).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); @@ -1706,7 +1706,7 @@ static class C } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).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), @@ -1734,8 +1734,8 @@ static class C Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "M").WithArguments("int[]", "M").WithLocation(6, 12) }; - CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); - CreateCompilationWithSpan(source).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics); } [Fact] @@ -1758,7 +1758,7 @@ static class C } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).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), @@ -1798,8 +1798,8 @@ static class C Diagnostic(ErrorCode.ERR_CannotInferDelegateType, "x => a.M(x)").WithLocation(8, 10) }; - CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); - CreateCompilationWithSpan(source).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics); } [Theory, MemberData(nameof(LangVersions))] @@ -1820,7 +1820,7 @@ unsafe static class C } """; - CreateCompilationWithSpan(source, TestOptions.UnsafeReleaseExe, TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, TestOptions.UnsafeReleaseExe, TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (5,9): error CS8757: No overload for 'C.M(Span)' matches function pointer 'delegate*' // C.R(&C.M); Diagnostic(ErrorCode.ERR_MethFuncPtrMismatch, "&C.M").WithArguments("C.M(System.Span)", "delegate*").WithLocation(5, 9)); @@ -1845,7 +1845,7 @@ static class C var expectedOutput = "1 a"; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12); var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); verifier.VerifyIL("", $$""" { @@ -1931,11 +1931,11 @@ .locals init (System.Linq.Expressions.ParameterExpression V_0) } """; - comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); verifier.VerifyIL("", expectedIl); - comp = CreateCompilationWithSpan(source); + comp = CreateCompilationWithSpanAndMemoryExtensions(source); verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); verifier.VerifyIL("", expectedIl); } @@ -1957,7 +1957,7 @@ public static void R(Expression e) { } public static void M({{type}} x) { } } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); var verifier = CompileAndVerify(comp).VerifyDiagnostics(); verifier.VerifyIL("", $$""" { @@ -2010,7 +2010,7 @@ static class C } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + 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)); @@ -2030,7 +2030,7 @@ class C } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics(); verifier.VerifyIL("C.M", """ { @@ -2062,7 +2062,7 @@ class C interface I { } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics(); verifier.VerifyIL("C.M", """ { @@ -2093,7 +2093,7 @@ class C interface I<{{variance}} T> { } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (5,29): error CS9244: The type 'ReadOnlySpan' 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' // I> M(I x) => x; Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "M").WithArguments("I", "T", "System.ReadOnlySpan").WithLocation(5, 29), @@ -2137,7 +2137,7 @@ class C interface I { } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( // (6,12): error CS0029: Cannot implicitly convert type 'I[]' to 'System.Span>' // => x; Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("I[]", $"System.{type}>").WithLocation(6, 12)); @@ -2149,8 +2149,8 @@ interface I { } Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("I[]", $"System.{type}>").WithLocation(6, 12) }; - CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); - CreateCompilationWithSpan(source).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics); } [Theory, CombinatorialData] @@ -2168,15 +2168,15 @@ class C interface I { } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( // (6,12): error CS0030: Cannot convert type 'I[]' to 'System.Span>' // => (Span>)x; Diagnostic(ErrorCode.ERR_NoExplicitConv, $"({type}>)x").WithArguments("I[]", $"System.{type}>").WithLocation(6, 12)); - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics(); - comp = CreateCompilationWithSpan(source); + comp = CreateCompilationWithSpanAndMemoryExtensions(source); var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics(); verifier.VerifyIL("C.M", $$""" @@ -2204,7 +2204,7 @@ class C interface I { } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (5,49): error CS0266: Cannot implicitly convert type 'I[]' to 'System.ReadOnlySpan>'. An explicit conversion exists (are you missing a cast?) // ReadOnlySpan> M(I[] x) => x; Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("I[]", "System.ReadOnlySpan>").WithLocation(5, 49)); @@ -2230,7 +2230,7 @@ interface I } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); var verifier = CompileAndVerify(comp, expectedOutput: "C", verify: Verification.FailsILVerify).VerifyDiagnostics(); verifier.VerifyIL("C.M", """ { @@ -2255,7 +2255,7 @@ class C ReadOnlySpan M(int[] x) => x; } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (5,38): error CS0029: Cannot implicitly convert type 'int[]' to 'System.ReadOnlySpan' // ReadOnlySpan M(int[] x) => x; Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("int[]", "System.ReadOnlySpan").WithLocation(5, 38)); @@ -2274,7 +2274,7 @@ class C } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics(); verifier.VerifyIL("C.M", """ { @@ -2301,7 +2301,7 @@ class C where T : struct ReadOnlySpan M(T?[] x) => x; } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (5,34): error CS0029: Cannot implicitly convert type 'T?[]' to 'System.ReadOnlySpan' // ReadOnlySpan M(T?[] x) => x; Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("T?[]", "System.ReadOnlySpan").WithLocation(5, 34)); @@ -2318,7 +2318,7 @@ class C where T : struct ReadOnlySpan M(T[] x) => x; } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (5,34): error CS0029: Cannot implicitly convert type 'T[]' to 'System.ReadOnlySpan' // ReadOnlySpan M(T[] x) => x; Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("T[]", "System.ReadOnlySpan").WithLocation(5, 34)); @@ -2339,7 +2339,7 @@ class C {{constraints}} Span F4(T[] x) => (Span)x; } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (4,34): error CS0029: Cannot implicitly convert type 'T[]' to 'System.ReadOnlySpan' // ReadOnlySpan F1(T[] x) => x; Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("T[]", "System.ReadOnlySpan").WithLocation(4, 34), @@ -2369,7 +2369,7 @@ class C Span F4(T[] x) => (Span)x; } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (6,34): error CS0266: Cannot implicitly convert type 'T[]' to 'System.ReadOnlySpan'. An explicit conversion exists (are you missing a cast?) // ReadOnlySpan F1(T[] x) => x; Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("T[]", "System.ReadOnlySpan").WithLocation(6, 34), @@ -2393,7 +2393,7 @@ class C Span F4(T[] x) => (Span)x; } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(); + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(); // Note: although a breaking change, the previous would fail with a runtime exception // (Span's constructor checks that the element types are identical). @@ -2405,8 +2405,8 @@ class C Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("T[]", "System.Span").WithLocation(8, 26) }; - CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); - CreateCompilationWithSpan(source).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics(expectedDiagnostics); } [Theory, CombinatorialData] @@ -2435,17 +2435,17 @@ public static void M({{destination}} xs) } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( // (3,5): error CS1503: Argument 1: cannot convert from 'C' to 'System.Span' // D.M(new C()); Diagnostic(ErrorCode.ERR_BadArgType, "new C()").WithArguments("1", "C", $"System.{destination}").WithLocation(3, 5)); var expectedOutput = "456"; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); - comp = CreateCompilationWithSpan(source); + comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); } @@ -2476,17 +2476,17 @@ public static void M({{destination}} xs) } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( // (3,5): error CS0030: Cannot convert type 'C' to 'System.Span' // D.M((Span)new C()); Diagnostic(ErrorCode.ERR_NoExplicitConv, $"({destination})new C()").WithArguments("C", $"System.{destination}").WithLocation(3, 5)); var expectedOutput = "456"; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); - comp = CreateCompilationWithSpan(source); + comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); } @@ -2517,7 +2517,7 @@ public static void M({{destination}} xs) } } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); CompileAndVerify(comp, expectedOutput: "456").VerifyDiagnostics(); } @@ -2681,7 +2681,7 @@ static class C public static void E(this Span arg) => Console.Write(arg[1]); } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( // (7,40): error CS1929: 'int[]' does not contain a definition for 'E' and the best extension method overload 'C.E(Span)' requires a receiver of type 'System.Span' // public static void M(int[] arg) => arg.E(); Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("int[]", "E", "C.E(System.Span)", "System.Span").WithLocation(7, 40)); @@ -2699,11 +2699,11 @@ .maxstack 1 } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); verifier.VerifyIL("C.M", expectedIl); - comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); verifier.VerifyIL("C.M", expectedIl); } @@ -2722,7 +2722,7 @@ static class C public static void E(this ref Span arg) => Console.Write(arg[1]); } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + 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)' requires a receiver of type 'ref System.Span' // public static void M(int[] arg) => arg.E(); Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("int[]", "E", "C.E(ref System.Span)", "ref System.Span").WithLocation(7, 40)); @@ -2743,7 +2743,7 @@ static class C public static void E(this {{modifier}} Span arg) => Console.Write(arg[1]); } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( // (7,40): error CS1929: 'int[]' does not contain a definition for 'E' and the best extension method overload 'C.E(ref Span)' requires a receiver of type 'ref System.Span' // public static void M(int[] arg) => arg.E(); Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("int[]", "E", $"C.E({modifier} System.Span)", $"{modifier} System.Span").WithLocation(7, 40)); @@ -2764,11 +2764,11 @@ .locals init (System.Span V_0) } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); verifier.VerifyIL("C.M", expectedIl); - comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); verifier.VerifyIL("C.M", expectedIl); } @@ -2812,7 +2812,7 @@ public static void E(this Span arg) { } } """; // PROTOTYPE: Needs type inference to work. - CreateCompilationWithSpan(source).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source).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)); @@ -2829,7 +2829,7 @@ static class C public static void E(this Span arg) { } } """; - var comp = CreateCompilationWithSpan(source); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source); var verifier = CompileAndVerify(comp).VerifyDiagnostics(); verifier.VerifyIL("C.M", """ { @@ -2879,7 +2879,7 @@ static class C public static void E(this Span arg, T x) { } } """; - var comp = CreateCompilationWithSpan(source); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source); var verifier = CompileAndVerify(comp).VerifyDiagnostics(); verifier.VerifyIL("C.M", """ { @@ -2930,7 +2930,7 @@ static class C public static void E(this Span arg, T x) { } } """; - var comp = CreateCompilationWithSpan(source); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source); var verifier = CompileAndVerify(comp).VerifyDiagnostics(); verifier.VerifyIL("C.M", """ { @@ -2981,7 +2981,7 @@ static class C public static void E(this Span arg, T x) { } } """; - var comp = CreateCompilationWithSpan(source); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source); var verifier = CompileAndVerify(comp).VerifyDiagnostics(); verifier.VerifyIL("C.M", """ { @@ -3031,7 +3031,7 @@ static class C public static void E(this Span arg) { } } """; - var comp = CreateCompilationWithSpan(source); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source); var verifier = CompileAndVerify(comp).VerifyDiagnostics(); verifier.VerifyIL("C.M", """ { @@ -3080,7 +3080,7 @@ static class C public static void E(this Span arg) { } } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( // (4,40): error CS1929: 'int[]' does not contain a definition for 'E' and the best extension method overload 'C.E(Span)' requires a receiver of type 'System.Span' // public static void M(int[] arg) => arg.E(); Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("int[]", "E", "C.E(System.Span)", "System.Span").WithLocation(4, 40)); @@ -3125,7 +3125,7 @@ static class C var expectedOutput = "8"; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); verifier.VerifyIL("C.M", """ { @@ -3154,7 +3154,7 @@ static void E2(this object[] arg) { } static void E3(this string[] arg) { } } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (3,45): error CS1929: 'Span' 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 arg) => arg.E1(); Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("System.Span", "E1", "C.E1(int[])", "int[]").WithLocation(3, 45), @@ -3184,7 +3184,7 @@ static void E2(this object[] arg) { } static void E3(this string[] arg) { } } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (3,46): error CS0030: Cannot convert type 'System.Span' to 'int[]' // static void M1(System.Span arg) => ((int[])arg).E1(); Diagnostic(ErrorCode.ERR_NoExplicitConv, "(int[])arg").WithArguments("System.Span", "int[]").WithLocation(3, 46), @@ -3263,7 +3263,7 @@ static void F1(T[] a) } } """; - CreateCompilationWithSpan(source).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics( // (11,9): error CS1929: 'T[]' does not contain a definition for 'M1' and the best extension method overload 'Extensions.M1(Span)' requires a receiver of type 'System.Span' // a.M1(); Diagnostic(ErrorCode.ERR_BadInstanceArgType, "a").WithArguments("T[]", "M1", "Extensions.M1(System.Span)", "System.Span").WithLocation(11, 9), @@ -3293,7 +3293,7 @@ static void F1(T[] a) } } """; - CreateCompilationWithSpan(source).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics( // (13,9): error CS1929: 'T[]' does not contain a definition for 'M1' and the best extension method overload 'Extensions.M1(Span)' requires a receiver of type 'System.Span' // a.M1(); Diagnostic(ErrorCode.ERR_BadInstanceArgType, "a").WithArguments("T[]", "M1", "Extensions.M1(System.Span)", "System.Span").WithLocation(13, 9)); @@ -3313,7 +3313,7 @@ static class C public static void E(this ReadOnlySpan arg) => Console.Write(arg[1]); } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( // (7,43): error CS1929: 'string[]' does not contain a definition for 'E' and the best extension method overload 'C.E(ReadOnlySpan)' requires a receiver of type 'System.ReadOnlySpan' // public static void M(string[] arg) => arg.E(); Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("string[]", "E", "C.E(System.ReadOnlySpan)", "System.ReadOnlySpan").WithLocation(7, 43)); @@ -3334,11 +3334,11 @@ .locals init (object[] V_0) } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); verifier.VerifyIL("C.M", expectedIl); - comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); verifier.VerifyIL("C.M", expectedIl); } @@ -3360,17 +3360,17 @@ static class C } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( // (5,3): error CS0121: The call is ambiguous between the following methods or properties: 'C.M(Span)' and 'C.M(IEnumerable)' // C.M(a); Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("C.M(System.Span)", "C.M(System.Collections.Generic.IEnumerable)").WithLocation(5, 3)); var expectedOutput = "1"; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); - comp = CreateCompilationWithSpan(source); + comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); } @@ -3389,7 +3389,7 @@ static class C public static void M(IEnumerable x) => Console.Write(2); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); CompileAndVerify(comp, expectedOutput: "1").VerifyDiagnostics(); } @@ -3410,17 +3410,17 @@ class C } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( // (5,13): error CS0121: The call is ambiguous between the following methods or properties: 'C.C(Span)' and 'C.C(IEnumerable)' // var c = new C(a); Diagnostic(ErrorCode.ERR_AmbigCall, "C").WithArguments("C.C(System.Span)", "C.C(System.Collections.Generic.IEnumerable)").WithLocation(5, 13)); var expectedOutput = "1"; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); - comp = CreateCompilationWithSpan(source); + comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); } @@ -3441,7 +3441,7 @@ static class C public static void M(ReadOnlySpan x) => Console.Write(" o" + x[0]); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); CompileAndVerify(comp, expectedOutput: "sa oSystem.String[] oa").VerifyDiagnostics(); } @@ -3461,7 +3461,7 @@ public static void M(string[] x) { } public static void M(ReadOnlySpan x) { } } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (4,3): error CS0121: The call is ambiguous between the following methods or properties: 'C.M(string[])' and 'C.M(ReadOnlySpan)' // C.M([..a]); Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("C.M(string[])", "C.M(System.ReadOnlySpan)").WithLocation(4, 3), @@ -3489,15 +3489,15 @@ static class C public static void M(ReadOnlySpan x) => Console.Write(" r" + x[0]); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12); CompileAndVerify(comp, expectedOutput: "aa rSystem.String[] ra ra ra").VerifyDiagnostics(); var expectedOutput = "ra rSystem.String[] ra ra ra"; - comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); - comp = CreateCompilationWithSpan(source); + comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); } @@ -3519,7 +3519,7 @@ static class C public static void M(ReadOnlySpan x) => Console.Write(" r" + x[0]); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); CompileAndVerify(comp, expectedOutput: "aa rSystem.Object[] ra ra").VerifyDiagnostics(); } @@ -3539,7 +3539,7 @@ static class C public static void M(ReadOnlySpan x) => Console.Write(2); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); CompileAndVerify(comp, expectedOutput: "111").VerifyDiagnostics(); } @@ -3560,7 +3560,7 @@ static class C public static void M(ReadOnlySpan x) => Console.Write(" o" + x[0]); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); CompileAndVerify(comp, expectedOutput: "sa").VerifyDiagnostics(); } @@ -3581,15 +3581,15 @@ static class C public static void M(ReadOnlySpan x) => Console.Write(" r" + x[0]); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12); CompileAndVerify(comp, expectedOutput: "aa").VerifyDiagnostics(); var expectedOutput = "ra"; - comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); - comp = CreateCompilationWithSpan(source); + comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); } @@ -3610,7 +3610,7 @@ static class C public static void M(ReadOnlySpan x) => Console.Write(" r" + x[0]); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); CompileAndVerify(comp, expectedOutput: "aa").VerifyDiagnostics(); } @@ -3632,7 +3632,7 @@ static class C public static void M(ReadOnlySpan x) => Console.Write(" 2" + x.Length); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); CompileAndVerify(comp, expectedOutput: "1null 1null 1null").VerifyDiagnostics(); } @@ -3655,7 +3655,7 @@ static class C public static void M(params ReadOnlySpan x) => Console.Write(" o" + x[0]); } """; - var comp = CreateCompilationWithSpan(source); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: "sa oSystem.String[] oSystem.String[] oa sa").VerifyDiagnostics(); } @@ -3675,7 +3675,7 @@ public static void M(params string[] x) { } public static void M(params ReadOnlySpan x) { } } """; - CreateCompilationWithSpan(source).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source).VerifyDiagnostics( // (4,3): error CS0121: The call is ambiguous between the following methods or properties: 'C.M(params string[])' and 'C.M(params ReadOnlySpan)' // C.M([..a]); Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("C.M(params string[])", "C.M(params System.ReadOnlySpan)").WithLocation(4, 3), @@ -3703,7 +3703,7 @@ static class C public static void M(params ReadOnlySpan x) => Console.Write(" r" + x[0]); } """; - var comp = CreateCompilationWithSpan(source); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: "ra rSystem.String[] ra ra ra").VerifyDiagnostics(); } @@ -3725,7 +3725,7 @@ static class C public static void M(params ReadOnlySpan x) => Console.Write(" r" + x[0]); } """; - var comp = CreateCompilationWithSpan(source); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: "aa rSystem.Object[] ra ra").VerifyDiagnostics(); } @@ -3744,7 +3744,7 @@ static class C public static void M(params ReadOnlySpan x) => Console.Write(2); } """; - var comp = CreateCompilationWithSpan(source); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: "11").VerifyDiagnostics(); } @@ -3763,7 +3763,7 @@ static class C public static void M(this ReadOnlySpan x) => Console.Write(" o" + x[0]); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); CompileAndVerify(comp, expectedOutput: "sa").VerifyDiagnostics(); } @@ -3782,15 +3782,15 @@ static class C public static void M(this ReadOnlySpan x) => Console.Write(" s" + x[0]); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12); CompileAndVerify(comp, expectedOutput: "oa").VerifyDiagnostics(); var expectedOutput = "sa"; - comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); - comp = CreateCompilationWithSpan(source); + comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); } @@ -3809,15 +3809,15 @@ static class C public static void M(this ReadOnlySpan x) => Console.Write(" r" + x[0]); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12); CompileAndVerify(comp, expectedOutput: "aa").VerifyDiagnostics(); var expectedOutput = "ra"; - comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); - comp = CreateCompilationWithSpan(source); + comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); } @@ -3836,7 +3836,7 @@ static class C public static void M(this ReadOnlySpan x) => Console.Write(" r" + x[0]); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); CompileAndVerify(comp, expectedOutput: "aa").VerifyDiagnostics(); } @@ -3855,7 +3855,7 @@ static class C public static void M(this ReadOnlySpan x) => Console.Write(2); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); CompileAndVerify(comp, expectedOutput: "11").VerifyDiagnostics(); } @@ -3874,7 +3874,7 @@ static class C public static void M(this Span x) => Console.Write(" s" + x[0]); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); CompileAndVerify(comp, expectedOutput: "aa").VerifyDiagnostics(); } @@ -3893,15 +3893,15 @@ static class C public static void M(this Span x) => Console.Write(" s" + x[0]); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12); CompileAndVerify(comp, expectedOutput: "aa").VerifyDiagnostics(); var expectedOutput = "sa"; - comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); - comp = CreateCompilationWithSpan(source); + comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); } @@ -3922,7 +3922,7 @@ static class C public static void M(this Span x) => Console.Write(" s" + x[0]); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); CompileAndVerify(comp, expectedOutput: "aa").VerifyDiagnostics(); } @@ -3943,15 +3943,15 @@ static class C public static void M(this Span x) => Console.Write(" s" + x[0]); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12); CompileAndVerify(comp, expectedOutput: "aa").VerifyDiagnostics(); var expectedOutput = "sa"; - comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); - comp = CreateCompilationWithSpan(source); + comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); } @@ -3971,7 +3971,7 @@ static class C public static void M(ReadOnlySpan arg) => Console.Write(2); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); CompileAndVerify(comp, expectedOutput: "112").VerifyDiagnostics(); } @@ -3993,15 +3993,15 @@ static class C public static void M(ReadOnlySpan arg) => Console.Write(2); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12); CompileAndVerify(comp, expectedOutput: "1121").VerifyDiagnostics(); var expectedOutput = "1122"; - comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); - comp = CreateCompilationWithSpan(source); + comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); } @@ -4020,7 +4020,7 @@ public static void M(Span arg) { } public static void M(ReadOnlySpan arg) { } } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (3,5): error CS1503: Argument 1: cannot convert from 'System.Span' to 'System.Span' // C.M(default(Span)); Diagnostic(ErrorCode.ERR_BadArgType, "default(Span)").WithArguments("1", "System.Span", "System.Span").WithLocation(3, 5), @@ -4043,17 +4043,17 @@ static class C public static void E(this ReadOnlySpan arg) => Console.Write(2); } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( // (3,2): error CS1929: 'int[]' does not contain a definition for 'E' and the best extension method overload 'C.E(Span)' requires a receiver of type 'System.Span' // (new int[0]).E(); Diagnostic(ErrorCode.ERR_BadInstanceArgType, "new int[0]").WithArguments("int[]", "E", "C.E(System.Span)", "System.Span").WithLocation(3, 2)); var expectedOutput = "1"; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); - comp = CreateCompilationWithSpan(source); + comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); } @@ -4072,7 +4072,7 @@ static class C public static void E(this ReadOnlySpan arg) => Console.Write(2); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); CompileAndVerify(comp, expectedOutput: "12").VerifyDiagnostics(); } @@ -4091,7 +4091,7 @@ static class C public static void E(this ReadOnlySpan arg) => Console.Write(2); } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( // (3,2): error CS1929: 'string[]' does not contain a definition for 'E' and the best extension method overload 'C.E(Span)' requires a receiver of type 'System.Span' // (new string[0]).E(); Diagnostic(ErrorCode.ERR_BadInstanceArgType, "new string[0]").WithArguments("string[]", "E", "C.E(System.Span)", "System.Span").WithLocation(3, 2), @@ -4101,10 +4101,10 @@ static class C var expectedOutput = "21"; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); - comp = CreateCompilationWithSpan(source); + comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); } @@ -4123,7 +4123,7 @@ public static void E(this Span arg) { } public static void E(this ReadOnlySpan arg) { } } """; - CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( // (3,1): error CS1929: 'Span' does not contain a definition for 'E' and the best extension method overload 'C.E(Span)' requires a receiver of type 'System.Span' // default(Span).E(); Diagnostic(ErrorCode.ERR_BadInstanceArgType, "default(Span)").WithArguments("System.Span", "E", "C.E(System.Span)", "System.Span").WithLocation(3, 1), @@ -4163,15 +4163,15 @@ static class C public static void M(IEnumerable x) => Console.Write(" e" + x.First()); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12); 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 = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); - comp = CreateCompilationWithSpan(source); + comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); } @@ -4204,7 +4204,7 @@ static class C public static void M(params IEnumerable x) => Console.Write(" e" + x.First()); } """; - var comp = CreateCompilationWithSpan(source); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: "ra rSystem.String[] ra ra ra ab rSystem.Object[] rb rb").VerifyDiagnostics(); } @@ -4230,15 +4230,15 @@ static class C public static void M(this IEnumerable x) => Console.Write(" e" + x.First()); } """; - var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12); CompileAndVerify(comp, expectedOutput: "aa ab").VerifyDiagnostics(); var expectedOutput = "ra ab"; - comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.RegularNext); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); - comp = CreateCompilationWithSpan(source); + comp = CreateCompilationWithSpanAndMemoryExtensions(source); CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); } } From 9dfaff2de68d38d49cabe92b74eadd5684cd1e9b Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Fri, 12 Jul 2024 11:03:23 +0200 Subject: [PATCH 2/7] Fix span source --- .../Test/Utilities/CSharp/TestSources.cs | 56 +++++++++++++------ 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/src/Compilers/Test/Utilities/CSharp/TestSources.cs b/src/Compilers/Test/Utilities/CSharp/TestSources.cs index f550ea7be6781..a740e48511826 100644 --- a/src/Compilers/Test/Utilities/CSharp/TestSources.cs +++ b/src/Compilers/Test/Utilities/CSharp/TestSources.cs @@ -13,9 +13,10 @@ namespace System { public readonly ref struct Span { - private readonly T[] arr; + internal readonly T[] arr; + internal readonly int start; - public ref T this[int i] => ref arr[i]; + public ref T this[int i] => ref arr[start + i]; public override int GetHashCode() => 1; public int Length { get; } @@ -30,8 +31,23 @@ public Span(T[] arr) this.arr = arr; this.Length = arr is null ? 0 : arr.Length; } + + public Span(T[] arr, int start, int length) + { + if (start + length > arr.Length) + { + throw new ArgumentOutOfRangeException(); + } - public void CopyTo(Span other) { } + this.arr = arr; + this.start = start; + this.Length = length; + } + + public void CopyTo(Span other) + { + Array.Copy(arr, start, other.arr, other.start, Length); + } /// Gets an enumerator for this span. public Enumerator GetEnumerator() => new Enumerator(this); @@ -76,19 +92,15 @@ public ref T Current public static implicit operator ReadOnlySpan(Span span) => new ReadOnlySpan(span.arr); - public Span Slice(int offset, int length) - { - var copy = new T[length]; - Array.Copy(arr, offset, copy, 0, length); - return new Span(copy); - } + public Span Slice(int offset, int length) => new Span(this.arr, offset, length); } public readonly ref struct ReadOnlySpan { private readonly T[] arr; + private readonly int start; - public ref readonly T this[int i] => ref arr[i]; + public ref readonly T this[int i] => ref arr[start + i]; public override int GetHashCode() => 2; public int Length { get; } @@ -103,8 +115,23 @@ public ReadOnlySpan(T[] arr) this.arr = arr; this.Length = arr is null ? 0 : arr.Length; } + + public ReadOnlySpan(T[] arr, int start, int length) + { + if (start + length > arr.Length) + { + throw new ArgumentOutOfRangeException(); + } + + this.arr = arr; + this.start = start; + this.Length = length; + } - public void CopyTo(Span other) { } + public void CopyTo(Span other) + { + Array.Copy(arr, start, other.arr, other.start, Length); + } /// Gets an enumerator for this span. public Enumerator GetEnumerator() => new Enumerator(this); @@ -149,12 +176,7 @@ public ref readonly T Current public static implicit operator ReadOnlySpan(string stringValue) => string.IsNullOrEmpty(stringValue) ? default : new ReadOnlySpan((T[])(object)stringValue.ToCharArray()); - public ReadOnlySpan Slice(int offset, int length) - { - var copy = new T[length]; - Array.Copy(arr, offset, copy, 0, length); - return new ReadOnlySpan(copy); - } + public ReadOnlySpan Slice(int offset, int length) => new ReadOnlySpan(this.arr, offset, length); } public readonly ref struct SpanLike From 5988b4fd3f8f0f6883d5a78570d9b5119930d68b Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Fri, 12 Jul 2024 11:07:47 +0200 Subject: [PATCH 3/7] Update tests on netcore --- .../CSharp/Test/Emit3/FirstClassSpanTests.cs | 84 ++++++++++++------- 1 file changed, 54 insertions(+), 30 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs b/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs index 25df33d6930c1..ce8cb494ed8ee 100644 --- a/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs +++ b/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs @@ -533,34 +533,58 @@ static class C var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); var verifier = CompileAndVerify(comp, expectedOutput: "12").VerifyDiagnostics(); - verifier.VerifyIL("", """ - { - // 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 System.Span.op_Implicit(int[])" - IL_000f: call "void C.M1(System.Span)" - IL_0014: ldsfld "int[] .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 .26B25D457597A7B0463F9620F666DD10AA2C4373A505967C7C8D70922A2D6ECE" - IL_0029: call "void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)" - IL_002e: dup - IL_002f: stsfld "int[] .26B25D457597A7B0463F9620F666DD10AA2C4373A505967C7C8D70922A2D6ECE_A6" - IL_0034: newobj "System.ReadOnlySpan..ctor(int[])" - IL_0039: call "void C.M2(System.ReadOnlySpan)" - IL_003e: ret - } - """); + if (ExecutionConditionUtil.IsCoreClr) + { + verifier.VerifyIL("", """ + { + // 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 System.Span.op_Implicit(int[])" + IL_000f: call "void C.M1(System.Span)" + IL_0014: ldtoken ".__StaticArrayInitTypeSize=4_Align=4 .26B25D457597A7B0463F9620F666DD10AA2C4373A505967C7C8D70922A2D6ECE4" + IL_0019: call "System.ReadOnlySpan System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan(System.RuntimeFieldHandle)" + IL_001e: call "void C.M2(System.ReadOnlySpan)" + IL_0023: ret + } + """); + } + else + { + verifier.VerifyIL("", """ + { + // 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 System.Span.op_Implicit(int[])" + IL_000f: call "void C.M1(System.Span)" + IL_0014: ldsfld "int[] .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 .26B25D457597A7B0463F9620F666DD10AA2C4373A505967C7C8D70922A2D6ECE" + IL_0029: call "void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)" + IL_002e: dup + IL_002f: stsfld "int[] .26B25D457597A7B0463F9620F666DD10AA2C4373A505967C7C8D70922A2D6ECE_A6" + IL_0034: newobj "System.ReadOnlySpan..ctor(int[])" + IL_0039: call "void C.M2(System.ReadOnlySpan)" + IL_003e: ret + } + """); + } } [Theory, MemberData(nameof(LangVersions))] @@ -3985,7 +4009,7 @@ public void OverloadResolution_SpanVsReadOnlySpan_02() C.M(default(Span)); C.M(default(ReadOnlySpan)); - C.M(new string[0]); + try { C.M(new string[0]); } catch (ArrayTypeMismatchException) { Console.Write(3); } static class C { @@ -3994,7 +4018,7 @@ static class C } """; var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular12); - CompileAndVerify(comp, expectedOutput: "1121").VerifyDiagnostics(); + CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsCoreClr ? "1123" : "1121").VerifyDiagnostics(); var expectedOutput = "1122"; From 2e98bd221882d987a91387f1486cc120b1cb8ed6 Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Thu, 11 Jul 2024 15:06:20 +0200 Subject: [PATCH 4/7] Avoid problems with string to ReadOnlySpan --- .../CSharp/Test/Emit3/FirstClassSpanTests.cs | 4 +++- .../Test/Utilities/CSharp/CSharpTestBase.cs | 5 +++-- src/Compilers/Test/Utilities/CSharp/TestSources.cs | 13 ++++++++++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs b/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs index ce8cb494ed8ee..2287d69ef80cf 100644 --- a/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs +++ b/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs @@ -1981,7 +1981,9 @@ public static void R(Expression e) { } public static void M({{type}} x) { } } """; - var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, + parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion), + noStringToReadOnlySpanConversionInSource: true); var verifier = CompileAndVerify(comp).VerifyDiagnostics(); verifier.VerifyIL("", $$""" { diff --git a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs index d660bee42e7fa..731075567b8d3 100644 --- a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs +++ b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs @@ -2575,7 +2575,7 @@ protected static CSharpCompilation CreateCompilationWithIndexAndRangeAndSpan(CSh parseOptions: parseOptions); } - protected static CSharpCompilation CreateCompilationWithSpanAndMemoryExtensions(CSharpTestSource text, CSharpCompilationOptions options = null, CSharpParseOptions parseOptions = null, TargetFramework targetFramework = TargetFramework.NetCoreApp) + protected static CSharpCompilation CreateCompilationWithSpanAndMemoryExtensions(CSharpTestSource text, CSharpCompilationOptions options = null, CSharpParseOptions parseOptions = null, TargetFramework targetFramework = TargetFramework.NetCoreApp, bool noStringToReadOnlySpanConversionInSource = false) { if (ExecutionConditionUtil.IsCoreClr) { @@ -2583,7 +2583,8 @@ protected static CSharpCompilation CreateCompilationWithSpanAndMemoryExtensions( } else { - var reference = CreateCompilation(new[] { TestSources.Span, TestSources.MemoryExtensions }, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + var spanSource = noStringToReadOnlySpanConversionInSource ? TestSources.SpanWithoutStringConversion : TestSources.Span; + var reference = CreateCompilation(new[] { spanSource, TestSources.MemoryExtensions }, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); return CreateCompilation( text, diff --git a/src/Compilers/Test/Utilities/CSharp/TestSources.cs b/src/Compilers/Test/Utilities/CSharp/TestSources.cs index a740e48511826..afa615376f192 100644 --- a/src/Compilers/Test/Utilities/CSharp/TestSources.cs +++ b/src/Compilers/Test/Utilities/CSharp/TestSources.cs @@ -8,6 +8,11 @@ namespace Microsoft.CodeAnalysis.CSharp.Test.Utilities { internal static class TestSources { + private const string StringToReadOnlySpanConversion = """ + // NOTE: This is defined on String in the BCL (and the target type is non-generic ReadOnlySpan). + public static implicit operator ReadOnlySpan(string stringValue) => string.IsNullOrEmpty(stringValue) ? default : new ReadOnlySpan((T[])(object)stringValue.ToCharArray()); + """; + internal const string Span = @" namespace System { @@ -174,7 +179,7 @@ public ref readonly T Current public static implicit operator ReadOnlySpan(T[] array) => array == null ? default : new ReadOnlySpan(array); - public static implicit operator ReadOnlySpan(string stringValue) => string.IsNullOrEmpty(stringValue) ? default : new ReadOnlySpan((T[])(object)stringValue.ToCharArray()); + " + StringToReadOnlySpanConversion + @" public ReadOnlySpan Slice(int offset, int length) => new ReadOnlySpan(this.arr, offset, length); } @@ -249,6 +254,12 @@ public static T[] ToArray(void* ptr, int count) } }"; + /// + /// Use if the non-standardly defined string-to-ReadOnlySpan conversion causes problems + /// (e.g., when converting from null to ReadOnlySpan you would get an ambiguity for the user-defined conversion). + /// + internal static readonly string SpanWithoutStringConversion = Span.Replace(StringToReadOnlySpanConversion, ""); + internal const string Index = @" namespace System From c899a80cc10eac98f955ce67ad3c1a0c33ee5212 Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Mon, 15 Jul 2024 13:36:04 +0200 Subject: [PATCH 5/7] Use new span source --- src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs b/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs index 2287d69ef80cf..eb31fc113b347 100644 --- a/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs +++ b/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs @@ -600,10 +600,10 @@ static class C public static void M2(span::System.ReadOnlySpan s) => System.Console.Write(s[0]); } """; - var spanDll = CreateCompilation(SpanSource, options: TestOptions.UnsafeReleaseDll) + var spanDll = CreateCompilation(TestSources.Span, options: TestOptions.UnsafeReleaseDll) .VerifyDiagnostics() .EmitToImageReference(aliases: ["span"]); - var verifier = CompileAndVerify([source, SpanSource], + var verifier = CompileAndVerify([source, TestSources.Span], references: [spanDll], expectedOutput: "12", verify: Verification.Fails, From d3eb2f714730ceaaecf4cc17268d0014d416497b Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Tue, 16 Jul 2024 09:53:00 +0200 Subject: [PATCH 6/7] Revert "Avoid problems with string to ReadOnlySpan" This reverts commit 2e98bd221882d987a91387f1486cc120b1cb8ed6. --- .../CSharp/Test/Emit3/FirstClassSpanTests.cs | 4 +--- .../Test/Utilities/CSharp/CSharpTestBase.cs | 5 ++--- src/Compilers/Test/Utilities/CSharp/TestSources.cs | 13 +------------ 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs b/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs index eb31fc113b347..439384ad8df7e 100644 --- a/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs +++ b/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs @@ -1981,9 +1981,7 @@ public static void R(Expression e) { } public static void M({{type}} x) { } } """; - var comp = CreateCompilationWithSpanAndMemoryExtensions(source, - parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion), - noStringToReadOnlySpanConversionInSource: true); + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); var verifier = CompileAndVerify(comp).VerifyDiagnostics(); verifier.VerifyIL("", $$""" { diff --git a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs index 731075567b8d3..d660bee42e7fa 100644 --- a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs +++ b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs @@ -2575,7 +2575,7 @@ protected static CSharpCompilation CreateCompilationWithIndexAndRangeAndSpan(CSh parseOptions: parseOptions); } - protected static CSharpCompilation CreateCompilationWithSpanAndMemoryExtensions(CSharpTestSource text, CSharpCompilationOptions options = null, CSharpParseOptions parseOptions = null, TargetFramework targetFramework = TargetFramework.NetCoreApp, bool noStringToReadOnlySpanConversionInSource = false) + protected static CSharpCompilation CreateCompilationWithSpanAndMemoryExtensions(CSharpTestSource text, CSharpCompilationOptions options = null, CSharpParseOptions parseOptions = null, TargetFramework targetFramework = TargetFramework.NetCoreApp) { if (ExecutionConditionUtil.IsCoreClr) { @@ -2583,8 +2583,7 @@ protected static CSharpCompilation CreateCompilationWithSpanAndMemoryExtensions( } else { - var spanSource = noStringToReadOnlySpanConversionInSource ? TestSources.SpanWithoutStringConversion : TestSources.Span; - var reference = CreateCompilation(new[] { spanSource, TestSources.MemoryExtensions }, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + var reference = CreateCompilation(new[] { TestSources.Span, TestSources.MemoryExtensions }, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); return CreateCompilation( text, diff --git a/src/Compilers/Test/Utilities/CSharp/TestSources.cs b/src/Compilers/Test/Utilities/CSharp/TestSources.cs index afa615376f192..a740e48511826 100644 --- a/src/Compilers/Test/Utilities/CSharp/TestSources.cs +++ b/src/Compilers/Test/Utilities/CSharp/TestSources.cs @@ -8,11 +8,6 @@ namespace Microsoft.CodeAnalysis.CSharp.Test.Utilities { internal static class TestSources { - private const string StringToReadOnlySpanConversion = """ - // NOTE: This is defined on String in the BCL (and the target type is non-generic ReadOnlySpan). - public static implicit operator ReadOnlySpan(string stringValue) => string.IsNullOrEmpty(stringValue) ? default : new ReadOnlySpan((T[])(object)stringValue.ToCharArray()); - """; - internal const string Span = @" namespace System { @@ -179,7 +174,7 @@ public ref readonly T Current public static implicit operator ReadOnlySpan(T[] array) => array == null ? default : new ReadOnlySpan(array); - " + StringToReadOnlySpanConversion + @" + public static implicit operator ReadOnlySpan(string stringValue) => string.IsNullOrEmpty(stringValue) ? default : new ReadOnlySpan((T[])(object)stringValue.ToCharArray()); public ReadOnlySpan Slice(int offset, int length) => new ReadOnlySpan(this.arr, offset, length); } @@ -254,12 +249,6 @@ public static T[] ToArray(void* ptr, int count) } }"; - /// - /// Use if the non-standardly defined string-to-ReadOnlySpan conversion causes problems - /// (e.g., when converting from null to ReadOnlySpan you would get an ambiguity for the user-defined conversion). - /// - internal static readonly string SpanWithoutStringConversion = Span.Replace(StringToReadOnlySpanConversion, ""); - internal const string Index = @" namespace System From 08d89deaf40d030461a78ab315c5fdee847e6b93 Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Tue, 16 Jul 2024 11:07:00 +0200 Subject: [PATCH 7/7] Special-case a test --- .../CSharp/Test/Emit3/FirstClassSpanTests.cs | 98 ++++++++++++++++--- 1 file changed, 87 insertions(+), 11 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs b/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs index 439384ad8df7e..d57e1ce0b174d 100644 --- a/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs +++ b/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs @@ -1964,12 +1964,10 @@ .locals init (System.Linq.Expressions.ParameterExpression V_0) verifier.VerifyIL("", expectedIl); } - [Theory, CombinatorialData] - public void Conversion_Array_Span_Implicit_ExpressionTree_02( - [CombinatorialLangVersions] LanguageVersion langVersion, - [CombinatorialValues("Span", "ReadOnlySpan")] string type) + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_Span_Implicit_ExpressionTree_02(LanguageVersion langVersion) { - var source = $$""" + var source = """ using System; using System.Linq.Expressions; @@ -1978,17 +1976,17 @@ public void Conversion_Array_Span_Implicit_ExpressionTree_02( static class C { public static void R(Expression e) { } - public static void M({{type}} x) { } + public static void M(Span x) { } } """; var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); var verifier = CompileAndVerify(comp).VerifyDiagnostics(); - verifier.VerifyIL("", $$""" + verifier.VerifyIL("", """ { // Code size 97 (0x61) .maxstack 9 IL_0000: ldnull - IL_0001: ldtoken "void C.M(System.{{type}})" + IL_0001: ldtoken "void C.M(System.Span)" IL_0006: call "System.Reflection.MethodBase System.Reflection.MethodBase.GetMethodFromHandle(System.RuntimeMethodHandle)" IL_000b: castclass "System.Reflection.MethodInfo" IL_0010: ldc.i4.1 @@ -1999,10 +1997,10 @@ .maxstack 9 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.{{type}}" + IL_0028: ldtoken "System.Span" IL_002d: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" - IL_0032: ldtoken "System.{{type}} System.{{type}}.op_Implicit(string[])" - IL_0037: ldtoken "System.{{type}}" + IL_0032: ldtoken "System.Span System.Span.op_Implicit(string[])" + IL_0037: ldtoken "System.Span" 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)" @@ -2016,6 +2014,84 @@ .maxstack 9 """); } + [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 e) { } + public static void M(ReadOnlySpan x) { } + } + """; + + var expectedIl = """ + { + // Code size 97 (0x61) + .maxstack 9 + IL_0000: ldnull + IL_0001: ldtoken "void C.M(System.ReadOnlySpan)" + 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" + IL_002d: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" + IL_0032: ldtoken "System.ReadOnlySpan System.ReadOnlySpan.op_Implicit(string[])" + IL_0037: ldtoken "System.ReadOnlySpan" + 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()" + IL_0056: call "System.Linq.Expressions.Expression System.Linq.Expressions.Expression.Lambda(System.Linq.Expressions.Expression, params System.Linq.Expressions.ParameterExpression[])" + IL_005b: call "void C.R(System.Linq.Expressions.Expression)" + IL_0060: ret + } + """; + + if (ExecutionConditionUtil.IsCoreClr) + { + var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var verifier = CompileAndVerify(comp).VerifyDiagnostics(); + verifier.VerifyIL("", expectedIl); + } + else + { + // The test ReadOnlySpan source contains a non-standard operator from `string` to `ReadOnlySpan` + // which is ambiguous with the one from `T[]` to `ReadOnlySpan` resulting in this slightly misleading error. + CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + // (4,15): error CS0037: Cannot convert null to 'ReadOnlySpan' because it is a non-nullable value type + // C.R(() => C.M(null)); + Diagnostic(ErrorCode.ERR_ValueCantBeNull, "null").WithArguments("System.ReadOnlySpan").WithLocation(4, 15)); + + var source2 = """ + namespace System; + + public readonly ref struct ReadOnlySpan + { + public static implicit operator ReadOnlySpan(T[] array) => throw null; + } + """; + + var comp = CreateCompilation([source, source2], parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var verifier = CompileAndVerify(comp).VerifyDiagnostics(); + verifier.VerifyIL("", expectedIl); + } + } + [Theory, CombinatorialData] public void Conversion_Array_Span_Implicit_ExpressionTree_03( [CombinatorialLangVersions] LanguageVersion langVersion,