Browse Source

Fix #3908: use the async iterator element type for yield

Yield translation derived its target type only from synchronous enumerable
interfaces, leaving async iterator yields untyped and preserving compiler
boxing casts. Use the element type already recovered by the async decompiler.

Assisted-by: Copilot:gpt-5.6-sol:GitHub Copilot CLI
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 86d2918e-5a24-48b4-9a86-41d331ec3720
pull/3911/head
Sebastien Lebreton 2 months ago
parent
commit
eb6d341866
  1. 33
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncStreams.cs
  2. 3
      ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

33
ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncStreams.cs

@ -6,6 +6,12 @@ using System.Threading.Tasks; @@ -6,6 +6,12 @@ using System.Threading.Tasks;
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
public enum AsyncStreamColor
{
Red,
Green
}
public class AsyncStreams
{
public static async IAsyncEnumerable<int> CountTo(int until)
@ -85,6 +91,33 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -85,6 +91,33 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
await Task.Yield();
}
}
public static async IAsyncEnumerable<IAsyncStreamEntry> ConstrainedGenericYield<T>(IAsyncEnumerable<T> items) where T : IAsyncStreamEntry
{
await foreach (T item in items)
{
yield return item;
}
}
public static IEnumerable<object> BoxedValues()
{
yield return true;
yield return 'a';
yield return AsyncStreamColor.Green;
}
public static async IAsyncEnumerable<object> BoxedValuesAsync()
{
yield return true;
await Task.Yield();
yield return 'a';
yield return AsyncStreamColor.Green;
}
}
public interface IAsyncStreamEntry
{
}
public struct TestStruct

3
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -433,7 +433,8 @@ namespace ICSharpCode.Decompiler.CSharp @@ -433,7 +433,8 @@ namespace ICSharpCode.Decompiler.CSharp
protected internal override TranslatedStatement VisitYieldReturn(YieldReturn inst)
{
var elementType = currentFunction.ReturnType.GetElementTypeFromIEnumerable(typeSystem, true, out var isGeneric);
var elementType = currentFunction.AsyncReturnType
?? currentFunction.ReturnType.GetElementTypeFromIEnumerable(typeSystem, true, out _);
var expr = exprBuilder.Translate(inst.Value, typeHint: elementType)
.ConvertTo(elementType, exprBuilder, allowImplicitConversion: true);
return new YieldReturnStatement {

Loading…
Cancel
Save