private BoundPatternSwitchLabel BindPatternSwitchSectionLabel( Binder sectionBinder, SwitchLabelSyntax node, LabelSymbol label, ref BoundPatternSwitchLabel defaultLabel, DiagnosticBag diagnostics) { switch (node.Kind()) { case SyntaxKind.CaseSwitchLabel: { var caseLabelSyntax = (CaseSwitchLabelSyntax)node; var pattern = sectionBinder.BindConstantAsPattern( node, SwitchGoverningType, caseLabelSyntax.Value, node.HasErrors, diagnostics, out bool wasExpression); bool hasErrors = pattern.HasErrors; SyntaxNode innerValueSyntax = caseLabelSyntax.Value.SkipParens(); if (innerValueSyntax.Kind() == SyntaxKind.DefaultLiteralExpression) { diagnostics.Add(ErrorCode.ERR_DefaultInSwitch, innerValueSyntax.Location); hasErrors = true; } pattern.WasCompilerGenerated = true; var constantValue = pattern.ConstantValue; if (!hasErrors && (object)constantValue != null && pattern.Value.Type == SwitchGoverningType && this.FindMatchingSwitchCaseLabel(constantValue, caseLabelSyntax) != label) { diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, pattern.ConstantValue.GetValueToDisplay() ?? label.Name); hasErrors = true; } // Until we've determined whether or not the switch label is reachable, we assume it // is. The caller updates isReachable after determining if the label is subsumed. const bool isReachable = true; return(new BoundPatternSwitchLabel(node, label, pattern, null, isReachable, hasErrors)); } case SyntaxKind.DefaultSwitchLabel: { var defaultLabelSyntax = (DefaultSwitchLabelSyntax)node; var pattern = new BoundWildcardPattern(node); bool hasErrors = pattern.HasErrors; if (defaultLabel != null) { diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, label.Name); hasErrors = true; } // We always treat the default label as reachable, even if the switch is complete. const bool isReachable = true; // Note that this is semantically last! The caller will place it in the decision tree // in the final position. defaultLabel = new BoundPatternSwitchLabel(node, label, pattern, null, isReachable, hasErrors); return(defaultLabel); } case SyntaxKind.CasePatternSwitchLabel: { var matchLabelSyntax = (CasePatternSwitchLabelSyntax)node; var pattern = sectionBinder.BindPattern( matchLabelSyntax.Pattern, SwitchGoverningType, node.HasErrors, diagnostics); return(new BoundPatternSwitchLabel(node, label, pattern, matchLabelSyntax.WhenClause != null ? sectionBinder.BindBooleanExpression(matchLabelSyntax.WhenClause.Condition, diagnostics) : null, true, node.HasErrors)); } default: throw ExceptionUtilities.UnexpectedValue(node); } }