Repository: dotnet/roslyn
File: src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs (C#)

Code before:
                if (returnRefKind != RefKind.None)
                {
                    if (conversion.Kind != ConversionKind.Identity)
                    {
                        Error(diagnostics, ErrorCode.ERR_RefReturnMustHaveIdentityConversion, argument.Syntax, returnType);
                        argument = argument.WithHasErrors();
                    }
                    else
                    {
                        return BindToNaturalType(argument, diagnostics);
                    }
                }
                else if (!conversion.IsImplicit || !conversion.IsValid)
                {
                    if (!badAsyncReturnAlreadyReported)
                    {
                        RefKind unusedRefKind;
                        if (IsEffectivelyGenericTaskReturningAsyncMethod()
                            && TypeSymbol.Equals(argument.Type, this.GetCurrentReturnType(out unusedRefKind), TypeCompareKind.ConsiderEverything2))
                        {
                            // Since this is an async method, the return expression must be of type '{0}' rather than '{1}'
                            Error(diagnostics, ErrorCode.ERR_BadAsyncReturnExpression, argument.Syntax, returnType, argument.Type);
                        }
                        else
                        {
                            var errorCount = diagnostics.DiagnosticBag?.AsEnumerable()
                                .Count(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error) ?? 0;

                            GenerateImplicitConversionError(diagnostics, argument.Syntax, conversion, argument, returnType);

                            var updatedErrorCount = diagnostics.DiagnosticBag?.AsEnumerable()
                                .Count(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error) ?? 0;
                            hasImplicitConversionError = errorCount < updatedErrorCount;

                            if (this.ContainingMemberOrLambda is LambdaSymbol)
                            {
                                ReportCantConvertLambdaReturn(argument.Syntax, diagnostics);
                            }
                        }
                    }
                }
            }

            return CreateConversion(argument.Syntax, argument, conversion, isCast: false, conversionGroupOpt: null, InConversionGroupFlags.Unspecified, returnType, diagnostics, hasImplicitConversionError);
        }

        private BoundTryStatement BindTryStatement(TryStatementSyntax node, BindingDiagnosticBag diagnostics)
        {
            Debug.Assert(node != null);

            var tryBlock = BindEmbeddedBlock(node.Block, diagnostics);

Review comment (suggestion):
Having to enumerate diagnostics isn't great, as there could be many. An alternative approach is to instead create a temporary diagnostic bag. This is a pattern that is commonly used in the compiler to avoid this problem.

It would like like:
```
    var conversionDiagnostics = BindingDiagnosticBag.GetInstance(diagnostics);
    GenerateImplicitConversionError(conversionDiagnostics, argument.Syntax, conversion, argument, returnType);

    hasImplicitConversionError = conversionDiagnostics.HasAnyResolvedErrors();
    diagnostics.AddRangeAndFree(conversionDiagnostics);
```

Code after:
            {
                if (returnRefKind != RefKind.None)
                {
                    if (conversion.Kind != ConversionKind.Identity)
                    {
                        Error(diagnostics, ErrorCode.ERR_RefReturnMustHaveIdentityConversion, argument.Syntax, returnType);
                        argument = argument.WithHasErrors();
                    }
                    else
                    {
                        return BindToNaturalType(argument, diagnostics);
                    }
                }
                else if (!conversion.IsImplicit || !conversion.IsValid)
                {
                    if (!badAsyncReturnAlreadyReported)
                    {
                        RefKind unusedRefKind;
                        if (IsEffectivelyGenericTaskReturningAsyncMethod()
                            && TypeSymbol.Equals(argument.Type, this.GetCurrentReturnType(out unusedRefKind), TypeCompareKind.ConsiderEverything2))
                        {
                            // Since this is an async method, the return expression must be of type '{0}' rather than '{1}'
                            Error(diagnostics, ErrorCode.ERR_BadAsyncReturnExpression, argument.Syntax, returnType, argument.Type);
                        }
                        else
                        {
                            var conversionDiagnostics = BindingDiagnosticBag.GetInstance(diagnostics);
                            GenerateImplicitConversionError(conversionDiagnostics, argument.Syntax, conversion, argument, returnType);

                            hasImplicitConversionError = conversionDiagnostics.AccumulatesDiagnostics && conversionDiagnostics.HasAnyResolvedErrors();
                            diagnostics.AddRangeAndFree(conversionDiagnostics);

                            if (this.ContainingMemberOrLambda is LambdaSymbol)
                            {
                                ReportCantConvertLambdaReturn(argument.Syntax, diagnostics);
                            }
                        }
                    }
                }
            }

            return CreateConversion(
                argument.Syntax,
                argument,
                conversion,
                isCast: false,
                conversionGroupOpt: null,
                InConversionGroupFlags.Unspecified,
                returnType,
                hasImplicitConversionError
                    ? BindingDiagnosticBag.Discarded