@@ -861,7 +861,8 @@ public override async Task<SyntaxList<StatementSyntax>> VisitSelectBlock(VBSynta
861861 lowerBoundCheck = ComparisonAdjustedForStringComparison ( node , range . LowerBound , caseTypeInfo , lowerBound , csCaseVar , switchExprTypeInfo , ComparisonKind . LessThanOrEqual ) ;
862862 } else {
863863 lowerBound = CommonConversions . TypeConversionAnalyzer . AddExplicitConversion ( range . LowerBound , lowerBound ) ;
864- lowerBoundCheck = SyntaxFactory . BinaryExpression ( SyntaxKind . LessThanOrEqualExpression , lowerBound , csCaseVar ) ;
864+ var ( lowerBoundForComparison , csCaseVarForLower ) = CastBothToUnderlyingTypeIfEnum ( switchExprTypeInfo . ConvertedType , lowerBound , csCaseVar ) ;
865+ lowerBoundCheck = SyntaxFactory . BinaryExpression ( SyntaxKind . LessThanOrEqualExpression , lowerBoundForComparison , csCaseVarForLower ) ;
865866 }
866867 var upperBound = await range . UpperBound . AcceptAsync < ExpressionSyntax > ( _expressionVisitor ) ;
867868 ExpressionSyntax upperBoundCheck ;
@@ -870,7 +871,8 @@ public override async Task<SyntaxList<StatementSyntax>> VisitSelectBlock(VBSynta
870871 upperBoundCheck = ComparisonAdjustedForStringComparison ( node , range . UpperBound , switchExprTypeInfo , csCaseVar , upperBound , caseTypeInfo , ComparisonKind . LessThanOrEqual ) ;
871872 } else {
872873 upperBound = CommonConversions . TypeConversionAnalyzer . AddExplicitConversion ( range . UpperBound , upperBound ) ;
873- upperBoundCheck = SyntaxFactory . BinaryExpression ( SyntaxKind . LessThanOrEqualExpression , csCaseVar , upperBound ) ;
874+ var ( csCaseVarForUpper , upperBoundForComparison ) = CastBothToUnderlyingTypeIfEnum ( switchExprTypeInfo . ConvertedType , csCaseVar , upperBound ) ;
875+ upperBoundCheck = SyntaxFactory . BinaryExpression ( SyntaxKind . LessThanOrEqualExpression , csCaseVarForUpper , upperBoundForComparison ) ;
874876 }
875877 var withinBounds = SyntaxFactory . BinaryExpression ( SyntaxKind . LogicalAndExpression , lowerBoundCheck , upperBoundCheck ) ;
876878 labels . Add ( VarWhen ( varName , withinBounds ) ) ;
@@ -930,6 +932,21 @@ bool IsExitStatement(StatementSyntax node)
930932 private static bool IsEnumOrNullableEnum ( ITypeSymbol convertedType ) =>
931933 convertedType ? . IsEnumType ( ) == true || convertedType ? . GetNullableUnderlyingType ( ) ? . IsEnumType ( ) == true ;
932934
935+ /// <summary>
936+ /// When the switch expression is an enum, C# does not support <= comparisons directly on enum values.
937+ /// Cast both sides to the enum's underlying integer type so the comparison compiles.
938+ /// </summary>
939+ private ( ExpressionSyntax Left , ExpressionSyntax Right ) CastBothToUnderlyingTypeIfEnum ( ITypeSymbol switchExprType , ExpressionSyntax left , ExpressionSyntax right )
940+ {
941+ var enumType = switchExprType ? . IsEnumType ( ) == true ? switchExprType as INamedTypeSymbol
942+ : switchExprType ? . GetNullableUnderlyingType ( ) as INamedTypeSymbol ;
943+ if ( enumType ? . EnumUnderlyingType is not { } underlyingType ) {
944+ return ( left , right ) ;
945+ }
946+ var typeSyntax = CommonConversions . GetTypeSyntax ( underlyingType ) ;
947+ return ( ValidSyntaxFactory . CastExpression ( typeSyntax , left ) , ValidSyntaxFactory . CastExpression ( typeSyntax , right ) ) ;
948+ }
949+
933950 private static CasePatternSwitchLabelSyntax VarWhen ( SyntaxToken varName , ExpressionSyntax binaryExp )
934951 {
935952 var patternMatch = ValidSyntaxFactory . VarPattern ( varName ) ;
0 commit comments