diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs
index 496c04f657904..26c94761926bf 100644
--- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs
+++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs
@@ -27,7 +27,7 @@ internal sealed class AsyncIteratorMethodToStateMachineRewriter : AsyncMethodToS
/// Where should we jump to to continue the execution of disposal path.
///
/// Initially, this is the method's return value label ().
- /// Inside a `try` or `catch` with a `finally`, we'll use the label directly preceding the `finally`.
+ /// Inside a `try` or `catch` with a `finally`, we'll use the label directly following the `finally`.
/// Inside a `try` or `catch` with an extracted `finally`, we will use the label preceding the extracted `finally`.
/// Inside a `finally`, we'll have no/null label (disposal continues without a jump).
///
@@ -351,7 +351,8 @@ private BoundExpressionStatement SetDisposeMode(bool value)
///
/// An async-iterator state machine has a flag indicating "dispose mode".
- /// We enter dispose mode by calling DisposeAsync() when the state machine is paused on a `yield return`.
+ /// We enter dispose mode by calling DisposeAsync() when the state machine is paused on a `yield return`,
+ /// or by reaching a `yield break`.
/// DisposeAsync() will resume execution of the state machine from that state (using existing dispatch mechanism
/// to restore execution from a given state, without executing other code to get there).
///
@@ -366,21 +367,11 @@ private BoundExpressionStatement SetDisposeMode(bool value)
public override BoundNode VisitTryStatement(BoundTryStatement node)
{
var savedDisposalLabel = _currentDisposalLabel;
+ LabelSymbol afterFinally = null;
if (node.FinallyBlockOpt is object)
{
- var finallyEntry = F.GenerateLabel("finallyEntry");
- _currentDisposalLabel = finallyEntry;
-
- // Add finallyEntry label:
- // try
- // {
- // ...
- // finallyEntry:
- // }
-
- node = node.Update(
- tryBlock: F.Block(node.TryBlock, F.Label(finallyEntry)),
- node.CatchBlocks, node.FinallyBlockOpt, node.FinallyLabelOpt, node.PreferFaultHandler);
+ afterFinally = F.GenerateLabel("afterFinally");
+ _currentDisposalLabel = afterFinally;
}
else if (node.FinallyLabelOpt is object)
{
@@ -389,6 +380,14 @@ public override BoundNode VisitTryStatement(BoundTryStatement node)
var result = (BoundStatement)base.VisitTryStatement(node);
+ if (afterFinally != null)
+ {
+ // Append a label immediately after the try-catch-finally statement,
+ // which disposal within `try`/`catch` blocks jumps to in order to pass control flow to the `finally` block implicitly:
+ // tryEnd:
+ result = F.Block(result, F.Label(afterFinally));
+ }
+
_currentDisposalLabel = savedDisposalLabel;
if (node.FinallyBlockOpt != null && _currentDisposalLabel is object)
diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs
index b64cdeddde990..66a25aab0e098 100644
--- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs
@@ -4691,7 +4691,7 @@ public async System.Collections.Generic.IAsyncEnumerator GetAsyncEnumerator
CompileAndVerify(comp, expectedOutput: expectedOutput);
}
- [Theory]
+ [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/79124")]
[InlineData(2, "1 Break Throw Caught Finally END DISPOSAL DONE")]
public void TryFinally_YieldBreakInDisposeMode(int iterations, string expectedOutput)
{
@@ -4728,16 +4728,11 @@ public static async System.Collections.Generic.IAsyncEnumerable M()
}
}";
var comp = CreateCompilationWithAsyncIterator(new[] { Run(iterations), source }, options: TestOptions.DebugExe);
- comp.VerifyDiagnostics();
- var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput,
- verify: Verification.FailsILVerify with
- {
- ILVerifyMessage = "[MoveNext]: Leave into try block. { Offset = 0x11a }"
- });
+ var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """
{
- // Code size 414 (0x19e)
+ // Code size 412 (0x19c)
.maxstack 3
.locals init (int V_0,
System.Runtime.CompilerServices.TaskAwaiter V_1,
@@ -4764,7 +4759,7 @@ .locals init (int V_0,
IL_002c: ldarg.0
IL_002d: ldfld "bool C.d__0.<>w__disposeMode"
IL_0032: brfalse.s IL_0039
- IL_0034: leave IL_0167
+ IL_0034: leave IL_0165
IL_0039: ldarg.0
IL_003a: ldc.i4.m1
IL_003b: dup
@@ -4779,7 +4774,7 @@ .locals init (int V_0,
IL_004d: dup
IL_004e: stloc.0
IL_004f: stfld "int C.d__0.<>1__state"
- IL_0054: leave IL_0190
+ IL_0054: leave IL_018e
IL_0059: ldarg.0
IL_005a: ldc.i4.m1
IL_005b: dup
@@ -4788,7 +4783,7 @@ .locals init (int V_0,
IL_0062: ldarg.0
IL_0063: ldfld "bool C.d__0.<>w__disposeMode"
IL_0068: brfalse.s IL_006f
- IL_006a: leave IL_0167
+ IL_006a: leave IL_0165
IL_006f: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get"
IL_0074: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"
IL_0079: stloc.1
@@ -4811,7 +4806,7 @@ .locals init (int V_0,
IL_009d: ldloca.s V_2
IL_009f: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)"
IL_00a4: nop
- IL_00a5: leave IL_019d
+ IL_00a5: leave IL_019b
IL_00aa: ldarg.0
IL_00ab: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"
IL_00b0: stloc.1
@@ -4840,103 +4835,102 @@ .locals init (int V_0,
IL_00db: ldarg.0
IL_00dc: ldc.i4.1
IL_00dd: stfld "bool C.d__0.<>w__disposeMode"
- IL_00e2: br.s IL_00e4
- IL_00e4: leave.s IL_00f9
+ IL_00e2: leave.s IL_00f7
}
finally
{
- IL_00e6: ldloc.0
- IL_00e7: ldc.i4.m1
- IL_00e8: bne.un.s IL_00f8
- IL_00ea: nop
- IL_00eb: ldstr "Throw "
- IL_00f0: call "void System.Console.Write(string)"
- IL_00f5: nop
- IL_00f6: ldnull
- IL_00f7: throw
- IL_00f8: endfinally
+ IL_00e4: ldloc.0
+ IL_00e5: ldc.i4.m1
+ IL_00e6: bne.un.s IL_00f6
+ IL_00e8: nop
+ IL_00e9: ldstr "Throw "
+ IL_00ee: call "void System.Console.Write(string)"
+ IL_00f3: nop
+ IL_00f4: ldnull
+ IL_00f5: throw
+ IL_00f6: endfinally
}
- IL_00f9: ldarg.0
- IL_00fa: ldfld "bool C.d__0.<>w__disposeMode"
- IL_00ff: brfalse.s IL_0103
- IL_0101: br.s IL_0104
- IL_0103: nop
- IL_0104: leave.s IL_011c
+ IL_00f7: ldarg.0
+ IL_00f8: ldfld "bool C.d__0.<>w__disposeMode"
+ IL_00fd: brfalse.s IL_0101
+ IL_00ff: leave.s IL_012e
+ IL_0101: nop
+ IL_0102: leave.s IL_011a
}
catch object
{
- IL_0106: pop
- IL_0107: nop
- IL_0108: ldstr "Caught "
- IL_010d: call "void System.Console.Write(string)"
- IL_0112: nop
- IL_0113: ldarg.0
- IL_0114: ldc.i4.1
- IL_0115: stfld "bool C.d__0.<>w__disposeMode"
- IL_011a: leave.s IL_0104
+ IL_0104: pop
+ IL_0105: nop
+ IL_0106: ldstr "Caught "
+ IL_010b: call "void System.Console.Write(string)"
+ IL_0110: nop
+ IL_0111: ldarg.0
+ IL_0112: ldc.i4.1
+ IL_0113: stfld "bool C.d__0.<>w__disposeMode"
+ IL_0118: leave.s IL_012e
}
- IL_011c: leave.s IL_0130
+ IL_011a: leave.s IL_012e
}
finally
{
- IL_011e: ldloc.0
- IL_011f: ldc.i4.m1
- IL_0120: bne.un.s IL_012f
- IL_0122: nop
- IL_0123: ldstr "Finally "
- IL_0128: call "void System.Console.Write(string)"
- IL_012d: nop
- IL_012e: nop
- IL_012f: endfinally
+ IL_011c: ldloc.0
+ IL_011d: ldc.i4.m1
+ IL_011e: bne.un.s IL_012d
+ IL_0120: nop
+ IL_0121: ldstr "Finally "
+ IL_0126: call "void System.Console.Write(string)"
+ IL_012b: nop
+ IL_012c: nop
+ IL_012d: endfinally
}
- IL_0130: ldarg.0
- IL_0131: ldfld "bool C.d__0.<>w__disposeMode"
- IL_0136: brfalse.s IL_013a
- IL_0138: leave.s IL_0167
- IL_013a: leave.s IL_0167
+ IL_012e: ldarg.0
+ IL_012f: ldfld "bool C.d__0.<>w__disposeMode"
+ IL_0134: brfalse.s IL_0138
+ IL_0136: leave.s IL_0165
+ IL_0138: leave.s IL_0165
}
catch System.Exception
{
- IL_013c: stloc.3
- IL_013d: ldarg.0
- IL_013e: ldc.i4.s -2
- IL_0140: stfld "int C.d__0.<>1__state"
- IL_0145: ldarg.0
- IL_0146: ldc.i4.0
- IL_0147: stfld "int C.d__0.<>2__current"
- IL_014c: ldarg.0
- IL_014d: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"
- IL_0152: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"
- IL_0157: nop
- IL_0158: ldarg.0
- IL_0159: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"
- IL_015e: ldloc.3
- IL_015f: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)"
- IL_0164: nop
- IL_0165: leave.s IL_019d
+ IL_013a: stloc.3
+ IL_013b: ldarg.0
+ IL_013c: ldc.i4.s -2
+ IL_013e: stfld "int C.d__0.<>1__state"
+ IL_0143: ldarg.0
+ IL_0144: ldc.i4.0
+ IL_0145: stfld "int C.d__0.<>2__current"
+ IL_014a: ldarg.0
+ IL_014b: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"
+ IL_0150: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"
+ IL_0155: nop
+ IL_0156: ldarg.0
+ IL_0157: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"
+ IL_015c: ldloc.3
+ IL_015d: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)"
+ IL_0162: nop
+ IL_0163: leave.s IL_019b
}
- IL_0167: ldarg.0
- IL_0168: ldc.i4.s -2
- IL_016a: stfld "int C.d__0.<>1__state"
- IL_016f: ldarg.0
- IL_0170: ldc.i4.0
- IL_0171: stfld "int C.d__0.<>2__current"
- IL_0176: ldarg.0
- IL_0177: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"
- IL_017c: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"
- IL_0181: nop
- IL_0182: ldarg.0
- IL_0183: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"
- IL_0188: ldc.i4.0
- IL_0189: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"
- IL_018e: nop
- IL_018f: ret
- IL_0190: ldarg.0
- IL_0191: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"
- IL_0196: ldc.i4.1
- IL_0197: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"
- IL_019c: nop
- IL_019d: ret
+ IL_0165: ldarg.0
+ IL_0166: ldc.i4.s -2
+ IL_0168: stfld "int C.d__0.<>1__state"
+ IL_016d: ldarg.0
+ IL_016e: ldc.i4.0
+ IL_016f: stfld "int C.d__0.<>2__current"
+ IL_0174: ldarg.0
+ IL_0175: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"
+ IL_017a: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"
+ IL_017f: nop
+ IL_0180: ldarg.0
+ IL_0181: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"
+ IL_0186: ldc.i4.0
+ IL_0187: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"
+ IL_018c: nop
+ IL_018d: ret
+ IL_018e: ldarg.0
+ IL_018f: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"
+ IL_0194: ldc.i4.1
+ IL_0195: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"
+ IL_019a: nop
+ IL_019b: ret
}
""");
}
@@ -6527,6 +6521,331 @@ public static async System.Collections.Generic.IAsyncEnumerable M()
CompileAndVerify(comp, expectedOutput: expectedOutput);
}
+ [Fact]
+ public void TryFinally_01()
+ {
+ // await in a catch/finally (so the catch and finally are extracted/rewritten), execution path through catch
+ string source = """
+using static System.Console;
+public class C
+{
+ public static async System.Collections.Generic.IAsyncEnumerable M()
+ {
+ yield return 1;
+
+ try
+ {
+ Write("Throw ");
+ throw new System.Exception("thrown");
+ }
+ catch
+ {
+ await System.Threading.Tasks.Task.CompletedTask;
+ Write("Caught ");
+ yield break;
+ }
+ finally
+ {
+ await System.Threading.Tasks.Task.CompletedTask;
+ Write("Finally ");
+ }
+ }
+}
+""";
+ var comp = CreateCompilationWithAsyncIterator(new[] { Run(2), source }, options: TestOptions.DebugExe);
+ var verifier = CompileAndVerify(comp, expectedOutput: "1 Throw Caught Finally END DISPOSAL DONE").VerifyDiagnostics();
+
+ verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """
+{
+ // Code size 647 (0x287)
+ .maxstack 3
+ .locals init (int V_0,
+ object V_1,
+ int V_2,
+ System.Runtime.CompilerServices.TaskAwaiter V_3,
+ C.d__0 V_4,
+ object V_5,
+ System.Runtime.CompilerServices.TaskAwaiter V_6,
+ System.Exception V_7)
+ IL_0000: ldarg.0
+ IL_0001: ldfld "int C.d__0.<>1__state"
+ IL_0006: stloc.0
+ .try
+ {
+ IL_0007: ldloc.0
+ IL_0008: ldc.i4.s -4
+ IL_000a: sub
+ IL_000b: switch (
+ IL_002a,
+ IL_002c,
+ IL_0035,
+ IL_0035,
+ IL_002e,
+ IL_0030)
+ IL_0028: br.s IL_0035
+ IL_002a: br.s IL_0062
+ IL_002c: br.s IL_0035
+ IL_002e: br.s IL_0086
+ IL_0030: br IL_0193
+ IL_0035: ldarg.0
+ IL_0036: ldfld "bool C.d__0.<>w__disposeMode"
+ IL_003b: brfalse.s IL_0042
+ IL_003d: leave IL_0242
+ IL_0042: ldarg.0
+ IL_0043: ldc.i4.m1
+ IL_0044: dup
+ IL_0045: stloc.0
+ IL_0046: stfld "int C.d__0.<>1__state"
+ IL_004b: nop
+ IL_004c: ldarg.0
+ IL_004d: ldc.i4.1
+ IL_004e: stfld "int C.d__0.<>2__current"
+ IL_0053: ldarg.0
+ IL_0054: ldc.i4.s -4
+ IL_0056: dup
+ IL_0057: stloc.0
+ IL_0058: stfld "int C.d__0.<>1__state"
+ IL_005d: leave IL_0279
+ IL_0062: ldarg.0
+ IL_0063: ldc.i4.m1
+ IL_0064: dup
+ IL_0065: stloc.0
+ IL_0066: stfld "int C.d__0.<>1__state"
+ IL_006b: ldarg.0
+ IL_006c: ldfld "bool C.d__0.<>w__disposeMode"
+ IL_0071: brfalse.s IL_0078
+ IL_0073: leave IL_0242
+ IL_0078: ldarg.0
+ IL_0079: ldnull
+ IL_007a: stfld "object C.d__0.<>s__1"
+ IL_007f: ldarg.0
+ IL_0080: ldc.i4.0
+ IL_0081: stfld "int C.d__0.<>s__2"
+ IL_0086: nop
+ .try
+ {
+ IL_0087: ldloc.0
+ IL_0088: brfalse.s IL_008c
+ IL_008a: br.s IL_008e
+ IL_008c: br.s IL_0107
+ IL_008e: ldarg.0
+ IL_008f: ldc.i4.0
+ IL_0090: stfld "int C.d__0.<>s__4"
+ .try
+ {
+ IL_0095: nop
+ IL_0096: ldstr "Throw "
+ IL_009b: call "void System.Console.Write(string)"
+ IL_00a0: nop
+ IL_00a1: ldstr "thrown"
+ IL_00a6: newobj "System.Exception..ctor(string)"
+ IL_00ab: throw
+ }
+ catch object
+ {
+ IL_00ac: stloc.1
+ IL_00ad: ldarg.0
+ IL_00ae: ldloc.1
+ IL_00af: stfld "object C.d__0.<>s__3"
+ IL_00b4: ldarg.0
+ IL_00b5: ldc.i4.1
+ IL_00b6: stfld "int C.d__0.<>s__4"
+ IL_00bb: leave.s IL_00bd
+ }
+ IL_00bd: ldarg.0
+ IL_00be: ldfld "int C.d__0.<>s__4"
+ IL_00c3: stloc.2
+ IL_00c4: ldloc.2
+ IL_00c5: ldc.i4.1
+ IL_00c6: beq.s IL_00ca
+ IL_00c8: br.s IL_013f
+ IL_00ca: nop
+ IL_00cb: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get"
+ IL_00d0: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"
+ IL_00d5: stloc.3
+ IL_00d6: ldloca.s V_3
+ IL_00d8: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"
+ IL_00dd: brtrue.s IL_0123
+ IL_00df: ldarg.0
+ IL_00e0: ldc.i4.0
+ IL_00e1: dup
+ IL_00e2: stloc.0
+ IL_00e3: stfld "int C.d__0.<>1__state"
+ IL_00e8: ldarg.0
+ IL_00e9: ldloc.3
+ IL_00ea: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"
+ IL_00ef: ldarg.0
+ IL_00f0: stloc.s V_4
+ IL_00f2: ldarg.0
+ IL_00f3: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"
+ IL_00f8: ldloca.s V_3
+ IL_00fa: ldloca.s V_4
+ IL_00fc: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)"
+ IL_0101: nop
+ IL_0102: leave IL_0286
+ IL_0107: ldarg.0
+ IL_0108: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"
+ IL_010d: stloc.3
+ IL_010e: ldarg.0
+ IL_010f: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"
+ IL_0114: initobj "System.Runtime.CompilerServices.TaskAwaiter"
+ IL_011a: ldarg.0
+ IL_011b: ldc.i4.m1
+ IL_011c: dup
+ IL_011d: stloc.0
+ IL_011e: stfld "int C.d__0.<>1__state"
+ IL_0123: ldloca.s V_3
+ IL_0125: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"
+ IL_012a: nop
+ IL_012b: ldstr "Caught "
+ IL_0130: call "void System.Console.Write(string)"
+ IL_0135: nop
+ IL_0136: ldarg.0
+ IL_0137: ldc.i4.1
+ IL_0138: stfld "bool C.d__0.<>w__disposeMode"
+ IL_013d: leave.s IL_0154
+ IL_013f: ldarg.0
+ IL_0140: ldnull
+ IL_0141: stfld "object C.d__0.<>s__3"
+ IL_0146: leave.s IL_0154
+ }
+ catch object
+ {
+ IL_0148: stloc.s V_5
+ IL_014a: ldarg.0
+ IL_014b: ldloc.s V_5
+ IL_014d: stfld "object C.d__0.<>s__1"
+ IL_0152: leave.s IL_0154
+ }
+ IL_0154: nop
+ IL_0155: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get"
+ IL_015a: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"
+ IL_015f: stloc.s V_6
+ IL_0161: ldloca.s V_6
+ IL_0163: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"
+ IL_0168: brtrue.s IL_01b0
+ IL_016a: ldarg.0
+ IL_016b: ldc.i4.1
+ IL_016c: dup
+ IL_016d: stloc.0
+ IL_016e: stfld "int C.d__0.<>1__state"
+ IL_0173: ldarg.0
+ IL_0174: ldloc.s V_6
+ IL_0176: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"
+ IL_017b: ldarg.0
+ IL_017c: stloc.s V_4
+ IL_017e: ldarg.0
+ IL_017f: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"
+ IL_0184: ldloca.s V_6
+ IL_0186: ldloca.s V_4
+ IL_0188: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)"
+ IL_018d: nop
+ IL_018e: leave IL_0286
+ IL_0193: ldarg.0
+ IL_0194: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"
+ IL_0199: stloc.s V_6
+ IL_019b: ldarg.0
+ IL_019c: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"
+ IL_01a1: initobj "System.Runtime.CompilerServices.TaskAwaiter"
+ IL_01a7: ldarg.0
+ IL_01a8: ldc.i4.m1
+ IL_01a9: dup
+ IL_01aa: stloc.0
+ IL_01ab: stfld "int C.d__0.<>1__state"
+ IL_01b0: ldloca.s V_6
+ IL_01b2: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"
+ IL_01b7: nop
+ IL_01b8: ldstr "Finally "
+ IL_01bd: call "void System.Console.Write(string)"
+ IL_01c2: nop
+ IL_01c3: nop
+ IL_01c4: ldarg.0
+ IL_01c5: ldfld "object C.d__0.<>s__1"
+ IL_01ca: stloc.s V_5
+ IL_01cc: ldloc.s V_5
+ IL_01ce: brfalse.s IL_01ed
+ IL_01d0: ldloc.s V_5
+ IL_01d2: isinst "System.Exception"
+ IL_01d7: stloc.s V_7
+ IL_01d9: ldloc.s V_7
+ IL_01db: brtrue.s IL_01e0
+ IL_01dd: ldloc.s V_5
+ IL_01df: throw
+ IL_01e0: ldloc.s V_7
+ IL_01e2: call "System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)"
+ IL_01e7: callvirt "void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()"
+ IL_01ec: nop
+ IL_01ed: ldarg.0
+ IL_01ee: ldfld "int C.d__0.<>s__2"
+ IL_01f3: pop
+ IL_01f4: ldarg.0
+ IL_01f5: ldfld "bool C.d__0.<>w__disposeMode"
+ IL_01fa: brfalse.s IL_01fe
+ IL_01fc: leave.s IL_0242
+ IL_01fe: ldarg.0
+ IL_01ff: ldnull
+ IL_0200: stfld "object C.d__0.<>s__1"
+ IL_0205: ldnull
+ IL_0206: throw
+ }
+ catch System.Exception
+ {
+ IL_0207: stloc.s V_7
+ IL_0209: ldarg.0
+ IL_020a: ldc.i4.s -2
+ IL_020c: stfld "int C.d__0.<>1__state"
+ IL_0211: ldarg.0
+ IL_0212: ldnull
+ IL_0213: stfld "object C.d__0.<>s__1"
+ IL_0218: ldarg.0
+ IL_0219: ldnull
+ IL_021a: stfld "object C.d__0.<>s__3"
+ IL_021f: ldarg.0
+ IL_0220: ldc.i4.0
+ IL_0221: stfld "int C.d__0.<>2__current"
+ IL_0226: ldarg.0
+ IL_0227: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"
+ IL_022c: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"
+ IL_0231: nop
+ IL_0232: ldarg.0
+ IL_0233: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"
+ IL_0238: ldloc.s V_7
+ IL_023a: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)"
+ IL_023f: nop
+ IL_0240: leave.s IL_0286
+ }
+ IL_0242: ldarg.0
+ IL_0243: ldc.i4.s -2
+ IL_0245: stfld "int C.d__0.<>1__state"
+ IL_024a: ldarg.0
+ IL_024b: ldnull
+ IL_024c: stfld "object C.d__0.<>s__1"
+ IL_0251: ldarg.0
+ IL_0252: ldnull
+ IL_0253: stfld "object C.d__0.<>s__3"
+ IL_0258: ldarg.0
+ IL_0259: ldc.i4.0
+ IL_025a: stfld "int C.d__0.<>2__current"
+ IL_025f: ldarg.0
+ IL_0260: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"
+ IL_0265: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"
+ IL_026a: nop
+ IL_026b: ldarg.0
+ IL_026c: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"
+ IL_0271: ldc.i4.0
+ IL_0272: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"
+ IL_0277: nop
+ IL_0278: ret
+ IL_0279: ldarg.0
+ IL_027a: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"
+ IL_027f: ldc.i4.1
+ IL_0280: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"
+ IL_0285: nop
+ IL_0286: ret
+}
+""");
+ }
+
[Fact]
public void AsyncIteratorWithAwaitOnly()
{
@@ -11379,8 +11698,8 @@ public static async IAsyncEnumerable AsAsyncEnumerable(this IEnumerable
verify: Verification.Skipped);
verifier.VerifyDiagnostics();
verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """
- {
- // Code size 518 (0x206)
+ {
+ // Code size 520 (0x208)
.maxstack 6
.locals init (int V_0,
T V_1, //item
@@ -11400,7 +11719,7 @@ .locals init (int V_0,
IL_0014: ldarg.0
IL_0015: ldfld "bool C.d__0.<>w__disposeMode"
IL_001a: brfalse.s IL_0021
- IL_001c: leave IL_01a5
+ IL_001c: leave IL_01a7
IL_0021: ldarg.0
IL_0022: ldc.i4.m1
IL_0023: dup
@@ -11457,7 +11776,7 @@ .locals init (int V_0,
IL_00b5: ldloc.0
IL_00b6: ldc.i4.s -4
IL_00b8: beq.s IL_00f0
- IL_00ba: br.s IL_0115
+ IL_00ba: br.s IL_0117
IL_00bc: ldarg.0
IL_00bd: ldfld "bool[] C.d__0.<>7__wrap1"
IL_00c2: ldc.i4.5
@@ -11480,7 +11799,7 @@ .locals init (int V_0,
IL_00e4: dup
IL_00e5: stloc.0
IL_00e6: stfld "int C.d__0.<>1__state"
- IL_00eb: leave IL_01f9
+ IL_00eb: leave IL_01fb
IL_00f0: ldarg.0
IL_00f1: ldc.i4.m1
IL_00f2: dup
@@ -11488,110 +11807,111 @@ .locals init (int V_0,
IL_00f4: stfld "int C.d__0.<>1__state"
IL_00f9: ldarg.0
IL_00fa: ldfld "bool C.d__0.<>w__disposeMode"
- IL_00ff: brtrue.s IL_0122
- IL_0101: ldarg.0
- IL_0102: ldfld "bool[] C.d__0.<>7__wrap1"
- IL_0107: ldc.i4.4
- IL_0108: ldc.i4.1
- IL_0109: stelem.i1
- IL_010a: ldarg.0
- IL_010b: ldflda "System.Threading.CancellationToken C.d__0.cancellationToken"
- IL_0110: call "void System.Threading.CancellationToken.ThrowIfCancellationRequested()"
- IL_0115: ldarg.0
- IL_0116: ldfld "System.Collections.Generic.IEnumerator C.d__0.<>7__wrap2"
- IL_011b: callvirt "bool System.Collections.IEnumerator.MoveNext()"
- IL_0120: brtrue.s IL_00bc
- IL_0122: leave.s IL_013c
+ IL_00ff: brfalse.s IL_0103
+ IL_0101: leave.s IL_013e
+ IL_0103: ldarg.0
+ IL_0104: ldfld "bool[] C.d__0.<>7__wrap1"
+ IL_0109: ldc.i4.4
+ IL_010a: ldc.i4.1
+ IL_010b: stelem.i1
+ IL_010c: ldarg.0
+ IL_010d: ldflda "System.Threading.CancellationToken C.d__0.cancellationToken"
+ IL_0112: call "void System.Threading.CancellationToken.ThrowIfCancellationRequested()"
+ IL_0117: ldarg.0
+ IL_0118: ldfld "System.Collections.Generic.IEnumerator C.d__0.<>7__wrap2"
+ IL_011d: callvirt "bool System.Collections.IEnumerator.MoveNext()"
+ IL_0122: brtrue.s IL_00bc
+ IL_0124: leave.s IL_013e
}
finally
{
- IL_0124: ldloc.0
- IL_0125: ldc.i4.m1
- IL_0126: bne.un.s IL_013b
- IL_0128: ldarg.0
- IL_0129: ldfld "System.Collections.Generic.IEnumerator C.d__0.<>7__wrap2"
- IL_012e: brfalse.s IL_013b
- IL_0130: ldarg.0
- IL_0131: ldfld "System.Collections.Generic.IEnumerator C.d__0.<>7__wrap2"
- IL_0136: callvirt "void System.IDisposable.Dispose()"
- IL_013b: endfinally
+ IL_0126: ldloc.0
+ IL_0127: ldc.i4.m1
+ IL_0128: bne.un.s IL_013d
+ IL_012a: ldarg.0
+ IL_012b: ldfld "System.Collections.Generic.IEnumerator C.d__0.<>7__wrap2"
+ IL_0130: brfalse.s IL_013d
+ IL_0132: ldarg.0
+ IL_0133: ldfld "System.Collections.Generic.IEnumerator C.d__0.<>7__wrap2"
+ IL_0138: callvirt "void System.IDisposable.Dispose()"
+ IL_013d: endfinally
}
- IL_013c: ldarg.0
- IL_013d: ldfld "bool C.d__0.<>w__disposeMode"
- IL_0142: brfalse.s IL_0146
- IL_0144: leave.s IL_01a5
- IL_0146: ldarg.0
- IL_0147: ldnull
- IL_0148: stfld "System.Collections.Generic.IEnumerator C.d__0.<>7__wrap2"
- IL_014d: leave.s IL_01a5
+ IL_013e: ldarg.0
+ IL_013f: ldfld "bool C.d__0.<>w__disposeMode"
+ IL_0144: brfalse.s IL_0148
+ IL_0146: leave.s IL_01a7
+ IL_0148: ldarg.0
+ IL_0149: ldnull
+ IL_014a: stfld "System.Collections.Generic.IEnumerator C.d__0.<>7__wrap2"
+ IL_014f: leave.s IL_01a7
}
catch System.Exception
{
- IL_014f: stloc.2
- IL_0150: ldarg.0
- IL_0151: ldc.i4.s -2
- IL_0153: stfld "int C.d__0.<>1__state"
- IL_0158: ldarg.0
- IL_0159: ldnull
- IL_015a: stfld "bool[] C.d__0.<>7__wrap1"
- IL_015f: ldarg.0
- IL_0160: ldnull
- IL_0161: stfld "System.Collections.Generic.IEnumerator C.d__0.<>7__wrap2"
- IL_0166: ldarg.0
- IL_0167: ldfld "System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"
- IL_016c: brfalse.s IL_0180
- IL_016e: ldarg.0
- IL_016f: ldfld "System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"
- IL_0174: callvirt "void System.Threading.CancellationTokenSource.Dispose()"
- IL_0179: ldarg.0
- IL_017a: ldnull
- IL_017b: stfld "System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"
- IL_0180: ldarg.0
- IL_0181: ldflda "T C.d__0.<>2__current"
- IL_0186: initobj "T"
- IL_018c: ldarg.0
- IL_018d: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"
- IL_0192: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"
- IL_0197: ldarg.0
- IL_0198: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"
- IL_019d: ldloc.2
- IL_019e: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)"
- IL_01a3: leave.s IL_0205
+ IL_0151: stloc.2
+ IL_0152: ldarg.0
+ IL_0153: ldc.i4.s -2
+ IL_0155: stfld "int C.d__0.<>1__state"
+ IL_015a: ldarg.0
+ IL_015b: ldnull
+ IL_015c: stfld "bool[] C.d__0.<>7__wrap1"
+ IL_0161: ldarg.0
+ IL_0162: ldnull
+ IL_0163: stfld "System.Collections.Generic.IEnumerator C.d__0.<>7__wrap2"
+ IL_0168: ldarg.0
+ IL_0169: ldfld "System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"
+ IL_016e: brfalse.s IL_0182
+ IL_0170: ldarg.0
+ IL_0171: ldfld "System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"
+ IL_0176: callvirt "void System.Threading.CancellationTokenSource.Dispose()"
+ IL_017b: ldarg.0
+ IL_017c: ldnull
+ IL_017d: stfld "System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"
+ IL_0182: ldarg.0
+ IL_0183: ldflda "T C.d__0.<>2__current"
+ IL_0188: initobj "T"
+ IL_018e: ldarg.0
+ IL_018f: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"
+ IL_0194: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"
+ IL_0199: ldarg.0
+ IL_019a: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"
+ IL_019f: ldloc.2
+ IL_01a0: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)"
+ IL_01a5: leave.s IL_0207
}
- IL_01a5: ldarg.0
- IL_01a6: ldc.i4.s -2
- IL_01a8: stfld "int C.d__0.<>1__state"
- IL_01ad: ldarg.0
- IL_01ae: ldnull
- IL_01af: stfld "bool[] C.d__0.<>7__wrap1"
- IL_01b4: ldarg.0
- IL_01b5: ldnull
- IL_01b6: stfld "System.Collections.Generic.IEnumerator C.d__0.<>7__wrap2"
- IL_01bb: ldarg.0
- IL_01bc: ldfld "System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"
- IL_01c1: brfalse.s IL_01d5
- IL_01c3: ldarg.0
- IL_01c4: ldfld "System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"
- IL_01c9: callvirt "void System.Threading.CancellationTokenSource.Dispose()"
- IL_01ce: ldarg.0
- IL_01cf: ldnull
- IL_01d0: stfld "System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"
- IL_01d5: ldarg.0
- IL_01d6: ldflda "T C.d__0.<>2__current"
- IL_01db: initobj "T"
- IL_01e1: ldarg.0
- IL_01e2: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"
- IL_01e7: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"
- IL_01ec: ldarg.0
- IL_01ed: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"
- IL_01f2: ldc.i4.0
- IL_01f3: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"
- IL_01f8: ret
- IL_01f9: ldarg.0
- IL_01fa: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"
- IL_01ff: ldc.i4.1
- IL_0200: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"
- IL_0205: ret
+ IL_01a7: ldarg.0
+ IL_01a8: ldc.i4.s -2
+ IL_01aa: stfld "int C.d__0.<>1__state"
+ IL_01af: ldarg.0
+ IL_01b0: ldnull
+ IL_01b1: stfld "bool[] C.d__0.<>7__wrap1"
+ IL_01b6: ldarg.0
+ IL_01b7: ldnull
+ IL_01b8: stfld "System.Collections.Generic.IEnumerator C.d__0.<>7__wrap2"
+ IL_01bd: ldarg.0
+ IL_01be: ldfld "System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"
+ IL_01c3: brfalse.s IL_01d7
+ IL_01c5: ldarg.0
+ IL_01c6: ldfld "System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"
+ IL_01cb: callvirt "void System.Threading.CancellationTokenSource.Dispose()"
+ IL_01d0: ldarg.0
+ IL_01d1: ldnull
+ IL_01d2: stfld "System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"
+ IL_01d7: ldarg.0
+ IL_01d8: ldflda "T C.d__0.<>2__current"
+ IL_01dd: initobj "T"
+ IL_01e3: ldarg.0
+ IL_01e4: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"
+ IL_01e9: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"
+ IL_01ee: ldarg.0
+ IL_01ef: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"
+ IL_01f4: ldc.i4.0
+ IL_01f5: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"
+ IL_01fa: ret
+ IL_01fb: ldarg.0
+ IL_01fc: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"
+ IL_0201: ldc.i4.1
+ IL_0202: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"
+ IL_0207: ret
}
""");
}