From 5d9cdce94c5db3d491f8ba52b8388040b8c6c580 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Fri, 28 Aug 2026 21:15:15 +0200 Subject: [PATCH] We need to properly compare the C# type, not just the StackType, otherwise our implicit conversions might end up converting to the wrong type. This also matters in the `1 => DateTime.Now, 2 => null` case -- BestCommonType infers `DateTime` here, but we need `DateTime?` instead. But both had `StackType.O` so this went wrong prior to this commit. --- .../TestCases/Pretty/SwitchExpressions.cs | 9 +++++++++ ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs | 6 ++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/SwitchExpressions.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/SwitchExpressions.cs index b4ecedbd4..db7d88763 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/SwitchExpressions.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/SwitchExpressions.cs @@ -244,6 +244,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty }).ToValidated(); } + public static bool NullableDateTime(int i) + { + return (i switch { + 0 => (DateTime?)DateTime.Now, + 1 => DateTime.UtcNow, + _ => null, + }).HasValue; + } + public static void ThrowDifferentExceptions(int i) { throw i switch { diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index 24c817873..2040832f5 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -4377,7 +4377,9 @@ namespace ICSharpCode.Decompiler.CSharp IType commonType = ti.GetBestCommonType( expressionsForTypeInference.SelectArray(e => e.ResolveResult), out bool success); - if (success && commonType.GetStackType() == inst.ResultType) + // Note: we need to ensure the compiler actually picked the type that we used for the + // implicit conversions. + if (success && NormalizeTypeVisitor.TypeErasure.EquivalentTypes(commonType, resultType)) { return switchExpr.WithILInstruction(inst).WithRR(new ResolveResult(commonType)); } @@ -4390,7 +4392,7 @@ namespace ICSharpCode.Decompiler.CSharp commonType = ti.GetBestCommonType( expressionsForTypeInference.SelectArray(e => e.ResolveResult), out success); - if (success && commonType.GetStackType() == inst.ResultType) + if (success && NormalizeTypeVisitor.TypeErasure.EquivalentTypes(commonType, resultType)) { return switchExpr.WithILInstruction(inst).WithRR(new ResolveResult(commonType)); }