Skip to content

Commit d3de70b

Browse files
committed
Use AsyncIteratorMethodBuilder
1 parent 06af4db commit d3de70b

8 files changed

Lines changed: 214 additions & 34 deletions

File tree

src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodBuilderMemberCollection.cs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,41 @@ private AsyncMethodBuilderMemberCollection(
107107

108108
internal static bool TryCreate(SyntheticBoundNodeFactory F, MethodSymbol method, TypeMap typeMap, out AsyncMethodBuilderMemberCollection collection)
109109
{
110-
if (method.IsVoidReturningAsync() || method.IsIterator)
110+
if (method.IsIterator)
111+
{
112+
var builderType = F.WellKnownType(WellKnownType.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder);
113+
Debug.Assert((object)builderType != null);
114+
115+
TryGetBuilderMember<MethodSymbol>(
116+
F,
117+
WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__Create,
118+
builderType,
119+
customBuilder: false,
120+
out MethodSymbol createBuilderMethod);
121+
122+
if (createBuilderMethod is null)
123+
{
124+
collection = default;
125+
return false;
126+
}
127+
128+
return TryCreate(
129+
F,
130+
customBuilder: false,
131+
builderType: builderType,
132+
resultType: F.SpecialType(SpecialType.System_Void),
133+
createBuilderMethod: createBuilderMethod,
134+
taskProperty: null,
135+
setException: 0, // unused
136+
setResult: WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__Complete,
137+
awaitOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__AwaitOnCompleted,
138+
awaitUnsafeOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__AwaitUnsafeOnCompleted,
139+
start: WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__MoveNext_T,
140+
setStateMachine: 0, // unused
141+
collection: out collection);
142+
}
143+
144+
if (method.IsVoidReturningAsync())
111145
{
112146
var builderType = F.WellKnownType(WellKnownType.System_Runtime_CompilerServices_AsyncVoidMethodBuilder);
113147
Debug.Assert((object)builderType != null);
@@ -151,7 +185,7 @@ internal static bool TryCreate(SyntheticBoundNodeFactory F, MethodSymbol method,
151185
bool customBuilder = returnType.IsCustomTaskType(out builderArgument);
152186
if (customBuilder)
153187
{
154-
builderType = ValidateBuilderType(F, builderArgument, returnType.DeclaredAccessibility, isGeneric:false);
188+
builderType = ValidateBuilderType(F, builderArgument, returnType.DeclaredAccessibility, isGeneric: false);
155189
if ((object)builderType != null)
156190
{
157191
taskProperty = GetCustomTaskProperty(F, builderType, returnType);
@@ -219,7 +253,7 @@ internal static bool TryCreate(SyntheticBoundNodeFactory F, MethodSymbol method,
219253
bool customBuilder = returnType.IsCustomTaskType(out builderArgument);
220254
if (customBuilder)
221255
{
222-
builderType = ValidateBuilderType(F, builderArgument, returnType.DeclaredAccessibility, isGeneric:true);
256+
builderType = ValidateBuilderType(F, builderArgument, returnType.DeclaredAccessibility, isGeneric: true);
223257
if ((object)builderType != null)
224258
{
225259
builderType = builderType.ConstructedFrom.Construct(resultType);
@@ -350,6 +384,12 @@ private static bool TryGetBuilderMember<TSymbol>(
350384
out TSymbol symbol)
351385
where TSymbol : Symbol
352386
{
387+
if (member == 0)
388+
{
389+
symbol = null;
390+
return true;
391+
}
392+
353393
if (customBuilder)
354394
{
355395
var descriptor = WellKnownMembers.GetDescriptor(member);

src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,10 @@ .locals init (int V_0,
184184
IL_003e: ldarg.0
185185
IL_003f: stloc.3
186186
IL_0040: ldarg.0
187-
IL_0041: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder C.<M>d__0.<>t__builder""
187+
IL_0041: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.<M>d__0.<>t__builder""
188188
IL_0046: ldloca.s V_2
189189
IL_0048: ldloca.s V_3
190-
IL_004a: call ""void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<System.Threading.Tasks.Task<int>[]>, C.<M>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter<System.Threading.Tasks.Task<int>[]>, ref C.<M>d__0)""
190+
IL_004a: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<System.Threading.Tasks.Task<int>[]>, C.<M>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter<System.Threading.Tasks.Task<int>[]>, ref C.<M>d__0)""
191191
IL_004f: leave IL_0169
192192
IL_0054: ldarg.0
193193
IL_0055: ldfld ""System.Runtime.CompilerServices.TaskAwaiter<System.Threading.Tasks.Task<int>[]> C.<M>d__0.<>u__1""
@@ -231,10 +231,10 @@ .locals init (int V_0,
231231
IL_00b9: ldarg.0
232232
IL_00ba: stloc.3
233233
IL_00bb: ldarg.0
234-
IL_00bc: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder C.<M>d__0.<>t__builder""
234+
IL_00bc: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.<M>d__0.<>t__builder""
235235
IL_00c1: ldloca.s V_5
236236
IL_00c3: ldloca.s V_3
237-
IL_00c5: call ""void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<int>, C.<M>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter<int>, ref C.<M>d__0)""
237+
IL_00c5: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<int>, C.<M>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter<int>, ref C.<M>d__0)""
238238
IL_00ca: leave IL_0169
239239
IL_00cf: ldarg.0
240240
IL_00d0: ldfld ""System.Runtime.CompilerServices.TaskAwaiter<int> C.<M>d__0.<>u__2""
@@ -435,12 +435,37 @@ public static async System.Collections.Generic.IAsyncEnumerator<int> M()
435435
}
436436

437437
[Fact]
438-
public void MissingTypeAndMembers_AsyncVoidMethodBuilder()
438+
public void MissingTypeAndMembers_AsyncIteratorMethodBuilder()
439439
{
440-
VerifyMissingMember(WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__Create,
441-
// (5,64): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create'
440+
VerifyMissingMember(WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__AwaitOnCompleted,
441+
// (5,64): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitOnCompleted'
442442
// async System.Collections.Generic.IAsyncEnumerable<int> M() { await Task.CompletedTask; yield return 3; }
443-
Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "{ await Task.CompletedTask; yield return 3; }").WithArguments("System.Runtime.CompilerServices.AsyncVoidMethodBuilder", "Create").WithLocation(5, 64)
443+
Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "{ await Task.CompletedTask; yield return 3; }").WithArguments("System.Runtime.CompilerServices.AsyncIteratorMethodBuilder", "AwaitOnCompleted").WithLocation(5, 64)
444+
);
445+
446+
VerifyMissingMember(WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__AwaitUnsafeOnCompleted,
447+
448+
// (5,64): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompleted'
449+
// async System.Collections.Generic.IAsyncEnumerable<int> M() { await Task.CompletedTask; yield return 3; }
450+
Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "{ await Task.CompletedTask; yield return 3; }").WithArguments("System.Runtime.CompilerServices.AsyncIteratorMethodBuilder", "AwaitUnsafeOnCompleted").WithLocation(5, 64)
451+
);
452+
453+
VerifyMissingMember(WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__Complete,
454+
// (5,64): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete'
455+
// async System.Collections.Generic.IAsyncEnumerable<int> M() { await Task.CompletedTask; yield return 3; }
456+
Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "{ await Task.CompletedTask; yield return 3; }").WithArguments("System.Runtime.CompilerServices.AsyncIteratorMethodBuilder", "Complete").WithLocation(5, 64)
457+
);
458+
459+
VerifyMissingMember(WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__Create,
460+
// (5,64): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Create'
461+
// async System.Collections.Generic.IAsyncEnumerable<int> M() { await Task.CompletedTask; yield return 3; }
462+
Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "{ await Task.CompletedTask; yield return 3; }").WithArguments("System.Runtime.CompilerServices.AsyncIteratorMethodBuilder", "Create").WithLocation(5, 64)
463+
);
464+
465+
VerifyMissingMember(WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__MoveNext_T,
466+
// (5,64): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.MoveNext'
467+
// async System.Collections.Generic.IAsyncEnumerable<int> M() { await Task.CompletedTask; yield return 3; }
468+
Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "{ await Task.CompletedTask; yield return 3; }").WithArguments("System.Runtime.CompilerServices.AsyncIteratorMethodBuilder", "MoveNext").WithLocation(5, 64)
444469
);
445470
}
446471

@@ -552,12 +577,12 @@ public void MissingTypeAndMembers_IValueTaskSource()
552577
}
553578

554579
[Fact]
555-
public void MissingMember_AsyncVoidMethodBuilder()
580+
public void MissingMember_AsyncIteratorMethodBuilder()
556581
{
557-
VerifyMissingMember(WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__Create,
558-
// (5,64): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create'
582+
VerifyMissingMember(WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__Create,
583+
// (5,64): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Create'
559584
// async System.Collections.Generic.IAsyncEnumerable<int> M() { await Task.CompletedTask; yield return 3; }
560-
Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "{ await Task.CompletedTask; yield return 3; }").WithArguments("System.Runtime.CompilerServices.AsyncVoidMethodBuilder", "Create").WithLocation(5, 64)
585+
Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "{ await Task.CompletedTask; yield return 3; }").WithArguments("System.Runtime.CompilerServices.AsyncIteratorMethodBuilder", "Create").WithLocation(5, 64)
561586
);
562587
}
563588

@@ -577,9 +602,6 @@ public void MissingTypeAndMembers_IAsyncStateMachine()
577602
);
578603

