From 72b6ff25c3b284722964ac4766be8a7e9aa696d9 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Mon, 1 Oct 2018 22:28:50 -0700 Subject: [PATCH] Test capture --- .../Emit/CodeGen/CodeGenAsyncForeachTests.cs | 58 +++++++++++++++---- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncForeachTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncForeachTests.cs index 45d95d51b44..b3423825bd3 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncForeachTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncForeachTests.cs @@ -727,6 +727,54 @@ class Element "Next(26) Convert(0) NextAsync(26) Dispose(37)", verify: Verification.Skipped); } + [Fact] + public void TestWithCaptureOfIterationVariable() + { + string source = @" +using static System.Console; +using System.Threading.Tasks; +public class C +{ + public static async System.Threading.Tasks.Task Main() + { + System.Action f = null; + foreach await (var i in new C()) + { + Write($""Got({i}) ""); + if (f == null) f = () => Write($""Captured({i})""); + } + f(); + } + public AsyncEnumerator GetAsyncEnumerator() + { + return new AsyncEnumerator(); + } + public sealed class AsyncEnumerator : System.IAsyncDisposable + { + int i = 0; + public int TryGetNext(out bool found) + { + found = i % 10 % 3 != 0; + return found ? i++ : 0; + } + public async Task WaitForNextAsync() + { + i = i + 11; + bool more = await Task.FromResult(i < 30); + return more; + } + public async ValueTask DisposeAsync() + { + await Task.Delay(10); + } + } +}"; + var comp = CreateCompilationWithTasksExtensions(new[] { source, s_interfaces }, options: TestOptions.DebugExe); + comp.VerifyDiagnostics(); + CompileAndVerify(comp, expectedOutput: "Got(11) Got(12) Got(24) Got(25) Captured(11)", + verify: Verification.Skipped); + } + [Fact] public void TestWithGenericIterationVariable() { @@ -3997,21 +4045,11 @@ .maxstack 3 // PROTOTYPE(async-streams) More test ideas - // test with captures: - // int[] values = { 7, 9, 13 }; - // Action f = null; - //foreach (var value in values) - //{ - // if (f == null) f = () => Console.WriteLine("First value: " + value); // captures 7, which ends up printed - //} - // f(); - // review instrumentation // test various things that could go wrong with binding the await for DisposeAsync // Misc other test ideas: // Verify that async-dispose doesn't have a similar bug with struct resource // spec: struct case should be blocked? - // spec: extension methods don't contribute } } -- GitLab