From 581a1de18544c4b9d3558fc783bb2e486712662a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=87=E7=85=8C?= Date: Sun, 31 Jan 2021 02:42:55 +0800 Subject: [PATCH 1/2] fix https://github.com/icsharpcode/ILSpy/issues/2288 --- .../IL/Transforms/TransformExpressionTrees.cs | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs b/ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs index f50e000268..29d4b2f392 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs @@ -515,15 +515,16 @@ ILInstruction Convert() Arguments = { left(), right() } }, method.ReturnType); case 4: - if (!invocation.Arguments[2].MatchLdcI4(out var isLifted)) + if (!invocation.Arguments[2].MatchLdcI4(out var isLiftedToNull)) return (null, SpecialType.UnknownType); if (!MatchGetMethodFromHandle(invocation.Arguments[3], out method)) return (null, SpecialType.UnknownType); - if (isLifted != 0) + bool isLifted = NullableType.IsNullable(leftType); + if (isLifted) method = CSharpOperators.LiftUserDefinedOperator((IMethod)method); return (() => new Call((IMethod)method) { Arguments = { left(), right() } - }, method.ReturnType); + }, isLiftedToNull != 0 ? NullableType.Create(method.Compilation, method.ReturnType) : method.ReturnType); default: return (null, SpecialType.UnknownType); } @@ -729,13 +730,12 @@ Func[] ConvertCallArguments(IList arguments, IMeth var (right, rightType) = ConvertInstruction(invocation.Arguments[1]); if (right == null) return (null, SpecialType.UnknownType); - if (invocation.Arguments.Count == 4 && invocation.Arguments[2].MatchLdcI4(out var isLifted) && MatchGetMethodFromHandle(invocation.Arguments[3], out var method)) + if (invocation.Arguments.Count == 4 && invocation.Arguments[2].MatchLdcI4(out var isLiftedToNull) && MatchGetMethodFromHandle(invocation.Arguments[3], out var method)) { - if (isLifted != 0) - { + bool isLifted = NullableType.IsNullable(leftType); + if (isLifted) method = CSharpOperators.LiftUserDefinedOperator((IMethod)method); - } - return (() => new Call((IMethod)method) { Arguments = { left(), right() } }, method.ReturnType); + return (() => new Call((IMethod)method) { Arguments = { left(), right() } }, isLiftedToNull != 0 ? NullableType.Create(method.Compilation, method.ReturnType) : method.ReturnType); } var rr = resolver.ResolveBinaryOperator(kind.ToBinaryOperatorType(), new ResolveResult(leftType), new ResolveResult(rightType)) as OperatorResolveResult; if (rr != null && !rr.IsError && rr.UserDefinedOperatorMethod != null) @@ -979,15 +979,16 @@ Block BuildBlock() Arguments = { left(), right() } }, method.ReturnType); case 4: - if (!invocation.Arguments[2].MatchLdcI4(out var isLifted)) + if (!invocation.Arguments[2].MatchLdcI4(out var isLiftedToNull)) return (null, SpecialType.UnknownType); if (!MatchGetMethodFromHandle(invocation.Arguments[3], out method)) return (null, SpecialType.UnknownType); - if (isLifted != 0) + bool isLifted = NullableType.IsNullable(leftType); + if (isLifted) method = CSharpOperators.LiftUserDefinedOperator((IMethod)method); return (() => new Call((IMethod)method) { Arguments = { left(), right() } - }, method.ReturnType); + }, isLiftedToNull != 0 ? NullableType.Create(method.Compilation, method.ReturnType) : method.ReturnType); default: return (null, SpecialType.UnknownType); } From 3b2f00e44fd634cc924f5e6dea38c1af09097252 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 15 Feb 2021 19:12:58 +0100 Subject: [PATCH 2/2] Add test case. --- .../TestCases/Pretty/ExpressionTrees.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExpressionTrees.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExpressionTrees.cs index bcf20b512e..525743cd4b 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExpressionTrees.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExpressionTrees.cs @@ -894,6 +894,12 @@ public void NullCoalescing() Test>((string a, string b) => a ?? b, (string a, string b) => a ?? b); Test>((int? a) => a ?? 1, (int? a) => a ?? 1); } + + public void NullableLifting(Guid? a, Guid? b) + { + ToCode(null, () => a == b); + ToCode(null, () => (Guid)a == (Guid)b); + } } internal static class Extensions