Repository: dotnet/roslyn
File: src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEntryPointSymbol.cs (C#)

Code before:
                Debug.Assert(
                    ReturnType.IsVoidType() ||
                    ReturnType.SpecialType == SpecialType.System_Int32);
                Debug.Assert(!compilation.IsRuntimeAsyncEnabledIn(this));
            }

            internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder<CSharpAttributeData> attributes)
            {
                base.AddSynthesizedAttributes(moduleBuilder, ref attributes);

                AddSynthesizedAttribute(ref attributes, this.DeclaringCompilation.SynthesizeDebuggerStepThroughAttribute());
            }

            public override string Name => MainName;

            public override ImmutableArray<ParameterSymbol> Parameters => _parameters;

            public override TypeWithAnnotations ReturnTypeWithAnnotations => _handleAsyncEntryPointMethod != null
                ? TypeWithAnnotations.Create(_handleAsyncEntryPointMethod.ReturnType)
                : TypeWithAnnotations.Create(_getAwaiterGetResultCall.Type);

            internal override BoundBlock CreateBody(BindingDiagnosticBag diagnostics)
            {
                var syntax = _userMainReturnTypeSyntax;

                if (_handleAsyncEntryPointMethod != null)
                {
                    // Use the new HandleAsyncEntryPoint API
                    var arguments = Parameters.SelectAsArray((p, s) => (BoundExpression)new BoundParameter(s, p, p.Type), _userMainReturnTypeSyntax);

                    // Main(args) or Main()
                    BoundCall userMainInvocation = new BoundCall(
                            syntax: syntax,
                            receiverOpt: null,
                            initialBindingReceiverIsSubjectToCloning: ThreeState.Unknown,
                            method: UserMain,
                            arguments: arguments,
                            argumentNamesOpt: default(ImmutableArray<string>),
                            argumentRefKindsOpt: default(ImmutableArray<RefKind>),
                            isDelegateCall: false,
                            expanded: false,
                            invokedAsExtensionMethod: false,
                            argsToParamsOpt: default(ImmutableArray<int>),
                            defaultArguments: default(BitVector),
                            resultKind: LookupResultKind.Viable,
                            type: UserMain.ReturnType)
                    { WasCompilerGenerated = true };

                    // HandleAsyncEntryPoint(Main(args)) or return HandleAsyncEntryPoint(Main(args))
                    BoundCall handleAsyncEntryPointCall = new BoundCall(
                            syntax: syntax,

Review comment (suggestion):
@Copilot rather than this approach, update `_getAwaiterGetResultCall` to be something like `_userEntryPointCall`, which is either the call to `GetResult`, or is the new API. That determination should happen in the constructor, and then `CreateBody` doesn't need to change beyond the simple variable rename. #Resolved

Code after:
                            argumentRefKindsOpt: default(ImmutableArray<RefKind>),
                            isDelegateCall: false,
                            expanded: false,
                            invokedAsExtensionMethod: false,
                            argsToParamsOpt: default(ImmutableArray<int>),
                            defaultArguments: default(BitVector),
                            resultKind: LookupResultKind.Viable,
                            type: handleAsyncEntryPointMethod.ReturnType)
                    { WasCompilerGenerated = true };
                }
                else
                {
                    // Fall back to the old GetAwaiter().GetResult() pattern
                    // The diagnostics that would be produced here will already have been captured and returned.
                    var success = binder.GetAwaitableExpressionInfo(userMainInvocation, out _userEntryPointInvocation!, runtimeAsyncAwaitCall: out _, _userMainReturnTypeSyntax, BindingDiagnosticBag.Discarded);
                }

                Debug.Assert(
                    ReturnType.IsVoidType() ||
                    ReturnType.SpecialType == SpecialType.System_Int32);
                Debug.Assert(!compilation.IsRuntimeAsyncEnabledIn(this));
            }

            internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder<CSharpAttributeData> attributes)
            {
                base.AddSynthesizedAttributes(moduleBuilder, ref attributes);

                AddSynthesizedAttribute(ref attributes, this.DeclaringCompilation.SynthesizeDebuggerStepThroughAttribute());
            }

            public override string Name => MainName;

            public override ImmutableArray<ParameterSymbol> Parameters => _parameters;

            public override TypeWithAnnotations ReturnTypeWithAnnotations => TypeWithAnnotations.Create(_userEntryPointInvocation.Type);

            internal override BoundBlock CreateBody(BindingDiagnosticBag diagnostics)
            {
                var syntax = _userMainReturnTypeSyntax;

                if (ReturnsVoid)
                {
                    return new BoundBlock(
                        syntax: syntax,
                        locals: ImmutableArray<LocalSymbol>.Empty,
                        statements: ImmutableArray.Create<BoundStatement>(
                            new BoundExpressionStatement(
                                syntax: syntax,
                                expression: _userEntryPointInvocation
                            )
                            { WasCompilerGenerated = true },