-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
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
Allow overriding the AsyncMethodBuilder on methods #54033
Conversation
/// Returns true if the method has a [AsyncMethodBuilder(typeof(B))] attribute. If so it returns the "B". | ||
/// Validation of builder type B is left for elsewhere. This method returns B without validation of any kind. | ||
/// </summary> | ||
internal static bool HasMethodLevelBuilder(this MethodSymbol method, [NotNullWhen(true)] out object? builderArgument) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm looking at one usage of IsCustomTaskType
in BoundLambda.CalculateReturnType
which I need to think more about.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't understand the comment about CalculateReturnType
. Could we share this implementation with TypeSymbolExtensions.IsCustomTaskType()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment about CalculateReturnType
is no longer relevant now that we're checking the builder from the return type.
Factored logic with IsCustomTaskType
.
@@ -190,6 +191,48 @@ public static bool IsAsyncReturningIAsyncEnumerator(this MethodSymbol method, CS | |||
&& method.ReturnType.IsIAsyncEnumeratorType(compilation); | |||
} | |||
|
|||
#nullable enable | |||
public static bool IsAsyncReturningTaskViaOverride(this MethodSymbol method, [NotNullWhen(true)] out object? builderArgument) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var symbol = this.ContainingMemberOrLambda; | ||
return symbol?.Kind == SymbolKind.Method && ((MethodSymbol)symbol).IsAsyncReturningTaskViaOverride(out _); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these two methods ever called separately? If not, consider combining the methods. Same question for pair of methods below. #Closed
@@ -692,7 +677,7 @@ private BoundLambda ReallyBind(NamedTypeSymbol delegateType) | |||
bool reachableEndpoint = ControlFlowPass.Analyze(compilation, lambdaSymbol, block, diagnostics.DiagnosticBag); | |||
if (reachableEndpoint) | |||
{ | |||
if (DelegateNeedsReturn(invokeMethod)) | |||
if (Binder.MethodOrLambdaRequiresValue(lambdaSymbol, this.Binder.Compilation)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📝 Changes to this method are covered by BuilderFactoryOnMethod_OnLambda_NotTaskLikeTypes
. With this change the test doesn't report ERR_AnonymousReturnExpected
nor ERR_CantConvAsyncAnonFuncReturns
below. #Resolved
ignoredBuilderType, customBuilder: true, out MethodSymbol _) && | ||
TryGetBuilderMember(F, | ||
isGeneric ? WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__SetStateMachine : WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__SetStateMachine, | ||
ignoredBuilderType, customBuilder: true, out MethodSymbol _); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we use the existing TryCreate()
method instead? #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't make much difference. I did initially ;-) I'll change it back.
@@ -1056,6 +1056,11 @@ protected void AsyncMethodChecks(BindingDiagnosticBag diagnostics) | |||
hasErrors = true; | |||
} | |||
|
|||
if (this.HasMethodLevelBuilder(out _)) | |||
{ | |||
hasErrors = MessageID.IDS_AsyncMethodBuilderOverride.CheckFeatureAvailability(diagnostics, this.DeclaringCompilation, errorLocation); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dotnet/roslyn-compiler for a second review. Let me know if you need a walkthrough. Thanks |
This reverts commit 2a3fdf1.
@dotnet/roslyn-compiler for review. Thanks |
CS8935 here and in other locations. In reply to: 866274208 Refers to: src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncMethodBuilderOverrideTests.cs:889 in 3268386. [](commit_id = 3268386, deletion_comment = False) |
@@ -448,6 +475,7 @@ private static NamedTypeSymbol ValidateBuilderType(SyntheticBoundNodeFactory F, | |||
method.IsStatic && | |||
method.ParameterCount == 0 && | |||
!method.IsGenericMethod && | |||
method.RefKind == RefKind.None && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this actually just a bug fix? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need this change for proper behavior of method-level builders (see test BuilderOnMethod_CreateHasRefReturn
).
But yes it was a misbehavior of task-like types (see test AsyncMethod_CreateHasRefReturn
).
@@ -815,5 +815,29 @@ internal static ImmutableArray<INamespaceSymbol> GetPublicSymbols(this Immutable | |||
{ | |||
return symbol.GetSymbol<FunctionPointerTypeSymbol>(); | |||
} | |||
|
|||
/// <summary> | |||
/// Returns true if the method has a [AsyncMethodBuilder(typeof(B))] attribute. If so it returns the "B". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or add type
&& attr.CommonConstructorArguments.Length == 1 | ||
&& attr.CommonConstructorArguments[0].Kind == TypedConstantKind.Type) | ||
{ | ||
builderArgument = attr.CommonConstructorArguments[0].ValueInternal!; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kept in line with existing IsCustomTaskType
method.
Same question here, I guess. In reply to: 867086783 In reply to: 867086783 In reply to: 867086783 Refers to: src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs:1643 in 3268386. [](commit_id = 3268386, deletion_comment = False) |
/// Returns true if the method has a [AsyncMethodBuilder(typeof(B))] attribute. If so it returns the "B". | ||
/// Validation of builder type B is left for elsewhere. This method returns B without validation of any kind. | ||
/// </summary> | ||
internal static bool HasAsyncMethodBuilder(this Symbol symbol, [NotNullWhen(true)] out object? builderArgument) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These errors have nothing to do with accessibility? Also, several of these have no issues? In reply to: 867133974 In reply to: 867133974 Refers to: src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncMethodBuilderOverrideTests.cs:662 in 3268386. [](commit_id = 3268386, deletion_comment = False) |
I would have expected this to error? In reply to: 867139447 In reply to: 867139447 In reply to: 867139447 Refers to: src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncMethodBuilderOverrideTests.cs:918 in 3268386. [](commit_id = 3268386, deletion_comment = False) |
Done review pass (commit 25) |
Resolved offline In reply to: 867139447 Refers to: src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncMethodBuilderOverrideTests.cs:918 in 3268386. [](commit_id = 3268386, deletion_comment = False) |
Will fix this test to have builder on method and adjust name. In reply to: 867181628 In reply to: 867181628 Refers to: src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncMethodBuilderOverrideTests.cs:632 in 9440d0f. [](commit_id = 9440d0f, deletion_comment = False) |
Spec: https://github.com/dotnet/csharplang/blob/main/proposals/async-method-builders.md
Test plan: #51999
Current design choices:
public
accessibility