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.
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.
I didn't understand the comment about CalculateReturnType. Could we share this implementation with TypeSymbolExtensions.IsCustomTaskType()?
There was a problem hiding this comment.
The comment about CalculateReturnType is no longer relevant now that we're checking the builder from the return type.
Factored logic with IsCustomTaskType.
| } | ||
|
|
||
| #nullable enable | ||
| public static bool IsAsyncReturningTaskViaOverride(this MethodSymbol method, [NotNullWhen(true)] out object? builderArgument) |
| var symbol = this.ContainingMemberOrLambda; | ||
| return symbol?.Kind == SymbolKind.Method && ((MethodSymbol)symbol).IsAsyncReturningTaskViaOverride(out _); | ||
| } | ||
|
|
There was a problem hiding this comment.
Are these two methods ever called separately? If not, consider combining the methods. Same question for pair of methods below. #Closed
| if (reachableEndpoint) | ||
| { | ||
| if (DelegateNeedsReturn(invokeMethod)) | ||
| if (Binder.MethodOrLambdaRequiresValue(lambdaSymbol, this.Binder.Compilation)) |
There was a problem hiding this comment.
📝 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.
Could we use the existing TryCreate() method instead? #Closed
There was a problem hiding this comment.
It doesn't make much difference. I did initially ;-) I'll change it back.
|
|
||
| if (this.HasMethodLevelBuilder(out _)) | ||
| { | ||
| hasErrors = MessageID.IDS_AsyncMethodBuilderOverride.CheckFeatureAvailability(diagnostics, this.DeclaringCompilation, errorLocation); |
|
@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) |
| method.IsStatic && | ||
| method.ParameterCount == 0 && | ||
| !method.IsGenericMethod && | ||
| method.RefKind == RefKind.None && |
There was a problem hiding this comment.
Is this actually just a bug fix? #Resolved
There was a problem hiding this comment.
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).
| } | ||
|
|
||
| /// <summary> | ||
| /// Returns true if the method has a [AsyncMethodBuilder(typeof(B))] attribute. If so it returns the "B". |
| && attr.CommonConstructorArguments.Length == 1 | ||
| && attr.CommonConstructorArguments[0].Kind == TypedConstantKind.Type) | ||
| { | ||
| builderArgument = attr.CommonConstructorArguments[0].ValueInternal!; |
There was a problem hiding this comment.
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) |
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:
publicaccessibility