Skip to content

Commit 0f0b4b4

Browse files
authored
Use prototype Roslyn compiler for runtime-async (dotnet#115531)
This pulls in the prototype Roslyn compiler from the Roslyn runtime-async prototype branch. Currently the feature in the runtime is gated on a feature flag, so the tests are disabled. To run the tests locally, do the following: Uncomment add_compile_definitions(FEATURE_RUNTIME_ASYNC) - to enable the feature in the product. Remove DisableProjectBuild from src\tests\async\Directory.Build.targets
1 parent 98bb641 commit 0f0b4b4

File tree

39 files changed

+193
-81
lines changed

39 files changed

+193
-81
lines changed

NuGet.config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
<add key="dotnet-libraries-transport" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-libraries-transport/nuget/v3/index.json" />
2020
<add key="dotnet10" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet10/nuget/v3/index.json" />
2121
<add key="dotnet10-transport" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet10-transport/nuget/v3/index.json" />
22+
<!-- Need for prototype Roslyn compiler for runtime-async -->
23+
<add key="general-testing" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/general-testing/nuget/v3/index.json" />
2224
</packageSources>
2325
<auditSources>
2426
<clear />

src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Diagnostics;
55
using System.Reflection;
66
using System.Runtime.InteropServices;
7+
using System.Runtime.Versioning;
78
using System.Threading;
89
using System.Threading.Tasks;
910

@@ -19,6 +20,7 @@ public static partial class AsyncHelpers
1920
// It will not capture/restore any local state that is live across it.
2021
[BypassReadyToRun]
2122
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.Async)]
23+
[RequiresPreviewFeatures]
2224
public static void AwaitAwaiter<TAwaiter>(TAwaiter awaiter) where TAwaiter : INotifyCompletion
2325
{
2426
ref AsyncHelpers.RuntimeAsyncAwaitState state = ref AsyncHelpers.t_runtimeAsyncAwaitState;
@@ -34,6 +36,7 @@ public static void AwaitAwaiter<TAwaiter>(TAwaiter awaiter) where TAwaiter : INo
3436
// It will not capture/restore any local state that is live across it.
3537
[BypassReadyToRun]
3638
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.Async)]
39+
[RequiresPreviewFeatures]
3740
public static void UnsafeAwaitAwaiter<TAwaiter>(TAwaiter awaiter) where TAwaiter : ICriticalNotifyCompletion
3841
{
3942
ref AsyncHelpers.RuntimeAsyncAwaitState state = ref AsyncHelpers.t_runtimeAsyncAwaitState;
@@ -48,6 +51,7 @@ public static void UnsafeAwaitAwaiter<TAwaiter>(TAwaiter awaiter) where TAwaiter
4851
[Intrinsic]
4952
[BypassReadyToRun]
5053
[MethodImpl(MethodImplOptions.Async)]
54+
[RequiresPreviewFeatures]
5155
public static T Await<T>(Task<T> task)
5256
{
5357
TaskAwaiter<T> awaiter = task.GetAwaiter();
@@ -62,6 +66,7 @@ public static T Await<T>(Task<T> task)
6266
[Intrinsic]
6367
[BypassReadyToRun]
6468
[MethodImpl(MethodImplOptions.Async)]
69+
[RequiresPreviewFeatures]
6570
public static void Await(Task task)
6671
{
6772
TaskAwaiter awaiter = task.GetAwaiter();
@@ -76,6 +81,7 @@ public static void Await(Task task)
7681
[Intrinsic]
7782
[BypassReadyToRun]
7883
[MethodImpl(MethodImplOptions.Async)]
84+
[RequiresPreviewFeatures]
7985
public static T Await<T>(ValueTask<T> task)
8086
{
8187
ValueTaskAwaiter<T> awaiter = task.GetAwaiter();
@@ -90,6 +96,7 @@ public static T Await<T>(ValueTask<T> task)
9096
[Intrinsic]
9197
[BypassReadyToRun]
9298
[MethodImpl(MethodImplOptions.Async)]
99+
[RequiresPreviewFeatures]
93100
public static void Await(ValueTask task)
94101
{
95102
ValueTaskAwaiter awaiter = task.GetAwaiter();
@@ -104,6 +111,7 @@ public static void Await(ValueTask task)
104111
[Intrinsic]
105112
[BypassReadyToRun]
106113
[MethodImpl(MethodImplOptions.Async)]
114+
[RequiresPreviewFeatures]
107115
public static void Await(ConfiguredTaskAwaitable configuredAwaitable)
108116
{
109117
ConfiguredTaskAwaitable.ConfiguredTaskAwaiter awaiter = configuredAwaitable.GetAwaiter();
@@ -118,6 +126,7 @@ public static void Await(ConfiguredTaskAwaitable configuredAwaitable)
118126
[Intrinsic]
119127
[BypassReadyToRun]
120128
[MethodImpl(MethodImplOptions.Async)]
129+
[RequiresPreviewFeatures]
121130
public static void Await(ConfiguredValueTaskAwaitable configuredAwaitable)
122131
{
123132
ConfiguredValueTaskAwaitable.ConfiguredValueTaskAwaiter awaiter = configuredAwaitable.GetAwaiter();
@@ -132,6 +141,7 @@ public static void Await(ConfiguredValueTaskAwaitable configuredAwaitable)
132141
[Intrinsic]
133142
[BypassReadyToRun]
134143
[MethodImpl(MethodImplOptions.Async)]
144+
[RequiresPreviewFeatures]
135145
public static T Await<T>(ConfiguredTaskAwaitable<T> configuredAwaitable)
136146
{
137147
ConfiguredTaskAwaitable<T>.ConfiguredTaskAwaiter awaiter = configuredAwaitable.GetAwaiter();
@@ -146,6 +156,7 @@ public static T Await<T>(ConfiguredTaskAwaitable<T> configuredAwaitable)
146156
[Intrinsic]
147157
[BypassReadyToRun]
148158
[MethodImpl(MethodImplOptions.Async)]
159+
[RequiresPreviewFeatures]
149160
public static T Await<T>(ConfiguredValueTaskAwaitable<T> configuredAwaitable)
150161
{
151162
ConfiguredValueTaskAwaitable<T>.ConfiguredValueTaskAwaiter awaiter = configuredAwaitable.GetAwaiter();
@@ -157,15 +168,25 @@ public static T Await<T>(ConfiguredValueTaskAwaitable<T> configuredAwaitable)
157168
return awaiter.GetResult();
158169
}
159170
#else
171+
[RequiresPreviewFeatures]
160172
public static void UnsafeAwaitAwaiter<TAwaiter>(TAwaiter awaiter) where TAwaiter : ICriticalNotifyCompletion { throw new NotImplementedException(); }
173+
[RequiresPreviewFeatures]
161174
public static void AwaitAwaiter<TAwaiter>(TAwaiter awaiter) where TAwaiter : INotifyCompletion { throw new NotImplementedException(); }
175+
[RequiresPreviewFeatures]
162176
public static void Await(System.Threading.Tasks.Task task) { throw new NotImplementedException(); }
177+
[RequiresPreviewFeatures]
163178
public static T Await<T>(System.Threading.Tasks.Task<T> task) { throw new NotImplementedException(); }
179+
[RequiresPreviewFeatures]
164180
public static void Await(System.Threading.Tasks.ValueTask task) { throw new NotImplementedException(); }
181+
[RequiresPreviewFeatures]
165182
public static T Await<T>(System.Threading.Tasks.ValueTask<T> task) { throw new NotImplementedException(); }
183+
[RequiresPreviewFeatures]
166184
public static void Await(System.Runtime.CompilerServices.ConfiguredTaskAwaitable configuredAwaitable) { throw new NotImplementedException(); }
185+
[RequiresPreviewFeatures]
167186
public static void Await(System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable configuredAwaitable) { throw new NotImplementedException(); }
187+
[RequiresPreviewFeatures]
168188
public static T Await<T>(System.Runtime.CompilerServices.ConfiguredTaskAwaitable<T> configuredAwaitable) { throw new NotImplementedException(); }
189+
[RequiresPreviewFeatures]
169190
public static T Await<T>(System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable<T> configuredAwaitable) { throw new NotImplementedException(); }
170191
#endif
171192
}

src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeFeature.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,15 @@ public static bool IsSupported(string feature)
5454
{
5555
return feature switch
5656
{
57-
PortablePdb or CovariantReturnsOfClasses or ByRefFields or ByRefLikeGenerics or UnmanagedSignatureCallingConvention or DefaultImplementationsOfInterfaces or VirtualStaticsInInterfaces or NumericIntPtr => true,
57+
PortablePdb or
58+
CovariantReturnsOfClasses or
59+
ByRefFields or
60+
ByRefLikeGenerics or
61+
UnmanagedSignatureCallingConvention or
62+
DefaultImplementationsOfInterfaces or
63+
VirtualStaticsInInterfaces or
64+
NumericIntPtr => true,
65+
5866
nameof(IsDynamicCodeSupported) => IsDynamicCodeSupported,
5967
nameof(IsDynamicCodeCompiled) => IsDynamicCodeCompiled,
6068
_ => false,

src/libraries/System.Runtime/ref/System.Runtime.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13833,15 +13833,25 @@ public static void RunModuleConstructor(System.ModuleHandle module) { }
1383313833
[System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5007", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
1383413834
public static partial class AsyncHelpers
1383513835
{
13836+
[System.Runtime.Versioning.RequiresPreviewFeaturesAttribute]
1383613837
public static void UnsafeAwaitAwaiter<TAwaiter>(TAwaiter awaiter) where TAwaiter : ICriticalNotifyCompletion { }
13838+
[System.Runtime.Versioning.RequiresPreviewFeaturesAttribute]
1383713839
public static void AwaitAwaiter<TAwaiter>(TAwaiter awaiter) where TAwaiter : INotifyCompletion { }
13840+
[System.Runtime.Versioning.RequiresPreviewFeaturesAttribute]
1383813841
public static void Await(System.Threading.Tasks.Task task) { throw null; }
13842+
[System.Runtime.Versioning.RequiresPreviewFeaturesAttribute]
1383913843
public static T Await<T>(System.Threading.Tasks.Task<T> task) { throw null; }
13844+
[System.Runtime.Versioning.RequiresPreviewFeaturesAttribute]
1384013845
public static void Await(System.Threading.Tasks.ValueTask task) { throw null; }
13846+
[System.Runtime.Versioning.RequiresPreviewFeaturesAttribute]
1384113847
public static T Await<T>(System.Threading.Tasks.ValueTask<T> task) { throw null; }
13848+
[System.Runtime.Versioning.RequiresPreviewFeaturesAttribute]
1384213849
public static void Await(System.Runtime.CompilerServices.ConfiguredTaskAwaitable configuredAwaitable) { throw null; }
13850+
[System.Runtime.Versioning.RequiresPreviewFeaturesAttribute]
1384313851
public static void Await(System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable configuredAwaitable) { throw null; }
13852+
[System.Runtime.Versioning.RequiresPreviewFeaturesAttribute]
1384413853
public static T Await<T>(System.Runtime.CompilerServices.ConfiguredTaskAwaitable<T> configuredAwaitable) { throw null; }
13854+
[System.Runtime.Versioning.RequiresPreviewFeaturesAttribute]
1384513855
public static T Await<T>(System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable<T> configuredAwaitable) { throw null; }
1384613856
}
1384713857
public sealed partial class RuntimeWrappedException : System.Exception

src/tests/Directory.Build.props

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
<Import Project="$(MSBuildThisFileDirectory)\Common\dir.sdkbuild.props" Condition="'$(UsingMicrosoftNETSdk)' == 'true'" />
99
<Import Project="$(MSBuildThisFileDirectory)\Common\dir.common.props" Condition="'$(UsingMicrosoftNETSdk)' != 'true'" />
1010

11+
<PropertyGroup>
12+
<!-- Override the compiler version with a private build that supports runtime-async -->
13+
<MicrosoftNetCompilersToolsetVersion>5.0.0-1.25259.6</MicrosoftNetCompilersToolsetVersion>
14+
</PropertyGroup>
15+
1116
<PropertyGroup>
1217
<RunningOnUnix Condition="('$(RunningOnUnix)' == '') And ('$(MSBuildRuntimeType)' == 'Core') And ('$(OS)'!='Windows_NT')">true</RunningOnUnix>
1318
</PropertyGroup>

src/tests/async/Directory.Build.props

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,9 @@
77
<RunAnalyzers>true</RunAnalyzers>
88
<NoWarn>$(NoWarn);xUnit1013</NoWarn>
99
<EnableNETAnalyzers>false</EnableNETAnalyzers>
10+
<Features>$(Features);runtime-async=on</Features>
1011
</PropertyGroup>
12+
<ItemGroup>
13+
<Compile Include="$(MSBuildThisFileDirectory)RuntimeAsyncMethodGenerationAttribute.cs" />
14+
</ItemGroup>
1115
</Project>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
namespace System.Runtime.CompilerServices;
5+
6+
[AttributeUsage(AttributeTargets.Method)]
7+
public class RuntimeAsyncMethodGenerationAttribute(bool runtimeAsync) : Attribute
8+
{
9+
public bool RuntimeAsync { get; } = runtimeAsync;
10+
}

src/tests/async/awaitingnotasync/awaitingnotasync.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Runtime.CompilerServices;
5-
using System.Runtime.InteropServices;
65
using System.Threading.Tasks;
76
using Xunit;
87

@@ -14,13 +13,15 @@ public static void TestEntryPoint()
1413
AsyncEntryPoint().Wait();
1514
}
1615

16+
[System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)]
1717
private static async Task<T> GetTask<T>(T arg)
1818
{
1919
await Task.Yield();
2020
return arg;
2121
}
2222

2323
// TODO: switch every other scenario to use ValueTask
24+
[System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)]
2425
private static async ValueTask<T> GetValueTask<T>(T arg)
2526
{
2627
await Task.Yield();
@@ -33,13 +34,13 @@ private static async ValueTask<T> GetValueTask<T>(T arg)
3334

3435
private static T sIdentity<T>(T arg) => arg;
3536

36-
private static async2 Task AsyncEntryPoint()
37+
private static async Task AsyncEntryPoint()
3738
{
3839
// static field
3940
sField = GetTask(5);
4041
Assert.Equal(5, await sField);
4142

42-
// property
43+
// property
4344
Assert.Equal(6, await sProp);
4445

4546
// generic identity

src/tests/async/collectible-alc/collectible-alc.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public static void TestEntryPoint()
1717
AsyncEntryPoint().Wait();
1818
}
1919

20-
private static async2 Task AsyncEntryPoint()
20+
private static async Task AsyncEntryPoint()
2121
{
2222
WeakReference wr = await CallFooAsyncAndUnload();
2323

@@ -31,7 +31,7 @@ private static async2 Task AsyncEntryPoint()
3131
}
3232

3333
[MethodImpl(MethodImplOptions.NoInlining)]
34-
private static async2 Task<WeakReference> CallFooAsyncAndUnload()
34+
private static async Task<WeakReference> CallFooAsyncAndUnload()
3535
{
3636
TaskCompletionSource tcs = new();
3737
(Task<string> task, WeakReference wr) = CallFooAsyncInCollectibleALC(tcs.Task);
@@ -63,7 +63,7 @@ private static (Task<string>, WeakReference) CallFooAsyncInCollectibleALC(Task t
6363
}
6464

6565
// Task[] to work around a compiler bug
66-
private static async2 Task<string> FooAsync(Task[] t)
66+
private static async Task<string> FooAsync(Task[] t)
6767
{
6868
await t[0];
6969
return "done";

src/tests/async/cse-array-index-byref/cse-array-index-byref.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@ public static void TestEntryPoint()
1616
Assert.Equal(199_990_000, arr[0]);
1717
}
1818

19+
[System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)]
1920
private static async Task AsyncTestEntryPoint(int[] arr, int index)
2021
{
2122
await HoistedByref(arr, index);
2223
}
2324

2425
[MethodImpl(MethodImplOptions.NoInlining)]
25-
private static async2 Task<int> HoistedByref(int[] arr, int index)
26+
private static async Task<int> HoistedByref(int[] arr, int index)
2627
{
2728
for (int i = 0; i < 20000; i++)
2829
{

0 commit comments

Comments
 (0)