From 3311b8618894d4b304231573881ff0e7ed4ca276 Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Tue, 2 May 2023 13:45:22 -0700 Subject: [PATCH 1/2] Finalize testing and implementation around object initializers for inline arrays. --- .../Portable/Binder/Binder_Expressions.cs | 2 - ...ObjectOrCollectionInitializerExpression.cs | 2 - .../Semantic/Semantics/InlineArrayTests.cs | 414 +++++++++++++++++- 3 files changed, 410 insertions(+), 8 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs index 15dcf933b2534..4c64871fe4219 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs @@ -5144,8 +5144,6 @@ private BoundExpression BindObjectInitializerMember( case BoundKind.PointerElementAccess: return CheckValue(boundMember, valueKind, diagnostics); - // PROTOTYPE(InlineArrays): case BoundKind.InlineArrayAccess: - default: return BadObjectInitializerMemberAccess(boundMember, implicitReceiver, leftSyntax, diagnostics, valueKind, hasErrors); } diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ObjectOrCollectionInitializerExpression.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ObjectOrCollectionInitializerExpression.cs index 5d3d67d146dfb..121bc92182a8a 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ObjectOrCollectionInitializerExpression.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ObjectOrCollectionInitializerExpression.cs @@ -410,8 +410,6 @@ private void AddObjectInitializer( break; } - // PROTOTYPE(InlineArrays): case BoundKind.InlineArrayAccess: - case BoundKind.PointerElementAccess: { // Remember we haven't lowered this node yet. diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/InlineArrayTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/InlineArrayTests.cs index e23efc460f866..2b63d0f41ba40 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/InlineArrayTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/InlineArrayTests.cs @@ -2067,7 +2067,7 @@ .locals init (System.Range V_0, } [ConditionalFact(typeof(MonoOrCoreClrOnly))] - public void ElementAccess_ObjectInitializer_Int() + public void ElementAccess_ObjectInitializer_Int_01() { var src = @" class C @@ -2087,7 +2087,8 @@ static void Main() "; var comp = CreateCompilation(src + Buffer10Definition, targetFramework: TargetFramework.NetCoreApp, options: TestOptions.ReleaseExe); - // PROTOTYPE(InlineArrays): Should work? + // According to the language specification: "an argument_list enclosed in square brackets shall specify arguments for an accessible indexer on the object being initialized" + // Buffer10 doesn't have an indexer. comp.VerifyDiagnostics( // (14,37): error CS1913: Member '[0]' cannot be initialized. It is not a field or property. // static C M2() => new C() { F = {[0] = 111} }; @@ -2095,14 +2096,194 @@ static void Main() ); #if false // PROTOTYPE(InlineArrays): - var verifier = CompileAndVerify(comp, expectedOutput: "111", verify: Verification.Fails).VerifyDiagnostics(); + var tree = comp.SyntaxTrees.First(); + var model = comp.GetSemanticModel(tree); - verifier.VerifyIL("Program.M2", + var m2 = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "M2").Single(); + var m2Operation = model.GetOperation(m2); + VerifyOperationTree(comp, m2Operation, @" +"); +#endif + } + + [ConditionalFact(typeof(MonoOrCoreClrOnly))] + public void ElementAccess_ObjectInitializer_Int_02() + { + var src = @" +class C +{ + public Buffer10 F; +} + +class Program +{ + static void Main() + { + System.Console.Write(M2().F[0]); + } + + static C M2() => new C() { F = {[0] = 111} }; +} + +[System.Runtime.CompilerServices.InlineArray(10)] +public struct Buffer10 { + private T _element0; + + public T this[int i] + { + get => this[i]; + set => this[i] = value; + } } +" + InlineArrayAttributeDefinition; + + var comp = CreateCompilation(src, targetFramework: TargetFramework.NetCoreApp, options: TestOptions.ReleaseExe); + + // Keeping this an error even in presence of an indexer, in case we decide to handle initializers like that specially in the future. + comp.VerifyDiagnostics( + // (14,37): error CS1913: Member '[0]' cannot be initialized. It is not a field or property. + // static C M2() => new C() { F = {[0] = 111} }; + Diagnostic(ErrorCode.ERR_MemberCannotBeInitialized, "[0]").WithArguments("[0]").WithLocation(14, 37) + ); + +#if false // PROTOTYPE(InlineArrays): + var tree = comp.SyntaxTrees.First(); + var model = comp.GetSemanticModel(tree); + + var m2 = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "M2").Single(); + var m2Operation = model.GetOperation(m2); + VerifyOperationTree(comp, m2Operation, +@" "); #endif + } + + [ConditionalFact(typeof(MonoOrCoreClrOnly))] + public void ElementAccess_ObjectInitializer_Index_01() + { + var src = @" +class C +{ + public Buffer10 F; +} + +class Program +{ + static void Main() + { + System.Console.Write(M2().F[0]); + } + + static C M2() => new C() { F = {[^10] = 111} }; +} +"; + var comp = CreateCompilation(src + Buffer10Definition, targetFramework: TargetFramework.NetCoreApp, options: TestOptions.ReleaseExe); + + // According to the language specification: "an argument_list enclosed in square brackets shall specify arguments for an accessible indexer on the object being initialized" + // Buffer10 doesn't have an indexer. + comp.VerifyDiagnostics( + // (14,37): error CS1913: Member '[^10]' cannot be initialized. It is not a field or property. + // static C M2() => new C() { F = {[^10] = 111} }; + Diagnostic(ErrorCode.ERR_MemberCannotBeInitialized, "[^10]").WithArguments("[^10]").WithLocation(14, 37) + ); + +#if false // PROTOTYPE(InlineArrays): + var tree = comp.SyntaxTrees.First(); + var model = comp.GetSemanticModel(tree); + + var m2 = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "M2").Single(); + var m2Operation = model.GetOperation(m2); + VerifyOperationTree(comp, m2Operation, +@" +"); +#endif + } + + [ConditionalFact(typeof(MonoOrCoreClrOnly))] + public void ElementAccess_ObjectInitializer_Index_02() + { + var src = @" +class C +{ + public Buffer10 F; +} + +class Program +{ + static void Main() + { + System.Console.Write(M2().F[0]); + } + + static C M2() => new C() { F = {[^10] = 111} }; +} + +[System.Runtime.CompilerServices.InlineArray(10)] +public struct Buffer10 +{ + private T _element0; + + public T this[int i] + { + get => this[i]; + set => this[i] = value; + } + + public int Length => 10; +} +" + InlineArrayAttributeDefinition; + + var comp = CreateCompilation(src, targetFramework: TargetFramework.NetCoreApp, options: TestOptions.ReleaseExe); + + // Keeping this an error even in presence of an indexer, in case we decide to handle initializers like that specially in the future. + comp.VerifyDiagnostics( + // (14,37): error CS1913: Member '[^10]' cannot be initialized. It is not a field or property. + // static C M2() => new C() { F = {[^10] = 111} }; + Diagnostic(ErrorCode.ERR_MemberCannotBeInitialized, "[^10]").WithArguments("[^10]").WithLocation(14, 37) + ); + +#if false // PROTOTYPE(InlineArrays): + var tree = comp.SyntaxTrees.First(); + var model = comp.GetSemanticModel(tree); + + var m2 = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "M2").Single(); + var m2Operation = model.GetOperation(m2); + VerifyOperationTree(comp, m2Operation, +@" +"); +#endif + } + + [ConditionalFact(typeof(MonoOrCoreClrOnly))] + public void ElementAccess_ObjectInitializer_Range_01() + { + var src = @" +class C +{ + public Buffer10 F; +} + +class Program +{ + static void Main() + { + System.Console.Write(M2().F[0]); + } + + static C M2() => new C() { F = {[0..1] = 111} }; +} +"; + var comp = CreateCompilation(src + Buffer10Definition, targetFramework: TargetFramework.NetCoreApp, options: TestOptions.ReleaseExe); + + // According to the language specification: "an argument_list enclosed in square brackets shall specify arguments for an accessible indexer on the object being initialized" + // Buffer10 doesn't have an indexer. + comp.VerifyDiagnostics( + // (14,37): error CS1913: Member '[0..1]' cannot be initialized. It is not a field or property. + // static C M2() => new C() { F = {[0..1] = 111} }; + Diagnostic(ErrorCode.ERR_MemberCannotBeInitialized, "[0..1]").WithArguments("[0..1]").WithLocation(14, 37) + ); #if false // PROTOTYPE(InlineArrays): var tree = comp.SyntaxTrees.First(); @@ -8391,5 +8572,230 @@ public struct Buffer10 var compilation = CreateCompilation(source, targetFramework: TargetFramework.NetCoreApp); compilation.VerifyDiagnostics(); } + + [ConditionalFact(typeof(MonoOrCoreClrOnly))] + public void ElementAccess_IndexerIsIgnored_01() + { + var src = @" +class C +{ + public Buffer10 F; +} + +class Program +{ + static void Main() + { + var x = new C(); + System.Console.Write(M1(x)); + M2(x); + System.Console.Write(' '); + System.Console.Write(M1(x)); + } + + static int M1(C x) => x.F[0]; + static void M2(C x) => x.F[0] = 111; +} + +[System.Runtime.CompilerServices.InlineArray(10)] +public struct Buffer10 +{ + private T _element0; + + public T this[int i] + { + get => this[i]; + set => this[i] = value; + } +} +" + InlineArrayAttributeDefinition; + + var comp = CreateCompilation(src, targetFramework: TargetFramework.NetCoreApp, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify(comp, expectedOutput: "0 111", verify: Verification.Fails).VerifyDiagnostics(); + + verifier.VerifyIL("Program.M1", +@" +{ + // Code size 24 (0x18) + .maxstack 2 + .locals init (System.Span V_0) + IL_0000: ldarg.0 + IL_0001: ldflda ""Buffer10 C.F"" + IL_0006: ldc.i4.s 10 + IL_0008: call ""InlineArrayAsSpan, int>(ref Buffer10, int)"" + IL_000d: stloc.0 + IL_000e: ldloca.s V_0 + IL_0010: ldc.i4.0 + IL_0011: call ""ref int System.Span.this[int].get"" + IL_0016: ldind.i4 + IL_0017: ret +} +"); + + verifier.VerifyIL("Program.M2", +@" +{ + // Code size 26 (0x1a) + .maxstack 2 + .locals init (System.Span V_0) + IL_0000: ldarg.0 + IL_0001: ldflda ""Buffer10 C.F"" + IL_0006: ldc.i4.s 10 + IL_0008: call ""InlineArrayAsSpan, int>(ref Buffer10, int)"" + IL_000d: stloc.0 + IL_000e: ldloca.s V_0 + IL_0010: ldc.i4.0 + IL_0011: call ""ref int System.Span.this[int].get"" + IL_0016: ldc.i4.s 111 + IL_0018: stind.i4 + IL_0019: ret +} +"); + } + + [ConditionalFact(typeof(MonoOrCoreClrOnly))] + public void ElementAccess_Index_IndexerIsIgnored_01() + { + var src = @" +class C +{ + public Buffer10 F; +} + +class Program +{ + static void Main() + { + var x = new C(); + System.Console.Write(M1(x)); + M2(x); + System.Console.Write(' '); + System.Console.Write(M1(x)); + } + + static int M1(C x) => x.F[^10]; + static void M2(C x) => x.F[^10] = 111; +} + +[System.Runtime.CompilerServices.InlineArray(10)] +public struct Buffer10 +{ + private T _element0; + + public T this[int i] + { + get => this[i]; + set => this[i] = value; + } + + public int Length => 10; +} +" + InlineArrayAttributeDefinition; + + var comp = CreateCompilation(src, targetFramework: TargetFramework.NetCoreApp, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify(comp, expectedOutput: "0 111", verify: Verification.Fails).VerifyDiagnostics(); + + verifier.VerifyIL("Program.M1", +@" +{ + // Code size 24 (0x18) + .maxstack 2 + .locals init (System.Span V_0) + IL_0000: ldarg.0 + IL_0001: ldflda ""Buffer10 C.F"" + IL_0006: ldc.i4.s 10 + IL_0008: call ""InlineArrayAsSpan, int>(ref Buffer10, int)"" + IL_000d: stloc.0 + IL_000e: ldloca.s V_0 + IL_0010: ldc.i4.0 + IL_0011: call ""ref int System.Span.this[int].get"" + IL_0016: ldind.i4 + IL_0017: ret +} +"); + + verifier.VerifyIL("Program.M2", +@" +{ + // Code size 26 (0x1a) + .maxstack 2 + .locals init (System.Span V_0) + IL_0000: ldarg.0 + IL_0001: ldflda ""Buffer10 C.F"" + IL_0006: ldc.i4.s 10 + IL_0008: call ""InlineArrayAsSpan, int>(ref Buffer10, int)"" + IL_000d: stloc.0 + IL_000e: ldloca.s V_0 + IL_0010: ldc.i4.0 + IL_0011: call ""ref int System.Span.this[int].get"" + IL_0016: ldc.i4.s 111 + IL_0018: stind.i4 + IL_0019: ret +} +"); + } + + [ConditionalFact(typeof(MonoOrCoreClrOnly))] + public void Slice_SliceMethodIsIgnored_01() + { + var src = @" +class C +{ + public Buffer10 F; +} + +class Program +{ + static void Main() + { + var x = new C(); + System.Console.Write(M1(x)); + M2(x)[0] = 111; + System.Console.Write(' '); + System.Console.Write(M1(x)); + } + + static int M1(C x) => x.F[0]; + static System.Span M2(C x) => x.F[..5]; +} + +[System.Runtime.CompilerServices.InlineArray(10)] +public struct Buffer10 +{ + private T _element0; + + public T this[int i] + { + get => this[i]; + set => this[i] = value; + } + + public int Length => 10; + public System.Span Slice(int start, int length) => throw null; +} +" + InlineArrayAttributeDefinition; + + var comp = CreateCompilation(src, targetFramework: TargetFramework.NetCoreApp, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify(comp, expectedOutput: "0 111", verify: Verification.Fails).VerifyDiagnostics(); + + verifier.VerifyIL("Program.M2", +@" +{ + // Code size 24 (0x18) + .maxstack 3 + .locals init (System.Span V_0) + IL_0000: ldarg.0 + IL_0001: ldflda ""Buffer10 C.F"" + IL_0006: ldc.i4.s 10 + IL_0008: call ""InlineArrayAsSpan, int>(ref Buffer10, int)"" + IL_000d: stloc.0 + IL_000e: ldloca.s V_0 + IL_0010: ldc.i4.0 + IL_0011: ldc.i4.5 + IL_0012: call ""System.Span System.Span.Slice(int, int)"" + IL_0017: ret +} +"); + } } } From c61bd92de9fd6116b156d4c1d47f687478e8270a Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Thu, 4 May 2023 12:29:38 -0700 Subject: [PATCH 2/2] LDM desided to respect inline array indexers in object initializers --- .../Portable/Binder/Binder_Expressions.cs | 15 ++++---- .../Semantic/Semantics/InlineArrayTests.cs | 35 ++++++++++++------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs index 4c64871fe4219..e217537177b80 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs @@ -5035,7 +5035,7 @@ private BoundExpression BindObjectInitializerMember( MessageID.IDS_FeatureDictionaryInitializer.CheckFeatureAvailability(diagnostics, implicitIndexing.ArgumentList.OpenBracketToken); - boundMember = BindElementAccess(implicitIndexing, implicitReceiver, implicitIndexing.ArgumentList, diagnostics); + boundMember = BindElementAccess(implicitIndexing, implicitReceiver, implicitIndexing.ArgumentList, allowInlineArrayElementAccess: false, diagnostics); resultKind = boundMember.ResultKind; hasErrors = boundMember.HasAnyErrors || implicitReceiver.HasAnyErrors; @@ -7935,10 +7935,10 @@ private static bool IsMethodOrPropertyGroup(ArrayBuilder members) private BoundExpression BindElementAccess(ElementAccessExpressionSyntax node, BindingDiagnosticBag diagnostics) { BoundExpression receiver = BindExpression(node.Expression, diagnostics: diagnostics, invoked: false, indexed: true); - return BindElementAccess(node, receiver, node.ArgumentList, diagnostics); + return BindElementAccess(node, receiver, node.ArgumentList, allowInlineArrayElementAccess: true, diagnostics); } - private BoundExpression BindElementAccess(ExpressionSyntax node, BoundExpression receiver, BracketedArgumentListSyntax argumentList, BindingDiagnosticBag diagnostics) + private BoundExpression BindElementAccess(ExpressionSyntax node, BoundExpression receiver, BracketedArgumentListSyntax argumentList, bool allowInlineArrayElementAccess, BindingDiagnosticBag diagnostics) { AnalyzedArguments analyzedArguments = AnalyzedArguments.GetInstance(); try @@ -7955,7 +7955,7 @@ private BoundExpression BindElementAccess(ExpressionSyntax node, BoundExpression receiver = CheckValue(receiver, BindValueKind.RValue, diagnostics); receiver = BindToNaturalType(receiver, diagnostics); - return BindElementOrIndexerAccess(node, receiver, analyzedArguments, diagnostics); + return BindElementOrIndexerAccess(node, receiver, analyzedArguments, allowInlineArrayElementAccess, diagnostics); } finally { @@ -7963,7 +7963,7 @@ private BoundExpression BindElementAccess(ExpressionSyntax node, BoundExpression } } - private BoundExpression BindElementOrIndexerAccess(ExpressionSyntax node, BoundExpression expr, AnalyzedArguments analyzedArguments, BindingDiagnosticBag diagnostics) + private BoundExpression BindElementOrIndexerAccess(ExpressionSyntax node, BoundExpression expr, AnalyzedArguments analyzedArguments, bool allowInlineArrayElementAccess, BindingDiagnosticBag diagnostics) { if ((object)expr.Type == null) { @@ -7983,7 +7983,8 @@ private BoundExpression BindElementOrIndexerAccess(ExpressionSyntax node, BoundE } if (expr.Type.HasInlineArrayAttribute(out _) && analyzedArguments.Arguments.Count == 1 && expr.Type.TryGetInlineArrayElementType() is { HasType: true } elementType && - tryImplicitConversionToInlineArrayIndex(node, analyzedArguments.Arguments[0], diagnostics, out WellKnownType indexOrRangeWellknownType) is { } convertedIndex) + tryImplicitConversionToInlineArrayIndex(node, analyzedArguments.Arguments[0], diagnostics, out WellKnownType indexOrRangeWellknownType) is { } convertedIndex && + allowInlineArrayElementAccess) // PROTOTYPE(InlineArrays): Check this first after conflicting PRs are merged { return bindInlineArrayElementAccess(node, expr, analyzedArguments, convertedIndex, indexOrRangeWellknownType, elementType, diagnostics); } @@ -9641,7 +9642,7 @@ private BoundExpression BindElementBindingExpression(ElementBindingExpressionSyn { BoundExpression receiver = GetReceiverForConditionalBinding(node, diagnostics); - var memberAccess = BindElementAccess(node, receiver, node.ArgumentList, diagnostics); + var memberAccess = BindElementAccess(node, receiver, node.ArgumentList, allowInlineArrayElementAccess: true, diagnostics); return memberAccess; } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/InlineArrayTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/InlineArrayTests.cs index 2b63d0f41ba40..1e25c43c1824b 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/InlineArrayTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/InlineArrayTests.cs @@ -2090,9 +2090,9 @@ static void Main() // According to the language specification: "an argument_list enclosed in square brackets shall specify arguments for an accessible indexer on the object being initialized" // Buffer10 doesn't have an indexer. comp.VerifyDiagnostics( - // (14,37): error CS1913: Member '[0]' cannot be initialized. It is not a field or property. + // (14,37): error CS0021: Cannot apply indexing with [] to an expression of type 'Buffer10' // static C M2() => new C() { F = {[0] = 111} }; - Diagnostic(ErrorCode.ERR_MemberCannotBeInitialized, "[0]").WithArguments("[0]").WithLocation(14, 37) + Diagnostic(ErrorCode.ERR_BadIndexLHS, "[0]").WithArguments("Buffer10").WithLocation(14, 37) ); #if false // PROTOTYPE(InlineArrays): @@ -2140,13 +2140,22 @@ public T this[int i] " + InlineArrayAttributeDefinition; var comp = CreateCompilation(src, targetFramework: TargetFramework.NetCoreApp, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify(comp, expectedOutput: "111", verify: Verification.Fails).VerifyDiagnostics(); - // Keeping this an error even in presence of an indexer, in case we decide to handle initializers like that specially in the future. - comp.VerifyDiagnostics( - // (14,37): error CS1913: Member '[0]' cannot be initialized. It is not a field or property. - // static C M2() => new C() { F = {[0] = 111} }; - Diagnostic(ErrorCode.ERR_MemberCannotBeInitialized, "[0]").WithArguments("[0]").WithLocation(14, 37) - ); + verifier.VerifyIL("Program.M2", +@" +{ + // Code size 20 (0x14) + .maxstack 4 + IL_0000: newobj ""C..ctor()"" + IL_0005: dup + IL_0006: ldflda ""Buffer10 C.F"" + IL_000b: ldc.i4.0 + IL_000c: ldc.i4.s 111 + IL_000e: call ""void Buffer10.this[int].set"" + IL_0013: ret +} +"); #if false // PROTOTYPE(InlineArrays): var tree = comp.SyntaxTrees.First(); @@ -2184,9 +2193,9 @@ static void Main() // According to the language specification: "an argument_list enclosed in square brackets shall specify arguments for an accessible indexer on the object being initialized" // Buffer10 doesn't have an indexer. comp.VerifyDiagnostics( - // (14,37): error CS1913: Member '[^10]' cannot be initialized. It is not a field or property. + // (14,37): error CS0021: Cannot apply indexing with [] to an expression of type 'Buffer10' // static C M2() => new C() { F = {[^10] = 111} }; - Diagnostic(ErrorCode.ERR_MemberCannotBeInitialized, "[^10]").WithArguments("[^10]").WithLocation(14, 37) + Diagnostic(ErrorCode.ERR_BadIndexLHS, "[^10]").WithArguments("Buffer10").WithLocation(14, 37) ); #if false // PROTOTYPE(InlineArrays): @@ -2237,7 +2246,7 @@ public T this[int i] var comp = CreateCompilation(src, targetFramework: TargetFramework.NetCoreApp, options: TestOptions.ReleaseExe); - // Keeping this an error even in presence of an indexer, in case we decide to handle initializers like that specially in the future. + // This scenario fails due to https://github.com/dotnet/roslyn/issues/67533 comp.VerifyDiagnostics( // (14,37): error CS1913: Member '[^10]' cannot be initialized. It is not a field or property. // static C M2() => new C() { F = {[^10] = 111} }; @@ -2280,9 +2289,9 @@ static void Main() // According to the language specification: "an argument_list enclosed in square brackets shall specify arguments for an accessible indexer on the object being initialized" // Buffer10 doesn't have an indexer. comp.VerifyDiagnostics( - // (14,37): error CS1913: Member '[0..1]' cannot be initialized. It is not a field or property. + // (14,37): error CS0021: Cannot apply indexing with [] to an expression of type 'Buffer10' // static C M2() => new C() { F = {[0..1] = 111} }; - Diagnostic(ErrorCode.ERR_MemberCannotBeInitialized, "[0..1]").WithArguments("[0..1]").WithLocation(14, 37) + Diagnostic(ErrorCode.ERR_BadIndexLHS, "[0..1]").WithArguments("Buffer10").WithLocation(14, 37) ); #if false // PROTOTYPE(InlineArrays):