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

Code before:

            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, checkNotNull: true);
            var fac = ValueSetFactory.ForInput(output);
            var values = fac?.Related(rel.Relation.Operator(), rel.ConstantValue);
            if (values?.IsEmpty == true)
            {
                tests.Add(Tests.False.Instance);
            }

Review comment (suggestion):
>output = @this.MakeConvertToType(input: input, syntax: bin.Syntax, type: bin.NarrowedType, isExplicitTest: false, tests: builder); [](http://example.com/codeflow?start=24&length=130)

It looks like our intent on this branch is to convert output to the ```bin.NarrowedType```, but do that without introducing any implicit null checks. It also looks like the intent can be achieved by replacing this line with the following code. Then all tests, including the new ones, are passing without a need to make any additional compiler changes. 
```
                        var evaluation = new BoundDagTypeEvaluation(bin.Syntax, bin.NarrowedType, input);
                        output = new BoundDagTemp(bin.Syntax, bin.NarrowedType, evaluation);
                        builder.Add(new Tests.One(evaluation));
```

 #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);