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

Code before:
                currentNode = currentNode.Left as BoundBinaryPattern;
            } while (currentNode != null);

            currentNode = binaryPatternStack.Pop();
            Tests result = MakeTestsAndBindings(input, currentNode.Left, out output, bindings);

            do
            {
                result = makeTestsAndBindingsForBinaryPattern(this, result, output, input, currentNode, out output, bindings);
            } while (binaryPatternStack.TryPop(out currentNode));

            binaryPatternStack.Free();

            return result;

            static Tests makeTestsAndBindingsForBinaryPattern(DecisionDagBuilder @this, Tests leftTests, BoundDagTemp leftOutput, BoundDagTemp input, BoundBinaryPattern bin, out BoundDagTemp output, ArrayBuilder<BoundPatternBinding> bindings)
            {
                var builder = ArrayBuilder<Tests>.GetInstance(2);
                if (bin.Disjunction)
                {
                    builder.Add(leftTests);
                    builder.Add(@this.MakeTestsAndBindings(input, bin.Right, bindings));
                    var result = Tests.OrSequence.Create(builder);
                    output = input;
                    return result;
                }
                else
                {
                    builder.Add(leftTests);
                    builder.Add(@this.MakeTestsAndBindings(leftOutput, bin.Right, out var rightOutput, bindings));
                    output = rightOutput;
                    Debug.Assert(bin.HasErrors || output.Type.Equals(bin.NarrowedType, TypeCompareKind.AllIgnoreOptions));
                    return Tests.AndSequence.Create(builder);
                }
            }
        }

        private Tests MakeTestsAndBindingsForRelationalPattern(
            BoundDagTemp input,
            BoundRelationalPattern rel,
            out BoundDagTemp output)
        {
            var type = rel.Value.Type ?? input.Type;
            Debug.Assert(type is { });
            // check if the test is always true or always false
            var tests = ArrayBuilder<Tests>.GetInstance(2);
            output = MakeConvertToType(input, rel.Syntax, type, isExplicitTest: false, tests);
            var fac = ValueSetFactory.ForInput(output);
            var values = fac?.Related(rel.Relation.Operator(), rel.ConstantValue);
            if (values?.IsEmpty == true)
            {

Review comment (bug):
>output = @this.MakeConvertToType(input: input, syntax: bin.Syntax, type: bin.NarrowedType, isExplicitTest: false, tests: builder); [](http://example.com/codeflow?start=24&length=130)

It is not obvious why is this a wrong thing to do. Is it possible that the problem is with how NarrowedType is getting calculated? #Closed

Code after:
            {
                result = makeTestsAndBindingsForBinaryPattern(this, result, output, input, currentNode, out output, bindings);
            } while (binaryPatternStack.TryPop(out currentNode));

            binaryPatternStack.Free();

            return result;

            static Tests makeTestsAndBindingsForBinaryPattern(DecisionDagBuilder @this, Tests leftTests, BoundDagTemp leftOutput, BoundDagTemp input, BoundBinaryPattern bin, out BoundDagTemp output, ArrayBuilder<BoundPatternBinding> bindings)
            {
                var builder = ArrayBuilder<Tests>.GetInstance(2);
                if (bin.Disjunction)
                {
                    builder.Add(leftTests);
                    builder.Add(@this.MakeTestsAndBindings(input, bin.Right, bindings));
                    var result = Tests.OrSequence.Create(builder);
                    if (bin.InputType.Equals(bin.NarrowedType))
                    {
                        output = input;
                        return result;
                    }
                    else
                    {
                        builder = ArrayBuilder<Tests>.GetInstance(2);
                        builder.Add(result);
                        var evaluation = new BoundDagTypeEvaluation(bin.Syntax, bin.NarrowedType, input);
                        output = new BoundDagTemp(bin.Syntax, bin.NarrowedType, evaluation);
                        builder.Add(new Tests.One(evaluation));
                        return Tests.AndSequence.Create(builder);
                    }
                }
                else
                {
                    builder.Add(leftTests);
                    builder.Add(@this.MakeTestsAndBindings(leftOutput, bin.Right, out var rightOutput, bindings));
                    output = rightOutput;
                    Debug.Assert(bin.HasErrors || output.Type.Equals(bin.NarrowedType, TypeCompareKind.AllIgnoreOptions));
                    return Tests.AndSequence.Create(builder);
                }
            }
        }

        private Tests MakeTestsAndBindingsForRelationalPattern(
            BoundDagTemp input,
            BoundRelationalPattern rel,
            out BoundDagTemp output)
        {
            var type = rel.Value.Type ?? input.Type;
            Debug.Assert(type is { });
            // check if the test is always true or always false
            var tests = ArrayBuilder<Tests>.GetInstance(2);