Skip to content

Commit f372b6e

Browse files
authored
Add RuntimeAsyncMethodGenerationAttribute (#77543)
Adds control for whether to use runtime async. The flowchart is as follows: 1. The flag `System.Runtime.CompilerServices.RuntimeFeature.Async` must be present. 2. Assuming that flag is present, we look for the presence of `System.Runtime.CompilerServices.RuntimeAsyncMethodGenerationAttribute` on the method. If that attribute is present, we use the preference expressed in the attribute. The preference does not carry to nested contexts, such as local functions or lambdas. 3. If the attribute is not present, we look for `features:runtime-async=on` on the command line. If that is present, then the feature is on by default. Otherwise, the feature is off.
1 parent c641c52 commit f372b6e

File tree

6 files changed

+484
-14
lines changed

6 files changed

+484
-14
lines changed

src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs

+6-4
Original file line numberDiff line numberDiff line change
@@ -316,9 +316,7 @@ internal bool IsNullableAnalysisEnabledAlways
316316
/// Returns true if this method should be processed with runtime async handling instead
317317
/// of compiler async state machine generation.
318318
/// </summary>
319-
#pragma warning disable IDE0060 // Remove unused parameter
320319
internal bool IsRuntimeAsyncEnabledIn(MethodSymbol method)
321-
#pragma warning restore IDE0060 // Remove unused parameter
322320
{
323321
// PROTOTYPE: EE tests fail this assert, handle and test
324322
//Debug.Assert(ReferenceEquals(method.ContainingAssembly, Assembly));
@@ -327,8 +325,12 @@ internal bool IsRuntimeAsyncEnabledIn(MethodSymbol method)
327325
return false;
328326
}
329327

330-
// PROTOTYPE: Check for attributes that turn on/off the feature member-by-member
331-
return true;
328+
return method switch
329+
{
330+
SourceMethodSymbol { IsRuntimeAsyncEnabledInMethod: ThreeState.True } => true,
331+
SourceMethodSymbol { IsRuntimeAsyncEnabledInMethod: ThreeState.False } => false,
332+
_ => Feature("runtime-async") == "on"
333+
};
332334
}
333335

334336
/// <summary>

src/Compilers/CSharp/Portable/Symbols/Attributes/WellKnownAttributeData/MethodWellKnownAttributeData.cs

+16
Original file line numberDiff line numberDiff line change
@@ -149,5 +149,21 @@ public UnmanagedCallersOnlyAttributeData? UnmanagedCallersOnlyAttributeData
149149
SetDataStored();
150150
}
151151
}
152+
153+
private ThreeState _runtimeAsyncMethodGenerationSetting;
154+
public ThreeState RuntimeAsyncMethodGenerationSetting
155+
{
156+
get
157+
{
158+
VerifySealed(expected: true);
159+
return _runtimeAsyncMethodGenerationSetting;
160+
}
161+
set
162+
{
163+
VerifySealed(expected: false);
164+
_runtimeAsyncMethodGenerationSetting = value;
165+
SetDataStored();
166+
}
167+
}
152168
}
153169
}

src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs

+11
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,14 @@ private void DecodeWellKnownAttributeAppliedToMethod(ref DecodeWellKnownAttribut
651651
arguments.AttributeSyntaxOpt);
652652
}
653653
}
654+
else if (attribute.IsTargetAttribute(AttributeDescription.RuntimeAsyncMethodGenerationAttribute))
655+
{
656+
// PROTOTYPE: Validate langversion? Validate previewness of the runtime feature flag?
657+
arguments.GetOrCreateData<MethodWellKnownAttributeData>().RuntimeAsyncMethodGenerationSetting =
658+
attribute.CommonConstructorArguments[0].DecodeValue<bool>(SpecialType.System_Boolean)
659+
? ThreeState.True
660+
: ThreeState.False;
661+
}
654662
else
655663
{
656664
var compilation = this.DeclaringCompilation;
@@ -661,6 +669,9 @@ private void DecodeWellKnownAttributeAppliedToMethod(ref DecodeWellKnownAttribut
661669
}
662670
}
663671

672+
internal ThreeState IsRuntimeAsyncEnabledInMethod
673+
=> GetDecodedWellKnownAttributeData()?.RuntimeAsyncMethodGenerationSetting ?? ThreeState.Unknown;
674+
664675
internal override ImmutableArray<string> NotNullMembers =>
665676
GetDecodedWellKnownAttributeData()?.NotNullMembers ?? ImmutableArray<string>.Empty;
666677

0 commit comments

Comments
 (0)