We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
await foreach
using System.Threading; using System.Threading.Tasks; struct S1 { public S2 GetAsyncEnumerator(CancellationToken token = default) { return new S2(); } } struct S2 { bool stop; public ValueTask DisposeAsync() { System.Console.Write("D"); return ValueTask.CompletedTask; } public int Current => 123; public async ValueTask<bool> MoveNextAsync() { if (!stop) { stop = true; return true; } return false; } } class C { static async Task Main() { await Test(new S1()); } static async Task Test(S1 s1) { await foreach (var i in s1) { System.Console.Write(i); } } }
Expected output: "123D"
Observed: an infinite loop
If S2 is changed to a class, the code behaves as expected. It is quite possible that generated code makes unexpected copies of the struct.
S2
A generic case also exhibits the same problem:
#nullable disable using System; using System.Threading; using System.Threading.Tasks; interface ICustomEnumerator { public int Current {get;} public ValueTask<bool> MoveNextAsync(); } interface IGetEnumerator<TEnumerator> where TEnumerator : ICustomEnumerator { TEnumerator GetAsyncEnumerator(CancellationToken token = default); } struct S1 : IGetEnumerator<S2> { public S2 GetAsyncEnumerator(CancellationToken token = default) { return new S2(); } } struct S2 : ICustomEnumerator, IAsyncDisposable { bool stop; public ValueTask DisposeAsync() { System.Console.Write("D"); return ValueTask.CompletedTask; } public int Current => 123; public async ValueTask<bool> MoveNextAsync() { if (!stop) { stop = true; return true; } return false; } } class C { static async Task Main() { await Test<S1, S2>(); } static async Task Test<TEnumerable, TEnumerator>() where TEnumerable : IGetEnumerator<TEnumerator> where TEnumerator : ICustomEnumerator, IAsyncDisposable { await foreach (var i in default(TEnumerable)) { System.Console.Write(i); } } }
The text was updated successfully, but these errors were encountered:
CC @jcouv
Sorry, something went wrong.
jcouv
No branches or pull requests
Expected output: "123D"
Observed: an infinite loop
If
S2
is changed to a class, the code behaves as expected. It is quite possible that generated code makes unexpected copies of the struct.A generic case also exhibits the same problem:
The text was updated successfully, but these errors were encountered: