Repository: dotnet/roslyn
File: src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_StringConcat.cs (C#)

Code before:
        private void VisitAndAddConcatArgumentInReverseOrder(BoundExpression argument, bool argumentAlreadyVisited, ArrayBuilder<BoundExpression> finalArguments, ref WellKnownConcatRelatedMethods wellKnownConcatOptimizationMethods)
        {
            Debug.Assert(argument is not BoundBinaryOperator { InterpolatedStringHandlerData: null } op || !IsBinaryStringConcatenation(op));
            if (!argumentAlreadyVisited)
            {
                argument = VisitExpression(argument);
            }

            var precedingArgument = finalArguments.Count > 0 ? finalArguments[^1] : null;
            var (singleConcatArgument, nestedConcatArguments) = SimplifyConcatArgument(argument, ref precedingArgument, ref wellKnownConcatOptimizationMethods);

            // We should only get one result from simplification; either a single argument to add, or multiple nested arguments to add, or the current argument was optimized away
            // This last option can either mean that the argument was truly empty, and was dropped entirely, or that it was merged into the preceding argument, in which case we updated that argument in place and don't need to add anything new
            if (singleConcatArgument is null && nestedConcatArguments.IsDefault)
            {
                if (precedingArgument is not null)
                {
                    // We may have merged the current argument into the preceding argument, so we need to update that in the final arguments list
                    // If we didn't do any merging, then this is a no-op
                    finalArguments[^1] = precedingArgument;
                }

                return;
            }

            Debug.Assert(precedingArgument is null || ReferenceEquals(precedingArgument, finalArguments[^1]));
            Debug.Assert(singleConcatArgument is null ^ nestedConcatArguments.IsDefault);

            if (singleConcatArgument is not null)
            {
                finalArguments.Add(singleConcatArgument);
            }
            else
            {
                for (int i = nestedConcatArguments.Length - 1; i >= 0; i--)
                {
                    VisitAndAddConcatArgumentInReverseOrder(nestedConcatArguments[i], argumentAlreadyVisited: true, finalArguments, ref wellKnownConcatOptimizationMethods);
                }
            }
        }

        private enum StringConcatenationRewriteKind
        {
            AllStrings,
            AllStringsOrChars,
            InvolvesObjects,
        }

        private struct WellKnownConcatRelatedMethods(CSharpCompilation compilation)
        {
            private readonly CSharpCompilation _compilation = compilation;

Review comment (bug):
>Debug.Assert(precedingArgument is null || ReferenceEquals(precedingArgument, finalArguments[^1])); [](http://example.com/codeflow?start=12&length=98)

It feels like this assert could be stronger
```
Debug.Assert((finalArguments.Count == 0 && precedingArgument is null) || (finalArguments.Count != 0 && ReferenceEquals(precedingArgument, finalArguments[^1])));
``` #Closed

Code after:
        {
            Debug.Assert(argument is not BoundBinaryOperator { InterpolatedStringHandlerData: null } op || !IsBinaryStringConcatenation(op));
            if (!argumentAlreadyVisited)
            {
                argument = VisitExpression(argument);
            }

            var followingArgument = finalArguments.Count > 0 ? finalArguments[^1] : null;
            var (singleConcatArgument, nestedConcatArguments) = SimplifyConcatArgument(argument, ref followingArgument, ref wellKnownConcatOptimizationMethods);

            // We should only get one result from simplification; either a single argument to add, or multiple nested arguments to add, or the current argument was optimized away
            // This last option can either mean that the argument was truly empty and was dropped entirely, or that it was merged into the following argument, in which case we need to update the builder
            if (singleConcatArgument is null && nestedConcatArguments.IsDefault)
            {
                if (followingArgument is not null)
                {
                    // We may have merged the current argument into the following argument, so we need to update that in the final arguments list
                    // If we didn't do any merging, then this is a no-op
                    finalArguments[^1] = followingArgument;
                }

                return;
            }

            Debug.Assert((finalArguments.Count == 0 && followingArgument is null) || (finalArguments.Count != 0 && ReferenceEquals(followingArgument, finalArguments[^1])));
            Debug.Assert(singleConcatArgument is null ^ nestedConcatArguments.IsDefault);

            if (singleConcatArgument is not null)
            {
                finalArguments.Add(singleConcatArgument);
            }
            else
            {
                for (int i = nestedConcatArguments.Length - 1; i >= 0; i--)
                {
                    VisitAndAddConcatArgumentInReverseOrder(nestedConcatArguments[i], argumentAlreadyVisited: true, finalArguments, ref wellKnownConcatOptimizationMethods);
                }
            }
        }

        private enum StringConcatenationRewriteKind
        {
            AllStrings,
            AllStringsOrChars,
            InvolvesObjects,
        }

        private struct WellKnownConcatRelatedMethods(CSharpCompilation compilation)
        {
            private readonly CSharpCompilation _compilation = compilation;