diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs index 6f24e552a0ed7..7c90dfe9cffe2 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs @@ -484,6 +484,18 @@ void checkConstraintLanguageVersionAndRuntimeSupportForConversion(SyntaxNode syn CheckInlineArrayTypeIsSupported(syntax, source.Type, elementField.Type, diagnostics); } + else if (conversion.IsSpan) + { + if (destination.OriginalDefinition.Equals(Compilation.GetWellKnownType(WellKnownType.System_ReadOnlySpan_T), TypeCompareKind.AllIgnoreOptions)) + { + _ = GetWellKnownTypeMember(WellKnownMember.System_ReadOnlySpan_T__ctor_Array, diagnostics, syntax: syntax); + } + else + { + Debug.Assert(destination.OriginalDefinition.Equals(Compilation.GetWellKnownType(WellKnownType.System_Span_T), TypeCompareKind.AllIgnoreOptions)); + _ = GetWellKnownTypeMember(WellKnownMember.System_Span_T__ctor_Array, diagnostics, syntax: syntax); + } + } } } diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs index 8a32d3821bb6f..572b1e37ed34a 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs @@ -1241,7 +1241,7 @@ private BoundCall BindInvocationExpressionContinued( ParameterSymbol receiverParameter = method.Parameters.First(); // we will have a different receiver if ReplaceTypeOrValueReceiver has unwrapped TypeOrValue - if ((object)receiver != receiverArgument) + if ((object)receiver != methodGroup.Receiver) { // Because the receiver didn't pass through CoerceArguments, we need to apply an appropriate conversion here. Debug.Assert(argsToParams.IsDefault || argsToParams[0] == 0); diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/Conversion.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/Conversion.cs index 96888f4a2ff91..4a298445c97db 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/Conversion.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/Conversion.cs @@ -244,6 +244,7 @@ private static void AssertTrivialConversion(ConversionKind kind) case ConversionKind.InterpolatedString: case ConversionKind.InterpolatedStringHandler: case ConversionKind.InlineArray: + case ConversionKind.ImplicitSpan: isTrivial = true; break; @@ -294,6 +295,7 @@ internal static Conversion GetTrivialConversion(ConversionKind kind) internal static Conversion ImplicitPointer => new Conversion(ConversionKind.ImplicitPointer); internal static Conversion FunctionType => new Conversion(ConversionKind.FunctionType); internal static Conversion InlineArray => new Conversion(ConversionKind.InlineArray); + internal static Conversion ImplicitSpan => new Conversion(ConversionKind.ImplicitSpan); // trivial conversions that could be underlying in nullable conversion // NOTE: tuple conversions can be underlying as well, but they are not trivial @@ -819,6 +821,20 @@ public bool IsReference } } + /// + /// Returns true if the conversion is a span conversion. + /// + /// + /// Span conversion is available since C# 13 as part of the "first-class Span types" feature. + /// + internal bool IsSpan // PROTOTYPE: Make part of public API + { + get + { + return Kind == ConversionKind.ImplicitSpan; + } + } + /// /// Returns true if the conversion is an implicit user-defined conversion or explicit user-defined conversion. /// diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionKind.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionKind.cs index 69ad0370f5ca2..b72eeca287d21 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionKind.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionKind.cs @@ -68,5 +68,7 @@ internal enum ConversionKind : byte InterpolatedStringHandler, // A conversion from an interpolated string literal to a type attributed with InterpolatedStringBuilderAttribute InlineArray, // A conversion from an inline array to Span/ReadOnlySpan + + ImplicitSpan, // A conversion between array, (ReadOnly)Span, string - part of the "first-class Span types" feature } } diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionKindExtensions.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionKindExtensions.cs index e0d3c4578f7b6..10a6f6c44b291 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionKindExtensions.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionKindExtensions.cs @@ -53,6 +53,7 @@ public static bool IsImplicitConversion(this ConversionKind conversionKind) case ObjectCreation: case InlineArray: case CollectionExpression: + case ImplicitSpan: return true; case ExplicitNumeric: diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs index 28c1c79ac1461..58f825feac71a 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs @@ -602,6 +602,7 @@ private static bool IsStandardImplicitConversionFromExpression(ConversionKind ki case ConversionKind.StackAllocToPointerType: case ConversionKind.StackAllocToSpanType: case ConversionKind.InlineArray: + case ConversionKind.ImplicitSpan: return true; default: return false; @@ -906,6 +907,12 @@ private Conversion DeriveStandardExplicitFromOppositeStandardImplicitConversion( break; + case ConversionKind.ImplicitSpan: + // Implicit span conversion, unlike other standard implicit conversions, + // does not imply opposite standard explicit conversion. + impliedExplicitConversion = Conversion.NoConversion; + break; + default: throw ExceptionUtilities.UnexpectedValue(oppositeConversion.Kind); } @@ -1014,6 +1021,11 @@ private Conversion ClassifyImplicitBuiltInConversionFromExpression(BoundExpressi return Conversion.ImplicitDynamic; } + if (HasImplicitSpanConversion(source, destination, ref useSiteInfo)) + { + return Conversion.ImplicitSpan; + } + // The following conversions only exist for certain form of expressions, // if we have no expression none if them is applicable. if (sourceExpression == null) @@ -1916,6 +1928,12 @@ public Conversion ClassifyImplicitExtensionMethodThisArgConversion(BoundExpressi { return Conversion.ImplicitReference; } + + // PROTOTYPE: Investigate callers where Compilation is null. + if (Compilation is not null && HasImplicitSpanConversion(sourceType, destination, ref useSiteInfo)) + { + return Conversion.ImplicitSpan; + } } if (sourceExpressionOpt?.Kind == BoundKind.TupleLiteral) @@ -1977,6 +1995,7 @@ public static bool IsValidExtensionMethodThisArgConversion(Conversion conversion case ConversionKind.Identity: case ConversionKind.Boxing: case ConversionKind.ImplicitReference: + case ConversionKind.ImplicitSpan: return true; case ConversionKind.ImplicitTuple: @@ -3025,7 +3044,7 @@ internal bool HasImplicitConversionToOrImplementsVarianceCompatibleInterface(Bou // The rules for variant interface and delegate conversions are the same: // // An interface/delegate type S is convertible to an interface/delegate type T - // if and only if T is U and T is U such that for all + // if and only if S is U and T is U such that for all // parameters of U: // // * if the ith parameter of U is invariant then Si is exactly equal to Ti. @@ -3908,5 +3927,45 @@ private static bool IsIntegerTypeSupportingPointerConversions(TypeSymbol type) return false; } + + private bool HasImplicitSpanConversion(TypeSymbol source, TypeSymbol destination, ref CompoundUseSiteInfo useSiteInfo) + { + if (!Compilation.IsFeatureEnabled(MessageID.IDS_FeatureFirstClassSpan)) + { + return false; + } + + // SPEC: From any single-dimensional `array_type` with element type `Ei`... + if (source is ArrayTypeSymbol { IsSZArray: true, ElementTypeWithAnnotations: { } elementType }) + { + // SPEC: ...to `System.Span`. + if (destination.OriginalDefinition.Equals(Compilation.GetWellKnownType(WellKnownType.System_Span_T), TypeCompareKind.AllIgnoreOptions)) + { + var spanElementType = ((NamedTypeSymbol)destination).TypeArgumentsWithDefinitionUseSiteDiagnostics(ref useSiteInfo)[0]; + return hasIdentityConversion(elementType, spanElementType); + } + + // SPEC: ...to `System.ReadOnlySpan`, provided that `Ei` is covariance-convertible to `Ui`. + if (destination.OriginalDefinition.Equals(Compilation.GetWellKnownType(WellKnownType.System_ReadOnlySpan_T), TypeCompareKind.AllIgnoreOptions)) + { + var spanElementType = ((NamedTypeSymbol)destination).TypeArgumentsWithDefinitionUseSiteDiagnostics(ref useSiteInfo)[0]; + return hasCovariantConversion(elementType, spanElementType, ref useSiteInfo); + } + } + + return false; + + bool hasCovariantConversion(TypeWithAnnotations source, TypeWithAnnotations destination, ref CompoundUseSiteInfo useSiteInfo) + { + return hasIdentityConversion(source, destination) || + HasImplicitReferenceConversion(source, destination, ref useSiteInfo); + } + + bool hasIdentityConversion(TypeWithAnnotations source, TypeWithAnnotations destination) + { + return HasIdentityConversionInternal(source.Type, destination.Type) && + HasTopLevelNullabilityIdentityConversion(source, destination); + } + } } } diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/UserDefinedImplicitConversions.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/UserDefinedImplicitConversions.cs index 06f7ae0686a9b..d92bc7d996754 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/UserDefinedImplicitConversions.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/UserDefinedImplicitConversions.cs @@ -666,6 +666,8 @@ private static bool IsEncompassingImplicitConversionKind(ConversionKind kind) case ConversionKind.ImplicitPointer: // Added for C# 12 case ConversionKind.InlineArray: + // Added for C# 13 + case ConversionKind.ImplicitSpan: return true; default: diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 4c09a80debc1a..53b2b2adac17b 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -7956,4 +7956,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + + first-class Span types + \ No newline at end of file diff --git a/src/Compilers/CSharp/Portable/Errors/MessageID.cs b/src/Compilers/CSharp/Portable/Errors/MessageID.cs index 18fa9dbb51d6e..07ec814b1a908 100644 --- a/src/Compilers/CSharp/Portable/Errors/MessageID.cs +++ b/src/Compilers/CSharp/Portable/Errors/MessageID.cs @@ -286,6 +286,8 @@ internal enum MessageID IDS_FeatureRefUnsafeInIteratorAsync = MessageBase + 12843, IDS_FeatureRefStructInterfaces = MessageBase + 12844, + + IDS_FeatureFirstClassSpan = MessageBase + 12845, } // Message IDs may refer to strings that need to be localized. @@ -472,6 +474,7 @@ internal static LanguageVersion RequiredVersion(this MessageID feature) case MessageID.IDS_FeatureParamsCollections: case MessageID.IDS_FeatureRefUnsafeInIteratorAsync: case MessageID.IDS_FeatureRefStructInterfaces: + case MessageID.IDS_FeatureFirstClassSpan: return LanguageVersion.Preview; // C# 12.0 features. diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs index c139e3daf28c4..09bcd2e580f8e 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs @@ -8890,6 +8890,7 @@ private TypeWithState VisitConversion( break; case ConversionKind.InlineArray: + case ConversionKind.ImplicitSpan: if (checkConversion) { conversion = GenerateConversion(_conversions, conversionOperand, operandType.Type, targetType, fromExplicitCast, extensionMethodThisArgument, isChecked: conversionOpt?.Checked ?? false); diff --git a/src/Compilers/CSharp/Portable/Lowering/DiagnosticsPass_ExpressionTrees.cs b/src/Compilers/CSharp/Portable/Lowering/DiagnosticsPass_ExpressionTrees.cs index 1f401b2ef6eff..ca544bb53940a 100644 --- a/src/Compilers/CSharp/Portable/Lowering/DiagnosticsPass_ExpressionTrees.cs +++ b/src/Compilers/CSharp/Portable/Lowering/DiagnosticsPass_ExpressionTrees.cs @@ -811,6 +811,8 @@ public override BoundNode VisitConversion(BoundConversion node) } break; + // PROTOTYPE: ImplicitSpan + default: if (_inExpressionLambda && node.Conversion.Method is MethodSymbol method && (method.IsAbstract || method.IsVirtual) && method.IsStatic) diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Conversion.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Conversion.cs index 4f6b4f96c378d..ec2931a2623d8 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Conversion.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Conversion.cs @@ -614,6 +614,32 @@ private BoundExpression MakeConversionNodeCore( return _factory.Call(null, createSpan, rewrittenOperand, _factory.Literal(length), useStrictArgumentRefKinds: true); } + case ConversionKind.ImplicitSpan: + { + var spanType = (NamedTypeSymbol)rewrittenType; + + WellKnownMember ctorMember; + if (spanType.OriginalDefinition.Equals(_compilation.GetWellKnownType(WellKnownType.System_ReadOnlySpan_T), TypeCompareKind.AllIgnoreOptions)) + { + ctorMember = WellKnownMember.System_ReadOnlySpan_T__ctor_Array; + } + else + { + Debug.Assert(spanType.OriginalDefinition.Equals(_compilation.GetWellKnownType(WellKnownType.System_Span_T), TypeCompareKind.AllIgnoreOptions)); + ctorMember = WellKnownMember.System_Span_T__ctor_Array; + } + + if (!TryGetWellKnownTypeMember(rewrittenOperand.Syntax, ctorMember, out MethodSymbol? ctor)) + { + Debug.Fail("We should have reported an error during binding for missing members for span conversion."); + return BadExpression(rewrittenOperand.Syntax, rewrittenType, []); + } + else + { + return new BoundObjectCreationExpression(rewrittenOperand.Syntax, ctor.AsMember((NamedTypeSymbol)rewrittenType), rewrittenOperand); + } + } + default: break; } diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index 482f74b8c1b7e..43efba95fb988 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -2317,6 +2317,11 @@ typy souborů + + first-class Span types + first-class Span types + + generic attributes obecné atributy diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index 458820646f0bd..fa820535f23e7 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -2317,6 +2317,11 @@ Dateitypen + + first-class Span types + first-class Span types + + generic attributes Generische Attribute diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index de96942b43ca1..b00d32316581c 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -2317,6 +2317,11 @@ tipos de archivo + + first-class Span types + first-class Span types + + generic attributes atributos genéricos diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index cd8e3b4571564..b9dcdc4eea745 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -2317,6 +2317,11 @@ types de fichier + + first-class Span types + first-class Span types + + generic attributes attributs génériques diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index ee6c972ccf03d..a74a5e663019b 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -2317,6 +2317,11 @@ tipi di file + + first-class Span types + first-class Span types + + generic attributes attributi generici diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index 049964d81ce3a..550addc69a38c 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -2317,6 +2317,11 @@ ファイルの種類 + + first-class Span types + first-class Span types + + generic attributes 汎用属性 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index dd8ef848b9a66..f7cb69c9bebe7 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -2317,6 +2317,11 @@ 파일 형식 + + first-class Span types + first-class Span types + + generic attributes 제네릭 특성 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 871593fc5cad5..52289e76246a0 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -2317,6 +2317,11 @@ typy plików + + first-class Span types + first-class Span types + + generic attributes atrybuty ogólne diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index a4f21ff34b491..2d0cff5f73cc6 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -2317,6 +2317,11 @@ tipos de arquivo + + first-class Span types + first-class Span types + + generic attributes atributos genéricos diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index 7bc750767181d..714d9b412b217 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -2317,6 +2317,11 @@ типы файлов + + first-class Span types + first-class Span types + + generic attributes универсальные атрибуты diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 61a78dded475d..c485c0a4c9ec8 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -2317,6 +2317,11 @@ dosya türleri + + first-class Span types + first-class Span types + + generic attributes genel öznitelikler diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index b0175426fa302..6f78c4575cbd3 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -2317,6 +2317,11 @@ 文件类型 + + first-class Span types + first-class Span types + + generic attributes 通用属性 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index 59932f5945760..f0998b8629821 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -2317,6 +2317,11 @@ 檔案類型 + + first-class Span types + first-class Span types + + generic attributes 一般屬性 diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs index 999bf6667331d..1a9ce95de49b5 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs @@ -3575,7 +3575,12 @@ public sealed class JsonSerializerOptions } } "; - var v = CompileAndVerify(source, options: TestOptions.DebugExe); + CreateCompilation(source, options: TestOptions.DebugExe).VerifyDiagnostics( + // (12,69): error CS0656: Missing compiler required member 'System.ReadOnlySpan`1..ctor' + // System.Text.Json.Serialization.JsonSerializer.Parse(await TestAsync()); + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "await TestAsync()").WithArguments("System.ReadOnlySpan`1", ".ctor").WithLocation(12, 69)); + + var v = CompileAndVerify(source, parseOptions: TestOptions.Regular12, options: TestOptions.DebugExe); v.VerifyMethodBody("Program.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenFunctionPointersTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenFunctionPointersTests.cs index 73f912f5b7d23..93998dad18434 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenFunctionPointersTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenFunctionPointersTests.cs @@ -7167,7 +7167,7 @@ .locals init (delegate*, System.Span> V_0) IL_0000: ldftn ""System.Span C.ChopSpan(System.Span)"" IL_0006: stloc.0 IL_0007: ldsfld ""char[] C.chars"" - IL_000c: call ""System.Span System.Span.op_Implicit(char[])"" + IL_000c: newobj ""System.Span..ctor(char[])"" IL_0011: ldloc.0 IL_0012: calli ""delegate*, System.Span>"" IL_0017: call ""System.ReadOnlySpan System.Span.op_Implicit(System.Span)"" diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenReadOnlySpanConstructionTest.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenReadOnlySpanConstructionTest.cs index 2e808a3d5ec6f..02fcc6af09a6a 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenReadOnlySpanConstructionTest.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenReadOnlySpanConstructionTest.cs @@ -193,38 +193,33 @@ public static void Main() expectedOutput: type == "byte" ? "TrueTrue" : null, verify: type == "byte" ? Verification.Passes : Verification.Skipped).VerifyIL("Test.Main", @$" {{ - // Code size 77 (0x4d) + // Code size 75 (0x4b) .maxstack 2 .locals init (System.ReadOnlySpan<{type}> V_0, //s1 - System.ReadOnlySpan<{type}> V_1, //s2 - System.ReadOnlySpan<{type}> V_2) - IL_0000: ldloca.s V_2 + System.ReadOnlySpan<{type}> V_1) //s2 + IL_0000: ldloca.s V_0 IL_0002: initobj ""System.ReadOnlySpan<{type}>"" - IL_0008: ldloc.2 - IL_0009: stloc.0 - IL_000a: ldloca.s V_2 - IL_000c: initobj ""System.ReadOnlySpan<{type}>"" - IL_0012: ldloc.2 - IL_0013: stloc.1 - IL_0014: ldloca.s V_0 - IL_0016: call ""int System.ReadOnlySpan<{type}>.Length.get"" - IL_001b: ldloca.s V_1 - IL_001d: call ""int System.ReadOnlySpan<{type}>.Length.get"" - IL_0022: ceq - IL_0024: call ""void System.Console.Write(bool)"" - IL_0029: ldnull - IL_002a: call ""System.ReadOnlySpan<{type}> System.ReadOnlySpan<{type}>.op_Implicit({type}[])"" - IL_002f: stloc.0 - IL_0030: ldnull - IL_0031: call ""System.ReadOnlySpan<{type}> System.ReadOnlySpan<{type}>.op_Implicit({type}[])"" - IL_0036: stloc.1 - IL_0037: ldloca.s V_0 - IL_0039: call ""int System.ReadOnlySpan<{type}>.Length.get"" - IL_003e: ldloca.s V_1 - IL_0040: call ""int System.ReadOnlySpan<{type}>.Length.get"" - IL_0045: ceq - IL_0047: call ""void System.Console.Write(bool)"" - IL_004c: ret + IL_0008: ldloca.s V_1 + IL_000a: initobj ""System.ReadOnlySpan<{type}>"" + IL_0010: ldloca.s V_0 + IL_0012: call ""int System.ReadOnlySpan<{type}>.Length.get"" + IL_0017: ldloca.s V_1 + IL_0019: call ""int System.ReadOnlySpan<{type}>.Length.get"" + IL_001e: ceq + IL_0020: call ""void System.Console.Write(bool)"" + IL_0025: ldloca.s V_0 + IL_0027: ldnull + IL_0028: call ""System.ReadOnlySpan<{type}>..ctor({type}[])"" + IL_002d: ldloca.s V_1 + IL_002f: ldnull + IL_0030: call ""System.ReadOnlySpan<{type}>..ctor({type}[])"" + IL_0035: ldloca.s V_0 + IL_0037: call ""int System.ReadOnlySpan<{type}>.Length.get"" + IL_003c: ldloca.s V_1 + IL_003e: call ""int System.ReadOnlySpan<{type}>.Length.get"" + IL_0043: ceq + IL_0045: call ""void System.Console.Write(bool)"" + IL_004a: ret }}"); } @@ -417,40 +412,40 @@ public static void Main() CompileAndVerify(comp, expectedOutput: "3", verify: Verification.Passes).VerifyIL("Test.Main", @" { - // Code size 72 (0x48) - .maxstack 4 + // Code size 73 (0x49) + .maxstack 5 .locals init (System.ReadOnlySpan V_0) //s1 - IL_0000: ldc.i4.4 - IL_0001: newarr ""object"" - IL_0006: dup - IL_0007: ldc.i4.0 - IL_0008: ldc.i4.1 - IL_0009: box ""int"" - IL_000e: stelem.ref - IL_000f: dup - IL_0010: ldc.i4.1 - IL_0011: ldc.i4.2 - IL_0012: box ""int"" - IL_0017: stelem.ref - IL_0018: dup - IL_0019: ldc.i4.2 - IL_001a: ldstr ""3"" - IL_001f: call ""int int.Parse(string)"" - IL_0024: box ""int"" - IL_0029: stelem.ref - IL_002a: dup - IL_002b: ldc.i4.3 - IL_002c: ldc.i4.4 - IL_002d: box ""int"" - IL_0032: stelem.ref - IL_0033: call ""System.ReadOnlySpan System.ReadOnlySpan.op_Implicit(object[])"" - IL_0038: stloc.0 - IL_0039: ldloca.s V_0 - IL_003b: ldc.i4.2 - IL_003c: call ""ref readonly object System.ReadOnlySpan.this[int].get"" - IL_0041: ldind.ref - IL_0042: call ""void System.Console.Write(object)"" - IL_0047: ret + IL_0000: ldloca.s V_0 + IL_0002: ldc.i4.4 + IL_0003: newarr ""object"" + IL_0008: dup + IL_0009: ldc.i4.0 + IL_000a: ldc.i4.1 + IL_000b: box ""int"" + IL_0010: stelem.ref + IL_0011: dup + IL_0012: ldc.i4.1 + IL_0013: ldc.i4.2 + IL_0014: box ""int"" + IL_0019: stelem.ref + IL_001a: dup + IL_001b: ldc.i4.2 + IL_001c: ldstr ""3"" + IL_0021: call ""int int.Parse(string)"" + IL_0026: box ""int"" + IL_002b: stelem.ref + IL_002c: dup + IL_002d: ldc.i4.3 + IL_002e: ldc.i4.4 + IL_002f: box ""int"" + IL_0034: stelem.ref + IL_0035: call ""System.ReadOnlySpan..ctor(object[])"" + IL_003a: ldloca.s V_0 + IL_003c: ldc.i4.2 + IL_003d: call ""ref readonly object System.ReadOnlySpan.this[int].get"" + IL_0042: ldind.ref + IL_0043: call ""void System.Console.Write(object)"" + IL_0048: ret }"); } @@ -658,20 +653,20 @@ System.Collections.Generic.IEnumerator M2(T[] a) var cv = CompileAndVerify(comp, expectedOutput: "", verify: Verification.Passes); cv.VerifyIL("Test.<>c__1.b__1_0(T[])", @" { - // Code size 17 (0x11) + // Code size 18 (0x12) .maxstack 2 .locals init (System.ReadOnlySpan V_0) //span - IL_0000: ldarg.1 - IL_0001: call ""System.ReadOnlySpan System.ReadOnlySpan.op_Implicit(T[])"" - IL_0006: stloc.0 - IL_0007: ldloca.s V_0 - IL_0009: ldc.i4.0 - IL_000a: call ""ref readonly T System.ReadOnlySpan.this[int].get"" - IL_000f: pop - IL_0010: ret + IL_0000: ldloca.s V_0 + IL_0002: ldarg.1 + IL_0003: call ""System.ReadOnlySpan..ctor(T[])"" + IL_0008: ldloca.s V_0 + IL_000a: ldc.i4.0 + IL_000b: call ""ref readonly T System.ReadOnlySpan.this[int].get"" + IL_0010: pop + IL_0011: ret }"); cv.VerifyIL("Test.d__2.System.Collections.IEnumerator.MoveNext()", @"{ - // Code size 42 (0x2a) + // Code size 43 (0x2b) .maxstack 2 .locals init (int V_0, System.ReadOnlySpan V_1) //span @@ -685,16 +680,16 @@ .locals init (int V_0, IL_000c: ldarg.0 IL_000d: ldc.i4.m1 IL_000e: stfld ""int Test.d__2.<>1__state"" - IL_0013: ldarg.0 - IL_0014: ldfld ""T[] Test.d__2.a"" - IL_0019: call ""System.ReadOnlySpan System.ReadOnlySpan.op_Implicit(T[])"" - IL_001e: stloc.1 - IL_001f: ldloca.s V_1 - IL_0021: ldc.i4.0 - IL_0022: call ""ref readonly T System.ReadOnlySpan.this[int].get"" - IL_0027: pop - IL_0028: ldc.i4.0 - IL_0029: ret + IL_0013: ldloca.s V_1 + IL_0015: ldarg.0 + IL_0016: ldfld ""T[] Test.d__2.a"" + IL_001b: call ""System.ReadOnlySpan..ctor(T[])"" + IL_0020: ldloca.s V_1 + IL_0022: ldc.i4.0 + IL_0023: call ""ref readonly T System.ReadOnlySpan.this[int].get"" + IL_0028: pop + IL_0029: ldc.i4.0 + IL_002a: ret }"); } @@ -725,18 +720,18 @@ public static void Main() ", WithNullableEnable(TestOptions.ReleaseExe)); var cv = CompileAndVerify(comp, expectedOutput: "100", verify: Verification.Passes); cv.VerifyIL("X.<>c__DisplayClass0_0.b__0(int)", @"{ - // Code size 26 (0x1a) + // Code size 27 (0x1b) .maxstack 2 .locals init (System.ReadOnlySpan V_0) //s - IL_0000: ldarg.0 - IL_0001: ldfld ""TSrc[] X.<>c__DisplayClass0_0.a"" - IL_0006: call ""System.ReadOnlySpan System.ReadOnlySpan.op_Implicit(TSrc[])"" - IL_000b: stloc.0 - IL_000c: ldloca.s V_0 - IL_000e: ldarg.1 - IL_000f: call ""ref readonly TSrc System.ReadOnlySpan.this[int].get"" - IL_0014: ldobj ""TSrc"" - IL_0019: ret + IL_0000: ldloca.s V_0 + IL_0002: ldarg.0 + IL_0003: ldfld ""TSrc[] X.<>c__DisplayClass0_0.a"" + IL_0008: call ""System.ReadOnlySpan..ctor(TSrc[])"" + IL_000d: ldloca.s V_0 + IL_000f: ldarg.1 + IL_0010: call ""ref readonly TSrc System.ReadOnlySpan.this[int].get"" + IL_0015: ldobj ""TSrc"" + IL_001a: ret }"); } @@ -913,7 +908,7 @@ .maxstack 4 IL_000c: ldc.i4.1 IL_000d: ldc.i4.s 20 IL_000f: stelem.i1 - IL_0010: call ""System.ReadOnlySpan System.ReadOnlySpan.op_Implicit(byte[])"" + IL_0010: newobj ""System.ReadOnlySpan..ctor(byte[])"" IL_0015: ret } "; @@ -1475,7 +1470,7 @@ public static int M() return s[0]; }} }}"; - var compilation = CreateCompilationWithMscorlibAndSpan(csharp, TestOptions.ReleaseDll); + var compilation = CreateCompilationWithMscorlibAndSpan(csharp, TestOptions.ReleaseDll, TestOptions.Regular12); compilation.MakeMemberMissing(WellKnownMember.System_Runtime_CompilerServices_RuntimeHelpers__CreateSpanRuntimeFieldHandle); compilation.MakeMemberMissing(WellKnownMember.System_ReadOnlySpan_T__ctor_Array); @@ -1498,6 +1493,14 @@ .locals init (System.ReadOnlySpan V_0) //s IL_0020: ret }} "); + + compilation = CreateCompilationWithMscorlibAndSpan(csharp, TestOptions.ReleaseDll); + compilation.MakeMemberMissing(WellKnownMember.System_Runtime_CompilerServices_RuntimeHelpers__CreateSpanRuntimeFieldHandle); + compilation.MakeMemberMissing(WellKnownMember.System_ReadOnlySpan_T__ctor_Array); + compilation.VerifyDiagnostics( + // (6,38): error CS0656: Missing compiler required member 'System.ReadOnlySpan`1..ctor' + // System.ReadOnlySpan s = new int[] { 1, 2, 4, 8, 16, 32, 64, 128 }; + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "new int[] { 1, 2, 4, 8, 16, 32, 64, 128 }").WithArguments("System.ReadOnlySpan`1", ".ctor").WithLocation(6, 38)); } [Fact] @@ -1733,8 +1736,8 @@ public static void Main() "; CompileAndVerify(source, expectedOutput: "34361843576", verify: Verification.Skipped, targetFramework: TargetFramework.Net70).VerifyIL("Test.Main", @" { - // Code size 528 (0x210) - .maxstack 2 + // Code size 530 (0x212) + .maxstack 3 .locals init (System.ReadOnlySpan V_0, //s1 System.ReadOnlySpan V_1, //s2 System.ReadOnlySpan V_2, //s3 @@ -1764,246 +1767,246 @@ .locals init (System.ReadOnlySpan V_0, //s1 ulong V_26, //v8 System.ReadOnlySpan V_27, char V_28) //v9 - IL_0000: ldsflda "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" - IL_0005: ldc.i4.s 32 - IL_0007: newobj ""System.ReadOnlySpan..ctor(void*, int)"" - IL_000c: stloc.0 - IL_000d: ldsflda "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" - IL_0012: ldc.i4.s 32 - IL_0014: newobj ""System.ReadOnlySpan..ctor(void*, int)"" - IL_0019: stloc.1 - IL_001a: ldtoken "".__StaticArrayInitTypeSize=32_Align=2 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C40512"" - IL_001f: call ""System.ReadOnlySpan System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan(System.RuntimeFieldHandle)"" - IL_0024: stloc.2 - IL_0025: ldtoken "".__StaticArrayInitTypeSize=32_Align=2 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C40512"" - IL_002a: call ""System.ReadOnlySpan System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan(System.RuntimeFieldHandle)"" - IL_002f: stloc.3 - IL_0030: ldtoken "".__StaticArrayInitTypeSize=32_Align=4 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C40514"" - IL_0035: call ""System.ReadOnlySpan System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan(System.RuntimeFieldHandle)"" - IL_003a: stloc.s V_4 - IL_003c: ldtoken "".__StaticArrayInitTypeSize=32_Align=4 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C40514"" - IL_0041: call ""System.ReadOnlySpan System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan(System.RuntimeFieldHandle)"" - IL_0046: stloc.s V_5 - IL_0048: ldtoken "".__StaticArrayInitTypeSize=32_Align=8 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C40518"" - IL_004d: call ""System.ReadOnlySpan System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan(System.RuntimeFieldHandle)"" - IL_0052: stloc.s V_6 - IL_0054: ldtoken "".__StaticArrayInitTypeSize=32_Align=8 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C40518"" - IL_0059: call ""System.ReadOnlySpan System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan(System.RuntimeFieldHandle)"" - IL_005e: stloc.s V_7 - IL_0060: ldtoken "".__StaticArrayInitTypeSize=32_Align=2 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C40512"" - IL_0065: call ""System.ReadOnlySpan System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan(System.RuntimeFieldHandle)"" - IL_006a: stloc.s V_8 - IL_006c: ldc.i4.0 - IL_006d: conv.i8 - IL_006e: stloc.s V_9 - IL_0070: ldloc.0 - IL_0071: stloc.s V_10 - IL_0073: ldc.i4.0 - IL_0074: stloc.s V_11 - IL_0076: br.s IL_0092 - IL_0078: ldloca.s V_10 - IL_007a: ldloc.s V_11 - IL_007c: call ""ref readonly sbyte System.ReadOnlySpan.this[int].get"" - IL_0081: ldind.i1 - IL_0082: stloc.s V_12 - IL_0084: ldloc.s V_9 - IL_0086: ldloc.s V_12 - IL_0088: conv.i8 - IL_0089: add - IL_008a: stloc.s V_9 - IL_008c: ldloc.s V_11 - IL_008e: ldc.i4.1 - IL_008f: add - IL_0090: stloc.s V_11 - IL_0092: ldloc.s V_11 - IL_0094: ldloca.s V_10 - IL_0096: call ""int System.ReadOnlySpan.Length.get"" - IL_009b: blt.s IL_0078 - IL_009d: ldloc.1 - IL_009e: stloc.s V_13 - IL_00a0: ldc.i4.0 - IL_00a1: stloc.s V_11 - IL_00a3: br.s IL_00bf - IL_00a5: ldloca.s V_13 - IL_00a7: ldloc.s V_11 - IL_00a9: call ""ref readonly byte System.ReadOnlySpan.this[int].get"" - IL_00ae: ldind.u1 - IL_00af: stloc.s V_14 - IL_00b1: ldloc.s V_9 - IL_00b3: ldloc.s V_14 - IL_00b5: conv.u8 - IL_00b6: add - IL_00b7: stloc.s V_9 - IL_00b9: ldloc.s V_11 - IL_00bb: ldc.i4.1 - IL_00bc: add - IL_00bd: stloc.s V_11 - IL_00bf: ldloc.s V_11 - IL_00c1: ldloca.s V_13 - IL_00c3: call ""int System.ReadOnlySpan.Length.get"" - IL_00c8: blt.s IL_00a5 - IL_00ca: ldloc.2 - IL_00cb: stloc.s V_15 - IL_00cd: ldc.i4.0 - IL_00ce: stloc.s V_11 - IL_00d0: br.s IL_00ec - IL_00d2: ldloca.s V_15 - IL_00d4: ldloc.s V_11 - IL_00d6: call ""ref readonly short System.ReadOnlySpan.this[int].get"" - IL_00db: ldind.i2 - IL_00dc: stloc.s V_16 - IL_00de: ldloc.s V_9 - IL_00e0: ldloc.s V_16 - IL_00e2: conv.i8 - IL_00e3: add - IL_00e4: stloc.s V_9 - IL_00e6: ldloc.s V_11 - IL_00e8: ldc.i4.1 - IL_00e9: add - IL_00ea: stloc.s V_11 - IL_00ec: ldloc.s V_11 - IL_00ee: ldloca.s V_15 - IL_00f0: call ""int System.ReadOnlySpan.Length.get"" - IL_00f5: blt.s IL_00d2 - IL_00f7: ldloc.3 - IL_00f8: stloc.s V_17 - IL_00fa: ldc.i4.0 - IL_00fb: stloc.s V_11 - IL_00fd: br.s IL_0119 - IL_00ff: ldloca.s V_17 - IL_0101: ldloc.s V_11 - IL_0103: call ""ref readonly ushort System.ReadOnlySpan.this[int].get"" - IL_0108: ldind.u2 - IL_0109: stloc.s V_18 - IL_010b: ldloc.s V_9 - IL_010d: ldloc.s V_18 - IL_010f: conv.u8 - IL_0110: add - IL_0111: stloc.s V_9 - IL_0113: ldloc.s V_11 - IL_0115: ldc.i4.1 - IL_0116: add - IL_0117: stloc.s V_11 - IL_0119: ldloc.s V_11 - IL_011b: ldloca.s V_17 - IL_011d: call ""int System.ReadOnlySpan.Length.get"" - IL_0122: blt.s IL_00ff - IL_0124: ldloc.s V_4 - IL_0126: stloc.s V_19 - IL_0128: ldc.i4.0 - IL_0129: stloc.s V_11 - IL_012b: br.s IL_0147 - IL_012d: ldloca.s V_19 - IL_012f: ldloc.s V_11 - IL_0131: call ""ref readonly int System.ReadOnlySpan.this[int].get"" - IL_0136: ldind.i4 - IL_0137: stloc.s V_20 - IL_0139: ldloc.s V_9 - IL_013b: ldloc.s V_20 - IL_013d: conv.i8 - IL_013e: add - IL_013f: stloc.s V_9 - IL_0141: ldloc.s V_11 - IL_0143: ldc.i4.1 - IL_0144: add - IL_0145: stloc.s V_11 - IL_0147: ldloc.s V_11 - IL_0149: ldloca.s V_19 - IL_014b: call ""int System.ReadOnlySpan.Length.get"" - IL_0150: blt.s IL_012d - IL_0152: ldloc.s V_5 - IL_0154: stloc.s V_21 - IL_0156: ldc.i4.0 - IL_0157: stloc.s V_11 - IL_0159: br.s IL_0175 - IL_015b: ldloca.s V_21 - IL_015d: ldloc.s V_11 - IL_015f: call ""ref readonly uint System.ReadOnlySpan.this[int].get"" - IL_0164: ldind.u4 - IL_0165: stloc.s V_22 - IL_0167: ldloc.s V_9 - IL_0169: ldloc.s V_22 - IL_016b: conv.u8 - IL_016c: add - IL_016d: stloc.s V_9 - IL_016f: ldloc.s V_11 - IL_0171: ldc.i4.1 - IL_0172: add - IL_0173: stloc.s V_11 - IL_0175: ldloc.s V_11 - IL_0177: ldloca.s V_21 - IL_0179: call ""int System.ReadOnlySpan.Length.get"" - IL_017e: blt.s IL_015b - IL_0180: ldloc.s V_6 - IL_0182: stloc.s V_23 - IL_0184: ldc.i4.0 - IL_0185: stloc.s V_11 - IL_0187: br.s IL_01a2 - IL_0189: ldloca.s V_23 - IL_018b: ldloc.s V_11 - IL_018d: call ""ref readonly long System.ReadOnlySpan.this[int].get"" - IL_0192: ldind.i8 - IL_0193: stloc.s V_24 - IL_0195: ldloc.s V_9 - IL_0197: ldloc.s V_24 - IL_0199: add - IL_019a: stloc.s V_9 - IL_019c: ldloc.s V_11 - IL_019e: ldc.i4.1 - IL_019f: add - IL_01a0: stloc.s V_11 - IL_01a2: ldloc.s V_11 - IL_01a4: ldloca.s V_23 - IL_01a6: call ""int System.ReadOnlySpan.Length.get"" - IL_01ab: blt.s IL_0189 - IL_01ad: ldloc.s V_7 - IL_01af: stloc.s V_25 - IL_01b1: ldc.i4.0 - IL_01b2: stloc.s V_11 - IL_01b4: br.s IL_01cf - IL_01b6: ldloca.s V_25 - IL_01b8: ldloc.s V_11 - IL_01ba: call ""ref readonly ulong System.ReadOnlySpan.this[int].get"" - IL_01bf: ldind.i8 - IL_01c0: stloc.s V_26 - IL_01c2: ldloc.s V_9 - IL_01c4: ldloc.s V_26 - IL_01c6: add - IL_01c7: stloc.s V_9 - IL_01c9: ldloc.s V_11 - IL_01cb: ldc.i4.1 - IL_01cc: add - IL_01cd: stloc.s V_11 - IL_01cf: ldloc.s V_11 - IL_01d1: ldloca.s V_25 - IL_01d3: call ""int System.ReadOnlySpan.Length.get"" - IL_01d8: blt.s IL_01b6 - IL_01da: ldloc.s V_8 - IL_01dc: stloc.s V_27 - IL_01de: ldc.i4.0 - IL_01df: stloc.s V_11 - IL_01e1: br.s IL_01fd - IL_01e3: ldloca.s V_27 - IL_01e5: ldloc.s V_11 - IL_01e7: call ""ref readonly char System.ReadOnlySpan.this[int].get"" - IL_01ec: ldind.u2 - IL_01ed: stloc.s V_28 - IL_01ef: ldloc.s V_9 - IL_01f1: ldloc.s V_28 - IL_01f3: conv.u8 - IL_01f4: add - IL_01f5: stloc.s V_9 - IL_01f7: ldloc.s V_11 - IL_01f9: ldc.i4.1 - IL_01fa: add - IL_01fb: stloc.s V_11 - IL_01fd: ldloc.s V_11 - IL_01ff: ldloca.s V_27 - IL_0201: call ""int System.ReadOnlySpan.Length.get"" - IL_0206: blt.s IL_01e3 - IL_0208: ldloc.s V_9 - IL_020a: call ""void System.Console.Write(long)"" - IL_020f: ret + IL_0000: ldloca.s V_0 + IL_0002: ldsflda "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" + IL_0007: ldc.i4.s 32 + IL_0009: call ""System.ReadOnlySpan..ctor(void*, int)"" + IL_000e: ldloca.s V_1 + IL_0010: ldsflda "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" + IL_0015: ldc.i4.s 32 + IL_0017: call ""System.ReadOnlySpan..ctor(void*, int)"" + IL_001c: ldtoken "".__StaticArrayInitTypeSize=32_Align=2 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C40512"" + IL_0021: call ""System.ReadOnlySpan System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan(System.RuntimeFieldHandle)"" + IL_0026: stloc.2 + IL_0027: ldtoken "".__StaticArrayInitTypeSize=32_Align=2 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C40512"" + IL_002c: call ""System.ReadOnlySpan System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan(System.RuntimeFieldHandle)"" + IL_0031: stloc.3 + IL_0032: ldtoken "".__StaticArrayInitTypeSize=32_Align=4 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C40514"" + IL_0037: call ""System.ReadOnlySpan System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan(System.RuntimeFieldHandle)"" + IL_003c: stloc.s V_4 + IL_003e: ldtoken "".__StaticArrayInitTypeSize=32_Align=4 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C40514"" + IL_0043: call ""System.ReadOnlySpan System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan(System.RuntimeFieldHandle)"" + IL_0048: stloc.s V_5 + IL_004a: ldtoken "".__StaticArrayInitTypeSize=32_Align=8 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C40518"" + IL_004f: call ""System.ReadOnlySpan System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan(System.RuntimeFieldHandle)"" + IL_0054: stloc.s V_6 + IL_0056: ldtoken "".__StaticArrayInitTypeSize=32_Align=8 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C40518"" + IL_005b: call ""System.ReadOnlySpan System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan(System.RuntimeFieldHandle)"" + IL_0060: stloc.s V_7 + IL_0062: ldtoken "".__StaticArrayInitTypeSize=32_Align=2 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C40512"" + IL_0067: call ""System.ReadOnlySpan System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan(System.RuntimeFieldHandle)"" + IL_006c: stloc.s V_8 + IL_006e: ldc.i4.0 + IL_006f: conv.i8 + IL_0070: stloc.s V_9 + IL_0072: ldloc.0 + IL_0073: stloc.s V_10 + IL_0075: ldc.i4.0 + IL_0076: stloc.s V_11 + IL_0078: br.s IL_0094 + IL_007a: ldloca.s V_10 + IL_007c: ldloc.s V_11 + IL_007e: call ""ref readonly sbyte System.ReadOnlySpan.this[int].get"" + IL_0083: ldind.i1 + IL_0084: stloc.s V_12 + IL_0086: ldloc.s V_9 + IL_0088: ldloc.s V_12 + IL_008a: conv.i8 + IL_008b: add + IL_008c: stloc.s V_9 + IL_008e: ldloc.s V_11 + IL_0090: ldc.i4.1 + IL_0091: add + IL_0092: stloc.s V_11 + IL_0094: ldloc.s V_11 + IL_0096: ldloca.s V_10 + IL_0098: call ""int System.ReadOnlySpan.Length.get"" + IL_009d: blt.s IL_007a + IL_009f: ldloc.1 + IL_00a0: stloc.s V_13 + IL_00a2: ldc.i4.0 + IL_00a3: stloc.s V_11 + IL_00a5: br.s IL_00c1 + IL_00a7: ldloca.s V_13 + IL_00a9: ldloc.s V_11 + IL_00ab: call ""ref readonly byte System.ReadOnlySpan.this[int].get"" + IL_00b0: ldind.u1 + IL_00b1: stloc.s V_14 + IL_00b3: ldloc.s V_9 + IL_00b5: ldloc.s V_14 + IL_00b7: conv.u8 + IL_00b8: add + IL_00b9: stloc.s V_9 + IL_00bb: ldloc.s V_11 + IL_00bd: ldc.i4.1 + IL_00be: add + IL_00bf: stloc.s V_11 + IL_00c1: ldloc.s V_11 + IL_00c3: ldloca.s V_13 + IL_00c5: call ""int System.ReadOnlySpan.Length.get"" + IL_00ca: blt.s IL_00a7 + IL_00cc: ldloc.2 + IL_00cd: stloc.s V_15 + IL_00cf: ldc.i4.0 + IL_00d0: stloc.s V_11 + IL_00d2: br.s IL_00ee + IL_00d4: ldloca.s V_15 + IL_00d6: ldloc.s V_11 + IL_00d8: call ""ref readonly short System.ReadOnlySpan.this[int].get"" + IL_00dd: ldind.i2 + IL_00de: stloc.s V_16 + IL_00e0: ldloc.s V_9 + IL_00e2: ldloc.s V_16 + IL_00e4: conv.i8 + IL_00e5: add + IL_00e6: stloc.s V_9 + IL_00e8: ldloc.s V_11 + IL_00ea: ldc.i4.1 + IL_00eb: add + IL_00ec: stloc.s V_11 + IL_00ee: ldloc.s V_11 + IL_00f0: ldloca.s V_15 + IL_00f2: call ""int System.ReadOnlySpan.Length.get"" + IL_00f7: blt.s IL_00d4 + IL_00f9: ldloc.3 + IL_00fa: stloc.s V_17 + IL_00fc: ldc.i4.0 + IL_00fd: stloc.s V_11 + IL_00ff: br.s IL_011b + IL_0101: ldloca.s V_17 + IL_0103: ldloc.s V_11 + IL_0105: call ""ref readonly ushort System.ReadOnlySpan.this[int].get"" + IL_010a: ldind.u2 + IL_010b: stloc.s V_18 + IL_010d: ldloc.s V_9 + IL_010f: ldloc.s V_18 + IL_0111: conv.u8 + IL_0112: add + IL_0113: stloc.s V_9 + IL_0115: ldloc.s V_11 + IL_0117: ldc.i4.1 + IL_0118: add + IL_0119: stloc.s V_11 + IL_011b: ldloc.s V_11 + IL_011d: ldloca.s V_17 + IL_011f: call ""int System.ReadOnlySpan.Length.get"" + IL_0124: blt.s IL_0101 + IL_0126: ldloc.s V_4 + IL_0128: stloc.s V_19 + IL_012a: ldc.i4.0 + IL_012b: stloc.s V_11 + IL_012d: br.s IL_0149 + IL_012f: ldloca.s V_19 + IL_0131: ldloc.s V_11 + IL_0133: call ""ref readonly int System.ReadOnlySpan.this[int].get"" + IL_0138: ldind.i4 + IL_0139: stloc.s V_20 + IL_013b: ldloc.s V_9 + IL_013d: ldloc.s V_20 + IL_013f: conv.i8 + IL_0140: add + IL_0141: stloc.s V_9 + IL_0143: ldloc.s V_11 + IL_0145: ldc.i4.1 + IL_0146: add + IL_0147: stloc.s V_11 + IL_0149: ldloc.s V_11 + IL_014b: ldloca.s V_19 + IL_014d: call ""int System.ReadOnlySpan.Length.get"" + IL_0152: blt.s IL_012f + IL_0154: ldloc.s V_5 + IL_0156: stloc.s V_21 + IL_0158: ldc.i4.0 + IL_0159: stloc.s V_11 + IL_015b: br.s IL_0177 + IL_015d: ldloca.s V_21 + IL_015f: ldloc.s V_11 + IL_0161: call ""ref readonly uint System.ReadOnlySpan.this[int].get"" + IL_0166: ldind.u4 + IL_0167: stloc.s V_22 + IL_0169: ldloc.s V_9 + IL_016b: ldloc.s V_22 + IL_016d: conv.u8 + IL_016e: add + IL_016f: stloc.s V_9 + IL_0171: ldloc.s V_11 + IL_0173: ldc.i4.1 + IL_0174: add + IL_0175: stloc.s V_11 + IL_0177: ldloc.s V_11 + IL_0179: ldloca.s V_21 + IL_017b: call ""int System.ReadOnlySpan.Length.get"" + IL_0180: blt.s IL_015d + IL_0182: ldloc.s V_6 + IL_0184: stloc.s V_23 + IL_0186: ldc.i4.0 + IL_0187: stloc.s V_11 + IL_0189: br.s IL_01a4 + IL_018b: ldloca.s V_23 + IL_018d: ldloc.s V_11 + IL_018f: call ""ref readonly long System.ReadOnlySpan.this[int].get"" + IL_0194: ldind.i8 + IL_0195: stloc.s V_24 + IL_0197: ldloc.s V_9 + IL_0199: ldloc.s V_24 + IL_019b: add + IL_019c: stloc.s V_9 + IL_019e: ldloc.s V_11 + IL_01a0: ldc.i4.1 + IL_01a1: add + IL_01a2: stloc.s V_11 + IL_01a4: ldloc.s V_11 + IL_01a6: ldloca.s V_23 + IL_01a8: call ""int System.ReadOnlySpan.Length.get"" + IL_01ad: blt.s IL_018b + IL_01af: ldloc.s V_7 + IL_01b1: stloc.s V_25 + IL_01b3: ldc.i4.0 + IL_01b4: stloc.s V_11 + IL_01b6: br.s IL_01d1 + IL_01b8: ldloca.s V_25 + IL_01ba: ldloc.s V_11 + IL_01bc: call ""ref readonly ulong System.ReadOnlySpan.this[int].get"" + IL_01c1: ldind.i8 + IL_01c2: stloc.s V_26 + IL_01c4: ldloc.s V_9 + IL_01c6: ldloc.s V_26 + IL_01c8: add + IL_01c9: stloc.s V_9 + IL_01cb: ldloc.s V_11 + IL_01cd: ldc.i4.1 + IL_01ce: add + IL_01cf: stloc.s V_11 + IL_01d1: ldloc.s V_11 + IL_01d3: ldloca.s V_25 + IL_01d5: call ""int System.ReadOnlySpan.Length.get"" + IL_01da: blt.s IL_01b8 + IL_01dc: ldloc.s V_8 + IL_01de: stloc.s V_27 + IL_01e0: ldc.i4.0 + IL_01e1: stloc.s V_11 + IL_01e3: br.s IL_01ff + IL_01e5: ldloca.s V_27 + IL_01e7: ldloc.s V_11 + IL_01e9: call ""ref readonly char System.ReadOnlySpan.this[int].get"" + IL_01ee: ldind.u2 + IL_01ef: stloc.s V_28 + IL_01f1: ldloc.s V_9 + IL_01f3: ldloc.s V_28 + IL_01f5: conv.u8 + IL_01f6: add + IL_01f7: stloc.s V_9 + IL_01f9: ldloc.s V_11 + IL_01fb: ldc.i4.1 + IL_01fc: add + IL_01fd: stloc.s V_11 + IL_01ff: ldloc.s V_11 + IL_0201: ldloca.s V_27 + IL_0203: call ""int System.ReadOnlySpan.Length.get"" + IL_0208: blt.s IL_01e5 + IL_020a: ldloc.s V_9 + IL_020c: call ""void System.Console.Write(long)"" + IL_0211: ret }"); } @@ -2046,7 +2049,7 @@ public static void Main() CompileAndVerify(compilation, expectedOutput: "34361843576", verify: Verification.Skipped).VerifyIL("Test.Main", @" { - // Code size 720 (0x2d0) + // Code size 722 (0x2d2) .maxstack 3 .locals init (System.ReadOnlySpan V_0, //s1 System.ReadOnlySpan V_1, //s2 @@ -2077,316 +2080,316 @@ .locals init (System.ReadOnlySpan V_0, //s1 ulong V_26, //v8 System.ReadOnlySpan V_27, char V_28) //v9 - IL_0000: ldsflda "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" - IL_0005: ldc.i4.s 32 - IL_0007: newobj ""System.ReadOnlySpan..ctor(void*, int)"" - IL_000c: stloc.0 - IL_000d: ldsflda "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" - IL_0012: ldc.i4.s 32 - IL_0014: newobj ""System.ReadOnlySpan..ctor(void*, int)"" - IL_0019: stloc.1 - IL_001a: ldsfld ""short[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A5"" - IL_001f: dup - IL_0020: brtrue.s IL_003b - IL_0022: pop - IL_0023: ldc.i4.s 16 - IL_0025: newarr ""short"" - IL_002a: dup - IL_002b: ldtoken "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" - IL_0030: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"" - IL_0035: dup - IL_0036: stsfld ""short[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A5"" - IL_003b: newobj ""System.ReadOnlySpan..ctor(short[])"" - IL_0040: stloc.2 - IL_0041: ldsfld ""ushort[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A13"" - IL_0046: dup - IL_0047: brtrue.s IL_0062 - IL_0049: pop - IL_004a: ldc.i4.s 16 - IL_004c: newarr ""ushort"" - IL_0051: dup - IL_0052: ldtoken "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" - IL_0057: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"" - IL_005c: dup - IL_005d: stsfld ""ushort[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A13"" - IL_0062: newobj ""System.ReadOnlySpan..ctor(ushort[])"" - IL_0067: stloc.3 - IL_0068: ldsfld ""int[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A6"" - IL_006d: dup - IL_006e: brtrue.s IL_0088 - IL_0070: pop - IL_0071: ldc.i4.8 - IL_0072: newarr ""int"" - IL_0077: dup - IL_0078: ldtoken "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" - IL_007d: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"" - IL_0082: dup - IL_0083: stsfld ""int[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A6"" - IL_0088: newobj ""System.ReadOnlySpan..ctor(int[])"" - IL_008d: stloc.s V_4 - IL_008f: ldsfld ""uint[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A14"" - IL_0094: dup - IL_0095: brtrue.s IL_00af - IL_0097: pop - IL_0098: ldc.i4.8 - IL_0099: newarr ""uint"" - IL_009e: dup - IL_009f: ldtoken "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" - IL_00a4: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"" - IL_00a9: dup - IL_00aa: stsfld ""uint[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A14"" - IL_00af: newobj ""System.ReadOnlySpan..ctor(uint[])"" - IL_00b4: stloc.s V_5 - IL_00b6: ldsfld ""long[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A7"" - IL_00bb: dup - IL_00bc: brtrue.s IL_00d6 - IL_00be: pop - IL_00bf: ldc.i4.4 - IL_00c0: newarr ""long"" - IL_00c5: dup - IL_00c6: ldtoken "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" - IL_00cb: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"" - IL_00d0: dup - IL_00d1: stsfld ""long[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A7"" - IL_00d6: newobj ""System.ReadOnlySpan..ctor(long[])"" - IL_00db: stloc.s V_6 - IL_00dd: ldsfld ""ulong[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A15"" - IL_00e2: dup - IL_00e3: brtrue.s IL_00fd - IL_00e5: pop - IL_00e6: ldc.i4.4 - IL_00e7: newarr ""ulong"" - IL_00ec: dup - IL_00ed: ldtoken "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" - IL_00f2: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"" - IL_00f7: dup - IL_00f8: stsfld ""ulong[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A15"" - IL_00fd: newobj ""System.ReadOnlySpan..ctor(ulong[])"" - IL_0102: stloc.s V_7 - IL_0104: ldsfld ""char[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A1"" - IL_0109: dup - IL_010a: brtrue.s IL_0125 - IL_010c: pop - IL_010d: ldc.i4.s 16 - IL_010f: newarr ""char"" - IL_0114: dup - IL_0115: ldtoken "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" - IL_011a: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"" - IL_011f: dup - IL_0120: stsfld ""char[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A1"" - IL_0125: newobj ""System.ReadOnlySpan..ctor(char[])"" - IL_012a: stloc.s V_8 - IL_012c: ldc.i4.0 - IL_012d: conv.i8 - IL_012e: stloc.s V_9 - IL_0130: ldloc.0 - IL_0131: stloc.s V_10 - IL_0133: ldc.i4.0 - IL_0134: stloc.s V_11 - IL_0136: br.s IL_0152 - IL_0138: ldloca.s V_10 - IL_013a: ldloc.s V_11 - IL_013c: call ""ref readonly sbyte System.ReadOnlySpan.this[int].get"" - IL_0141: ldind.i1 - IL_0142: stloc.s V_12 - IL_0144: ldloc.s V_9 - IL_0146: ldloc.s V_12 - IL_0148: conv.i8 - IL_0149: add - IL_014a: stloc.s V_9 - IL_014c: ldloc.s V_11 - IL_014e: ldc.i4.1 - IL_014f: add - IL_0150: stloc.s V_11 - IL_0152: ldloc.s V_11 - IL_0154: ldloca.s V_10 - IL_0156: call ""int System.ReadOnlySpan.Length.get"" - IL_015b: blt.s IL_0138 - IL_015d: ldloc.1 - IL_015e: stloc.s V_13 - IL_0160: ldc.i4.0 - IL_0161: stloc.s V_11 - IL_0163: br.s IL_017f - IL_0165: ldloca.s V_13 - IL_0167: ldloc.s V_11 - IL_0169: call ""ref readonly byte System.ReadOnlySpan.this[int].get"" - IL_016e: ldind.u1 - IL_016f: stloc.s V_14 - IL_0171: ldloc.s V_9 - IL_0173: ldloc.s V_14 - IL_0175: conv.u8 - IL_0176: add - IL_0177: stloc.s V_9 - IL_0179: ldloc.s V_11 - IL_017b: ldc.i4.1 - IL_017c: add - IL_017d: stloc.s V_11 - IL_017f: ldloc.s V_11 - IL_0181: ldloca.s V_13 - IL_0183: call ""int System.ReadOnlySpan.Length.get"" - IL_0188: blt.s IL_0165 - IL_018a: ldloc.2 - IL_018b: stloc.s V_15 - IL_018d: ldc.i4.0 - IL_018e: stloc.s V_11 - IL_0190: br.s IL_01ac - IL_0192: ldloca.s V_15 - IL_0194: ldloc.s V_11 - IL_0196: call ""ref readonly short System.ReadOnlySpan.this[int].get"" - IL_019b: ldind.i2 - IL_019c: stloc.s V_16 - IL_019e: ldloc.s V_9 - IL_01a0: ldloc.s V_16 - IL_01a2: conv.i8 - IL_01a3: add - IL_01a4: stloc.s V_9 - IL_01a6: ldloc.s V_11 - IL_01a8: ldc.i4.1 - IL_01a9: add - IL_01aa: stloc.s V_11 - IL_01ac: ldloc.s V_11 - IL_01ae: ldloca.s V_15 - IL_01b0: call ""int System.ReadOnlySpan.Length.get"" - IL_01b5: blt.s IL_0192 - IL_01b7: ldloc.3 - IL_01b8: stloc.s V_17 - IL_01ba: ldc.i4.0 - IL_01bb: stloc.s V_11 - IL_01bd: br.s IL_01d9 - IL_01bf: ldloca.s V_17 - IL_01c1: ldloc.s V_11 - IL_01c3: call ""ref readonly ushort System.ReadOnlySpan.this[int].get"" - IL_01c8: ldind.u2 - IL_01c9: stloc.s V_18 - IL_01cb: ldloc.s V_9 - IL_01cd: ldloc.s V_18 - IL_01cf: conv.u8 - IL_01d0: add - IL_01d1: stloc.s V_9 - IL_01d3: ldloc.s V_11 - IL_01d5: ldc.i4.1 - IL_01d6: add - IL_01d7: stloc.s V_11 - IL_01d9: ldloc.s V_11 - IL_01db: ldloca.s V_17 - IL_01dd: call ""int System.ReadOnlySpan.Length.get"" - IL_01e2: blt.s IL_01bf - IL_01e4: ldloc.s V_4 - IL_01e6: stloc.s V_19 - IL_01e8: ldc.i4.0 - IL_01e9: stloc.s V_11 - IL_01eb: br.s IL_0207 - IL_01ed: ldloca.s V_19 - IL_01ef: ldloc.s V_11 - IL_01f1: call ""ref readonly int System.ReadOnlySpan.this[int].get"" - IL_01f6: ldind.i4 - IL_01f7: stloc.s V_20 - IL_01f9: ldloc.s V_9 - IL_01fb: ldloc.s V_20 - IL_01fd: conv.i8 - IL_01fe: add - IL_01ff: stloc.s V_9 - IL_0201: ldloc.s V_11 - IL_0203: ldc.i4.1 - IL_0204: add - IL_0205: stloc.s V_11 - IL_0207: ldloc.s V_11 - IL_0209: ldloca.s V_19 - IL_020b: call ""int System.ReadOnlySpan.Length.get"" - IL_0210: blt.s IL_01ed - IL_0212: ldloc.s V_5 - IL_0214: stloc.s V_21 - IL_0216: ldc.i4.0 - IL_0217: stloc.s V_11 - IL_0219: br.s IL_0235 - IL_021b: ldloca.s V_21 - IL_021d: ldloc.s V_11 - IL_021f: call ""ref readonly uint System.ReadOnlySpan.this[int].get"" - IL_0224: ldind.u4 - IL_0225: stloc.s V_22 - IL_0227: ldloc.s V_9 - IL_0229: ldloc.s V_22 - IL_022b: conv.u8 - IL_022c: add - IL_022d: stloc.s V_9 - IL_022f: ldloc.s V_11 - IL_0231: ldc.i4.1 - IL_0232: add - IL_0233: stloc.s V_11 - IL_0235: ldloc.s V_11 - IL_0237: ldloca.s V_21 - IL_0239: call ""int System.ReadOnlySpan.Length.get"" - IL_023e: blt.s IL_021b - IL_0240: ldloc.s V_6 - IL_0242: stloc.s V_23 - IL_0244: ldc.i4.0 - IL_0245: stloc.s V_11 - IL_0247: br.s IL_0262 - IL_0249: ldloca.s V_23 - IL_024b: ldloc.s V_11 - IL_024d: call ""ref readonly long System.ReadOnlySpan.this[int].get"" - IL_0252: ldind.i8 - IL_0253: stloc.s V_24 - IL_0255: ldloc.s V_9 - IL_0257: ldloc.s V_24 - IL_0259: add - IL_025a: stloc.s V_9 - IL_025c: ldloc.s V_11 - IL_025e: ldc.i4.1 - IL_025f: add - IL_0260: stloc.s V_11 - IL_0262: ldloc.s V_11 - IL_0264: ldloca.s V_23 - IL_0266: call ""int System.ReadOnlySpan.Length.get"" - IL_026b: blt.s IL_0249 - IL_026d: ldloc.s V_7 - IL_026f: stloc.s V_25 - IL_0271: ldc.i4.0 - IL_0272: stloc.s V_11 - IL_0274: br.s IL_028f - IL_0276: ldloca.s V_25 - IL_0278: ldloc.s V_11 - IL_027a: call ""ref readonly ulong System.ReadOnlySpan.this[int].get"" - IL_027f: ldind.i8 - IL_0280: stloc.s V_26 - IL_0282: ldloc.s V_9 - IL_0284: ldloc.s V_26 - IL_0286: add - IL_0287: stloc.s V_9 - IL_0289: ldloc.s V_11 - IL_028b: ldc.i4.1 - IL_028c: add - IL_028d: stloc.s V_11 - IL_028f: ldloc.s V_11 - IL_0291: ldloca.s V_25 - IL_0293: call ""int System.ReadOnlySpan.Length.get"" - IL_0298: blt.s IL_0276 - IL_029a: ldloc.s V_8 - IL_029c: stloc.s V_27 - IL_029e: ldc.i4.0 - IL_029f: stloc.s V_11 - IL_02a1: br.s IL_02bd - IL_02a3: ldloca.s V_27 - IL_02a5: ldloc.s V_11 - IL_02a7: call ""ref readonly char System.ReadOnlySpan.this[int].get"" - IL_02ac: ldind.u2 - IL_02ad: stloc.s V_28 - IL_02af: ldloc.s V_9 - IL_02b1: ldloc.s V_28 - IL_02b3: conv.u8 - IL_02b4: add - IL_02b5: stloc.s V_9 - IL_02b7: ldloc.s V_11 - IL_02b9: ldc.i4.1 - IL_02ba: add - IL_02bb: stloc.s V_11 - IL_02bd: ldloc.s V_11 - IL_02bf: ldloca.s V_27 - IL_02c1: call ""int System.ReadOnlySpan.Length.get"" - IL_02c6: blt.s IL_02a3 - IL_02c8: ldloc.s V_9 - IL_02ca: call ""void System.Console.Write(long)"" - IL_02cf: ret + IL_0000: ldloca.s V_0 + IL_0002: ldsflda "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" + IL_0007: ldc.i4.s 32 + IL_0009: call ""System.ReadOnlySpan..ctor(void*, int)"" + IL_000e: ldloca.s V_1 + IL_0010: ldsflda "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" + IL_0015: ldc.i4.s 32 + IL_0017: call ""System.ReadOnlySpan..ctor(void*, int)"" + IL_001c: ldsfld ""short[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A5"" + IL_0021: dup + IL_0022: brtrue.s IL_003d + IL_0024: pop + IL_0025: ldc.i4.s 16 + IL_0027: newarr ""short"" + IL_002c: dup + IL_002d: ldtoken "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" + IL_0032: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"" + IL_0037: dup + IL_0038: stsfld ""short[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A5"" + IL_003d: newobj ""System.ReadOnlySpan..ctor(short[])"" + IL_0042: stloc.2 + IL_0043: ldsfld ""ushort[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A13"" + IL_0048: dup + IL_0049: brtrue.s IL_0064 + IL_004b: pop + IL_004c: ldc.i4.s 16 + IL_004e: newarr ""ushort"" + IL_0053: dup + IL_0054: ldtoken "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" + IL_0059: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"" + IL_005e: dup + IL_005f: stsfld ""ushort[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A13"" + IL_0064: newobj ""System.ReadOnlySpan..ctor(ushort[])"" + IL_0069: stloc.3 + IL_006a: ldsfld ""int[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A6"" + IL_006f: dup + IL_0070: brtrue.s IL_008a + IL_0072: pop + IL_0073: ldc.i4.8 + IL_0074: newarr ""int"" + IL_0079: dup + IL_007a: ldtoken "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" + IL_007f: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"" + IL_0084: dup + IL_0085: stsfld ""int[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A6"" + IL_008a: newobj ""System.ReadOnlySpan..ctor(int[])"" + IL_008f: stloc.s V_4 + IL_0091: ldsfld ""uint[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A14"" + IL_0096: dup + IL_0097: brtrue.s IL_00b1 + IL_0099: pop + IL_009a: ldc.i4.8 + IL_009b: newarr ""uint"" + IL_00a0: dup + IL_00a1: ldtoken "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" + IL_00a6: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"" + IL_00ab: dup + IL_00ac: stsfld ""uint[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A14"" + IL_00b1: newobj ""System.ReadOnlySpan..ctor(uint[])"" + IL_00b6: stloc.s V_5 + IL_00b8: ldsfld ""long[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A7"" + IL_00bd: dup + IL_00be: brtrue.s IL_00d8 + IL_00c0: pop + IL_00c1: ldc.i4.4 + IL_00c2: newarr ""long"" + IL_00c7: dup + IL_00c8: ldtoken "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" + IL_00cd: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"" + IL_00d2: dup + IL_00d3: stsfld ""long[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A7"" + IL_00d8: newobj ""System.ReadOnlySpan..ctor(long[])"" + IL_00dd: stloc.s V_6 + IL_00df: ldsfld ""ulong[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A15"" + IL_00e4: dup + IL_00e5: brtrue.s IL_00ff + IL_00e7: pop + IL_00e8: ldc.i4.4 + IL_00e9: newarr ""ulong"" + IL_00ee: dup + IL_00ef: ldtoken "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" + IL_00f4: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"" + IL_00f9: dup + IL_00fa: stsfld ""ulong[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A15"" + IL_00ff: newobj ""System.ReadOnlySpan..ctor(ulong[])"" + IL_0104: stloc.s V_7 + IL_0106: ldsfld ""char[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A1"" + IL_010b: dup + IL_010c: brtrue.s IL_0127 + IL_010e: pop + IL_010f: ldc.i4.s 16 + IL_0111: newarr ""char"" + IL_0116: dup + IL_0117: ldtoken "".__StaticArrayInitTypeSize=32 .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051"" + IL_011c: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"" + IL_0121: dup + IL_0122: stsfld ""char[] .AF9613760F72635FBDB44A5A0A63C39F12AF30F950A6EE5C971BE188E89C4051_A1"" + IL_0127: newobj ""System.ReadOnlySpan..ctor(char[])"" + IL_012c: stloc.s V_8 + IL_012e: ldc.i4.0 + IL_012f: conv.i8 + IL_0130: stloc.s V_9 + IL_0132: ldloc.0 + IL_0133: stloc.s V_10 + IL_0135: ldc.i4.0 + IL_0136: stloc.s V_11 + IL_0138: br.s IL_0154 + IL_013a: ldloca.s V_10 + IL_013c: ldloc.s V_11 + IL_013e: call ""ref readonly sbyte System.ReadOnlySpan.this[int].get"" + IL_0143: ldind.i1 + IL_0144: stloc.s V_12 + IL_0146: ldloc.s V_9 + IL_0148: ldloc.s V_12 + IL_014a: conv.i8 + IL_014b: add + IL_014c: stloc.s V_9 + IL_014e: ldloc.s V_11 + IL_0150: ldc.i4.1 + IL_0151: add + IL_0152: stloc.s V_11 + IL_0154: ldloc.s V_11 + IL_0156: ldloca.s V_10 + IL_0158: call ""int System.ReadOnlySpan.Length.get"" + IL_015d: blt.s IL_013a + IL_015f: ldloc.1 + IL_0160: stloc.s V_13 + IL_0162: ldc.i4.0 + IL_0163: stloc.s V_11 + IL_0165: br.s IL_0181 + IL_0167: ldloca.s V_13 + IL_0169: ldloc.s V_11 + IL_016b: call ""ref readonly byte System.ReadOnlySpan.this[int].get"" + IL_0170: ldind.u1 + IL_0171: stloc.s V_14 + IL_0173: ldloc.s V_9 + IL_0175: ldloc.s V_14 + IL_0177: conv.u8 + IL_0178: add + IL_0179: stloc.s V_9 + IL_017b: ldloc.s V_11 + IL_017d: ldc.i4.1 + IL_017e: add + IL_017f: stloc.s V_11 + IL_0181: ldloc.s V_11 + IL_0183: ldloca.s V_13 + IL_0185: call ""int System.ReadOnlySpan.Length.get"" + IL_018a: blt.s IL_0167 + IL_018c: ldloc.2 + IL_018d: stloc.s V_15 + IL_018f: ldc.i4.0 + IL_0190: stloc.s V_11 + IL_0192: br.s IL_01ae + IL_0194: ldloca.s V_15 + IL_0196: ldloc.s V_11 + IL_0198: call ""ref readonly short System.ReadOnlySpan.this[int].get"" + IL_019d: ldind.i2 + IL_019e: stloc.s V_16 + IL_01a0: ldloc.s V_9 + IL_01a2: ldloc.s V_16 + IL_01a4: conv.i8 + IL_01a5: add + IL_01a6: stloc.s V_9 + IL_01a8: ldloc.s V_11 + IL_01aa: ldc.i4.1 + IL_01ab: add + IL_01ac: stloc.s V_11 + IL_01ae: ldloc.s V_11 + IL_01b0: ldloca.s V_15 + IL_01b2: call ""int System.ReadOnlySpan.Length.get"" + IL_01b7: blt.s IL_0194 + IL_01b9: ldloc.3 + IL_01ba: stloc.s V_17 + IL_01bc: ldc.i4.0 + IL_01bd: stloc.s V_11 + IL_01bf: br.s IL_01db + IL_01c1: ldloca.s V_17 + IL_01c3: ldloc.s V_11 + IL_01c5: call ""ref readonly ushort System.ReadOnlySpan.this[int].get"" + IL_01ca: ldind.u2 + IL_01cb: stloc.s V_18 + IL_01cd: ldloc.s V_9 + IL_01cf: ldloc.s V_18 + IL_01d1: conv.u8 + IL_01d2: add + IL_01d3: stloc.s V_9 + IL_01d5: ldloc.s V_11 + IL_01d7: ldc.i4.1 + IL_01d8: add + IL_01d9: stloc.s V_11 + IL_01db: ldloc.s V_11 + IL_01dd: ldloca.s V_17 + IL_01df: call ""int System.ReadOnlySpan.Length.get"" + IL_01e4: blt.s IL_01c1 + IL_01e6: ldloc.s V_4 + IL_01e8: stloc.s V_19 + IL_01ea: ldc.i4.0 + IL_01eb: stloc.s V_11 + IL_01ed: br.s IL_0209 + IL_01ef: ldloca.s V_19 + IL_01f1: ldloc.s V_11 + IL_01f3: call ""ref readonly int System.ReadOnlySpan.this[int].get"" + IL_01f8: ldind.i4 + IL_01f9: stloc.s V_20 + IL_01fb: ldloc.s V_9 + IL_01fd: ldloc.s V_20 + IL_01ff: conv.i8 + IL_0200: add + IL_0201: stloc.s V_9 + IL_0203: ldloc.s V_11 + IL_0205: ldc.i4.1 + IL_0206: add + IL_0207: stloc.s V_11 + IL_0209: ldloc.s V_11 + IL_020b: ldloca.s V_19 + IL_020d: call ""int System.ReadOnlySpan.Length.get"" + IL_0212: blt.s IL_01ef + IL_0214: ldloc.s V_5 + IL_0216: stloc.s V_21 + IL_0218: ldc.i4.0 + IL_0219: stloc.s V_11 + IL_021b: br.s IL_0237 + IL_021d: ldloca.s V_21 + IL_021f: ldloc.s V_11 + IL_0221: call ""ref readonly uint System.ReadOnlySpan.this[int].get"" + IL_0226: ldind.u4 + IL_0227: stloc.s V_22 + IL_0229: ldloc.s V_9 + IL_022b: ldloc.s V_22 + IL_022d: conv.u8 + IL_022e: add + IL_022f: stloc.s V_9 + IL_0231: ldloc.s V_11 + IL_0233: ldc.i4.1 + IL_0234: add + IL_0235: stloc.s V_11 + IL_0237: ldloc.s V_11 + IL_0239: ldloca.s V_21 + IL_023b: call ""int System.ReadOnlySpan.Length.get"" + IL_0240: blt.s IL_021d + IL_0242: ldloc.s V_6 + IL_0244: stloc.s V_23 + IL_0246: ldc.i4.0 + IL_0247: stloc.s V_11 + IL_0249: br.s IL_0264 + IL_024b: ldloca.s V_23 + IL_024d: ldloc.s V_11 + IL_024f: call ""ref readonly long System.ReadOnlySpan.this[int].get"" + IL_0254: ldind.i8 + IL_0255: stloc.s V_24 + IL_0257: ldloc.s V_9 + IL_0259: ldloc.s V_24 + IL_025b: add + IL_025c: stloc.s V_9 + IL_025e: ldloc.s V_11 + IL_0260: ldc.i4.1 + IL_0261: add + IL_0262: stloc.s V_11 + IL_0264: ldloc.s V_11 + IL_0266: ldloca.s V_23 + IL_0268: call ""int System.ReadOnlySpan.Length.get"" + IL_026d: blt.s IL_024b + IL_026f: ldloc.s V_7 + IL_0271: stloc.s V_25 + IL_0273: ldc.i4.0 + IL_0274: stloc.s V_11 + IL_0276: br.s IL_0291 + IL_0278: ldloca.s V_25 + IL_027a: ldloc.s V_11 + IL_027c: call ""ref readonly ulong System.ReadOnlySpan.this[int].get"" + IL_0281: ldind.i8 + IL_0282: stloc.s V_26 + IL_0284: ldloc.s V_9 + IL_0286: ldloc.s V_26 + IL_0288: add + IL_0289: stloc.s V_9 + IL_028b: ldloc.s V_11 + IL_028d: ldc.i4.1 + IL_028e: add + IL_028f: stloc.s V_11 + IL_0291: ldloc.s V_11 + IL_0293: ldloca.s V_25 + IL_0295: call ""int System.ReadOnlySpan.Length.get"" + IL_029a: blt.s IL_0278 + IL_029c: ldloc.s V_8 + IL_029e: stloc.s V_27 + IL_02a0: ldc.i4.0 + IL_02a1: stloc.s V_11 + IL_02a3: br.s IL_02bf + IL_02a5: ldloca.s V_27 + IL_02a7: ldloc.s V_11 + IL_02a9: call ""ref readonly char System.ReadOnlySpan.this[int].get"" + IL_02ae: ldind.u2 + IL_02af: stloc.s V_28 + IL_02b1: ldloc.s V_9 + IL_02b3: ldloc.s V_28 + IL_02b5: conv.u8 + IL_02b6: add + IL_02b7: stloc.s V_9 + IL_02b9: ldloc.s V_11 + IL_02bb: ldc.i4.1 + IL_02bc: add + IL_02bd: stloc.s V_11 + IL_02bf: ldloc.s V_11 + IL_02c1: ldloca.s V_27 + IL_02c3: call ""int System.ReadOnlySpan.Length.get"" + IL_02c8: blt.s IL_02a5 + IL_02ca: ldloc.s V_9 + IL_02cc: call ""void System.Console.Write(long)"" + IL_02d1: ret }"); } @@ -2510,7 +2513,7 @@ public static void Main() } }"; - var compilation = CreateCompilationWithIL(csharp, ilSource); + var compilation = CreateCompilationWithIL(csharp, ilSource, parseOptions: TestOptions.Regular12); var verifier = CompileAndVerify(compilation, verify: Verification.Skipped); var expected = @@ -2537,10 +2540,17 @@ .maxstack 4 // We should get the same IL with regular ReadOnlySpan implementation, // but with WellKnownMember.System_ReadOnlySpan_T__ctor_Array missing - compilation = CreateCompilationWithMscorlibAndSpan(csharp); + compilation = CreateCompilationWithMscorlibAndSpan(csharp, parseOptions: TestOptions.Regular12); compilation.MakeMemberMissing(WellKnownMember.System_ReadOnlySpan_T__ctor_Array); verifier = CompileAndVerify(compilation, verify: Verification.Skipped); verifier.VerifyIL("Test.StaticData.get", expected); + + compilation = CreateCompilationWithMscorlibAndSpan(csharp); + compilation.MakeMemberMissing(WellKnownMember.System_ReadOnlySpan_T__ctor_Array); + compilation.VerifyDiagnostics( + // (6,51): error CS0656: Missing compiler required member 'System.ReadOnlySpan`1..ctor' + // public static ReadOnlySpan StaticData => new int[] { 10, 20 }; + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "new int[] { 10, 20 }").WithArguments("System.ReadOnlySpan`1", ".ctor").WithLocation(6, 51)); } [Theory] @@ -2761,7 +2771,7 @@ .maxstack 2 .maxstack 1 IL_0000: ldc.i4.3 IL_0001: newarr "object" - IL_0006: call "System.ReadOnlySpan System.ReadOnlySpan.op_Implicit(object[])" + IL_0006: newobj "System.ReadOnlySpan..ctor(object[])" IL_000b: ret } """); @@ -2772,7 +2782,7 @@ .maxstack 1 .maxstack 1 IL_0000: ldc.i4.3 IL_0001: newarr "C" - IL_0006: call "System.ReadOnlySpan System.ReadOnlySpan.op_Implicit(C[])" + IL_0006: newobj "System.ReadOnlySpan..ctor(C[])" IL_000b: ret } """); @@ -2869,7 +2879,7 @@ public static System.ReadOnlySpan M() => new string[] { "hello", "world" }; } """; - var compilation = CreateCompilationWithMscorlibAndSpan(src); + var compilation = CreateCompilationWithMscorlibAndSpan(src, parseOptions: TestOptions.Regular12); compilation.MakeMemberMissing(WellKnownMember.System_ReadOnlySpan_T__ctor_Array); var ilVerifyMessage = """ @@ -2897,6 +2907,13 @@ .maxstack 4 IL_001b: ret } """); + + compilation = CreateCompilationWithMscorlibAndSpan(src); + compilation.MakeMemberMissing(WellKnownMember.System_ReadOnlySpan_T__ctor_Array); + compilation.VerifyDiagnostics( + // (7,12): error CS0656: Missing compiler required member 'System.ReadOnlySpan`1..ctor' + // => new string[] { "hello", "world" }; + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, @"new string[] { ""hello"", ""world"" }").WithArguments("System.ReadOnlySpan`1", ".ctor").WithLocation(7, 12)); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69472")] @@ -2944,7 +2961,7 @@ .locals init (string V_0, //hello IL_0017: ldc.i4.1 IL_0018: ldloc.1 IL_0019: stelem.ref - IL_001a: call "System.ReadOnlySpan System.ReadOnlySpan.op_Implicit(string[])" + IL_001a: newobj "System.ReadOnlySpan..ctor(string[])" IL_001f: ret } """); @@ -3295,7 +3312,7 @@ .maxstack 4 IL_0007: ldc.i4.0 IL_0008: ldsfld "System.DateTime C.dateTime" IL_000d: stelem "System.DateTime" - IL_0012: call "System.ReadOnlySpan System.ReadOnlySpan.op_Implicit(System.DateTime[])" + IL_0012: newobj "System.ReadOnlySpan..ctor(System.DateTime[])" IL_0017: ret } """; @@ -3415,7 +3432,7 @@ public static System.ReadOnlySpan M() .maxstack 1 IL_0000: ldc.i4.1 IL_0001: newarr "S" - IL_0006: call "System.ReadOnlySpan System.ReadOnlySpan.op_Implicit(S[])" + IL_0006: newobj "System.ReadOnlySpan..ctor(S[])" IL_000b: ret } """); @@ -3438,7 +3455,7 @@ public class C .maxstack 1 IL_0000: ldc.i4.1 IL_0001: newarr "int?" - IL_0006: call "System.ReadOnlySpan System.ReadOnlySpan.op_Implicit(int?[])" + IL_0006: newobj "System.ReadOnlySpan..ctor(int?[])" IL_000b: ret } """); diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/ForeachTest.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/ForeachTest.cs index 92fb52b297fc0..2e40dc9b4a7fa 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/ForeachTest.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/ForeachTest.cs @@ -547,31 +547,31 @@ public static void Main() CompileAndVerify(comp, expectedOutput: "123", verify: Verification.Fails).VerifyIL("Test.Main", @" { - // Code size 45 (0x2d) - .maxstack 2 + // Code size 46 (0x2e) + .maxstack 3 .locals init (System.ReadOnlySpan V_0, int V_1) - IL_0000: ldsflda "".__StaticArrayInitTypeSize=3 .039058C6F2C0CB492C533B0A4D14EF77CC0F78ABCCCED5287D84A1A2011CFB81"" - IL_0005: ldc.i4.3 - IL_0006: newobj ""System.ReadOnlySpan..ctor(void*, int)"" - IL_000b: stloc.0 - IL_000c: ldc.i4.0 - IL_000d: stloc.1 - IL_000e: br.s IL_0022 - IL_0010: ldloca.s V_0 - IL_0012: ldloc.1 - IL_0013: call ""ref readonly byte System.ReadOnlySpan.this[int].get"" - IL_0018: ldind.u1 - IL_0019: call ""void System.Console.Write(int)"" - IL_001e: ldloc.1 - IL_001f: ldc.i4.1 - IL_0020: add - IL_0021: stloc.1 - IL_0022: ldloc.1 - IL_0023: ldloca.s V_0 - IL_0025: call ""int System.ReadOnlySpan.Length.get"" - IL_002a: blt.s IL_0010 - IL_002c: ret + IL_0000: ldloca.s V_0 + IL_0002: ldsflda "".__StaticArrayInitTypeSize=3 .039058C6F2C0CB492C533B0A4D14EF77CC0F78ABCCCED5287D84A1A2011CFB81"" + IL_0007: ldc.i4.3 + IL_0008: call ""System.ReadOnlySpan..ctor(void*, int)"" + IL_000d: ldc.i4.0 + IL_000e: stloc.1 + IL_000f: br.s IL_0023 + IL_0011: ldloca.s V_0 + IL_0013: ldloc.1 + IL_0014: call ""ref readonly byte System.ReadOnlySpan.this[int].get"" + IL_0019: ldind.u1 + IL_001a: call ""void System.Console.Write(int)"" + IL_001f: ldloc.1 + IL_0020: ldc.i4.1 + IL_0021: add + IL_0022: stloc.1 + IL_0023: ldloc.1 + IL_0024: ldloca.s V_0 + IL_0026: call ""int System.ReadOnlySpan.Length.get"" + IL_002b: blt.s IL_0011 + IL_002d: ret }"); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/IndexAndRangeTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/IndexAndRangeTests.cs index 0749e47f7df78..c11bf8a3a1d12 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/IndexAndRangeTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/IndexAndRangeTests.cs @@ -1028,52 +1028,52 @@ static void Main() 9"); verifier.VerifyIL("C.Main", @" { - // Code size 112 (0x70) + // Code size 113 (0x71) .maxstack 4 .locals init (System.Span V_0) //s - IL_0000: ldc.i4.4 - IL_0001: newarr ""int"" - IL_0006: dup - IL_0007: ldtoken "".__StaticArrayInitTypeSize=16 .B35A10C764778866E34111165FC69660C6171DF0CB0141E39FA0217EF7A97646"" - IL_000c: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"" - IL_0011: call ""System.Span System.Span.op_Implicit(int[])"" - IL_0016: stloc.0 - IL_0017: ldloca.s V_0 - IL_0019: dup - IL_001a: call ""int System.Span.Length.get"" - IL_001f: ldc.i4.2 - IL_0020: sub - IL_0021: call ""ref int System.Span.this[int].get"" - IL_0026: ldind.i4 - IL_0027: call ""void System.Console.WriteLine(int)"" - IL_002c: ldloca.s V_0 - IL_002e: dup - IL_002f: call ""int System.Span.Length.get"" - IL_0034: ldc.i4.2 - IL_0035: sub - IL_0036: call ""ref int System.Span.this[int].get"" - IL_003b: dup - IL_003c: ldind.i4 - IL_003d: call ""void System.Console.WriteLine(int)"" - IL_0042: ldloca.s V_0 - IL_0044: dup - IL_0045: call ""int System.Span.Length.get"" - IL_004a: ldc.i4.2 - IL_004b: sub - IL_004c: call ""ref int System.Span.this[int].get"" - IL_0051: ldc.i4.s 9 - IL_0053: stind.i4 - IL_0054: ldloca.s V_0 - IL_0056: dup - IL_0057: call ""int System.Span.Length.get"" - IL_005c: ldc.i4.2 - IL_005d: sub - IL_005e: call ""ref int System.Span.this[int].get"" - IL_0063: ldind.i4 - IL_0064: call ""void System.Console.WriteLine(int)"" - IL_0069: ldind.i4 - IL_006a: call ""void System.Console.WriteLine(int)"" - IL_006f: ret + IL_0000: ldloca.s V_0 + IL_0002: ldc.i4.4 + IL_0003: newarr ""int"" + IL_0008: dup + IL_0009: ldtoken "".__StaticArrayInitTypeSize=16 .B35A10C764778866E34111165FC69660C6171DF0CB0141E39FA0217EF7A97646"" + IL_000e: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"" + IL_0013: call ""System.Span..ctor(int[])"" + IL_0018: ldloca.s V_0 + IL_001a: dup + IL_001b: call ""int System.Span.Length.get"" + IL_0020: ldc.i4.2 + IL_0021: sub + IL_0022: call ""ref int System.Span.this[int].get"" + IL_0027: ldind.i4 + IL_0028: call ""void System.Console.WriteLine(int)"" + IL_002d: ldloca.s V_0 + IL_002f: dup + IL_0030: call ""int System.Span.Length.get"" + IL_0035: ldc.i4.2 + IL_0036: sub + IL_0037: call ""ref int System.Span.this[int].get"" + IL_003c: dup + IL_003d: ldind.i4 + IL_003e: call ""void System.Console.WriteLine(int)"" + IL_0043: ldloca.s V_0 + IL_0045: dup + IL_0046: call ""int System.Span.Length.get"" + IL_004b: ldc.i4.2 + IL_004c: sub + IL_004d: call ""ref int System.Span.this[int].get"" + IL_0052: ldc.i4.s 9 + IL_0054: stind.i4 + IL_0055: ldloca.s V_0 + IL_0057: dup + IL_0058: call ""int System.Span.Length.get"" + IL_005d: ldc.i4.2 + IL_005e: sub + IL_005f: call ""ref int System.Span.this[int].get"" + IL_0064: ldind.i4 + IL_0065: call ""void System.Console.WriteLine(int)"" + IL_006a: ldind.i4 + IL_006b: call ""void System.Console.WriteLine(int)"" + IL_0070: ret } "); } @@ -1187,67 +1187,67 @@ static void Main() 6"); verifier.VerifyIL("C.Main", @" { - // Code size 136 (0x88) - .maxstack 4 - .locals init (System.Span V_0, //s - System.Index V_1, //index - System.Span& V_2, - int V_3, - int V_4) - IL_0000: ldc.i4.4 - IL_0001: newarr ""int"" - IL_0006: dup - IL_0007: ldtoken "".__StaticArrayInitTypeSize=16 .B35A10C764778866E34111165FC69660C6171DF0CB0141E39FA0217EF7A97646"" - IL_000c: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"" - IL_0011: call ""System.Span System.Span.op_Implicit(int[])"" - IL_0016: stloc.0 - IL_0017: ldloca.s V_0 - IL_0019: dup - IL_001a: call ""int System.Span.Length.get"" - IL_001f: ldc.i4.2 - IL_0020: sub - IL_0021: call ""ref int System.Span.this[int].get"" - IL_0026: ldind.i4 - IL_0027: call ""void System.Console.WriteLine(int)"" - IL_002c: ldloca.s V_1 - IL_002e: ldc.i4.1 - IL_002f: ldc.i4.1 - IL_0030: call ""System.Index..ctor(int, bool)"" - IL_0035: ldloca.s V_0 - IL_0037: stloc.2 - IL_0038: ldloc.2 - IL_0039: ldloca.s V_1 - IL_003b: ldloc.2 - IL_003c: call ""int System.Span.Length.get"" - IL_0041: call ""int System.Index.GetOffset(int)"" - IL_0046: call ""ref int System.Span.this[int].get"" - IL_004b: ldind.i4 - IL_004c: call ""void System.Console.WriteLine(int)"" - IL_0051: ldloca.s V_0 - IL_0053: dup - IL_0054: call ""int System.Span.Length.get"" - IL_0059: stloc.3 - IL_005a: ldloc.3 - IL_005b: ldc.i4.2 - IL_005c: sub - IL_005d: stloc.s V_4 - IL_005f: ldloc.s V_4 - IL_0061: ldloc.3 - IL_0062: ldloc.s V_4 - IL_0064: sub - IL_0065: call ""System.Span System.Span.Slice(int, int)"" - IL_006a: stloc.0 - IL_006b: ldloca.s V_0 - IL_006d: ldc.i4.0 - IL_006e: call ""ref int System.Span.this[int].get"" - IL_0073: ldind.i4 - IL_0074: call ""void System.Console.WriteLine(int)"" - IL_0079: ldloca.s V_0 - IL_007b: ldc.i4.1 - IL_007c: call ""ref int System.Span.this[int].get"" - IL_0081: ldind.i4 - IL_0082: call ""void System.Console.WriteLine(int)"" - IL_0087: ret + // Code size 137 (0x89) + .maxstack 4 + .locals init (System.Span V_0, //s + System.Index V_1, //index + System.Span& V_2, + int V_3, + int V_4) + IL_0000: ldloca.s V_0 + IL_0002: ldc.i4.4 + IL_0003: newarr ""int"" + IL_0008: dup + IL_0009: ldtoken "".__StaticArrayInitTypeSize=16 .B35A10C764778866E34111165FC69660C6171DF0CB0141E39FA0217EF7A97646"" + IL_000e: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"" + IL_0013: call ""System.Span..ctor(int[])"" + IL_0018: ldloca.s V_0 + IL_001a: dup + IL_001b: call ""int System.Span.Length.get"" + IL_0020: ldc.i4.2 + IL_0021: sub + IL_0022: call ""ref int System.Span.this[int].get"" + IL_0027: ldind.i4 + IL_0028: call ""void System.Console.WriteLine(int)"" + IL_002d: ldloca.s V_1 + IL_002f: ldc.i4.1 + IL_0030: ldc.i4.1 + IL_0031: call ""System.Index..ctor(int, bool)"" + IL_0036: ldloca.s V_0 + IL_0038: stloc.2 + IL_0039: ldloc.2 + IL_003a: ldloca.s V_1 + IL_003c: ldloc.2 + IL_003d: call ""int System.Span.Length.get"" + IL_0042: call ""int System.Index.GetOffset(int)"" + IL_0047: call ""ref int System.Span.this[int].get"" + IL_004c: ldind.i4 + IL_004d: call ""void System.Console.WriteLine(int)"" + IL_0052: ldloca.s V_0 + IL_0054: dup + IL_0055: call ""int System.Span.Length.get"" + IL_005a: stloc.3 + IL_005b: ldloc.3 + IL_005c: ldc.i4.2 + IL_005d: sub + IL_005e: stloc.s V_4 + IL_0060: ldloc.s V_4 + IL_0062: ldloc.3 + IL_0063: ldloc.s V_4 + IL_0065: sub + IL_0066: call ""System.Span System.Span.Slice(int, int)"" + IL_006b: stloc.0 + IL_006c: ldloca.s V_0 + IL_006e: ldc.i4.0 + IL_006f: call ""ref int System.Span.this[int].get"" + IL_0074: ldind.i4 + IL_0075: call ""void System.Console.WriteLine(int)"" + IL_007a: ldloca.s V_0 + IL_007c: ldc.i4.1 + IL_007d: call ""ref int System.Span.this[int].get"" + IL_0082: ldind.i4 + IL_0083: call ""void System.Console.WriteLine(int)"" + IL_0088: ret } "); } diff --git a/src/Compilers/CSharp/Test/Emit2/Emit/NumericIntPtrTests.cs b/src/Compilers/CSharp/Test/Emit2/Emit/NumericIntPtrTests.cs index 458de9f14813a..397849855206e 100644 --- a/src/Compilers/CSharp/Test/Emit2/Emit/NumericIntPtrTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/Emit/NumericIntPtrTests.cs @@ -11744,7 +11744,7 @@ void verify(CSharpCompilation comp) var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("00")); verifier.VerifyIL("Program.F", """ { - // Code size 48 (0x30) + // Code size 49 (0x31) .maxstack 3 .locals init (System.Span V_0, //s System.Span V_1, @@ -11762,20 +11762,20 @@ .locals init (System.Span V_0, //s IL_000d: ldloc.2 IL_000e: newobj "System.Span..ctor(void*, int)" IL_0013: stloc.1 - IL_0014: br.s IL_0022 - IL_0016: ldarg.0 - IL_0017: newarr "char" - IL_001c: call "System.Span System.Span.op_Implicit(char[])" - IL_0021: stloc.1 - IL_0022: ldloc.1 - IL_0023: stloc.0 - IL_0024: ldloca.s V_0 - IL_0026: ldarg.0 - IL_0027: ldc.i4.1 - IL_0028: sub - IL_0029: call "ref char System.Span.this[int].get" - IL_002e: ldind.u2 - IL_002f: ret + IL_0014: br.s IL_0023 + IL_0016: ldloca.s V_1 + IL_0018: ldarg.0 + IL_0019: newarr "char" + IL_001e: call "System.Span..ctor(char[])" + IL_0023: ldloc.1 + IL_0024: stloc.0 + IL_0025: ldloca.s V_0 + IL_0027: ldarg.0 + IL_0028: ldc.i4.1 + IL_0029: sub + IL_002a: call "ref char System.Span.this[int].get" + IL_002f: ldind.u2 + IL_0030: ret } """); } diff --git a/src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs b/src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs index 2ed198808f074..2423f86fccd03 100644 --- a/src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs @@ -20658,20 +20658,20 @@ static void Main() expectedOutput: IncludeExpectedOutput("[1, 2], [3, null], ")); verifier.VerifyIL("Program.F1", """ { - // Code size 28 (0x1c) - .maxstack 4 - IL_0000: ldc.i4.2 - IL_0001: newarr "T" - IL_0006: dup - IL_0007: ldc.i4.0 - IL_0008: ldarg.0 - IL_0009: stelem "T" - IL_000e: dup - IL_000f: ldc.i4.1 - IL_0010: ldarg.1 - IL_0011: stelem "T" - IL_0016: call "System.Span System.Span.op_Implicit(T[])" - IL_001b: ret + // Code size 28 (0x1c) + .maxstack 4 + IL_0000: ldc.i4.2 + IL_0001: newarr "T" + IL_0006: dup + IL_0007: ldc.i4.0 + IL_0008: ldarg.0 + IL_0009: stelem "T" + IL_000e: dup + IL_000f: ldc.i4.1 + IL_0010: ldarg.1 + IL_0011: stelem "T" + IL_0016: newobj "System.Span..ctor(T[])" + IL_001b: ret } """); verifier.VerifyIL("Program.F2", """ @@ -20688,7 +20688,7 @@ .maxstack 4 IL_000f: ldc.i4.1 IL_0010: ldarg.1 IL_0011: stelem "T" - IL_0016: call "System.ReadOnlySpan System.ReadOnlySpan.op_Implicit(T[])" + IL_0016: newobj "System.ReadOnlySpan..ctor(T[])" IL_001b: ret } """); @@ -28773,7 +28773,7 @@ .maxstack 4 IL_0017: ldc.i4.0 IL_0018: ldc.i4.1 IL_0019: stelem.i4 - IL_001a: call "System.Span System.Span.op_Implicit(int[])" + IL_001a: newobj "System.Span..ctor(int[])" IL_001f: pop IL_0020: ret } @@ -28797,7 +28797,7 @@ .locals init (int V_0) IL_0011: ldc.i4.0 IL_0012: ldc.i4.1 IL_0013: stelem.i4 - IL_0014: call "System.Span System.Span.op_Implicit(int[])" + IL_0014: newobj "System.Span..ctor(int[])" IL_0019: pop IL_001a: ret } diff --git a/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests.cs b/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests.cs index ac537827d6664..f24169b941513 100644 --- a/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests.cs @@ -9099,42 +9099,42 @@ static void Main() CompileAndVerify(compilation, expectedOutput: @"2") .VerifyIL("C.Main", @"{ - // Code size 84 (0x54) + // Code size 85 (0x55) .maxstack 2 .locals init (System.Span V_0, //chars int V_1) - IL_0000: ldstr ""string 2"" - IL_0005: call ""char[] System.Linq.Enumerable.ToArray(System.Collections.Generic.IEnumerable)"" - IL_000a: call ""System.Span System.Span.op_Implicit(char[])"" - IL_000f: stloc.0 - IL_0010: ldloca.s V_0 - IL_0012: call ""int System.Span.Length.get"" - IL_0017: brfalse.s IL_003f - IL_0019: ldloc.0 - IL_001a: ldstr ""string 1"" - IL_001f: call ""System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"" - IL_0024: call ""bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)"" - IL_0029: brtrue.s IL_0043 - IL_002b: ldloc.0 - IL_002c: ldstr ""string 2"" - IL_0031: call ""System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"" - IL_0036: call ""bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)"" - IL_003b: brtrue.s IL_0047 - IL_003d: br.s IL_004b - IL_003f: ldc.i4.0 - IL_0040: stloc.1 - IL_0041: br.s IL_004d - IL_0043: ldc.i4.1 - IL_0044: stloc.1 - IL_0045: br.s IL_004d - IL_0047: ldc.i4.2 - IL_0048: stloc.1 - IL_0049: br.s IL_004d - IL_004b: ldc.i4.3 - IL_004c: stloc.1 - IL_004d: ldloc.1 - IL_004e: call ""void System.Console.WriteLine(int)"" - IL_0053: ret + IL_0000: ldloca.s V_0 + IL_0002: ldstr ""string 2"" + IL_0007: call ""char[] System.Linq.Enumerable.ToArray(System.Collections.Generic.IEnumerable)"" + IL_000c: call ""System.Span..ctor(char[])"" + IL_0011: ldloca.s V_0 + IL_0013: call ""int System.Span.Length.get"" + IL_0018: brfalse.s IL_0040 + IL_001a: ldloc.0 + IL_001b: ldstr ""string 1"" + IL_0020: call ""System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"" + IL_0025: call ""bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)"" + IL_002a: brtrue.s IL_0044 + IL_002c: ldloc.0 + IL_002d: ldstr ""string 2"" + IL_0032: call ""System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"" + IL_0037: call ""bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)"" + IL_003c: brtrue.s IL_0048 + IL_003e: br.s IL_004c + IL_0040: ldc.i4.0 + IL_0041: stloc.1 + IL_0042: br.s IL_004e + IL_0044: ldc.i4.1 + IL_0045: stloc.1 + IL_0046: br.s IL_004e + IL_0048: ldc.i4.2 + IL_0049: stloc.1 + IL_004a: br.s IL_004e + IL_004c: ldc.i4.3 + IL_004d: stloc.1 + IL_004e: ldloc.1 + IL_004f: call ""void System.Console.WriteLine(int)"" + IL_0054: ret }"); } diff --git a/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs b/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs new file mode 100644 index 0000000000000..7cd1e2df1928f --- /dev/null +++ b/src/Compilers/CSharp/Test/Emit3/FirstClassSpanTests.cs @@ -0,0 +1,1755 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Linq; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; +using Xunit; + +namespace Microsoft.CodeAnalysis.CSharp.UnitTests; + +public class FirstClassSpanTests : CSharpTestBase +{ + public static TheoryData LangVersions() + { + return new TheoryData() + { + LanguageVersion.CSharp12, + LanguageVersionFacts.CSharpNext, + LanguageVersion.Preview, + }; + } + + private sealed class CombinatorialLangVersions() + : CombinatorialValuesAttribute(LangVersions().Select(d => d.Single()).ToArray()); + + [Fact, WorkItem("https://github.com/dotnet/runtime/issues/101261")] + public void Example_StringValuesAmbiguity() + { + var source = """ + using System; + + Console.Write(C.M(new StringValues())); + + static class C + { + public static string M(StringValues sv) => StringExtensions.Join(",", sv); + } + + static class StringExtensions + { + public static string Join(string separator, params string[] values) => "array"; + public static string Join(string separator, params ReadOnlySpan values) => "span"; + } + + readonly struct StringValues + { + public static implicit operator string(StringValues values) => null; + public static implicit operator string[](StringValues value) => null; + } + """; + + CreateCompilationWithSpan(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), + // (13,49): error CS8652: The feature 'params collections' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public static string Join(string separator, params ReadOnlySpan values) => "span"; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "params ReadOnlySpan values").WithArguments("params collections").WithLocation(13, 49)); + + var expectedOutput = "array"; + + var expectedIl = """ + { + // Code size 17 (0x11) + .maxstack 2 + IL_0000: ldstr "," + IL_0005: ldarg.0 + IL_0006: call "string[] StringValues.op_Implicit(StringValues)" + IL_000b: call "string StringExtensions.Join(string, params string[])" + IL_0010: ret + } + """; + + var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + verifier.VerifyIL("C.M", expectedIl); + + comp = CreateCompilationWithSpan(source); + verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + verifier.VerifyIL("C.M", expectedIl); + } + + [Fact] + public void BreakingChange_Inheritance_UserDefinedConversion_ArrayToSpan() + { + var source = """ + using System; + + var a = new string[0]; + var d = new Derived(); + d.M(a); + + class Base + { + public void M(Span s) => Console.Write("Base"); + } + + class Derived : Base + { + public static implicit operator Derived(Span r) => new Derived(); + + public void M(Derived s) => Console.WriteLine("Derived"); + } + """; + + var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12); + CompileAndVerify(comp, expectedOutput: "Base").VerifyDiagnostics(); + + var expectedOutput = "Derived"; + + comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + + comp = CreateCompilationWithSpan(source); + CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + } + + [Fact] + public void BreakingChange_ExtensionMethodLookup_ArrayToSpan() + { + var source = """ + using System; + + namespace N1 + { + using N2; + + public class C + { + public static void Main() + { + var a = new string[0]; + a.Test(); + } + } + + public static class N1Ext + { + public static void Test(this Span x) => Console.WriteLine("N1"); + } + } + + namespace N2 + { + public static class N2Ext + { + public static void Test(this string[] x) => Console.WriteLine("N2"); + } + } + """; + + var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: "N2").VerifyDiagnostics(); + + var expectedOutput = "N1"; + + var expectedDiagnostics = new[] + { + // (5,5): hidden CS8019: Unnecessary using directive. + // using N2; + Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using N2;").WithLocation(5, 5) + }; + + comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(expectedDiagnostics); + + comp = CreateCompilationWithSpan(source, TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void BreakingChange_ExtensionMethodLookup_SpanVsIEnumerable() + { + var source = """ + var arr = new char[] { '/' }; + arr.M('/'); + + static class E + { + public static void M(this System.Span s, T x) { } + public static void M(this System.Collections.Generic.IEnumerable e, T x) { } + } + """; + CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(); + + var expectedDiagnostics = new[] + { + // (2,5): error CS0121: The call is ambiguous between the following methods or properties: 'E.M(Span, T)' and 'E.M(IEnumerable, T)' + // arr.M('/'); + Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("E.M(System.Span, T)", "E.M(System.Collections.Generic.IEnumerable, T)").WithLocation(2, 5) + }; + + CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpan(source).VerifyDiagnostics(expectedDiagnostics); + } + + [Theory, MemberData(nameof(LangVersions))] + public void BreakingChange_ExtensionMethodLookup_SpanVsIEnumerable_Workaround(LanguageVersion langVersion) + { + var source = """ + var arr = new char[] { '/' }; + arr.M('/'); + + static class E + { + public static void M(this System.Span s, T x) { } + public static void M(this System.Collections.Generic.IEnumerable e, T x) { } + public static void M(this T[] a, T x) { } + } + """; + var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var verifier = CompileAndVerify(comp).VerifyDiagnostics(); + verifier.VerifyIL("", """ + { + // Code size 19 (0x13) + .maxstack 4 + IL_0000: ldc.i4.1 + IL_0001: newarr "char" + IL_0006: dup + IL_0007: ldc.i4.0 + IL_0008: ldc.i4.s 47 + IL_000a: stelem.i2 + IL_000b: ldc.i4.s 47 + IL_000d: call "void E.M(char[], char)" + IL_0012: ret + } + """); + } + + [Theory, CombinatorialData] + public void Conversion_Array_Span_Implicit( + [CombinatorialValues("Span", "ReadOnlySpan")] string destination, + bool cast) + { + var source = $$""" + using System; + {{destination}} s = {{(cast ? $"({destination})" : "")}}arr(); + report(s); + static int[] arr() => new int[] { 1, 2, 3 }; + static void report({{destination}} s) { foreach (var x in s) { Console.Write(x); } } + """; + + var expectedOutput = "123"; + + var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12); + var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("", $$""" + { + // Code size 16 (0x10) + .maxstack 1 + IL_0000: call "int[] Program.<
$>g__arr|0_0()" + IL_0005: call "System.{{destination}} System.{{destination}}.op_Implicit(int[])" + IL_000a: call "void Program.<
$>g__report|0_1(System.{{destination}})" + IL_000f: ret + } + """); + + var expectedIl = $$""" + { + // Code size 16 (0x10) + .maxstack 1 + IL_0000: call "int[] Program.<
$>g__arr|0_0()" + IL_0005: newobj "System.{{destination}}..ctor(int[])" + IL_000a: call "void Program.<
$>g__report|0_1(System.{{destination}})" + IL_000f: ret + } + """; + + comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + verifier = CompileAndVerify(comp, expectedOutput: expectedOutput); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("", expectedIl); + + comp = CreateCompilationWithSpan(source); + verifier = CompileAndVerify(comp, expectedOutput: expectedOutput); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("", expectedIl); + } + + [Fact] + public void Conversion_Array_Span_Implicit_MissingCtor() + { + var source = """ + using System; + Span s = arr(); + static int[] arr() => new int[] { 1, 2, 3 }; + """; + + var comp = CreateCompilationWithSpan(source); + comp.MakeMemberMissing(WellKnownMember.System_Span_T__ctor_Array); + comp.VerifyDiagnostics( + // (2,15): error CS0656: Missing compiler required member 'System.Span`1..ctor' + // Span s = arr(); + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "arr()").WithArguments("System.Span`1", ".ctor").WithLocation(2, 15)); + } + + [Fact] + public void Conversion_Array_Span_Implicit_SpanTwice() + { + static string getSpanSource(string output) => $$""" + namespace System + { + public readonly ref struct Span + { + public Span(T[] array) => Console.Write("{{output}}"); + } + } + """; + + var spanComp = CreateCompilation(getSpanSource("External"), assemblyName: "Span1") + .VerifyDiagnostics() + .EmitToImageReference(); + + var source = """ + using System; + Span s = arr(); + static int[] arr() => new int[] { 1, 2, 3 }; + """; + + var comp = CreateCompilation([source, getSpanSource("Internal")], [spanComp], assemblyName: "Consumer"); + var verifier = CompileAndVerify(comp, expectedOutput: "Internal"); + verifier.VerifyDiagnostics( + // (2,1): warning CS0436: The type 'Span' in '' conflicts with the imported type 'Span' in 'Span1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. Using the type defined in ''. + // Span s = arr(); + Diagnostic(ErrorCode.WRN_SameFullNameThisAggAgg, "Span").WithArguments("", "System.Span", "Span1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "System.Span").WithLocation(2, 1)); + + verifier.VerifyIL("", """ + { + // Code size 12 (0xc) + .maxstack 1 + IL_0000: call "int[] Program.<
$>g__arr|0_0()" + IL_0005: newobj "System.Span..ctor(int[])" + IL_000a: pop + IL_000b: ret + } + """); + } + + [Fact] + public void Conversion_Array_Span_Implicit_SemanticModel() + { + var source = """ + class C + { + System.Span M(int[] arg) { return arg; } + } + """; + + var comp = CreateCompilationWithSpan(source); + var tree = comp.SyntaxTrees.Single(); + var model = comp.GetSemanticModel(tree); + + var arg = tree.GetRoot().DescendantNodes().OfType().Single().Expression; + Assert.Equal("arg", arg!.ToString()); + + var argType = model.GetTypeInfo(arg); + Assert.Equal("System.Int32[]", argType.Type.ToTestDisplayString()); + Assert.Equal("System.Span", argType.ConvertedType.ToTestDisplayString()); + + var argConv = model.GetConversion(arg); + Assert.True(argConv.IsSpan); + Assert.True(argConv.IsImplicit); + Assert.False(argConv.IsUserDefined); + Assert.False(argConv.IsIdentity); + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_Span_Implicit_UnrelatedElementType(LanguageVersion langVersion) + { + var source = """ + class C + { + System.Span M(int[] arg) => arg; + } + """; + CreateCompilationWithSpan(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)); + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_Span_Implicit_NullableAnalysis(LanguageVersion langVersion) + { + var source = """ + #nullable enable + class C + { + System.Span M1(string[] arg) => arg; + System.Span M2(string?[] arg) => arg; + System.Span M3(string[] arg) => arg; + System.Span M4(string?[] arg) => arg; + System.Span M5(int?[] arg) => arg; + System.Span M6(int[] arg) => arg; + System.Span M7(int?[] arg) => arg; + } + """; + var targetType = langVersion > LanguageVersion.CSharp12 ? "System.Span" : "string[]"; + CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + // (5,46): warning CS8619: Nullability of reference types in value of type 'string?[]' doesn't match target type 'string[]'. + // System.Span M2(string?[] arg) => arg; + Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[]", targetType).WithLocation(5, 46), + // (8,40): error CS0029: Cannot implicitly convert type 'int?[]' to 'System.Span' + // System.Span M5(int?[] arg) => arg; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("int?[]", "System.Span").WithLocation(8, 40), + // (9,40): error CS0029: Cannot implicitly convert type 'int[]' to 'System.Span' + // System.Span M6(int[] arg) => arg; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("int[]", "System.Span").WithLocation(9, 40)); + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_ReadOnlySpan_Implicit_NullableAnalysis(LanguageVersion langVersion) + { + var source = """ + #nullable enable + class C + { + System.ReadOnlySpan M1(string[] arg) => arg; + System.ReadOnlySpan M2(string?[] arg) => arg; + System.ReadOnlySpan M3(string[] arg) => arg; + System.ReadOnlySpan M4(string?[] arg) => arg; + System.ReadOnlySpan M5(int?[] arg) => arg; + System.ReadOnlySpan M6(int[] arg) => arg; + System.ReadOnlySpan M7(int?[] arg) => arg; + System.ReadOnlySpan M8(string?[] arg) => arg; + System.ReadOnlySpan M9(string?[] arg) => arg; + } + """; + CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + // (5,54): warning CS8619: Nullability of reference types in value of type 'string?[]' doesn't match target type 'string[]'. + // System.ReadOnlySpan M2(string?[] arg) => arg; + Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[]", targetType("string")).WithLocation(5, 54), + // (8,48): error CS0029: Cannot implicitly convert type 'int?[]' to 'System.ReadOnlySpan' + // System.ReadOnlySpan M5(int?[] arg) => arg; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("int?[]", "System.ReadOnlySpan").WithLocation(8, 48), + // (9,48): error CS0029: Cannot implicitly convert type 'int[]' to 'System.ReadOnlySpan' + // System.ReadOnlySpan M6(int[] arg) => arg; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("int[]", "System.ReadOnlySpan").WithLocation(9, 48), + // (11,54): warning CS8619: Nullability of reference types in value of type 'string?[]' doesn't match target type 'string[]'. + // System.ReadOnlySpan M8(string?[] arg) => arg; + Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[]", targetType("string")).WithLocation(11, 54), + // (12,54): warning CS8619: Nullability of reference types in value of type 'string?[]' doesn't match target type 'object[]'. + // System.ReadOnlySpan M9(string?[] arg) => arg; + Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[]", targetType("object")).WithLocation(12, 54)); + + string targetType(string inner) + => langVersion > LanguageVersion.CSharp12 ? $"System.ReadOnlySpan<{inner}>" : $"{inner}[]"; + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_Span_Implicit_NullableAnalysis_Nested(LanguageVersion langVersion) + { + var source = """ + #nullable enable + class C + { + System.Span M1(string[][] arg) => arg; + System.Span M2(string?[][] arg) => arg; + System.Span M3(string[][] arg) => arg; + System.Span M4(string?[][] arg) => arg; + System.Span M5(int?[][] arg) => arg; + System.Span M6(int[][] arg) => arg; + System.Span M7(int?[][] arg) => arg; + } + """; + var targetType = langVersion > LanguageVersion.CSharp12 ? "System.Span" : "string[][]"; + CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + // (5,50): warning CS8619: Nullability of reference types in value of type 'string?[][]' doesn't match target type 'string[][]'. + // System.Span M2(string?[][] arg) => arg; + Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[][]", targetType).WithLocation(5, 50), + // (8,44): error CS0029: Cannot implicitly convert type 'int?[][]' to 'System.Span' + // System.Span M5(int?[][] arg) => arg; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("int?[][]", "System.Span").WithLocation(8, 44), + // (9,44): error CS0029: Cannot implicitly convert type 'int[][]' to 'System.Span' + // System.Span M6(int[][] arg) => arg; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("int[][]", "System.Span").WithLocation(9, 44)); + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_ReadOnlySpan_Implicit_NullableAnalysis_Nested(LanguageVersion langVersion) + { + var source = """ + #nullable enable + class C + { + System.ReadOnlySpan M1(string[][] arg) => arg; + System.ReadOnlySpan M2(string?[][] arg) => arg; + System.ReadOnlySpan M3(string[][] arg) => arg; + System.ReadOnlySpan M4(string?[][] arg) => arg; + System.ReadOnlySpan M5(int?[][] arg) => arg; + System.ReadOnlySpan M6(int[][] arg) => arg; + System.ReadOnlySpan M7(int?[][] arg) => arg; + System.ReadOnlySpan M8(string?[][] arg) => arg; + System.ReadOnlySpan M9(string?[][] arg) => arg; + } + """; + CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + // (5,58): warning CS8619: Nullability of reference types in value of type 'string?[][]' doesn't match target type 'string[][]'. + // System.ReadOnlySpan M2(string?[][] arg) => arg; + Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[][]", targetType("string")).WithLocation(5, 58), + // (8,52): error CS0029: Cannot implicitly convert type 'int?[][]' to 'System.ReadOnlySpan' + // System.ReadOnlySpan M5(int?[][] arg) => arg; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("int?[][]", "System.ReadOnlySpan").WithLocation(8, 52), + // (9,52): error CS0029: Cannot implicitly convert type 'int[][]' to 'System.ReadOnlySpan' + // System.ReadOnlySpan M6(int[][] arg) => arg; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("int[][]", "System.ReadOnlySpan").WithLocation(9, 52), + // (11,58): warning CS8619: Nullability of reference types in value of type 'string?[][]' doesn't match target type 'string[][]'. + // System.ReadOnlySpan M8(string?[][] arg) => arg; + Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[][]", targetType("string")).WithLocation(11, 58), + // (12,58): warning CS8619: Nullability of reference types in value of type 'string?[][]' doesn't match target type 'object[][]'. + // System.ReadOnlySpan M9(string?[][] arg) => arg; + Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "arg").WithArguments("string?[][]", targetType("object")).WithLocation(12, 58)); + + string targetType(string inner) + => langVersion > LanguageVersion.CSharp12 ? $"System.ReadOnlySpan<{inner}[]>" : $"{inner}[][]"; + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_Span_Implicit_NullableAnalysis_Outer(LanguageVersion langVersion) + { + var source = """ + #nullable enable + class C + { + System.Span? M1(string[] arg) => arg; + System.ReadOnlySpan? M2(string[] arg) => arg; + } + """; + CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + // (4,26): 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' + // System.Span? M1(string[] arg) => arg; + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "M1").WithArguments("System.Nullable", "T", "System.Span").WithLocation(4, 26), + // (5,34): 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 'Nullable' + // System.ReadOnlySpan? M2(string[] arg) => arg; + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "M2").WithArguments("System.Nullable", "T", "System.ReadOnlySpan").WithLocation(5, 34)); + } + + [Fact] + public void Conversion_Array_Span_Implicit_NullableAnalysis_ExtensionMethodReceiver() + { + var source = """ + #nullable enable + static class C + { + static void MS(string[] a, string?[] b) + { + a.M1(); b.M1(); + a.M2(); b.M2(); + a.M3(); b.M3(); + a.M4(); b.M4(); + } + static void M1(this System.Span arg) { } + static void M2(this System.Span arg) { } + static void M3(this System.ReadOnlySpan arg) { } + static void M4(this System.ReadOnlySpan arg) { } + static void MI(int[] a, int?[] b) + { + a.M5(); b.M5(); + a.M6(); b.M6(); + a.M7(); b.M7(); + a.M8(); b.M8(); + } + static void M5(this System.Span arg) { } + static void M6(this System.Span arg) { } + static void M7(this System.ReadOnlySpan arg) { } + static void M8(this System.ReadOnlySpan arg) { } + } + """; + CreateCompilationWithSpan(source).VerifyDiagnostics( + // (6,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(6, 17), + // (7,9): warning CS8620: Argument of type 'string[]' cannot be used for parameter 'arg' of type 'Span' in 'void C.M2(Span arg)' due to differences in the nullability of reference types. + // a.M2(); b.M2(); + Diagnostic(ErrorCode.WRN_NullabilityMismatchInArgument, "a").WithArguments("string[]", "System.Span", "arg", "void C.M2(Span arg)").WithLocation(7, 9), + // (8,17): warning CS8620: Argument of type 'string?[]' cannot be used for parameter 'arg' of type 'ReadOnlySpan' in 'void C.M3(ReadOnlySpan arg)' due to differences in the nullability of reference types. + // a.M3(); b.M3(); + Diagnostic(ErrorCode.WRN_NullabilityMismatchInArgument, "b").WithArguments("string?[]", "System.ReadOnlySpan", "arg", "void C.M3(ReadOnlySpan arg)").WithLocation(8, 17), + // (17,9): error CS1929: 'int[]' does not contain a definition for 'M5' and the best extension method overload 'C.M5(Span)' requires a receiver of type 'System.Span' + // a.M5(); b.M5(); + Diagnostic(ErrorCode.ERR_BadInstanceArgType, "a").WithArguments("int[]", "M5", "C.M5(System.Span)", "System.Span").WithLocation(17, 9), + // (18,17): error CS1929: 'int?[]' does not contain a definition for 'M6' and the best extension method overload 'C.M6(Span)' requires a receiver of type 'System.Span' + // a.M6(); b.M6(); + Diagnostic(ErrorCode.ERR_BadInstanceArgType, "b").WithArguments("int?[]", "M6", "C.M6(System.Span)", "System.Span").WithLocation(18, 17), + // (19,9): error CS1929: 'int[]' does not contain a definition for 'M7' and the best extension method overload 'C.M7(ReadOnlySpan)' requires a receiver of type 'System.ReadOnlySpan' + // a.M7(); b.M7(); + Diagnostic(ErrorCode.ERR_BadInstanceArgType, "a").WithArguments("int[]", "M7", "C.M7(System.ReadOnlySpan)", "System.ReadOnlySpan").WithLocation(19, 9), + // (20,17): error CS1929: 'int?[]' does not contain a definition for 'M8' and the best extension method overload 'C.M8(ReadOnlySpan)' requires a receiver of type 'System.ReadOnlySpan' + // a.M8(); b.M8(); + Diagnostic(ErrorCode.ERR_BadInstanceArgType, "b").WithArguments("int?[]", "M8", "C.M8(System.ReadOnlySpan)", "System.ReadOnlySpan").WithLocation(20, 17)); + } + + [Theory, CombinatorialData] + public void Conversion_Array_Span_Implicit_Ref_01( + [CombinatorialValues("ref", "ref readonly", "in")] string modifier) + { + var source = $$""" + class C + { + System.Span M1({{modifier}} string[] arg) => arg; + System.ReadOnlySpan M2({{modifier}} string[] arg) => arg; + } + """; + var comp = CreateCompilationWithSpan(source); + var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics(); + verifier.VerifyIL("C.M1", """ + { + // Code size 8 (0x8) + .maxstack 1 + IL_0000: ldarg.1 + IL_0001: ldind.ref + IL_0002: newobj "System.Span..ctor(string[])" + IL_0007: ret + } + """); + verifier.VerifyIL("C.M2", """ + { + // Code size 8 (0x8) + .maxstack 1 + IL_0000: ldarg.1 + IL_0001: ldind.ref + IL_0002: newobj "System.ReadOnlySpan..ctor(string[])" + IL_0007: ret + } + """); + } + + [Theory, CombinatorialData] + public void Conversion_Array_Span_Implicit_Ref_02( + [CombinatorialLangVersions] LanguageVersion langVersion, + [CombinatorialValues("ref", "ref readonly", "in")] string modifier) + { + var source = $$""" + using System; + + class C + { + Span M1(string[] arg) => M2({{argModifier(modifier)}} + arg); // 1 + Span M2({{modifier}} Span arg) => arg; + + ReadOnlySpan M3(string[] arg) => M4({{argModifier(modifier)}} + arg); // 2 + ReadOnlySpan M4({{modifier}} ReadOnlySpan arg) => arg; + } + """; + CreateCompilationWithSpan(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), + // (10,9): error CS1503: Argument 1: cannot convert from 'ref string[]' to 'ref System.ReadOnlySpan' + // arg); // 2 + Diagnostic(ErrorCode.ERR_BadArgType, "arg").WithArguments("1", $"{argModifier(modifier)} string[]", $"{modifier} System.ReadOnlySpan").WithLocation(10, 9)); + + static string argModifier(string paramModifier) + => paramModifier == "ref readonly" ? "in" : paramModifier; + } + + [Fact] + public void Conversion_Array_Span_Implicit_Out() + { + var source = """ + class C + { + System.Span M1(out string[] arg) => arg = null; + System.ReadOnlySpan M2(out string[] arg) => arg = null; + } + """; + var comp = CreateCompilationWithSpan(source); + var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics(); + verifier.VerifyIL("C.M1", """ + { + // Code size 12 (0xc) + .maxstack 3 + .locals init (string[] V_0) + IL_0000: ldarg.1 + IL_0001: ldnull + IL_0002: dup + IL_0003: stloc.0 + IL_0004: stind.ref + IL_0005: ldloc.0 + IL_0006: newobj "System.Span..ctor(string[])" + IL_000b: ret + } + """); + verifier.VerifyIL("C.M2", """ + { + // Code size 12 (0xc) + .maxstack 3 + .locals init (string[] V_0) + IL_0000: ldarg.1 + IL_0001: ldnull + IL_0002: dup + IL_0003: stloc.0 + IL_0004: stind.ref + IL_0005: ldloc.0 + IL_0006: newobj "System.ReadOnlySpan..ctor(string[])" + IL_000b: ret + } + """); + } + + [Fact] + public void Conversion_Array_Span_Implicit_Value() + { + var source = """ + class C + { + void M() + { + System.Span s = A(); + System.ReadOnlySpan r = A(); + } + string[] A() => null; + } + """; + var comp = CreateCompilationWithSpan(source, TestOptions.DebugDll); + var verifier = CompileAndVerify(comp).VerifyDiagnostics(); + verifier.VerifyIL("C.M", """ + { + // Code size 28 (0x1c) + .maxstack 2 + .locals init (System.Span V_0, //s + System.ReadOnlySpan V_1) //r + IL_0000: nop + IL_0001: ldloca.s V_0 + IL_0003: ldarg.0 + IL_0004: call "string[] C.A()" + IL_0009: call "System.Span..ctor(string[])" + IL_000e: ldloca.s V_1 + IL_0010: ldarg.0 + IL_0011: call "string[] C.A()" + IL_0016: call "System.ReadOnlySpan..ctor(string[])" + IL_001b: ret + } + """); + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_Span_Opposite_Implicit(LanguageVersion langVersion) + { + var source = """ + class C + { + int[] M(System.Span arg) => arg; + } + """; + CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + // (3,39): error CS0029: Cannot implicitly convert type 'System.Span' to 'int[]' + // int[] M(System.Span arg) => arg; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "arg").WithArguments("System.Span", "int[]").WithLocation(3, 39)); + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_Span_Opposite_Explicit(LanguageVersion langVersion) + { + var source = """ + class C + { + int[] M(System.Span arg) => (int[])arg; + } + """; + CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + // (3,39): error CS0030: Cannot convert type 'System.Span' to 'int[]' + // int[] M(System.Span arg) => (int[])arg; + Diagnostic(ErrorCode.ERR_NoExplicitConv, "(int[])arg").WithArguments("System.Span", "int[]").WithLocation(3, 39)); + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_Span_Opposite_Explicit_UserDefined(LanguageVersion langVersion) + { + var source = """ + class C + { + int[] M(System.Span arg) => (int[])arg; + } + + namespace System + { + readonly ref struct Span + { + public static explicit operator T[](Span span) => throw null; + } + } + """; + var verifier = CompileAndVerify(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", """ + { + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldarg.1 + IL_0001: call "int[] System.Span.op_Explicit(System.Span)" + IL_0006: ret + } + """); + } + + [Fact] + public void Conversion_Array_Span_Implicit_Params() + { + var source = """ + using System; + + class C + { + void M(string[] a) + { + M1(a); + M2(a); + } + void M1(params Span s) { } + void M2(params ReadOnlySpan s) { } + } + """; + var comp = CreateCompilationWithSpan(source); + var verifier = CompileAndVerify(comp).VerifyDiagnostics(); + verifier.VerifyIL("C.M", """ + { + // Code size 25 (0x19) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: newobj "System.Span..ctor(string[])" + IL_0007: call "void C.M1(params System.Span)" + IL_000c: ldarg.0 + IL_000d: ldarg.1 + IL_000e: newobj "System.ReadOnlySpan..ctor(string[])" + IL_0013: call "void C.M2(params System.ReadOnlySpan)" + IL_0018: ret + } + """); + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_Span_Implicit_Multidimensional(LanguageVersion langVersion) + { + var source = """ + using System; + + class C + { + Span M1(string[,] a) => a; + Span M2(string[][] a) => a; + Span M3(string[,] a) => a; + Span M4(string[][] a) => a; + Span M5(string[,][] a) => a; + Span M6(string[][][] a) => a; + Span M7(string[][][] a) => a; + } + """; + CreateCompilationWithSpan(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), + // (6,38): error CS0029: Cannot implicitly convert type 'string[][]' to 'System.Span' + // Span M2(string[][] a) => a; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "a").WithArguments("string[][]", "System.Span").WithLocation(6, 38), + // (7,39): error CS0029: Cannot implicitly convert type 'string[*,*]' to 'System.Span' + // Span M3(string[,] a) => a; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "a").WithArguments("string[*,*]", "System.Span").WithLocation(7, 39), + // (9,43): error CS0029: Cannot implicitly convert type 'string[*,*][]' to 'System.Span' + // Span M5(string[,][] a) => a; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "a").WithArguments("string[*,*][]", "System.Span").WithLocation(9, 43), + // (11,43): error CS0029: Cannot implicitly convert type 'string[][][]' to 'System.Span' + // Span M7(string[][][] a) => a; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "a").WithArguments("string[][][]", "System.Span").WithLocation(11, 43)); + } + + [Theory, CombinatorialData] + public void Conversion_Array_ReadOnlySpan_Covariant(bool cast) + { + var source = $$""" + using System; + + class C + { + ReadOnlySpan M(string[] x) => {{(cast ? "(ReadOnlySpan)" : "")}}x; + } + """; + + var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12); + var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics(); + verifier.VerifyIL("C.M", """ + { + // Code size 9 (0x9) + .maxstack 1 + .locals init (object[] V_0) + IL_0000: ldarg.1 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: call "System.ReadOnlySpan System.ReadOnlySpan.op_Implicit(object[])" + IL_0008: ret + } + """); + + var expectedIl = """ + { + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldarg.1 + IL_0001: newobj "System.ReadOnlySpan..ctor(object[])" + IL_0006: ret + } + """; + + comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics(); + verifier.VerifyIL("C.M", expectedIl); + + comp = CreateCompilationWithSpan(source); + verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics(); + verifier.VerifyIL("C.M", expectedIl); + } + + [Theory, CombinatorialData] + public void Conversion_Array_ReadOnlySpan_Interface_Covariant(bool cast) + { + var source = $$""" + using System; + + class C + { + ReadOnlySpan> M(I[] x) => {{(cast ? "(ReadOnlySpan>)" : "")}}x; + } + + interface I { } + """; + + var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12); + var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics(); + verifier.VerifyIL("C.M", """ + { + // Code size 9 (0x9) + .maxstack 1 + .locals init (I[] V_0) + IL_0000: ldarg.1 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: call "System.ReadOnlySpan> System.ReadOnlySpan>.op_Implicit(I[])" + IL_0008: ret + } + """); + + var expectedIl = """ + { + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldarg.1 + IL_0001: newobj "System.ReadOnlySpan>..ctor(I[])" + IL_0006: ret + } + """; + + comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics(); + verifier.VerifyIL("C.M", expectedIl); + + comp = CreateCompilationWithSpan(source); + verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics(); + verifier.VerifyIL("C.M", expectedIl); + } + + [Theory, CombinatorialData] + public void Conversion_Array_ReadOnlySpan_Interface_Outside( + [CombinatorialLangVersions] LanguageVersion langVersion, + [CombinatorialValues("", "in", "out")] string variance) + { + var source = $$""" + using System; + + class C + { + I> M(I x) => x; + } + + interface I<{{variance}} T> { } + """; + CreateCompilationWithSpan(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), + // (5,49): error CS0266: Cannot implicitly convert type 'I' to 'I>'. An explicit conversion exists (are you missing a cast?) + // I> M(I x) => x; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("I", "I>").WithLocation(5, 49)); + } + + [Theory, CombinatorialData] + public void Conversion_Array_ReadOnlySpan_Interface_Outside_AllowsRefStruct( + [CombinatorialValues("", "in", "out")] string variance) + { + var source = $$""" + using System; + + class C + { + I> M(I x) => x; + } + + interface I<{{variance}} T> where T : allows ref struct { } + """; + CreateCompilation(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics( + // (5,49): error CS0266: Cannot implicitly convert type 'I' to 'I>'. An explicit conversion exists (are you missing a cast?) + // I> M(I x) => x; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("I", "I>").WithLocation(5, 49)); + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_ReadOnlySpan_Interface_Invariant(LanguageVersion langVersion) + { + var source = """ + using System; + + class C + { + ReadOnlySpan> M(I[] x) => x; + } + + interface I { } + """; + CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + // (5,49): error CS0029: Cannot implicitly convert type 'I[]' to 'System.ReadOnlySpan>' + // ReadOnlySpan> M(I[] x) => x; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("I[]", "System.ReadOnlySpan>").WithLocation(5, 49)); + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_ReadOnlySpan_Interface_Contravariant(LanguageVersion langVersion) + { + var source = """ + using System; + + class C + { + ReadOnlySpan> M(I[] x) => x; + } + + interface I { } + """; + CreateCompilationWithSpan(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)); + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_ReadOnlySpan_Interface_Contravariant_Cast(LanguageVersion langVersion) + { + var source = """ + using System; + + C.M(new[] { new C() })[0].Report(); + + class C : I + { + public void Report() => Console.Write("C"); + public static ReadOnlySpan> M(I[] x) => (ReadOnlySpan>)x; + } + + interface I + { + void Report(); + } + """; + + var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + var verifier = CompileAndVerify(comp, expectedOutput: "C", verify: Verification.FailsILVerify).VerifyDiagnostics(); + verifier.VerifyIL("C.M", """ + { + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: castclass "I[]" + IL_0006: call "System.ReadOnlySpan> System.ReadOnlySpan>.op_Implicit(I[])" + IL_000b: ret + } + """); + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_ReadOnlySpan_Covariant_ValueType(LanguageVersion langVersion) + { + var source = """ + using System; + + class C + { + ReadOnlySpan M(int[] x) => x; + } + """; + CreateCompilationWithSpan(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)); + } + + [Fact] + public void Conversion_Array_ReadOnlySpan_Covariant_TypeParameter() + { + var source = """ + using System; + + class C + { + ReadOnlySpan M(T[] x) => x; + } + """; + + var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12); + var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics(); + verifier.VerifyIL("C.M", """ + { + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldarg.1 + IL_0001: call "System.ReadOnlySpan System.ReadOnlySpan.op_Implicit(T[])" + IL_0006: ret + } + """); + + var expectedIl = """ + { + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldarg.1 + IL_0001: newobj "System.ReadOnlySpan..ctor(T[])" + IL_0006: ret + } + """; + + comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics(); + verifier.VerifyIL("C.M", expectedIl); + + comp = CreateCompilationWithSpan(source); + verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify).VerifyDiagnostics(); + verifier.VerifyIL("C.M", expectedIl); + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_ReadOnlySpan_Covariant_TypeParameter_NullableValueType_01(LanguageVersion langVersion) + { + var source = """ + using System; + + class C where T : struct + { + ReadOnlySpan M(T?[] x) => x; + } + """; + CreateCompilationWithSpan(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)); + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_ReadOnlySpan_Covariant_TypeParameter_NullableValueType_02(LanguageVersion langVersion) + { + var source = """ + using System; + + class C where T : struct + { + ReadOnlySpan M(T[] x) => x; + } + """; + CreateCompilationWithSpan(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)); + } + + [Theory, CombinatorialData] + public void Conversion_Array_Span_ThroughUserImplicit( + [CombinatorialValues("Span", "ReadOnlySpan")] string destination) + { + var source = $$""" + using System; + + D.M(new C()); + + class C + { + public static implicit operator int[](C c) => new int[] { 4, 5, 6 }; + } + + static class D + { + public static void M({{destination}} xs) + { + foreach (var x in xs) + { + Console.Write(x); + } + } + } + """; + + CreateCompilationWithSpan(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); + CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + + comp = CreateCompilationWithSpan(source); + CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + } + + [Fact] + public void Conversion_Array_Span_ThroughUserImplicit_MissingCtor() + { + var source = """ + using System; + + D.M(new C()); + + class C + { + public static implicit operator int[](C c) => new int[] { 4, 5, 6 }; + } + + static class D + { + public static void M(Span xs) + { + foreach (var x in xs) + { + Console.Write(x); + } + } + } + """; + + var expectedDiagnostics = new[] + { + // (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.Span").WithLocation(3, 5) + }; + + verifyWithMissing(WellKnownMember.System_ReadOnlySpan_T__ctor_Array, TestOptions.Regular12, expectedDiagnostics); + verifyWithMissing(WellKnownMember.System_Span_T__ctor_Array, TestOptions.Regular12, expectedDiagnostics); + + expectedDiagnostics = [ + // (3,5): error CS0656: Missing compiler required member 'System.Span`1..ctor' + // D.M(new C()); + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "new C()").WithArguments("System.Span`1", ".ctor").WithLocation(3, 5) + ]; + + verifyWithMissing(WellKnownMember.System_ReadOnlySpan_T__ctor_Array, TestOptions.RegularNext); + verifyWithMissing(WellKnownMember.System_Span_T__ctor_Array, TestOptions.RegularNext, expectedDiagnostics); + + verifyWithMissing(WellKnownMember.System_ReadOnlySpan_T__ctor_Array, TestOptions.RegularPreview); + verifyWithMissing(WellKnownMember.System_Span_T__ctor_Array, TestOptions.RegularPreview, expectedDiagnostics); + + void verifyWithMissing(WellKnownMember member, CSharpParseOptions parseOptions, params DiagnosticDescription[] expected) + { + var comp = CreateCompilationWithSpan(source, parseOptions: parseOptions); + comp.MakeMemberMissing(member); + if (expected.Length == 0) + { + CompileAndVerify(comp, expectedOutput: "456").VerifyDiagnostics(); + } + else + { + comp.VerifyDiagnostics(expected); + } + } + } + + [Fact] + public void Conversion_Array_ReadOnlySpan_ThroughUserImplicit_MissingCtor() + { + var source = """ + using System; + + D.M(new C()); + + class C + { + public static implicit operator int[](C c) => new int[] { 4, 5, 6 }; + } + + static class D + { + public static void M(ReadOnlySpan xs) + { + foreach (var x in xs) + { + Console.Write(x); + } + } + } + """; + + var expectedDiagnostics = new[] + { + // (3,5): error CS1503: Argument 1: cannot convert from 'C' to 'System.ReadOnlySpan' + // D.M(new C()); + Diagnostic(ErrorCode.ERR_BadArgType, "new C()").WithArguments("1", "C", "System.ReadOnlySpan").WithLocation(3, 5) + }; + + verifyWithMissing(WellKnownMember.System_ReadOnlySpan_T__ctor_Array, TestOptions.Regular12, expectedDiagnostics); + verifyWithMissing(WellKnownMember.System_Span_T__ctor_Array, TestOptions.Regular12, expectedDiagnostics); + + expectedDiagnostics = [ + // (3,5): error CS0656: Missing compiler required member 'System.ReadOnlySpan`1..ctor' + // D.M(new C()); + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "new C()").WithArguments("System.ReadOnlySpan`1", ".ctor").WithLocation(3, 5) + ]; + + verifyWithMissing(WellKnownMember.System_ReadOnlySpan_T__ctor_Array, TestOptions.RegularNext, expectedDiagnostics); + verifyWithMissing(WellKnownMember.System_Span_T__ctor_Array, TestOptions.RegularNext); + + verifyWithMissing(WellKnownMember.System_ReadOnlySpan_T__ctor_Array, TestOptions.RegularPreview, expectedDiagnostics); + verifyWithMissing(WellKnownMember.System_Span_T__ctor_Array, TestOptions.RegularPreview); + + void verifyWithMissing(WellKnownMember member, CSharpParseOptions parseOptions, params DiagnosticDescription[] expected) + { + var comp = CreateCompilationWithSpan(source, parseOptions: parseOptions); + comp.MakeMemberMissing(member); + if (expected.Length == 0) + { + CompileAndVerify(comp, expectedOutput: "456").VerifyDiagnostics(); + } + else + { + comp.VerifyDiagnostics(expected); + } + } + } + + [Fact] + public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit() + { + var source = """ + using System; + + C.M(new int[] { 7, 8, 9 }); + + static class C + { + public static void M(int[] arg) => arg.E(); + public static void E(this Span arg) => Console.Write(arg[1]); + } + """; + CreateCompilationWithSpan(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)); + + var expectedOutput = "8"; + + var expectedIl = """ + { + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: newobj "System.Span..ctor(int[])" + IL_0006: call "void C.E(System.Span)" + IL_000b: ret + } + """; + + var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + verifier.VerifyIL("C.M", expectedIl); + + comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + verifier.VerifyIL("C.M", expectedIl); + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit_Ref(LanguageVersion langVersion) + { + var source = """ + using System; + + C.M(new int[] { 7, 8, 9 }); + + static class C + { + public static void M(int[] arg) => arg.E(); + public static void E(this ref Span arg) => Console.Write(arg[1]); + } + """; + CreateCompilationWithSpan(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)); + } + + [Theory, CombinatorialData] + public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit_RefReadOnly( + [CombinatorialValues("ref readonly", "in")] string modifier) + { + var source = $$""" + using System; + + C.M(new int[] { 7, 8, 9 }); + + static class C + { + public static void M(int[] arg) => arg.E(); + public static void E(this {{modifier}} Span arg) => Console.Write(arg[1]); + } + """; + CreateCompilationWithSpan(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)); + + var expectedOutput = "8"; + + var expectedIl = $$""" + { + // Code size 15 (0xf) + .maxstack 1 + .locals init (System.Span V_0) + IL_0000: ldarg.0 + IL_0001: newobj "System.Span..ctor(int[])" + IL_0006: stloc.0 + IL_0007: ldloca.s V_0 + IL_0009: call "void C.E({{modifier}} System.Span)" + IL_000e: ret + } + """; + + var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + verifier.VerifyIL("C.M", expectedIl); + + comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + verifier.VerifyIL("C.M", expectedIl); + } + + [Fact] + public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit_Overloads_01() + { + var source = """ + using System; + + static class C + { + static void M(int[] arg) => arg.E(); + + static void E(this Span arg) { } + static void E(this ReadOnlySpan arg) { } + } + """; + CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (5,33): 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' + // static void M(int[] arg) => arg.E(); + Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("int[]", "E", "C.E(System.Span)", "System.Span").WithLocation(5, 33)); + + var expectedDiagnostics = new[] + { + // (5,37): error CS0121: The call is ambiguous between the following methods or properties: 'C.E(Span)' and 'C.E(ReadOnlySpan)' + // static void M(int[] arg) => arg.E(); + Diagnostic(ErrorCode.ERR_AmbigCall, "E").WithArguments("C.E(System.Span)", "C.E(System.ReadOnlySpan)").WithLocation(5, 37) + }; + + CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithSpan(source).VerifyDiagnostics(expectedDiagnostics); + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit_Overloads_02(LanguageVersion langVersion) + { + var source = """ + using System; + + C.M1(default); + C.M2(default); + + static class C + { + public static void M1(Span arg) => arg.E(); + public static void M2(ReadOnlySpan arg) => arg.E(); + + static void E(this Span arg) => Console.Write("S "); + static void E(this ReadOnlySpan arg) => Console.Write("R "); + } + """; + + var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + CompileAndVerify(comp, expectedOutput: "S R").VerifyDiagnostics(); + } + + [Fact] + public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit_MissingCtor() + { + var source = """ + using System; + + C.M(new int[] { 7, 8, 9 }); + + static class C + { + public static void M(int[] arg) => arg.E(); + public static void E(this Span arg) => Console.Write(arg[1]); + } + """; + var comp = CreateCompilationWithSpan(source); + comp.MakeMemberMissing(WellKnownMember.System_Span_T__ctor_Array); + comp.VerifyDiagnostics( + // (7,40): error CS0656: Missing compiler required member 'System.Span`1..ctor' + // public static void M(int[] arg) => arg.E(); + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "arg").WithArguments("System.Span`1", ".ctor").WithLocation(7, 40)); + } + + [Fact] + public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit_Generic_01() + { + var source = """ + using System; + static class C + { + public static void M(int[] arg) => arg.E(); + public static void E(this Span arg) { } + } + """; + // PROTOTYPE: Needs type inference to work. + CreateCompilationWithSpan(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)); + } + + [Fact] + public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit_Generic_02() + { + var source = """ + using System; + static class C + { + public static void M(int[] arg) => arg.E(); + public static void E(this Span arg) { } + } + """; + var comp = CreateCompilationWithSpan(source); + var verifier = CompileAndVerify(comp).VerifyDiagnostics(); + verifier.VerifyILMultiple("C.M", """ + { + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: newobj "System.Span..ctor(int[])" + IL_0006: call "void C.E(System.Span)" + IL_000b: ret + } + """); + + var tree = comp.SyntaxTrees.Single(); + var invocation = tree.GetRoot().DescendantNodes().OfType().Single(); + Assert.Equal("arg.E()", invocation.ToString()); + + var model = comp.GetSemanticModel(tree); + var info = model.GetSymbolInfo(invocation); + Assert.Equal("void System.Span.E()", info.Symbol!.ToTestDisplayString()); + } + + [Fact] + public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit_Generic_03() + { + var source = """ + using System; + static class C + { + public static void M(int[] arg) => arg.E(42); + public static void E(this Span arg, T x) { } + } + """; + var comp = CreateCompilationWithSpan(source); + var verifier = CompileAndVerify(comp).VerifyDiagnostics(); + verifier.VerifyILMultiple("C.M", """ + { + // Code size 14 (0xe) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: newobj "System.Span..ctor(int[])" + IL_0006: ldc.i4.s 42 + IL_0008: call "void C.E(System.Span, int)" + IL_000d: ret + } + """); + + var tree = comp.SyntaxTrees.Single(); + var invocation = tree.GetRoot().DescendantNodes().OfType().Single(); + Assert.Equal("arg.E(42)", invocation.ToString()); + + var model = comp.GetSemanticModel(tree); + var info = model.GetSymbolInfo(invocation); + Assert.Equal("void System.Span.E(System.Int32 x)", info.Symbol!.ToTestDisplayString()); + } + + [Fact] + public void Conversion_Array_Span_ExtensionMethodReceiver_Implicit_Generic_04() + { + var source = """ + using System; + static class C + { + public static void M(int[] arg) => arg.E(42); + public static void E(this Span arg, T x) { } + } + """; + var comp = CreateCompilationWithSpan(source); + var verifier = CompileAndVerify(comp).VerifyDiagnostics(); + verifier.VerifyILMultiple("C.M", """ + { + // Code size 14 (0xe) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: newobj "System.Span..ctor(int[])" + IL_0006: ldc.i4.s 42 + IL_0008: call "void C.E(System.Span, int)" + IL_000d: ret + } + """); + + var tree = comp.SyntaxTrees.Single(); + var invocation = tree.GetRoot().DescendantNodes().OfType().Single(); + Assert.Equal("arg.E(42)", invocation.ToString()); + + var model = comp.GetSemanticModel(tree); + var info = model.GetSymbolInfo(invocation); + Assert.Equal("void System.Span.E(System.Int32 x)", info.Symbol!.ToTestDisplayString()); + } + + [Fact] + public void Conversion_Array_Span_ExtensionMethodReceiver_Explicit() + { + var source = """ + using System; + + C.M(new int[] { 7, 8, 9 }); + + static class C + { + public static void M(int[] arg) => ((Span)arg).E(); + public static void E(this Span arg) => Console.Write(arg[1]); + } + """; + + var expectedOutput = "8"; + + var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12); + var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + verifier.VerifyIL("C.M", """ + { + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: call "System.Span System.Span.op_Implicit(int[])" + IL_0006: call "void C.E(System.Span)" + IL_000b: ret + } + """); + + var expectedIl = """ + { + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: newobj "System.Span..ctor(int[])" + IL_0006: call "void C.E(System.Span)" + IL_000b: ret + } + """; + + comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + verifier.VerifyIL("C.M", expectedIl); + + comp = CreateCompilationWithSpan(source); + verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + verifier.VerifyIL("C.M", expectedIl); + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_Span_ExtensionMethodReceiver_Opposite_Implicit(LanguageVersion langVersion) + { + var source = """ + static class C + { + static void M(System.Span arg) => arg.E(); + static void E(this int[] arg) { } + } + """; + CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + // (3,44): error CS1929: 'Span' does not contain a definition for 'E' and the best extension method overload 'C.E(int[])' requires a receiver of type 'int[]' + // static void M(System.Span arg) => arg.E(); + Diagnostic(ErrorCode.ERR_BadInstanceArgType, "arg").WithArguments("System.Span", "E", "C.E(int[])", "int[]").WithLocation(3, 44)); + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_Span_ExtensionMethodReceiver_Opposite_Explicit(LanguageVersion langVersion) + { + var source = """ + static class C + { + static void M(System.Span arg) => ((int[])arg).E(); + static void E(this int[] arg) { } + } + """; + CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics( + // (3,45): error CS0030: Cannot convert type 'System.Span' to 'int[]' + // static void M(System.Span arg) => ((int[])arg).E(); + Diagnostic(ErrorCode.ERR_NoExplicitConv, "(int[])arg").WithArguments("System.Span", "int[]").WithLocation(3, 45)); + } + + [Theory, MemberData(nameof(LangVersions))] + public void Conversion_Array_Span_ExtensionMethodReceiver_Opposite_Explicit_UserDefined(LanguageVersion langVersion) + { + var source = """ + static class C + { + static void M(System.Span arg) => ((int[])arg).E(); + static void E(this int[] arg) { } + } + + namespace System + { + readonly ref struct Span + { + public static explicit operator T[](Span span) => throw null; + } + } + """; + var verifier = CompileAndVerify(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", """ + { + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: call "int[] System.Span.op_Explicit(System.Span)" + IL_0006: call "void C.E(int[])" + IL_000b: ret + } + """); + } +} diff --git a/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IConversionExpression.cs b/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IConversionExpression.cs index 7d648397969bc..0205fafada58f 100644 --- a/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IConversionExpression.cs +++ b/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IConversionExpression.cs @@ -3404,6 +3404,54 @@ public void F(Buffer10 arg) additionalOperationTreeVerifier: new ExpectedSymbolVerifier().Verify); } + [CompilerTrait(CompilerFeature.IOperation)] + [Fact] + public void ConversionExpression_Implicit_ArrayToSpan() + { + var source = """ + class C + { + System.Span F(int[] arg) + { + System.Span /**/span = arg/**/; + return span; + } + } + """; + + var expectedOperationTree = """ + IVariableDeclaratorOperation (Symbol: System.Span span) (OperationKind.VariableDeclarator, Type: null) (Syntax: 'span = arg') + Initializer: + IVariableInitializerOperation (OperationKind.VariableInitializer, Type: null) (Syntax: '= arg') + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.Span, IsImplicit) (Syntax: 'arg') + Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Operand: + IParameterReferenceOperation: arg (OperationKind.ParameterReference, Type: System.Int32[]) (Syntax: 'arg') + """; + + var expectedDiagnostics = DiagnosticDescription.None; + + var comp = CreateCompilationWithSpan(source); + VerifyOperationTreeAndDiagnosticsForTest(comp, expectedOperationTree, expectedDiagnostics, + additionalOperationTreeVerifier: new ExpectedSymbolVerifier().Verify); + + // In C# 12, the conversion is user-defined unlike above: + + expectedOperationTree = """ + IVariableDeclaratorOperation (Symbol: System.Span span) (OperationKind.VariableDeclarator, Type: null) (Syntax: 'span = arg') + Initializer: + IVariableInitializerOperation (OperationKind.VariableInitializer, Type: null) (Syntax: '= arg') + IConversionOperation (TryCast: False, Unchecked) (OperatorMethod: System.Span System.Span.op_Implicit(System.Int32[] array)) (OperationKind.Conversion, Type: System.Span, IsImplicit) (Syntax: 'arg') + Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: True) (MethodSymbol: System.Span System.Span.op_Implicit(System.Int32[] array)) + Operand: + IParameterReferenceOperation: arg (OperationKind.ParameterReference, Type: System.Int32[]) (Syntax: 'arg') + """; + + comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12); + VerifyOperationTreeAndDiagnosticsForTest(comp, expectedOperationTree, expectedDiagnostics, + additionalOperationTreeVerifier: new ExpectedSymbolVerifier().Verify); + } + #endregion #region Explicit Conversion diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs index 3deff89e08733..dacd26ce21902 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs @@ -3938,62 +3938,62 @@ Starting try verifier.VerifyIL("", @" { - // Code size 127 (0x7f) - .maxstack 4 + // Code size 128 (0x80) + .maxstack 5 .locals init (System.Span V_0, //s System.Runtime.CompilerServices.DefaultInterpolatedStringHandler V_1) - IL_0000: ldc.i4.1 - IL_0001: newarr ""char"" - IL_0006: dup - IL_0007: ldc.i4.0 - IL_0008: ldc.i4.s 105 - IL_000a: stelem.i2 - IL_000b: call ""System.Span System.Span.op_Implicit(char[])"" - IL_0010: stloc.0 + IL_0000: ldloca.s V_0 + IL_0002: ldc.i4.1 + IL_0003: newarr ""char"" + IL_0008: dup + IL_0009: ldc.i4.0 + IL_000a: ldc.i4.s 105 + IL_000c: stelem.i2 + IL_000d: call ""System.Span..ctor(char[])"" .try { - IL_0011: ldstr ""Starting try"" - IL_0016: call ""void System.Console.WriteLine(string)"" - IL_001b: newobj ""MyException..ctor()"" - IL_0020: dup - IL_0021: ldloca.s V_0 - IL_0023: constrained. ""System.Span"" - IL_0029: callvirt ""string object.ToString()"" - IL_002e: callvirt ""void MyException.Prop.set"" - IL_0033: throw + IL_0012: ldstr ""Starting try"" + IL_0017: call ""void System.Console.WriteLine(string)"" + IL_001c: newobj ""MyException..ctor()"" + IL_0021: dup + IL_0022: ldloca.s V_0 + IL_0024: constrained. ""System.Span"" + IL_002a: callvirt ""string object.ToString()"" + IL_002f: callvirt ""void MyException.Prop.set"" + IL_0034: throw } filter { - IL_0034: isinst ""MyException"" - IL_0039: dup - IL_003a: brtrue.s IL_0040 - IL_003c: pop - IL_003d: ldc.i4.0 - IL_003e: br.s IL_006f - IL_0040: callvirt ""string object.ToString()"" - IL_0045: ldloca.s V_1 - IL_0047: ldc.i4.0 - IL_0048: ldc.i4.1 - IL_0049: call ""System.Runtime.CompilerServices.DefaultInterpolatedStringHandler..ctor(int, int)"" - IL_004e: ldloca.s V_1 - IL_0050: ldloc.0 - IL_0051: call ""System.ReadOnlySpan System.Span.op_Implicit(System.Span)"" - IL_0056: call ""void System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan)"" - IL_005b: ldloca.s V_1 - IL_005d: call ""string System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.ToStringAndClear()"" - IL_0062: callvirt ""string string.Trim()"" - IL_0067: call ""bool string.op_Equality(string, string)"" - IL_006c: ldc.i4.0 - IL_006d: cgt.un - IL_006f: endfilter + IL_0035: isinst ""MyException"" + IL_003a: dup + IL_003b: brtrue.s IL_0041 + IL_003d: pop + IL_003e: ldc.i4.0 + IL_003f: br.s IL_0070 + IL_0041: callvirt ""string object.ToString()"" + IL_0046: ldloca.s V_1 + IL_0048: ldc.i4.0 + IL_0049: ldc.i4.1 + IL_004a: call ""System.Runtime.CompilerServices.DefaultInterpolatedStringHandler..ctor(int, int)"" + IL_004f: ldloca.s V_1 + IL_0051: ldloc.0 + IL_0052: call ""System.ReadOnlySpan System.Span.op_Implicit(System.Span)"" + IL_0057: call ""void System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan)"" + IL_005c: ldloca.s V_1 + IL_005e: call ""string System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.ToStringAndClear()"" + IL_0063: callvirt ""string string.Trim()"" + IL_0068: call ""bool string.op_Equality(string, string)"" + IL_006d: ldc.i4.0 + IL_006e: cgt.un + IL_0070: endfilter } // end filter { // handler - IL_0071: pop - IL_0072: ldstr ""Caught"" - IL_0077: call ""void System.Console.WriteLine(string)"" - IL_007c: leave.s IL_007e + IL_0072: pop + IL_0073: ldstr ""Caught"" + IL_0078: call ""void System.Console.WriteLine(string)"" + IL_007d: leave.s IL_007f } - IL_007e: ret + IL_007f: ret } "); } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RawInterpolationTests_Handler.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RawInterpolationTests_Handler.cs index 6ca1b71853154..5a6a7410d4a88 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RawInterpolationTests_Handler.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RawInterpolationTests_Handler.cs @@ -2368,62 +2368,62 @@ Starting try verifier.VerifyIL("", @" { - // Code size 127 (0x7f) - .maxstack 4 + // Code size 128 (0x80) + .maxstack 5 .locals init (System.Span V_0, //s System.Runtime.CompilerServices.DefaultInterpolatedStringHandler V_1) - IL_0000: ldc.i4.1 - IL_0001: newarr ""char"" - IL_0006: dup - IL_0007: ldc.i4.0 - IL_0008: ldc.i4.s 105 - IL_000a: stelem.i2 - IL_000b: call ""System.Span System.Span.op_Implicit(char[])"" - IL_0010: stloc.0 + IL_0000: ldloca.s V_0 + IL_0002: ldc.i4.1 + IL_0003: newarr ""char"" + IL_0008: dup + IL_0009: ldc.i4.0 + IL_000a: ldc.i4.s 105 + IL_000c: stelem.i2 + IL_000d: call ""System.Span..ctor(char[])"" .try { - IL_0011: ldstr ""Starting try"" - IL_0016: call ""void System.Console.WriteLine(string)"" - IL_001b: newobj ""MyException..ctor()"" - IL_0020: dup - IL_0021: ldloca.s V_0 - IL_0023: constrained. ""System.Span"" - IL_0029: callvirt ""string object.ToString()"" - IL_002e: callvirt ""void MyException.Prop.set"" - IL_0033: throw + IL_0012: ldstr ""Starting try"" + IL_0017: call ""void System.Console.WriteLine(string)"" + IL_001c: newobj ""MyException..ctor()"" + IL_0021: dup + IL_0022: ldloca.s V_0 + IL_0024: constrained. ""System.Span"" + IL_002a: callvirt ""string object.ToString()"" + IL_002f: callvirt ""void MyException.Prop.set"" + IL_0034: throw } filter { - IL_0034: isinst ""MyException"" - IL_0039: dup - IL_003a: brtrue.s IL_0040 - IL_003c: pop - IL_003d: ldc.i4.0 - IL_003e: br.s IL_006f - IL_0040: callvirt ""string object.ToString()"" - IL_0045: ldloca.s V_1 - IL_0047: ldc.i4.0 - IL_0048: ldc.i4.1 - IL_0049: call ""System.Runtime.CompilerServices.DefaultInterpolatedStringHandler..ctor(int, int)"" - IL_004e: ldloca.s V_1 - IL_0050: ldloc.0 - IL_0051: call ""System.ReadOnlySpan System.Span.op_Implicit(System.Span)"" - IL_0056: call ""void System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan)"" - IL_005b: ldloca.s V_1 - IL_005d: call ""string System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.ToStringAndClear()"" - IL_0062: callvirt ""string string.Trim()"" - IL_0067: call ""bool string.op_Equality(string, string)"" - IL_006c: ldc.i4.0 - IL_006d: cgt.un - IL_006f: endfilter + IL_0035: isinst ""MyException"" + IL_003a: dup + IL_003b: brtrue.s IL_0041 + IL_003d: pop + IL_003e: ldc.i4.0 + IL_003f: br.s IL_0070 + IL_0041: callvirt ""string object.ToString()"" + IL_0046: ldloca.s V_1 + IL_0048: ldc.i4.0 + IL_0049: ldc.i4.1 + IL_004a: call ""System.Runtime.CompilerServices.DefaultInterpolatedStringHandler..ctor(int, int)"" + IL_004f: ldloca.s V_1 + IL_0051: ldloc.0 + IL_0052: call ""System.ReadOnlySpan System.Span.op_Implicit(System.Span)"" + IL_0057: call ""void System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan)"" + IL_005c: ldloca.s V_1 + IL_005e: call ""string System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.ToStringAndClear()"" + IL_0063: callvirt ""string string.Trim()"" + IL_0068: call ""bool string.op_Equality(string, string)"" + IL_006d: ldc.i4.0 + IL_006e: cgt.un + IL_0070: endfilter } // end filter { // handler - IL_0071: pop - IL_0072: ldstr ""Caught"" - IL_0077: call ""void System.Console.WriteLine(string)"" - IL_007c: leave.s IL_007e + IL_0072: pop + IL_0073: ldstr ""Caught"" + IL_0078: call ""void System.Console.WriteLine(string)"" + IL_007d: leave.s IL_007f } - IL_007e: ret + IL_007f: ret } "); } diff --git a/src/Compilers/Core/Portable/InternalUtilities/ArrayExtensions.cs b/src/Compilers/Core/Portable/InternalUtilities/ArrayExtensions.cs index 9078c540e2db3..4f1b9628f71a3 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/ArrayExtensions.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/ArrayExtensions.cs @@ -26,6 +26,12 @@ internal static T[] Copy(this T[] array, int start, int length) return newArray; } + public static int IndexOf(this T[] array, T value) + => Array.IndexOf(array, value); + + public static bool Contains(this T[] array, T value) + => Array.IndexOf(array, value) >= 0; + internal static T[] InsertAt(this T[] array, int position, T item) { T[] newArray = new T[array.Length + 1]; diff --git a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs index 8388968457fb4..224edaa0b38a3 100644 --- a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs +++ b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs @@ -2347,6 +2347,12 @@ unsafe public ReadOnlySpan(void* pointer, int length) public ReadOnlySpan(T[] arr) { + if (arr == null) + { + this = default; + return; + } + this.arr = arr; this.Length = arr.Length; } diff --git a/src/Workspaces/Core/Portable/CodeRefactorings/ExportCodeRefactoringProviderAttribute.cs b/src/Workspaces/Core/Portable/CodeRefactorings/ExportCodeRefactoringProviderAttribute.cs index ccc282edc2fb3..b7dc5662aef4f 100644 --- a/src/Workspaces/Core/Portable/CodeRefactorings/ExportCodeRefactoringProviderAttribute.cs +++ b/src/Workspaces/Core/Portable/CodeRefactorings/ExportCodeRefactoringProviderAttribute.cs @@ -6,6 +6,7 @@ using System.Composition; using System.Diagnostics.CodeAnalysis; using System.Linq; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CodeRefactorings; diff --git a/src/Workspaces/Core/Portable/Workspace/Host/Mef/MefHostServices.cs b/src/Workspaces/Core/Portable/Workspace/Host/Mef/MefHostServices.cs index 9078fc1ef6412..3f0e3532e99d7 100644 --- a/src/Workspaces/Core/Portable/Workspace/Host/Mef/MefHostServices.cs +++ b/src/Workspaces/Core/Portable/Workspace/Host/Mef/MefHostServices.cs @@ -12,6 +12,7 @@ using System.Linq; using System.Reflection; using System.Threading; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Host.Mef; diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/ArrayExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/ArrayExtensions.cs index ddee284eecaba..6dddc2904ceff 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/ArrayExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/ArrayExtensions.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Diagnostics.CodeAnalysis; namespace Microsoft.CodeAnalysis.Shared.Extensions; @@ -11,7 +10,4 @@ internal static class ArrayExtensions { public static bool IsNullOrEmpty([NotNullWhen(returnValue: false)] this T[]? array) => array == null || array.Length == 0; - - public static bool Contains(this T[] array, T item) - => Array.IndexOf(array, item) >= 0; }