/// <summary>
        /// Record declared variables in the pattern.
        /// </summary>
        private void NoteDeclaredPatternVariables(BoundPattern pattern)
        {
            if (IsInside)
            {
                switch (pattern)
                {
                case BoundDeclarationPattern decl:
                {
                    // The variable may be null if it is a discard designation `_`.
                    if (decl.Variable?.Kind == SymbolKind.Local)
                    {
                        // Because this API only returns local symbols and parameters,
                        // we exclude pattern variables that have become fields in scripts.
                        _variablesDeclared.Add(decl.Variable);
                    }
                }
                break;

                case BoundRecursivePattern recur:
                {
                    if (recur.Variable?.Kind == SymbolKind.Local)
                    {
                        _variablesDeclared.Add(recur.Variable);
                    }
                }
                break;
                }
            }
        }
        internal override BoundSwitchExpressionArm BindSwitchExpressionArm(SwitchExpressionArmSyntax node, DiagnosticBag diagnostics)
        {
            Debug.Assert(node == _arm);
            Binder armBinder = this.GetBinder(node);
            bool   hasErrors = _switchExpressionBinder.SwitchGoverningType.IsErrorType();
            ImmutableArray <LocalSymbol> locals = _armScopeBinder.Locals;
            BoundPattern    pattern             = armBinder.BindPattern(node.Pattern, _switchExpressionBinder.SwitchGoverningType, _switchExpressionBinder.SwitchGoverningValEscape, hasErrors, diagnostics);
            BoundExpression whenClause          = node.WhenClause != null
                ? armBinder.BindBooleanExpression(node.WhenClause.Condition, diagnostics)
                : null;

            BoundExpression armResult = armBinder.BindValue(node.Expression, diagnostics, BindValueKind.RValue);
            var             label     = new GeneratedLabelSymbol("arm");

            return(new BoundSwitchExpressionArm(node, locals, pattern, whenClause, armResult, label, hasErrors | pattern.HasErrors));
        }
            public BoundExpression LowerIsPattern(
                BoundIsPatternExpression isPatternExpression, BoundPattern pattern, CSharpCompilation compilation, DiagnosticBag diagnostics)
            {
                BoundDecisionDag decisionDag    = isPatternExpression.DecisionDag;
                LabelSymbol      whenTrueLabel  = isPatternExpression.WhenTrueLabel;
                LabelSymbol      whenFalseLabel = isPatternExpression.WhenFalseLabel;
                BoundExpression  loweredInput   = _localRewriter.VisitExpression(isPatternExpression.Expression);

                // The optimization of sharing pattern-matching temps with user variables can always apply to
                // an is-pattern expression because there is no when clause that could possibly intervene during
                // the execution of the pattern-matching automaton and change one of those variables.
                decisionDag = ShareTempsAndEvaluateInput(loweredInput, decisionDag, expr => _sideEffectBuilder.Add(expr), out _);
                var node = decisionDag.RootNode;

                // We follow the "good" path in the decision dag. We depend on it being nicely linear in structure.
                // If we add "or" patterns that assumption breaks down.
                while (node.Kind != BoundKind.LeafDecisionDagNode && node.Kind != BoundKind.WhenDecisionDagNode)
                {
                    switch (node)
                    {
                    case BoundEvaluationDecisionDagNode evalNode:
                    {
                        LowerOneTest(evalNode.Evaluation);
                        node = evalNode.Next;
                    }
                    break;

                    case BoundTestDecisionDagNode testNode:
                    {
                        Debug.Assert(testNode.WhenFalse is BoundLeafDecisionDagNode x && x.Label == whenFalseLabel);
                        if (testNode.WhenTrue is BoundEvaluationDecisionDagNode e &&
                            TryLowerTypeTestAndCast(testNode.Test, e.Evaluation, out BoundExpression sideEffect, out BoundExpression testExpression))
                        {
                            _sideEffectBuilder.Add(sideEffect);
                            AddConjunct(testExpression);
                            node = e.Next;
                        }
 public override void VisitPattern(BoundPattern pattern)
 {
     base.VisitPattern(pattern);
     NoteDeclaredPatternVariables(pattern);
 }