diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs index 57d3ca2c04709..4c7e808ad2a4d 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs @@ -2572,11 +2572,9 @@ private void CoerceArguments( private static TypeSymbol GetCorrespondingParameterType(ref MemberAnalysisResult result, ImmutableArray parameters, int arg) { int paramNum = result.ParameterFromArgument(arg); - var type = - (paramNum == parameters.Length - 1 && result.Kind == MemberResolutionKind.ApplicableInExpandedForm) ? - ((ArrayTypeSymbol)parameters[paramNum].Type).ElementType : - parameters[paramNum].Type; - return type; + return (paramNum == parameters.Length - 1 && result.Kind == MemberResolutionKind.ApplicableInExpandedForm) + ? parameters[paramNum].Type.GetElementTypeOfParamsType() + : parameters[paramNum].Type; } private BoundExpression BindArrayCreationExpression(ArrayCreationExpressionSyntax node, DiagnosticBag diagnostics) diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs index 8433042b22052..41f254bf5bb47 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs @@ -815,7 +815,7 @@ public static bool IsValidParams(Symbol member) // Note: we need to confirm the "arrayness" on the original definition because // it's possible that the type becomes an array as a result of substitution. ParameterSymbol final = member.GetParameters().Last(); - return final.IsParams && ((ParameterSymbol)final.OriginalDefinition).Type.IsSZArray(); + return final.IsParams && final.OriginalDefinition.Type.IsPossibleParamsType(); } private static bool IsOverride(Symbol overridden, Symbol overrider) @@ -2874,7 +2874,8 @@ private EffectiveParameters GetEffectiveParametersInExpandedForm( var refs = ArrayBuilder.GetInstance(); bool anyRef = false; var parameters = member.GetParameters(); - var elementType = ((ArrayTypeSymbol)parameters[parameters.Length - 1].Type).ElementType; + var paramsType = parameters[parameters.Length - 1].Type; + var elementType = paramsType.GetElementTypeOfParamsType(); bool hasAnyRefArg = argumentRefKinds.Any(); hasAnyRefOmittedArgument = false; diff --git a/src/Compilers/CSharp/Portable/Errors/MessageID.cs b/src/Compilers/CSharp/Portable/Errors/MessageID.cs index ac66a0408661d..9f78193afb744 100644 --- a/src/Compilers/CSharp/Portable/Errors/MessageID.cs +++ b/src/Compilers/CSharp/Portable/Errors/MessageID.cs @@ -162,6 +162,8 @@ internal enum MessageID IDS_FeatureIndexingMovableFixedBuffers = MessageBase + 12744, IDS_FeatureRecursivePatterns = MessageBase + 12745, IDS_FeatureNestedStackalloc = MessageBase + 12746, + + IDS_FeatureParamsArrayInterfaceAndSpan = MessageBase + 12747, } // Message IDs may refer to strings that need to be localized. @@ -221,6 +223,7 @@ internal static LanguageVersion RequiredVersion(this MessageID feature) // C# 8.0 features. case MessageID.IDS_FeatureRecursivePatterns: case MessageID.IDS_FeatureNestedStackalloc: + case MessageID.IDS_FeatureParamsArrayInterfaceAndSpan: // semantic check return LanguageVersion.CSharp8; // C# 7.3 features. diff --git a/src/Compilers/CSharp/Portable/LanguageVersion.cs b/src/Compilers/CSharp/Portable/LanguageVersion.cs index ec46ca42cee28..8ab047aec8329 100644 --- a/src/Compilers/CSharp/Portable/LanguageVersion.cs +++ b/src/Compilers/CSharp/Portable/LanguageVersion.cs @@ -360,5 +360,10 @@ internal static bool AllowImprovedOverloadCandidates(this LanguageVersion self) { return self >= MessageID.IDS_FeatureImprovedOverloadCandidates.RequiredVersion(); } + + internal static bool AllowParamsArrayInterfaceAndSpan(this LanguageVersion self) + { + return self >= MessageID.IDS_FeatureParamsArrayInterfaceAndSpan.RequiredVersion(); + } } } diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs index 92c56257d93ca..fa7c0d56e7b5c 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs @@ -887,7 +887,12 @@ private BoundExpression BuildParamsArray( } } - var paramArrayType = parameters[paramsParam].Type; + var paramsType = parameters[paramsParam].Type; + if (paramsType.IsPossibleArrayGenericInterface()) + { + paramsType = ArrayTypeSymbol.CreateSZArray(_compilation.Assembly, paramsType.GetElementTypeOfParamsType()); + } + var arrayArgs = paramArray.ToImmutableAndFree(); // If this is a zero-length array, rather than using "new T[0]", optimize with "Array.Empty()" @@ -896,14 +901,13 @@ private BoundExpression BuildParamsArray( // of expression lambdas will appropriately understand Array.Empty(). if (arrayArgs.Length == 0 && !_inExpressionLambda) { - ArrayTypeSymbol ats = paramArrayType as ArrayTypeSymbol; - if (ats != null) // could be null if there's a semantic error, e.g. the params parameter type isn't an array + if (paramsType is ArrayTypeSymbol arrayType) // could be false if there's a semantic error, or if the params parameter type isn't an array { MethodSymbol arrayEmpty = _compilation.GetWellKnownTypeMember(WellKnownMember.System_Array__Empty) as MethodSymbol; if (arrayEmpty != null) // will be null if Array.Empty doesn't exist in reference assemblies { // return an invocation of "Array.Empty()" - arrayEmpty = arrayEmpty.Construct(ImmutableArray.Create(ats.ElementType)); + arrayEmpty = arrayEmpty.Construct(ImmutableArray.Create(arrayType.ElementType)); return new BoundCall( syntax, null, @@ -922,25 +926,77 @@ private BoundExpression BuildParamsArray( } } - return CreateParamArrayArgument(syntax, paramArrayType, arrayArgs, this, null); + return CreateParamArrayArgument(syntax, paramsType, arrayArgs, this, null); } - private static BoundExpression CreateParamArrayArgument(SyntaxNode syntax, - TypeSymbol paramArrayType, + private static BoundExpression CreateParamArrayArgument( + SyntaxNode syntax, + TypeSymbol paramsType, ImmutableArray arrayArgs, LocalRewriter localRewriter, Binder binder) { Debug.Assert(localRewriter == null ^ binder == null); - TypeSymbol int32Type = (localRewriter != null ? localRewriter._compilation : binder.Compilation).GetSpecialType(SpecialType.System_Int32); + CSharpCompilation compilation = localRewriter != null ? localRewriter._compilation : binder.Compilation; + TypeSymbol int32Type = compilation.GetSpecialType(SpecialType.System_Int32); BoundExpression arraySize = MakeLiteral(syntax, ConstantValue.Create(arrayArgs.Length), int32Type, localRewriter); - return new BoundArrayCreation( - syntax, - ImmutableArray.Create(arraySize), - new BoundArrayInitialization(syntax, arrayArgs) { WasCompilerGenerated = true }, - paramArrayType) { WasCompilerGenerated = true }; + var initializer = new BoundArrayInitialization(syntax, arrayArgs) { WasCompilerGenerated = true }; + + if (paramsType.IsSZArray()) + { + return new BoundArrayCreation(syntax, ImmutableArray.Create(arraySize), initializer, paramsType) { WasCompilerGenerated = true }; + } + + TypeSymbol elementType = paramsType.GetElementTypeOfParamsType(); + bool isReferenceType = elementType.IsReferenceType; + + BoundExpression[] args; + if (isReferenceType) + { + args = new BoundExpression[] + { + new BoundArrayCreation( + syntax, + ImmutableArray.Create(arraySize), + initializer, + ArrayTypeSymbol.CreateSZArray(compilation.Assembly, elementType)) + { WasCompilerGenerated = true } + }; + } + else + { + args = new BoundExpression[] + { + new BoundConvertedStackAllocExpression( + syntax, + elementType, + arraySize, + initializer, + paramsType) + { WasCompilerGenerated = true }, + arraySize, + }; + } + + WellKnownMember constructor = compilation.IsReadOnlySpanType(paramsType) + ? isReferenceType ? WellKnownMember.System_ReadOnlySpan_T__ctor2 : WellKnownMember.System_ReadOnlySpan_T__ctor + : isReferenceType ? WellKnownMember.System_Span_T__ctor2 : WellKnownMember.System_Span_T__ctor; + + // TODO use TryGetWellKnownTypeMember instead, should test with a missing ctor + var spanConstructor = compilation.GetWellKnownTypeMember(constructor) as MethodSymbol; + if (spanConstructor == null) + { + return new BoundBadExpression( + syntax: syntax, + resultKind: LookupResultKind.NotInvocable, + symbols: ImmutableArray.Empty, + childBoundNodes: ImmutableArray.Empty, + type: ErrorTypeSymbol.UnknownResultType); + } + + return new BoundObjectCreationExpression(syntax, spanConstructor.AsMember((NamedTypeSymbol)paramsType), binder, arguments: args); } /// diff --git a/src/Compilers/CSharp/Portable/Symbols/MemberSignatureComparer.cs b/src/Compilers/CSharp/Portable/Symbols/MemberSignatureComparer.cs index 738c937392fdf..fde42c4a6f958 100644 --- a/src/Compilers/CSharp/Portable/Symbols/MemberSignatureComparer.cs +++ b/src/Compilers/CSharp/Portable/Symbols/MemberSignatureComparer.cs @@ -96,7 +96,8 @@ internal class MemberSignatureComparer : IEqualityComparer considerTypeConstraints: false, considerCallingConvention: false, considerRefKindDifferences: false, - considerCustomModifiers: false); //shouldn't actually matter for source members + considerCustomModifiers: false, //shouldn't actually matter for source members + considerParamsElementTypes: true); /// /// This instance is used to determine if a partial method implementation matches the definition. @@ -302,6 +303,8 @@ internal class MemberSignatureComparer : IEqualityComparer // Ignore the names of the tuple elements private readonly bool _ignoreTupleNames; + private readonly bool _considerParamsElementTypes; + private MemberSignatureComparer( bool considerName, bool considerExplicitlyImplementedInterfaces, @@ -310,6 +313,7 @@ private MemberSignatureComparer( bool considerCallingConvention, bool considerRefKindDifferences, bool considerCustomModifiers, + bool considerParamsElementTypes = false, bool ignoreDynamic = true, bool ignoreTupleNames = true) { @@ -324,6 +328,7 @@ private MemberSignatureComparer( _considerCustomModifiers = considerCustomModifiers; _ignoreDynamic = ignoreDynamic; _ignoreTupleNames = ignoreTupleNames; + _considerParamsElementTypes = considerParamsElementTypes; } #region IEqualityComparer Members @@ -374,10 +379,21 @@ public bool Equals(Symbol member1, Symbol member2) return false; } - if (member1.GetParameterCount() > 0 && !HaveSameParameterTypes(member1.GetParameters(), typeMap1, member2.GetParameters(), typeMap2, - _considerRefKindDifferences, _considerCustomModifiers, _ignoreDynamic, _ignoreTupleNames)) + var parameters1 = member1.GetParameters(); + var parameters2 = member2.GetParameters(); + + if (member1.GetParameterCount() > 0) { - return false; + if (!HaveSameParameterTypes(parameters1, typeMap1, parameters2, typeMap2, _considerRefKindDifferences, _considerCustomModifiers, _ignoreDynamic, _ignoreTupleNames)) + { + return false; + } + + if (_considerParamsElementTypes && member1.HasParamsParameter() && member2.HasParamsParameter() && + !HaveSameParamsElementTypes(parameters1, parameters2)) + { + return false; + } } if (_considerCallingConvention) @@ -693,6 +709,14 @@ private static bool HaveSameParameterTypes(ImmutableArray param return true; } + private static bool HaveSameParamsElementTypes(ImmutableArray parameters1, ImmutableArray parameters2) + { + Debug.Assert(parameters1.Length == parameters2.Length); + var elementType1 = parameters1.Last().Type.GetElementTypeOfParamsType(); + var elementType2 = parameters2.Last().Type.GetElementTypeOfParamsType(); + return elementType1.Equals(elementType2, TypeCompareKind.IgnoreTupleNames); + } + private static TypeWithModifiers SubstituteType(TypeMap typeMap, TypeWithModifiers typeSymbol) { return typeMap == null ? typeSymbol : typeSymbol.SubstituteType(typeMap); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs b/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs index a3cbec6f96231..7f299b5288daa 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs @@ -92,7 +92,7 @@ public static ImmutableArray MakeParameters( addRefReadOnlyModifier, diagnostics); - ReportParameterErrors(owner, parameterSyntax, parameter, thisKeyword, paramsKeyword, firstDefault, diagnostics); + ReportParameterErrors(owner, parameterSyntax, parameter, thisKeyword, paramsKeyword, firstDefault, binder.Compilation, diagnostics); builder.Add(parameter); ++parameterIndex; @@ -269,13 +269,13 @@ private static void CheckParameterModifiers( } } - private static void ReportParameterErrors( - Symbol owner, + private static void ReportParameterErrors(Symbol owner, ParameterSyntax parameterSyntax, SourceParameterSymbol parameter, SyntaxToken thisKeyword, SyntaxToken paramsKeyword, int firstDefault, + CSharpCompilation compilation, DiagnosticBag diagnostics) { TypeSymbol parameterType = parameter.Type; @@ -295,12 +295,24 @@ private static void ReportParameterErrors( // error CS1670: params is not valid in this context diagnostics.Add(ErrorCode.ERR_IllegalParams, paramsKeyword.GetLocation()); } - else if (parameter.IsParams && !parameterType.IsSZArray()) + else if (parameter.IsParams) { - // error CS0225: The params parameter must be a single dimensional array - diagnostics.Add(ErrorCode.ERR_ParamsMustBeArray, paramsKeyword.GetLocation()); + if (!parameterType.IsPossibleParamsType()) + { + // error CS0225: The params parameter must be assignable from array. + diagnostics.Add(ErrorCode.ERR_ParamsMustBeArray, paramsKeyword.GetLocation()); + return; + } + + if (!parameterType.IsSZArray() && !compilation.LanguageVersion.AllowParamsArrayInterfaceAndSpan()) + { + diagnostics.Add(ErrorCode.ERR_ParamsMustBeArray, paramsKeyword.GetLocation(), + new CSharpRequiredLanguageVersion(MessageID.IDS_FeatureParamsArrayInterfaceAndSpan.RequiredVersion())); + return; + } } - else if (parameter.Type.IsStatic && !parameter.ContainingSymbol.ContainingType.IsInterfaceType()) + + if (parameter.Type.IsStatic && !parameter.ContainingSymbol.ContainingType.IsInterfaceType()) { // error CS0721: '{0}': static types cannot be used as parameters diagnostics.Add(ErrorCode.ERR_ParameterIsStaticClass, owner.Locations[0], parameter.Type); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index 6cc3282ee5662..7d4892a91a330 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -1551,9 +1551,7 @@ private void CheckMemberNameConflicts(DiagnosticBag diagnostics) // That takes care of the first category of conflict; we detect the // second and third categories as follows: - var conversion = symbol as SourceUserDefinedConversionSymbol; - var method = symbol as SourceMemberMethodSymbol; - if ((object)conversion != null) + if (symbol is SourceUserDefinedConversionSymbol conversion) { // Does this conversion collide *as a conversion* with any previously-seen // conversion? @@ -1584,7 +1582,7 @@ private void CheckMemberNameConflicts(DiagnosticBag diagnostics) // Do not add the conversion to the set of previously-seen methods; that set // is only non-conversion methods. } - else if ((object)method != null) + else if (symbol is SourceMemberMethodSymbol method) { // Does this method collide *as a method* with any previously-seen // conversion? diff --git a/src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs b/src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs index 6d774b845f79d..9e59271e41efb 100644 --- a/src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs +++ b/src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs @@ -316,28 +316,35 @@ public static bool IsExpressionTree(this TypeSymbol _type) /// return true if the type is constructed from a generic interface that /// might be implemented by an array. /// - public static bool IsPossibleArrayGenericInterface(this TypeSymbol _type) + public static bool IsPossibleArrayGenericInterface(this TypeSymbol type) { - NamedTypeSymbol t = _type as NamedTypeSymbol; - if ((object)t == null) + if (type.Kind == SymbolKind.NamedType) { - return false; + switch (((NamedTypeSymbol)type).OriginalDefinition.SpecialType) + { + case SpecialType.System_Collections_Generic_IList_T: + case SpecialType.System_Collections_Generic_ICollection_T: + case SpecialType.System_Collections_Generic_IEnumerable_T: + case SpecialType.System_Collections_Generic_IReadOnlyList_T: + case SpecialType.System_Collections_Generic_IReadOnlyCollection_T: + return true; + } } - t = t.OriginalDefinition; - - SpecialType st = t.SpecialType; + return false; + } - if (st == SpecialType.System_Collections_Generic_IList_T || - st == SpecialType.System_Collections_Generic_ICollection_T || - st == SpecialType.System_Collections_Generic_IEnumerable_T || - st == SpecialType.System_Collections_Generic_IReadOnlyList_T || - st == SpecialType.System_Collections_Generic_IReadOnlyCollection_T) - { - return true; - } + public static bool IsPossibleParamsType(this TypeSymbol type) + { + return type.IsSZArray() || type.IsPossibleArrayGenericInterface() || type.IsWellKnownTypeSpanOrReadOnlySpan(); + } - return false; + public static TypeSymbol GetElementTypeOfParamsType(this TypeSymbol type) + { + Debug.Assert(type.IsPossibleParamsType()); + return type.TypeKind == TypeKind.Array + ? ((ArrayTypeSymbol)type).ElementType + : ((NamedTypeSymbol)type).TypeArgumentsNoUseSiteDiagnostics[0]; } private static readonly string[] s_expressionsNamespaceName = { "Expressions", "Linq", MetadataHelpers.SystemString, "" }; @@ -1557,7 +1564,28 @@ private static bool IsWellKnownInteropServicesTopLevelType(this ITypeSymbol type } var globalNamespace = systemNamespace.ContainingNamespace; + return globalNamespace != null && globalNamespace.IsGlobalNamespace; + } + internal static bool IsWellKnownTypeSpanOrReadOnlySpan(this TypeSymbol type) + { + if ((type.Name != "Span" && type.Name != "ReadOnlySpan") || type.ContainingType != null) + { + return false; + } + + if (type.Kind != SymbolKind.NamedType || ((NamedTypeSymbol)type).Arity != 1) + { + return false; + } + + var systemNamespace = type.ContainingNamespace; + if (systemNamespace?.Name != "System") + { + return false; + } + + var globalNamespace = systemNamespace.ContainingNamespace; return globalNamespace != null && globalNamespace.IsGlobalNamespace; } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/ParamsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/ParamsTests.cs new file mode 100644 index 0000000000000..335c3c4b36fc8 --- /dev/null +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/ParamsTests.cs @@ -0,0 +1,115 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.CodeAnalysis.CSharp.Symbols; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; +using Xunit; +using System.Threading; +using System.Linq; + +namespace Microsoft.CodeAnalysis.CSharp.Semantic.UnitTests.Semantics +{ + public class ParamsTests : CSharpTestBase + { + [Fact] + public void Test() + { + var source = @" +using System; + +unsafe class C +{ + static void M(params Span a) {} + + public static void Main() + { + var x = new C(); + M(x, x, x); + } +}"; + + CreateCompilationWithMscorlibAndSpan(source, options: TestOptions.DebugExe.WithAllowUnsafe(true)) + .VerifyEmitDiagnostics(); + } + + [Fact] + public void TestGoodParams() + { + var source = @" +using System; +using System.Linq; +using System.Collections; +using System.Collections.Generic; + +static class C +{ + static void Dump(this IEnumerable p) + { + var e = p?.Cast(); + Console.WriteLine(e == null ? """" : !e.Any() ? """" : string.Join("", "", e.Select(i => i ?? ""null""))); + } + + static void M1(params IList p) => p.Dump(); + static void M2(params ICollection p) => p.Dump(); + static void M3(params IEnumerable p) => p.Dump(); + static void M4(params IReadOnlyList p) => p.Dump(); + static void M5(params IReadOnlyCollection p) => p.Dump(); + + static void Main() + { + M1(); + M1(null); + M1(null, null); + M1(""1"", ""2"", ""3""); + + M2(); + M2(null); + M2(null, null); + M2(""1"", ""2"", ""3""); + + M3(); + M3(null); + M3(null, null); + M3(""1"", ""2"", ""3""); + + M4(); + M4(null); + M4(null, null); + M4(""1"", ""2"", ""3""); + + M5(); + M5(null); + M5(null, null); + M5(""1"", ""2"", ""3""); + } +} +"; + var comp = CreateCompilationWithMscorlib45(source, references: new[] { LinqAssemblyRef }, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: @" + + +null, null +1, 2, 3 + + +null, null +1, 2, 3 + + +null, null +1, 2, 3 + + +null, null +1, 2, 3 + + +null, null +1, 2, 3 +"); + } + } +} diff --git a/src/Compilers/Core/Portable/WellKnownMember.cs b/src/Compilers/Core/Portable/WellKnownMember.cs index a0a67d443c7e9..28e6138d6bf8c 100644 --- a/src/Compilers/Core/Portable/WellKnownMember.cs +++ b/src/Compilers/Core/Portable/WellKnownMember.cs @@ -423,11 +423,13 @@ internal enum WellKnownMember System_ObsoleteAttribute__ctor, - System_Span_T__ctor, + System_Span_T__ctor, // Span(void*, int) + System_Span_T__ctor2, // Span(T[]) System_Span_T__get_Item, System_Span_T__get_Length, - System_ReadOnlySpan_T__ctor, + System_ReadOnlySpan_T__ctor, // ReadOnlySpan(void*, int) + System_ReadOnlySpan_T__ctor2, // ReadOnlySpan(T[]) System_ReadOnlySpan_T__get_Item, System_ReadOnlySpan_T__get_Length, diff --git a/src/Compilers/Core/Portable/WellKnownMembers.cs b/src/Compilers/Core/Portable/WellKnownMembers.cs index 2961c38f3d371..9ab2b697e9dae 100644 --- a/src/Compilers/Core/Portable/WellKnownMembers.cs +++ b/src/Compilers/Core/Portable/WellKnownMembers.cs @@ -2919,7 +2919,7 @@ static WellKnownMembers() (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Void, // Return Type (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_String, (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Boolean, - + // System_Span__ctor (byte)(MemberFlags.Constructor), // Flags (byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.System_Span_T - WellKnownType.ExtSentinel), // DeclaringTypeId @@ -2929,6 +2929,14 @@ static WellKnownMembers() (byte)SignatureTypeCode.Pointer, (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Void, (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Int32, + // System_Span__ctor2 + (byte)(MemberFlags.Constructor), // Flags + (byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.System_Span_T - WellKnownType.ExtSentinel), // DeclaringTypeId + 0, // Arity + 1, // Method Signature + (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Void, // Return Type + (byte)SignatureTypeCode.SZArray, (byte)SignatureTypeCode.GenericTypeParameter, 0, + // System_Span__get_Item (byte)(MemberFlags.PropertyGet), // Flags (byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.System_Span_T - WellKnownType.ExtSentinel), // DeclaringTypeId @@ -2953,6 +2961,14 @@ static WellKnownMembers() (byte)SignatureTypeCode.Pointer, (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Void, (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Int32, + // System_ReadOnlySpan__ctor2 + (byte)(MemberFlags.Constructor), // Flags + (byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.System_ReadOnlySpan_T - WellKnownType.ExtSentinel), // DeclaringTypeId + 0, // Arity + 1, // Method Signature + (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Void, // Return Type + (byte)SignatureTypeCode.SZArray, (byte)SignatureTypeCode.GenericTypeParameter, 0, + // System_ReadOnlySpan__get_Item (byte)(MemberFlags.PropertyGet), // Flags (byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.System_ReadOnlySpan_T - WellKnownType.ExtSentinel), // DeclaringTypeId @@ -3396,9 +3412,11 @@ static WellKnownMembers() ".ctor", // System_Runtime_CompilerServices_IsByRefLikeAttribute__ctor ".ctor", // System_Runtime_CompilerServices_ObsoleteAttribute__ctor ".ctor", // System_Span__ctor + ".ctor", // System_Span__ctor2 "get_Item", // System_Span__get_Item "get_Length", // System_Span__get_Length ".ctor", // System_ReadOnlySpan__ctor + ".ctor", // System_ReadOnlySpan__ctor2 "get_Item", // System_ReadOnlySpan__get_Item "get_Length", // System_ReadOnlySpan__get_Length ".ctor", // System_Runtime_CompilerServices_IsUnmanagedAttribute__ctor