579604
VerifyMissingType(WellKnownType.System_Runtime_CompilerServices_IAsyncStateMachine,
580-
// (5,64): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetStateMachine'
581-
// async System.Collections.Generic.IAsyncEnumerable<int> M() { await Task.CompletedTask; yield return 3; }
582-
Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "{ await Task.CompletedTask; yield return 3; }").WithArguments("System.Runtime.CompilerServices.AsyncVoidMethodBuilder", "SetStateMachine").WithLocation(5, 64),
583605
// (5,64): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext'
584606
// async System.Collections.Generic.IAsyncEnumerable<int> M() { await Task.CompletedTask; yield return 3; }
585607
Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "{ await Task.CompletedTask; yield return 3; }").WithArguments("System.Runtime.CompilerServices.IAsyncStateMachine", "MoveNext").WithLocation(5, 64),
@@ -1166,8 +1188,8 @@ .maxstack 2
11661188
IL_000f: call ""int System.Environment.CurrentManagedThreadId.get""
11671189
IL_0014: stfld ""int C.<M>d__0.<>l__initialThreadId""
11681190
IL_0019: ldarg.0
1169-
IL_001a: call ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create()""
1170-
IL_001f: stfld ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder C.<M>d__0.<>t__builder""
1191+
IL_001a: call ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Create()""
1192+
IL_001f: stfld ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.<M>d__0.<>t__builder""
11711193
IL_0024: ret
11721194
}", sequencePoints: "C+<M>d__0..ctor", source: source);
11731195
}
@@ -1186,8 +1208,8 @@ .maxstack 2
11861208
IL_000e: call ""int System.Environment.CurrentManagedThreadId.get""
11871209
IL_0013: stfld ""int C.<M>d__0.<>l__initialThreadId""
11881210
IL_0018: ldarg.0
1189-
IL_0019: call ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create()""
1190-
IL_001e: stfld ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder C.<M>d__0.<>t__builder""
1211+
IL_0019: call ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Create()""
1212+
IL_001e: stfld ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.<M>d__0.<>t__builder""
11911213
IL_0023: ret
11921214
}", sequencePoints: "C+<M>d__0..ctor", source: source);
11931215
}
@@ -1220,9 +1242,9 @@ .locals init (C.<M>d__0 V_0,
12201242
IL_001f: ldarg.0
12211243
IL_0020: stloc.0
12221244
IL_0021: ldarg.0
1223-
IL_0022: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder C.<M>d__0.<>t__builder""
1245+
IL_0022: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.<M>d__0.<>t__builder""
12241246
IL_0027: ldloca.s V_0
1225-
IL_0029: call ""void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Start<C.<M>d__0>(ref C.<M>d__0)""
1247+
IL_0029: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.MoveNext<C.<M>d__0>(ref C.<M>d__0)""
12261248
IL_002e: ldarg.0
12271249
IL_002f: ldarg.0
12281250
IL_0030: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore<bool> C.<M>d__0.<>v__promiseOfValueOrEnd""
@@ -1236,8 +1258,8 @@ .locals init (C.<M>d__0 V_0,
12361258
.maxstack 2
12371259
.locals init (System.Threading.Tasks.ValueTask V_0)
12381260
IL_0000: ldarg.0
1239-
IL_0001: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder C.<M>d__0.<>t__builder""
1240-
IL_0006: call ""void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetResult()""
1261+
IL_0001: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.<M>d__0.<>t__builder""
1262+
IL_0006: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()""
12411263
IL_000b: ldarg.0
12421264
IL_000c: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore<bool> C.<M>d__0.<>v__promiseOfValueOrEnd""
12431265
IL_0011: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore<bool>.Reset()""
@@ -1366,10 +1388,10 @@ .locals init (int V_0,
13661388
IL_0049: ldarg.0
13671389
IL_004a: stloc.2
13681390
IL_004b: ldarg.0
1369-
IL_004c: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder C.<M>d__0.<>t__builder""
1391+
IL_004c: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.<M>d__0.<>t__builder""
13701392
IL_0051: ldloca.s V_1
13711393
IL_0053: ldloca.s V_2
1372-
IL_0055: call ""void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter, C.<M>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.<M>d__0)""
1394+
IL_0055: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter, C.<M>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.<M>d__0)""
13731395
IL_005a: nop
13741396
IL_005b: leave IL_00e6
13751397
// async: resume
@@ -1482,10 +1504,10 @@ .locals init (int V_0,
14821504
IL_003f: ldarg.0
14831505
IL_0040: stloc.2
14841506
IL_0041: ldarg.0
1485-
IL_0042: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder C.<M>d__0.<>t__builder""
1507+
IL_0042: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.<M>d__0.<>t__builder""
14861508
IL_0047: ldloca.s V_1
14871509
IL_0049: ldloca.s V_2
1488-
IL_004b: call ""void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter, C.<M>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.<M>d__0)""
1510+
IL_004b: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter, C.<M>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.<M>d__0)""
14891511
IL_0050: leave IL_00d5
14901512
// async: resume
14911513
IL_0055: ldarg.0

