diff --git a/ICSharpCode.Decompiler.Tests/Semantics/ConversionTests.cs b/ICSharpCode.Decompiler.Tests/Semantics/ConversionTests.cs index e4c315c45..7a9b9f51f 100644 --- a/ICSharpCode.Decompiler.Tests/Semantics/ConversionTests.cs +++ b/ICSharpCode.Decompiler.Tests/Semantics/ConversionTests.cs @@ -1592,6 +1592,18 @@ namespace ICSharpCode.Decompiler.Tests.Semantics Is.EqualTo(C.None)); } + [Test, Ignore("Known bug: CSharpConversions does not support nullable conversions derived from tuple conversions, but csc accepts them")] + public void LiftedTupleConversions() + { + // csc accepts the nullable conversions derived from tuple conversions: + // (int, string) t = (1, "one"); + // (long, object)? a = t; + // (int, string)? tn = t; + // (long, object)? b = tn; + Assert.That(ImplicitConversion(typeof((int, string)), typeof((long, object)?)).IsValid, "(int, string) -> (long, object)?"); + Assert.That(ImplicitConversion(typeof((int, string)?), typeof((long, object)?)).IsValid, "(int, string)? -> (long, object)?"); + } + [Test] public void UserDefinedImplicitConversion_OperatorDeclaredInBaseClassOfSource() { diff --git a/ICSharpCode.Decompiler.Tests/Semantics/ExplicitConversionTest.cs b/ICSharpCode.Decompiler.Tests/Semantics/ExplicitConversionTest.cs index ba096e0ff..32808dc46 100644 --- a/ICSharpCode.Decompiler.Tests/Semantics/ExplicitConversionTest.cs +++ b/ICSharpCode.Decompiler.Tests/Semantics/ExplicitConversionTest.cs @@ -731,6 +731,29 @@ namespace ICSharpCode.Decompiler.Tests.Semantics Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(StructImplementingIEnumerableOfString)), Is.EqualTo(C.None)); } + [Test, Ignore("Known bug: CSharpConversions does not support nullable conversions derived from tuple conversions, but csc accepts them")] + public void ExplicitLiftedTupleConversions() + { + // csc accepts the explicit nullable conversions derived from tuple conversions: + // (int, string)? tn = ...; + // (long, object) c = ((long, object))tn; + // (int, string)? d = ((int, string)?)lo; with lo of type (long, object)? + Assert.That(ExplicitConversion(typeof((int, string)?), typeof((long, object))).IsValid, "(int, string)? -> (long, object)"); + Assert.That(ExplicitConversion(typeof((long, object)?), typeof((int, string)?)).IsValid, "(long, object)? -> (int, string)?"); + } + + [Test, Ignore("Known bug: CSharpConversions rejects explicit user-defined conversions to a nullable target when the operator result needs an explicit numeric conversion, but csc accepts them")] + public void UserDefinedExplicitConversion_ExplicitNumericConversionToNullableTarget() + { + // csc accepts: + // int? d = (int?)new ImplicitToLong(); -- UD op to long, then explicit long -> int? + // int? e = (int?)new ExplicitToLongOrUInt(); -- UD ops to long/uint, then explicit -> int? + var c = ExplicitConversion(typeof(UserDefinedExplicitConversionTestCases.ImplicitToLong), typeof(int?)); + Assert.That(c.IsValid, "(int?)ImplicitToLong"); + var c2 = ExplicitConversion(typeof(UserDefinedExplicitConversionTestCases.ExplicitToLongOrUInt), typeof(int?)); + Assert.That(c2.IsValid, "(int?)ExplicitToLongOrUInt"); + } + [Test] public void ExplicitTypeParameterConversionFromEffectiveBaseClass() {