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

Code before:
                            isRefEscape: false);
                    }

                    if (conversion.Conversion.IsUserDefined)
                    {
                        var operatorMethod = conversion.Conversion.Method;
                        Debug.Assert(operatorMethod is not null);

                        return CheckInvocationEscape(
                            conversion.Syntax,
                            MethodInvocationInfo.FromUserDefinedConversion(operatorMethod, conversion.Operand, conversion.HasAnyErrors),
                            checkingReceiver,
                            escapeFrom,
                            escapeTo,
                            diagnostics,
                            isRefEscape: false);
                    }

                    return CheckValEscape(node, conversion.Operand, escapeFrom, escapeTo, checkingReceiver: false, diagnostics: diagnostics);

                case BoundKind.AssignmentOperator:
                    var assignment = (BoundAssignmentOperator)expr;
                    // The result of an assignment is its right-hand side.
                    return CheckValEscape(node, assignment.Right, escapeFrom, escapeTo, checkingReceiver: false, diagnostics: diagnostics);

                case BoundKind.NullCoalescingAssignmentOperator:
                    var nullCoalescingAssignment = (BoundNullCoalescingAssignmentOperator)expr;
                    // The result of a null-coalescing assignment is its right-hand side.
                    return CheckValEscape(node, nullCoalescingAssignment.RightOperand, escapeFrom, escapeTo, checkingReceiver: false, diagnostics: diagnostics);

                case BoundKind.IncrementOperator:
                    var increment = (BoundIncrementOperator)expr;
                    if (increment.MethodOpt is { IsStatic: true } incrementMethod)
                    {
                        Debug.Assert(increment.OperatorKind.IsUserDefined());

                        var prefix = increment.OperatorKind.Operator() is UnaryOperatorKind.PrefixIncrement or UnaryOperatorKind.PrefixDecrement;
                        Debug.Assert(prefix || increment.OperatorKind.Operator() is UnaryOperatorKind.PostfixIncrement or UnaryOperatorKind.PostfixDecrement);

                        // Prefix increment can be analyzed like the underlying method call since that's what it returns.
                        // Postfix increment is better analyzed as only the operand since that's what it returns.
                        if (prefix)
                        {
                            return CheckInvocationEscape(
                                increment.Syntax,
                                MethodInvocationInfo.FromIncrementOperator(increment),
                                checkingReceiver,
                                escapeFrom,
                                escapeTo,
                                diagnostics,
                                isRefEscape: false);

Review comment (bug):
>return [](http://example.com/codeflow?start=28&length=6)

Are all changes made in this file (every affected code path) backed by targeted tests? I mean by tests that would fail without the changes.

Code after:
                    {
                        var operatorMethod = conversion.Conversion.Method;
                        Debug.Assert(operatorMethod is not null);

                        return CheckInvocationEscape(
                            conversion.Syntax,
                            MethodInvocationInfo.FromUserDefinedConversion(operatorMethod, conversion.Operand, conversion.HasAnyErrors),
                            checkingReceiver,
                            escapeFrom,
                            escapeTo,
                            diagnostics,
                            isRefEscape: false);
                    }

                    return CheckValEscape(node, conversion.Operand, escapeFrom, escapeTo, checkingReceiver: false, diagnostics: diagnostics);

                case BoundKind.AssignmentOperator:
                    var assignment = (BoundAssignmentOperator)expr;
                    // The result of an assignment is its right-hand side.
                    return CheckValEscape(node, assignment.Right, escapeFrom, escapeTo, checkingReceiver: false, diagnostics: diagnostics);

                case BoundKind.NullCoalescingAssignmentOperator:
                    var nullCoalescingAssignment = (BoundNullCoalescingAssignmentOperator)expr;
                    return CheckValEscape(node, nullCoalescingAssignment.LeftOperand, escapeFrom, escapeTo, checkingReceiver: false, diagnostics: diagnostics) &&
                        CheckValEscape(node, nullCoalescingAssignment.RightOperand, escapeFrom, escapeTo, checkingReceiver: false, diagnostics: diagnostics);

                case BoundKind.IncrementOperator:
                    var increment = (BoundIncrementOperator)expr;
                    if (increment.MethodOpt is { IsStatic: true } incrementMethod)
                    {
                        Debug.Assert(increment.OperatorKind.IsUserDefined());

                        var prefix = increment.OperatorKind.Operator() is UnaryOperatorKind.PrefixIncrement or UnaryOperatorKind.PrefixDecrement;
                        Debug.Assert(prefix || increment.OperatorKind.Operator() is UnaryOperatorKind.PostfixIncrement or UnaryOperatorKind.PostfixDecrement);

                        // Prefix increment can be analyzed like the underlying method call since that's what it returns.
                        // Postfix increment is better analyzed as only the operand since that's what it returns.
                        if (prefix)
                        {
                            return CheckInvocationEscape(
                                increment.Syntax,
                                MethodInvocationInfo.FromIncrementOperator(increment),
                                checkingReceiver,
                                escapeFrom,
                                escapeTo,
                                diagnostics,
                                isRefEscape: false);
                        }
                    }

                    return CheckValEscape(node, increment.Operand, escapeFrom, escapeTo, checkingReceiver: false, diagnostics: diagnostics);