src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,7 @@ public void AllWellKnownTypes()
575575
case WellKnownType.System_Threading_Tasks_Sources_IValueTaskSource_T:
576576
case WellKnownType.System_Threading_Tasks_ValueTask_T:
577577
case WellKnownType.System_Threading_Tasks_ValueTask:
578+
case WellKnownType.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder:
578579
// Not yet in the platform.
579580
case WellKnownType.Microsoft_CodeAnalysis_Runtime_Instrumentation:
580581
// Not always available.
@@ -903,7 +904,14 @@ public void AllWellKnownTypeMembers()
903904
case WellKnownMember.System_Threading_Tasks_Sources_ManualResetValueTaskSourceCore_T__SetException:
904905
case WellKnownMember.System_Threading_Tasks_Sources_IValueTaskSource_T__GetStatus:
905906
case WellKnownMember.System_Threading_Tasks_Sources_IValueTaskSource_T__OnCompleted:
907+
case WellKnownMember.System_Threading_Tasks_Sources_IValueTaskSource_T__GetResult:
906908
case WellKnownMember.System_Threading_Tasks_ValueTask_T__ctor:
909+
case WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__AwaitOnCompleted:
910+
case WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__AwaitUnsafeOnCompleted:
911+
case WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__Complete:
912+
case WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__Create:
913+
case WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__MoveNext_T:
914+
case WellKnownMember.System_Runtime_CompilerServices_AsyncStateMachineAttribute__ctor:
907915
// Not yet in the platform.
908916
continue;
909917
case WellKnownMember.Microsoft_CodeAnalysis_Runtime_Instrumentation__CreatePayloadForMethodsSpanningSingleFile:

0 commit comments

Comments
 (0)