diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer.cs index bc3dda1329..0542458402 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer.cs @@ -267,7 +267,8 @@ static bool IsUnconstrainedTypeParameter(ITypeParameterSymbol typeParameterSymbo if (castToTypeParam.HasValueTypeConstraint && castFrom.TypeKind == TypeKind.Class) { - return true; + return castFrom.SpecialType is not SpecialType.System_Enum + and not SpecialType.System_ValueType; } return false; diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzerTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzerTests.cs index 7e6523ce82..23337eb425 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzerTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzerTests.cs @@ -910,6 +910,35 @@ class GenericDerived : GenericBase await test.RunAsync(); } + [Fact, WorkItem(7031, "https://github.com/dotnet/roslyn-analyzers/issues/7031")] + public async Task GenericValueType() + { + // ensure runtime behavior is matches + _ = new Enum[] { StringComparison.OrdinalIgnoreCase }.Cast().ToArray(); + _ = new ValueType[] { int.MaxValue }.Cast().ToArray(); + + var test = new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.Net.Net90, + LanguageVersion = LanguageVersion.Latest, + + TestCode = @" +using System; +using System.Collections.Generic; +using System.Linq; + +public static class Program +{ + public static IEnumerable CastEnums(IEnumerable values) where T : struct, Enum + => values.Cast(); // CA2021 + + public static IEnumerable CastValueTypes(IEnumerable values) where T : struct + => values.Cast(); // CA2021 +}" + }; + await test.RunAsync(); + } + [Fact] public async Task NonGenericCasesVB() {