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

Code before:
            }
        }

        private Tests MakeTestsAndBindings(
            BoundDagTemp input,
            BoundPattern pattern,
            ArrayBuilder<BoundPatternBinding> bindings)
        {
            return MakeTestsAndBindings(input, pattern, out _, bindings);
        }

        /// <summary>
        /// Make the tests and variable bindings for the given pattern with the given input.  The pattern's
        /// "output" value is placed in <paramref name="output"/>.  The output is defined as the input
        /// narrowed according to the pattern's *narrowed type*; see https://github.com/dotnet/csharplang/issues/2850.
        /// </summary>
        private Tests MakeTestsAndBindings(
            BoundDagTemp input,
            BoundPattern pattern,
            out BoundDagTemp output,
            ArrayBuilder<BoundPatternBinding> bindings)
        {
            if (!pattern.HasErrors && !pattern.InputType.IsErrorType() && !pattern.InputType.Equals(input.Type, TypeCompareKind.AllIgnoreOptions))
            {
                var builder = ArrayBuilder<Tests>.GetInstance(1);
                input = MakeConvertToType(input: input, syntax: pattern.Syntax, type: pattern.InputType, isExplicitTest: false, tests: builder);
            }

            Debug.Assert(pattern.HasErrors || pattern.InputType.Equals(input.Type, TypeCompareKind.AllIgnoreOptions) || pattern.InputType.IsErrorType());

            switch (pattern)
            {
                case BoundDeclarationPattern declaration:
                    return MakeTestsAndBindingsForDeclarationPattern(input, declaration, out output, bindings);
                case BoundConstantPattern constant:
                    return MakeTestsForConstantPattern(input, constant, out output);
                case BoundDiscardPattern:
                case BoundSlicePattern:
                    output = input;
                    return Tests.True.Instance;
                case BoundListPattern list:
                    return MakeTestsAndBindingsForListPattern(input, list, out output, bindings);
                case BoundRecursivePattern recursive:
                    return MakeTestsAndBindingsForRecursivePattern(input, recursive, out output, bindings);
                case BoundITuplePattern iTuple:
                    return MakeTestsAndBindingsForITuplePattern(input, iTuple, out output, bindings);
                case BoundTypePattern type:
                    return MakeTestsForTypePattern(input, type, out output);
                case BoundRelationalPattern rel:
                    return MakeTestsAndBindingsForRelationalPattern(input, rel, out output);
                case BoundNegatedPattern neg:

Review comment (bug):
>input = MakeConvertToType(input: input, syntax: pattern.Syntax, type: pattern.InputType, isExplicitTest: false, tests: builder); [](http://example.com/codeflow?start=16&length=128)

I see no obvious connection of this change to the stated intent: "Avoid narrowing types in or patterns". I also see no obvious indicators that the change is somehow limited to `or` patterns. Therefore, consider providing some explanation. Also, pattern matching is very tricky area, therefore, changes in it usually require sharing detailed analysis of the issue. What is going wrong, where it is going wrong, why it is wrong? Why the change is the right change to make (the fact that it seem to lead to the expected behavior in the specific scenario is not enough) and is not expected to break anything? Often, including dumps of DUG before and after the change for scenario(s) along the explanation helps to make the case. #Closed

Code after:
            }
        }

        private Tests MakeTestsAndBindings(
            BoundDagTemp input,
            BoundPattern pattern,
            ArrayBuilder<BoundPatternBinding> bindings)
        {
            return MakeTestsAndBindings(input, pattern, out _, bindings);
        }

        /// <summary>
        /// Make the tests and variable bindings for the given pattern with the given input.  The pattern's
        /// "output" value is placed in <paramref name="output"/>.  The output is defined as the input
        /// narrowed according to the pattern's *narrowed type*; see https://github.com/dotnet/csharplang/issues/2850.
        /// </summary>
        private Tests MakeTestsAndBindings(
            BoundDagTemp input,
            BoundPattern pattern,
            out BoundDagTemp output,
            ArrayBuilder<BoundPatternBinding> bindings)
        {
            Debug.Assert(pattern.HasErrors || pattern.InputType.Equals(input.Type, TypeCompareKind.AllIgnoreOptions) || pattern.InputType.IsErrorType());
            switch (pattern)
            {
                case BoundDeclarationPattern declaration:
                    return MakeTestsAndBindingsForDeclarationPattern(input, declaration, out output, bindings);
                case BoundConstantPattern constant:
                    return MakeTestsForConstantPattern(input, constant, out output);
                case BoundDiscardPattern:
                case BoundSlicePattern:
                    output = input;
                    return Tests.True.Instance;
                case BoundListPattern list:
                    return MakeTestsAndBindingsForListPattern(input, list, out output, bindings);
                case BoundRecursivePattern recursive:
                    return MakeTestsAndBindingsForRecursivePattern(input, recursive, out output, bindings);
                case BoundITuplePattern iTuple:
                    return MakeTestsAndBindingsForITuplePattern(input, iTuple, out output, bindings);
                case BoundTypePattern type:
                    return MakeTestsForTypePattern(input, type, out output);
                case BoundRelationalPattern rel:
                    return MakeTestsAndBindingsForRelationalPattern(input, rel, out output);
                case BoundNegatedPattern neg:
                    output = input;
                    return MakeTestsAndBindingsForNegatedPattern(input, neg, bindings);
                case BoundBinaryPattern bin:
                    return MakeTestsAndBindingsForBinaryPattern(input, bin, out output, bindings);
                default:
                    throw ExceptionUtilities.UnexpectedValue(pattern.Kind);
            }