diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_CollectionExpression.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_CollectionExpression.cs index 641913d90b11d..65c0eb04c461f 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_CollectionExpression.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_CollectionExpression.cs @@ -738,7 +738,7 @@ bool tryGetToArrayMethod(TypeSymbol spreadTypeOriginalDefinition, WellKnownType localsBuilder, numberIncludingLastSpread, sideEffects, - addElement: (ArrayBuilder expressions, BoundExpression arrayTemp, BoundExpression rewrittenValue) => + addElement: (ArrayBuilder expressions, BoundExpression arrayTemp, BoundExpression rewrittenValue, bool isLastElement) => { Debug.Assert(arrayTemp.Type is ArrayTypeSymbol); Debug.Assert(indexTemp.Type is { SpecialType: SpecialType.System_Int32 }); @@ -754,14 +754,17 @@ bool tryGetToArrayMethod(TypeSymbol spreadTypeOriginalDefinition, WellKnownType rewrittenValue, isRef: false, elementType)); - // index = index + 1; - expressions.Add( - new BoundAssignmentOperator( - expressionSyntax, - indexTemp, - _factory.Binary(BinaryOperatorKind.Addition, indexTemp.Type, indexTemp, _factory.Literal(1)), - isRef: false, - indexTemp.Type)); + if (!isLastElement) + { + // index = index + 1; + expressions.Add( + new BoundAssignmentOperator( + expressionSyntax, + indexTemp, + _factory.Binary(BinaryOperatorKind.Addition, indexTemp.Type, indexTemp, _factory.Literal(1)), + isRef: false, + indexTemp.Type)); + } }, tryOptimizeSpreadElement: (ArrayBuilder sideEffects, BoundExpression arrayTemp, BoundCollectionExpressionSpreadElement spreadElement, BoundExpression rewrittenSpreadOperand) => { @@ -1072,7 +1075,7 @@ private BoundExpression CreateAndPopulateList(BoundCollectionExpression node, Ty localsBuilder, numberIncludingLastSpread, sideEffects, - addElement: (ArrayBuilder expressions, BoundExpression spanTemp, BoundExpression rewrittenValue) => + addElement: (ArrayBuilder expressions, BoundExpression spanTemp, BoundExpression rewrittenValue, bool isLastElement) => { Debug.Assert(spanTemp.Type is NamedTypeSymbol); Debug.Assert(indexTemp.Type is { SpecialType: SpecialType.System_Int32 }); @@ -1088,14 +1091,17 @@ private BoundExpression CreateAndPopulateList(BoundCollectionExpression node, Ty rewrittenValue, isRef: false, elementType)); - // index = index + 1; - expressions.Add( - new BoundAssignmentOperator( - expressionSyntax, - indexTemp, - _factory.Binary(BinaryOperatorKind.Addition, indexTemp.Type, indexTemp, _factory.Literal(1)), - isRef: false, - indexTemp.Type)); + if (!isLastElement) + { + // index = index + 1; + expressions.Add( + new BoundAssignmentOperator( + expressionSyntax, + indexTemp, + _factory.Binary(BinaryOperatorKind.Addition, indexTemp.Type, indexTemp, _factory.Literal(1)), + isRef: false, + indexTemp.Type)); + } }, tryOptimizeSpreadElement: (ArrayBuilder sideEffects, BoundExpression spanTemp, BoundCollectionExpressionSpreadElement spreadElement, BoundExpression rewrittenSpreadOperand) => { @@ -1116,7 +1122,7 @@ private BoundExpression CreateAndPopulateList(BoundCollectionExpression node, Ty localsBuilder, numberIncludingLastSpread, sideEffects, - addElement: (ArrayBuilder expressions, BoundExpression listTemp, BoundExpression rewrittenValue) => + addElement: (ArrayBuilder expressions, BoundExpression listTemp, BoundExpression rewrittenValue, bool isLastElement) => { // list.Add(element); expressions.Add( @@ -1180,7 +1186,7 @@ private void AddCollectionExpressionElements( ArrayBuilder rewrittenExpressions, int numberIncludingLastSpread, ArrayBuilder sideEffects, - Action, BoundExpression, BoundExpression> addElement, + Action, BoundExpression, BoundExpression, bool> addElement, Func, BoundExpression, BoundCollectionExpressionSpreadElement, BoundExpression, bool> tryOptimizeSpreadElement) { for (int i = 0; i < elements.Length; i++) @@ -1202,7 +1208,7 @@ private void AddCollectionExpressionElements( { var rewrittenValue = VisitExpression(((BoundExpressionStatement)iteratorBody).Expression); var builder = ArrayBuilder.GetInstance(); - addElement(builder, rewrittenReceiver, rewrittenValue); + addElement(builder, rewrittenReceiver, rewrittenValue, false); var statements = builder.SelectAsArray(expr => (BoundStatement)new BoundExpressionStatement(expr.Syntax, expr)); builder.Free(); Debug.Assert(statements.Length > 0); @@ -1214,7 +1220,8 @@ private void AddCollectionExpressionElements( } else { - addElement(sideEffects, rewrittenReceiver, rewrittenExpression); + var isLastElement = i == (elements.Length - 1); + addElement(sideEffects, rewrittenReceiver, rewrittenExpression, isLastElement); } } } diff --git a/src/Compilers/CSharp/Test/Emit3/Semantics/CollectionExpressionTests.cs b/src/Compilers/CSharp/Test/Emit3/Semantics/CollectionExpressionTests.cs index 029c55e5c6c29..4a146ce4b4c8d 100644 --- a/src/Compilers/CSharp/Test/Emit3/Semantics/CollectionExpressionTests.cs +++ b/src/Compilers/CSharp/Test/Emit3/Semantics/CollectionExpressionTests.cs @@ -11331,7 +11331,7 @@ static void Main() verifier.VerifyIL("Program.Main", """ { - // Code size 162 (0xa2) + // Code size 158 (0x9e) .maxstack 3 .locals init (int V_0, System.Span V_1, @@ -11377,51 +11377,47 @@ .locals init (int V_0, IL_0046: ldc.i4.3 IL_0047: box "int" IL_004c: stind.ref - IL_004d: ldloc.2 - IL_004e: ldc.i4.1 - IL_004f: add - IL_0050: stloc.2 - IL_0051: dup - IL_0052: ldc.i4.0 - IL_0053: call "void CollectionExtensions.Report(object, bool)" - IL_0058: ldc.i4.0 - IL_0059: stloc.2 - IL_005a: dup - IL_005b: callvirt "int System.Collections.Generic.List.Count.get" - IL_0060: newarr "object" - IL_0065: stloc.3 - IL_0066: callvirt "System.Collections.Generic.List.Enumerator System.Collections.Generic.List.GetEnumerator()" - IL_006b: stloc.s V_4 + IL_004d: dup + IL_004e: ldc.i4.0 + IL_004f: call "void CollectionExtensions.Report(object, bool)" + IL_0054: ldc.i4.0 + IL_0055: stloc.2 + IL_0056: dup + IL_0057: callvirt "int System.Collections.Generic.List.Count.get" + IL_005c: newarr "object" + IL_0061: stloc.3 + IL_0062: callvirt "System.Collections.Generic.List.Enumerator System.Collections.Generic.List.GetEnumerator()" + IL_0067: stloc.s V_4 .try { - IL_006d: br.s IL_0081 - IL_006f: ldloca.s V_4 - IL_0071: call "dynamic System.Collections.Generic.List.Enumerator.Current.get" - IL_0076: stloc.s V_5 - IL_0078: ldloc.3 + IL_0069: br.s IL_007d + IL_006b: ldloca.s V_4 + IL_006d: call "dynamic System.Collections.Generic.List.Enumerator.Current.get" + IL_0072: stloc.s V_5 + IL_0074: ldloc.3 + IL_0075: ldloc.2 + IL_0076: ldloc.s V_5 + IL_0078: stelem.ref IL_0079: ldloc.2 - IL_007a: ldloc.s V_5 - IL_007c: stelem.ref - IL_007d: ldloc.2 - IL_007e: ldc.i4.1 - IL_007f: add - IL_0080: stloc.2 - IL_0081: ldloca.s V_4 - IL_0083: call "bool System.Collections.Generic.List.Enumerator.MoveNext()" - IL_0088: brtrue.s IL_006f - IL_008a: leave.s IL_009a + IL_007a: ldc.i4.1 + IL_007b: add + IL_007c: stloc.2 + IL_007d: ldloca.s V_4 + IL_007f: call "bool System.Collections.Generic.List.Enumerator.MoveNext()" + IL_0084: brtrue.s IL_006b + IL_0086: leave.s IL_0096 } finally { - IL_008c: ldloca.s V_4 - IL_008e: constrained. "System.Collections.Generic.List.Enumerator" - IL_0094: callvirt "void System.IDisposable.Dispose()" - IL_0099: endfinally + IL_0088: ldloca.s V_4 + IL_008a: constrained. "System.Collections.Generic.List.Enumerator" + IL_0090: callvirt "void System.IDisposable.Dispose()" + IL_0095: endfinally } - IL_009a: ldloc.3 - IL_009b: ldc.i4.0 - IL_009c: call "void CollectionExtensions.Report(object, bool)" - IL_00a1: ret + IL_0096: ldloc.3 + IL_0097: ldc.i4.0 + IL_0098: call "void CollectionExtensions.Report(object, bool)" + IL_009d: ret } """); } @@ -20376,7 +20372,7 @@ static void Main() { verifier.VerifyIL("Program.F(T, T, T)", """ { - // Code size 82 (0x52) + // Code size 78 (0x4e) .maxstack 3 .locals init (int V_0, System.Span V_1, @@ -20419,11 +20415,7 @@ .locals init (int V_0, IL_0046: ldarg.2 IL_0047: box "T" IL_004c: stind.ref - IL_004d: ldloc.2 - IL_004e: ldc.i4.1 - IL_004f: add - IL_0050: stloc.2 - IL_0051: ret + IL_004d: ret } """); } @@ -21931,7 +21923,7 @@ static void Main() verifier.VerifyIL("Program.F1", """ { - // Code size 39 (0x27) + // Code size 35 (0x23) .maxstack 3 .locals init (int V_0, System.Span V_1, @@ -21953,11 +21945,7 @@ .locals init (int V_0, IL_001b: call "ref object System.Span.this[int].get" IL_0020: ldarg.0 IL_0021: stind.ref - IL_0022: ldloc.2 - IL_0023: ldc.i4.1 - IL_0024: add - IL_0025: stloc.2 - IL_0026: ret + IL_0022: ret } """); verifier.VerifyIL("Program.F2", @@ -25064,7 +25052,7 @@ public void TopLevelStatement_01() expectedOutput: IncludeExpectedOutput("[1, null, 3], ")); verifier.VerifyIL("", """ { - // Code size 155 (0x9b) + // Code size 151 (0x97) .maxstack 3 .locals init (System.ReadOnlySpan V_0, //y <>y__InlineArray2 V_1, @@ -25122,18 +25110,14 @@ .locals init (System.ReadOnlySpan V_0, //y IL_0078: ldc.i4.3 IL_0079: box "int" IL_007e: stelem.ref - IL_007f: ldloc.3 - IL_0080: ldc.i4.1 - IL_0081: add - IL_0082: stloc.3 - IL_0083: ldloca.s V_0 - IL_0085: ldloc.s V_4 - IL_0087: call "System.ReadOnlySpan..ctor(object[])" - IL_008c: ldloca.s V_0 - IL_008e: call "void CollectionExtensions.Report(in System.ReadOnlySpan)" - IL_0093: ldloca.s V_0 - IL_0095: call "int System.ReadOnlySpan.Length.get" - IL_009a: ret + IL_007f: ldloca.s V_0 + IL_0081: ldloc.s V_4 + IL_0083: call "System.ReadOnlySpan..ctor(object[])" + IL_0088: ldloca.s V_0 + IL_008a: call "void CollectionExtensions.Report(in System.ReadOnlySpan)" + IL_008f: ldloca.s V_0 + IL_0091: call "int System.ReadOnlySpan.Length.get" + IL_0096: ret } """); } @@ -34675,7 +34659,7 @@ static void M(List e1) verifier.VerifyDiagnostics(); verifier.VerifyIL("C.M", """ { - // Code size 161 (0xa1) + // Code size 155 (0x9b) .maxstack 5 .locals init (int V_0, //i System.Collections.Generic.List V_1, @@ -34744,13 +34728,9 @@ .locals init (int V_0, //i IL_008d: call "ref int System.Span.this[int].get" IL_0092: ldloc.0 IL_0093: stind.i4 - IL_0094: ldloc.s V_5 - IL_0096: ldc.i4.1 - IL_0097: add - IL_0098: stloc.s V_5 - IL_009a: ldc.i4.0 - IL_009b: call "void CollectionExtensions.Report(object, bool)" - IL_00a0: ret + IL_0094: ldc.i4.0 + IL_0095: call "void CollectionExtensions.Report(object, bool)" + IL_009a: ret } """); @@ -35256,17 +35236,18 @@ static async Task M2() verifier.VerifyDiagnostics(); verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ { - // Code size 544 (0x220) + // Code size 498 (0x1f2) .maxstack 4 .locals init (int V_0, System.Collections.Generic.List V_1, //items int[] V_2, int[] V_3, - System.Span V_4, - System.ReadOnlySpan V_5, - System.Runtime.CompilerServices.TaskAwaiter V_6, - System.Span V_7, - System.Exception V_8) + int V_4, + System.Span V_5, + System.ReadOnlySpan V_6, + System.Runtime.CompilerServices.TaskAwaiter V_7, + System.Span V_8, + System.Exception V_9) IL_0000: ldarg.0 IL_0001: ldfld "int C.
d__0.<>1__state" IL_0006: stloc.0 @@ -35276,7 +35257,7 @@ .locals init (int V_0, IL_0008: brfalse.s IL_005f IL_000a: ldloc.0 IL_000b: ldc.i4.1 - IL_000c: beq IL_0185 + IL_000c: beq IL_0165 IL_0011: ldc.i4.1 IL_0012: newobj "System.Collections.Generic.List..ctor(int)" IL_0017: dup @@ -35288,8 +35269,8 @@ .locals init (int V_0, IL_0021: stfld "System.Collections.Generic.List C.
d__0.<>7__wrap3" IL_0026: call "System.Threading.Tasks.Task C.M2()" IL_002b: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" - IL_0030: stloc.s V_6 - IL_0032: ldloca.s V_6 + IL_0030: stloc.s V_7 + IL_0032: ldloca.s V_7 IL_0034: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" IL_0039: brtrue.s IL_007c IL_003b: ldarg.0 @@ -35298,17 +35279,17 @@ .locals init (int V_0, IL_003e: stloc.0 IL_003f: stfld "int C.
d__0.<>1__state" IL_0044: ldarg.0 - IL_0045: ldloc.s V_6 + IL_0045: ldloc.s V_7 IL_0047: stfld "System.Runtime.CompilerServices.TaskAwaiter C.
d__0.<>u__1" IL_004c: ldarg.0 IL_004d: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" - IL_0052: ldloca.s V_6 + IL_0052: ldloca.s V_7 IL_0054: ldarg.0 IL_0055: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.
d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.
d__0)" - IL_005a: leave IL_021f + IL_005a: leave IL_01f1 IL_005f: ldarg.0 IL_0060: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.
d__0.<>u__1" - IL_0065: stloc.s V_6 + IL_0065: stloc.s V_7 IL_0067: ldarg.0 IL_0068: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.
d__0.<>u__1" IL_006d: initobj "System.Runtime.CompilerServices.TaskAwaiter" @@ -35317,161 +35298,147 @@ .locals init (int V_0, IL_0075: dup IL_0076: stloc.0 IL_0077: stfld "int C.
d__0.<>1__state" - IL_007c: ldloca.s V_6 + IL_007c: ldloca.s V_7 IL_007e: call "int[] System.Runtime.CompilerServices.TaskAwaiter.GetResult()" IL_0083: stloc.3 - IL_0084: ldarg.0 - IL_0085: ldc.i4.0 - IL_0086: stfld "int C.
d__0.<>7__wrap4" - IL_008b: ldarg.0 - IL_008c: ldc.i4.1 - IL_008d: ldarg.0 - IL_008e: ldfld "System.Collections.Generic.List C.
d__0.<>7__wrap3" - IL_0093: callvirt "int System.Collections.Generic.List.Count.get" - IL_0098: ldloc.3 - IL_0099: ldlen - IL_009a: conv.i4 - IL_009b: add - IL_009c: add - IL_009d: newarr "int" - IL_00a2: stfld "int[] C.
d__0.<>7__wrap5" - IL_00a7: ldarg.0 - IL_00a8: ldfld "System.Collections.Generic.List C.
d__0.<>7__wrap3" - IL_00ad: call "System.Span System.Runtime.InteropServices.CollectionsMarshal.AsSpan(System.Collections.Generic.List)" - IL_00b2: stloc.s V_4 - IL_00b4: ldloca.s V_4 - IL_00b6: ldarg.0 - IL_00b7: ldfld "int[] C.
d__0.<>7__wrap5" - IL_00bc: newobj "System.Span..ctor(int[])" - IL_00c1: stloc.s V_7 - IL_00c3: ldloca.s V_7 - IL_00c5: ldarg.0 - IL_00c6: ldfld "int C.
d__0.<>7__wrap4" - IL_00cb: ldloca.s V_4 - IL_00cd: call "int System.Span.Length.get" - IL_00d2: call "System.Span System.Span.Slice(int, int)" - IL_00d7: call "void System.Span.CopyTo(System.Span)" - IL_00dc: ldarg.0 - IL_00dd: ldarg.0 - IL_00de: ldfld "int C.
d__0.<>7__wrap4" - IL_00e3: ldloca.s V_4 - IL_00e5: call "int System.Span.Length.get" - IL_00ea: add - IL_00eb: stfld "int C.
d__0.<>7__wrap4" - IL_00f0: ldloc.3 - IL_00f1: newobj "System.ReadOnlySpan..ctor(int[])" - IL_00f6: stloc.s V_5 - IL_00f8: ldloca.s V_5 - IL_00fa: ldarg.0 - IL_00fb: ldfld "int[] C.
d__0.<>7__wrap5" - IL_0100: newobj "System.Span..ctor(int[])" - IL_0105: stloc.s V_7 - IL_0107: ldloca.s V_7 - IL_0109: ldarg.0 - IL_010a: ldfld "int C.
d__0.<>7__wrap4" - IL_010f: ldloca.s V_5 - IL_0111: call "int System.ReadOnlySpan.Length.get" - IL_0116: call "System.Span System.Span.Slice(int, int)" - IL_011b: call "void System.ReadOnlySpan.CopyTo(System.Span)" - IL_0120: ldarg.0 - IL_0121: ldarg.0 - IL_0122: ldfld "int C.
d__0.<>7__wrap4" - IL_0127: ldloca.s V_5 - IL_0129: call "int System.ReadOnlySpan.Length.get" - IL_012e: add - IL_012f: stfld "int C.
d__0.<>7__wrap4" - IL_0134: ldarg.0 - IL_0135: ldarg.0 - IL_0136: ldfld "int[] C.
d__0.<>7__wrap5" - IL_013b: stfld "int[] C.
d__0.<>7__wrap1" - IL_0140: ldarg.0 + IL_0084: ldc.i4.0 + IL_0085: stloc.s V_4 + IL_0087: ldarg.0 + IL_0088: ldc.i4.1 + IL_0089: ldarg.0 + IL_008a: ldfld "System.Collections.Generic.List C.
d__0.<>7__wrap3" + IL_008f: callvirt "int System.Collections.Generic.List.Count.get" + IL_0094: ldloc.3 + IL_0095: ldlen + IL_0096: conv.i4 + IL_0097: add + IL_0098: add + IL_0099: newarr "int" + IL_009e: stfld "int[] C.
d__0.<>7__wrap4" + IL_00a3: ldarg.0 + IL_00a4: ldfld "System.Collections.Generic.List C.
d__0.<>7__wrap3" + IL_00a9: call "System.Span System.Runtime.InteropServices.CollectionsMarshal.AsSpan(System.Collections.Generic.List)" + IL_00ae: stloc.s V_5 + IL_00b0: ldloca.s V_5 + IL_00b2: ldarg.0 + IL_00b3: ldfld "int[] C.
d__0.<>7__wrap4" + IL_00b8: newobj "System.Span..ctor(int[])" + IL_00bd: stloc.s V_8 + IL_00bf: ldloca.s V_8 + IL_00c1: ldloc.s V_4 + IL_00c3: ldloca.s V_5 + IL_00c5: call "int System.Span.Length.get" + IL_00ca: call "System.Span System.Span.Slice(int, int)" + IL_00cf: call "void System.Span.CopyTo(System.Span)" + IL_00d4: ldloc.s V_4 + IL_00d6: ldloca.s V_5 + IL_00d8: call "int System.Span.Length.get" + IL_00dd: add + IL_00de: stloc.s V_4 + IL_00e0: ldloc.3 + IL_00e1: newobj "System.ReadOnlySpan..ctor(int[])" + IL_00e6: stloc.s V_6 + IL_00e8: ldloca.s V_6 + IL_00ea: ldarg.0 + IL_00eb: ldfld "int[] C.
d__0.<>7__wrap4" + IL_00f0: newobj "System.Span..ctor(int[])" + IL_00f5: stloc.s V_8 + IL_00f7: ldloca.s V_8 + IL_00f9: ldloc.s V_4 + IL_00fb: ldloca.s V_6 + IL_00fd: call "int System.ReadOnlySpan.Length.get" + IL_0102: call "System.Span System.Span.Slice(int, int)" + IL_0107: call "void System.ReadOnlySpan.CopyTo(System.Span)" + IL_010c: ldloc.s V_4 + IL_010e: ldloca.s V_6 + IL_0110: call "int System.ReadOnlySpan.Length.get" + IL_0115: add + IL_0116: stloc.s V_4 + IL_0118: ldarg.0 + IL_0119: ldarg.0 + IL_011a: ldfld "int[] C.
d__0.<>7__wrap4" + IL_011f: stfld "int[] C.
d__0.<>7__wrap1" + IL_0124: ldarg.0 + IL_0125: ldloc.s V_4 + IL_0127: stfld "int C.
d__0.<>7__wrap2" + IL_012c: call "System.Threading.Tasks.Task C.M2()" + IL_0131: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_0136: stloc.s V_7 + IL_0138: ldloca.s V_7 + IL_013a: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_013f: brtrue.s IL_0182 IL_0141: ldarg.0 - IL_0142: ldfld "int C.
d__0.<>7__wrap4" - IL_0147: stfld "int C.
d__0.<>7__wrap2" - IL_014c: call "System.Threading.Tasks.Task C.M2()" - IL_0151: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" - IL_0156: stloc.s V_6 - IL_0158: ldloca.s V_6 - IL_015a: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" - IL_015f: brtrue.s IL_01a2 - IL_0161: ldarg.0 - IL_0162: ldc.i4.1 - IL_0163: dup - IL_0164: stloc.0 - IL_0165: stfld "int C.
d__0.<>1__state" - IL_016a: ldarg.0 - IL_016b: ldloc.s V_6 - IL_016d: stfld "System.Runtime.CompilerServices.TaskAwaiter C.
d__0.<>u__1" - IL_0172: ldarg.0 - IL_0173: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" - IL_0178: ldloca.s V_6 - IL_017a: ldarg.0 - IL_017b: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.
d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.
d__0)" - IL_0180: leave IL_021f - IL_0185: ldarg.0 - IL_0186: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.
d__0.<>u__1" - IL_018b: stloc.s V_6 - IL_018d: ldarg.0 - IL_018e: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.
d__0.<>u__1" - IL_0193: initobj "System.Runtime.CompilerServices.TaskAwaiter" - IL_0199: ldarg.0 - IL_019a: ldc.i4.m1 - IL_019b: dup - IL_019c: stloc.0 - IL_019d: stfld "int C.
d__0.<>1__state" - IL_01a2: ldloca.s V_6 - IL_01a4: call "int[] System.Runtime.CompilerServices.TaskAwaiter.GetResult()" - IL_01a9: stloc.2 - IL_01aa: ldarg.0 - IL_01ab: ldfld "int[] C.
d__0.<>7__wrap1" - IL_01b0: ldarg.0 - IL_01b1: ldfld "int C.
d__0.<>7__wrap2" - IL_01b6: ldloc.2 - IL_01b7: ldc.i4.0 - IL_01b8: ldelem.i4 - IL_01b9: stelem.i4 - IL_01ba: ldarg.0 - IL_01bb: ldarg.0 - IL_01bc: ldfld "int C.
d__0.<>7__wrap4" - IL_01c1: ldc.i4.1 - IL_01c2: add - IL_01c3: stfld "int C.
d__0.<>7__wrap4" - IL_01c8: ldarg.0 - IL_01c9: ldfld "int[] C.
d__0.<>7__wrap5" - IL_01ce: ldarg.0 - IL_01cf: ldnull - IL_01d0: stfld "int[] C.
d__0.<>7__wrap1" - IL_01d5: ldarg.0 - IL_01d6: ldnull - IL_01d7: stfld "System.Collections.Generic.List C.
d__0.<>7__wrap3" - IL_01dc: ldarg.0 - IL_01dd: ldnull - IL_01de: stfld "int[] C.
d__0.<>7__wrap5" - IL_01e3: call "System.ReadOnlySpan System.ReadOnlySpan.op_Implicit(int[])" - IL_01e8: stloc.s V_5 - IL_01ea: ldloca.s V_5 - IL_01ec: call "void CollectionExtensions.Report(in System.ReadOnlySpan)" - IL_01f1: leave.s IL_020c + IL_0142: ldc.i4.1 + IL_0143: dup + IL_0144: stloc.0 + IL_0145: stfld "int C.
d__0.<>1__state" + IL_014a: ldarg.0 + IL_014b: ldloc.s V_7 + IL_014d: stfld "System.Runtime.CompilerServices.TaskAwaiter C.
d__0.<>u__1" + IL_0152: ldarg.0 + IL_0153: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_0158: ldloca.s V_7 + IL_015a: ldarg.0 + IL_015b: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.
d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.
d__0)" + IL_0160: leave IL_01f1 + IL_0165: ldarg.0 + IL_0166: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.
d__0.<>u__1" + IL_016b: stloc.s V_7 + IL_016d: ldarg.0 + IL_016e: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.
d__0.<>u__1" + IL_0173: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_0179: ldarg.0 + IL_017a: ldc.i4.m1 + IL_017b: dup + IL_017c: stloc.0 + IL_017d: stfld "int C.
d__0.<>1__state" + IL_0182: ldloca.s V_7 + IL_0184: call "int[] System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_0189: stloc.2 + IL_018a: ldarg.0 + IL_018b: ldfld "int[] C.
d__0.<>7__wrap1" + IL_0190: ldarg.0 + IL_0191: ldfld "int C.
d__0.<>7__wrap2" + IL_0196: ldloc.2 + IL_0197: ldc.i4.0 + IL_0198: ldelem.i4 + IL_0199: stelem.i4 + IL_019a: ldarg.0 + IL_019b: ldfld "int[] C.
d__0.<>7__wrap4" + IL_01a0: ldarg.0 + IL_01a1: ldnull + IL_01a2: stfld "int[] C.
d__0.<>7__wrap1" + IL_01a7: ldarg.0 + IL_01a8: ldnull + IL_01a9: stfld "System.Collections.Generic.List C.
d__0.<>7__wrap3" + IL_01ae: ldarg.0 + IL_01af: ldnull + IL_01b0: stfld "int[] C.
d__0.<>7__wrap4" + IL_01b5: call "System.ReadOnlySpan System.ReadOnlySpan.op_Implicit(int[])" + IL_01ba: stloc.s V_6 + IL_01bc: ldloca.s V_6 + IL_01be: call "void CollectionExtensions.Report(in System.ReadOnlySpan)" + IL_01c3: leave.s IL_01de } catch System.Exception { - IL_01f3: stloc.s V_8 - IL_01f5: ldarg.0 - IL_01f6: ldc.i4.s -2 - IL_01f8: stfld "int C.
d__0.<>1__state" - IL_01fd: ldarg.0 - IL_01fe: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" - IL_0203: ldloc.s V_8 - IL_0205: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" - IL_020a: leave.s IL_021f + IL_01c5: stloc.s V_9 + IL_01c7: ldarg.0 + IL_01c8: ldc.i4.s -2 + IL_01ca: stfld "int C.
d__0.<>1__state" + IL_01cf: ldarg.0 + IL_01d0: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_01d5: ldloc.s V_9 + IL_01d7: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" + IL_01dc: leave.s IL_01f1 } - IL_020c: ldarg.0 - IL_020d: ldc.i4.s -2 - IL_020f: stfld "int C.
d__0.<>1__state" - IL_0214: ldarg.0 - IL_0215: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" - IL_021a: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()" - IL_021f: ret + IL_01de: ldarg.0 + IL_01df: ldc.i4.s -2 + IL_01e1: stfld "int C.
d__0.<>1__state" + IL_01e6: ldarg.0 + IL_01e7: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_01ec: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()" + IL_01f1: ret } """); } @@ -35594,7 +35561,7 @@ static void Main() verifier.VerifyDiagnostics(); verifier.VerifyIL("C.Main", """ { - // Code size 150 (0x96) + // Code size 146 (0x92) .maxstack 4 .locals init (int V_0, System.Span V_1, @@ -35636,47 +35603,43 @@ .locals init (int V_0, IL_0037: call "ref int System.Span.this[int].get" IL_003c: ldc.i4.3 IL_003d: stind.i4 - IL_003e: ldloc.2 - IL_003f: ldc.i4.1 - IL_0040: add - IL_0041: stloc.2 - IL_0042: dup - IL_0043: ldc.i4.0 - IL_0044: call "void CollectionExtensions.Report(object, bool)" - IL_0049: dup - IL_004a: callvirt "int System.Collections.Generic.List.Count.get" - IL_004f: stloc.2 - IL_0050: ldloc.2 - IL_0051: newobj "System.Collections.Generic.List..ctor(int)" - IL_0056: stloc.3 - IL_0057: ldloc.3 - IL_0058: ldloc.2 - IL_0059: call "void System.Runtime.InteropServices.CollectionsMarshal.SetCount(System.Collections.Generic.List, int)" - IL_005e: ldloc.3 - IL_005f: call "System.Span System.Runtime.InteropServices.CollectionsMarshal.AsSpan(System.Collections.Generic.List)" - IL_0064: stloc.1 - IL_0065: ldc.i4.0 - IL_0066: stloc.0 - IL_0067: call "System.Span System.Runtime.InteropServices.CollectionsMarshal.AsSpan(System.Collections.Generic.List)" - IL_006c: stloc.s V_4 - IL_006e: ldloca.s V_4 - IL_0070: ldloca.s V_1 - IL_0072: ldloc.0 - IL_0073: ldloca.s V_4 - IL_0075: call "int System.Span.Length.get" - IL_007a: call "System.Span System.Span.Slice(int, int)" - IL_007f: call "void System.Span.CopyTo(System.Span)" - IL_0084: ldloc.0 - IL_0085: ldloca.s V_4 - IL_0087: call "int System.Span.Length.get" - IL_008c: add - IL_008d: stloc.0 - IL_008e: ldloc.3 - IL_008f: ldc.i4.0 - IL_0090: call "void CollectionExtensions.Report(object, bool)" - IL_0095: ret - } - """); + IL_003e: dup + IL_003f: ldc.i4.0 + IL_0040: call "void CollectionExtensions.Report(object, bool)" + IL_0045: dup + IL_0046: callvirt "int System.Collections.Generic.List.Count.get" + IL_004b: stloc.2 + IL_004c: ldloc.2 + IL_004d: newobj "System.Collections.Generic.List..ctor(int)" + IL_0052: stloc.3 + IL_0053: ldloc.3 + IL_0054: ldloc.2 + IL_0055: call "void System.Runtime.InteropServices.CollectionsMarshal.SetCount(System.Collections.Generic.List, int)" + IL_005a: ldloc.3 + IL_005b: call "System.Span System.Runtime.InteropServices.CollectionsMarshal.AsSpan(System.Collections.Generic.List)" + IL_0060: stloc.1 + IL_0061: ldc.i4.0 + IL_0062: stloc.0 + IL_0063: call "System.Span System.Runtime.InteropServices.CollectionsMarshal.AsSpan(System.Collections.Generic.List)" + IL_0068: stloc.s V_4 + IL_006a: ldloca.s V_4 + IL_006c: ldloca.s V_1 + IL_006e: ldloc.0 + IL_006f: ldloca.s V_4 + IL_0071: call "int System.Span.Length.get" + IL_0076: call "System.Span System.Span.Slice(int, int)" + IL_007b: call "void System.Span.CopyTo(System.Span)" + IL_0080: ldloc.0 + IL_0081: ldloca.s V_4 + IL_0083: call "int System.Span.Length.get" + IL_0088: add + IL_0089: stloc.0 + IL_008a: ldloc.3 + IL_008b: ldc.i4.0 + IL_008c: call "void CollectionExtensions.Report(object, bool)" + IL_0091: ret + } + """); } [Fact] @@ -37365,7 +37328,7 @@ static void Main() // Ideally we'd like to be able to use *both* something like AddRange, *and* AsSpan/CopyTo/etc. while building the same target collection verifier.VerifyIL("C.Main", """ { - // Code size 189 (0xbd) + // Code size 181 (0xb5) .maxstack 3 .locals init (int V_0, System.Span V_1, @@ -37409,74 +37372,66 @@ .locals init (int V_0, IL_0037: call "ref int System.Span.this[int].get" IL_003c: ldc.i4.3 IL_003d: stind.i4 - IL_003e: ldloc.2 - IL_003f: ldc.i4.1 - IL_0040: add - IL_0041: stloc.2 - IL_0042: dup - IL_0043: ldc.i4.0 - IL_0044: call "void CollectionExtensions.Report(object, bool)" - IL_0049: stloc.3 - IL_004a: ldc.i4.1 - IL_004b: ldloc.3 - IL_004c: callvirt "int System.Collections.Generic.ICollection.Count.get" - IL_0051: add - IL_0052: stloc.2 - IL_0053: ldloc.2 - IL_0054: newobj "System.Collections.Generic.List..ctor(int)" - IL_0059: stloc.s V_4 - IL_005b: ldloc.s V_4 - IL_005d: ldloc.2 - IL_005e: call "void System.Runtime.InteropServices.CollectionsMarshal.SetCount(System.Collections.Generic.List, int)" - IL_0063: ldloc.s V_4 - IL_0065: call "System.Span System.Runtime.InteropServices.CollectionsMarshal.AsSpan(System.Collections.Generic.List)" - IL_006a: stloc.1 - IL_006b: ldc.i4.0 - IL_006c: stloc.0 - IL_006d: ldloc.3 - IL_006e: callvirt "System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator()" - IL_0073: stloc.s V_5 + IL_003e: dup + IL_003f: ldc.i4.0 + IL_0040: call "void CollectionExtensions.Report(object, bool)" + IL_0045: stloc.3 + IL_0046: ldc.i4.1 + IL_0047: ldloc.3 + IL_0048: callvirt "int System.Collections.Generic.ICollection.Count.get" + IL_004d: add + IL_004e: stloc.2 + IL_004f: ldloc.2 + IL_0050: newobj "System.Collections.Generic.List..ctor(int)" + IL_0055: stloc.s V_4 + IL_0057: ldloc.s V_4 + IL_0059: ldloc.2 + IL_005a: call "void System.Runtime.InteropServices.CollectionsMarshal.SetCount(System.Collections.Generic.List, int)" + IL_005f: ldloc.s V_4 + IL_0061: call "System.Span System.Runtime.InteropServices.CollectionsMarshal.AsSpan(System.Collections.Generic.List)" + IL_0066: stloc.1 + IL_0067: ldc.i4.0 + IL_0068: stloc.0 + IL_0069: ldloc.3 + IL_006a: callvirt "System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator()" + IL_006f: stloc.s V_5 .try { - IL_0075: br.s IL_008f - IL_0077: ldloc.s V_5 - IL_0079: callvirt "int System.Collections.Generic.IEnumerator.Current.get" - IL_007e: stloc.s V_6 - IL_0080: ldloca.s V_1 - IL_0082: ldloc.0 - IL_0083: call "ref int System.Span.this[int].get" - IL_0088: ldloc.s V_6 - IL_008a: stind.i4 - IL_008b: ldloc.0 - IL_008c: ldc.i4.1 - IL_008d: add - IL_008e: stloc.0 - IL_008f: ldloc.s V_5 - IL_0091: callvirt "bool System.Collections.IEnumerator.MoveNext()" - IL_0096: brtrue.s IL_0077 - IL_0098: leave.s IL_00a6 + IL_0071: br.s IL_008b + IL_0073: ldloc.s V_5 + IL_0075: callvirt "int System.Collections.Generic.IEnumerator.Current.get" + IL_007a: stloc.s V_6 + IL_007c: ldloca.s V_1 + IL_007e: ldloc.0 + IL_007f: call "ref int System.Span.this[int].get" + IL_0084: ldloc.s V_6 + IL_0086: stind.i4 + IL_0087: ldloc.0 + IL_0088: ldc.i4.1 + IL_0089: add + IL_008a: stloc.0 + IL_008b: ldloc.s V_5 + IL_008d: callvirt "bool System.Collections.IEnumerator.MoveNext()" + IL_0092: brtrue.s IL_0073 + IL_0094: leave.s IL_00a2 } finally { + IL_0096: ldloc.s V_5 + IL_0098: brfalse.s IL_00a1 IL_009a: ldloc.s V_5 - IL_009c: brfalse.s IL_00a5 - IL_009e: ldloc.s V_5 - IL_00a0: callvirt "void System.IDisposable.Dispose()" - IL_00a5: endfinally + IL_009c: callvirt "void System.IDisposable.Dispose()" + IL_00a1: endfinally } - IL_00a6: ldloca.s V_1 - IL_00a8: ldloc.0 - IL_00a9: call "ref int System.Span.this[int].get" - IL_00ae: ldc.i4.4 - IL_00af: stind.i4 - IL_00b0: ldloc.0 - IL_00b1: ldc.i4.1 - IL_00b2: add - IL_00b3: stloc.0 - IL_00b4: ldloc.s V_4 - IL_00b6: ldc.i4.0 - IL_00b7: call "void CollectionExtensions.Report(object, bool)" - IL_00bc: ret + IL_00a2: ldloca.s V_1 + IL_00a4: ldloc.0 + IL_00a5: call "ref int System.Span.this[int].get" + IL_00aa: ldc.i4.4 + IL_00ab: stind.i4 + IL_00ac: ldloc.s V_4 + IL_00ae: ldc.i4.0 + IL_00af: call "void CollectionExtensions.Report(object, bool)" + IL_00b4: ret } """); }