Browse Source

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.
pull/4068/head
Daniel Grunwald 3 weeks ago
parent
commit
5d9cdce94c
  1. 9
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/SwitchExpressions.cs
  2. 6
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

9
ICSharpCode.Decompiler.Tests/TestCases/Pretty/SwitchExpressions.cs

@ -244,6 +244,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -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 {

6
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -4377,7 +4377,9 @@ namespace ICSharpCode.Decompiler.CSharp @@ -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 @@ -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));
}

Loading…
Cancel
Save