Skip to content

Commit cd55971

Browse files
committed
Fix #310 - nullable conversion with ignored result
It should also help a bit other conversions with ignored result - whenever we know what the conversion will always pass, we don't need to emit any code. In some cases, this may save a boxing conversion (and it will probably save some work for the JIT)
1 parent b64abe2 commit cd55971

File tree

2 files changed

+10
-3
lines changed

2 files changed

+10
-3
lines changed

src/FastExpressionCompiler/FastExpressionCompiler.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2763,6 +2763,12 @@ private static bool TryEmitConvert(UnaryExpression expr, IReadOnlyList<PE> param
27632763
var underlyingNullableSourceType = Nullable.GetUnderlyingType(sourceType);
27642764
var targetType = expr.Type;
27652765

2766+
if (targetType.IsAssignableFrom(sourceType) && (parent & ParentFlags.IgnoreResult) != 0)
2767+
{
2768+
// quick path for ignored result & conversion which can't cause exception: just do nothing
2769+
return TryEmit(opExpr, paramExprs, il, ref closure, setup, parent);
2770+
}
2771+
27662772
if (sourceTypeIsNullable && targetType == underlyingNullableSourceType)
27672773
{
27682774
if (!TryEmit(opExpr, paramExprs, il, ref closure, setup,
@@ -2813,9 +2819,7 @@ private static bool TryEmitConvert(UnaryExpression expr, IReadOnlyList<PE> param
28132819
if (method != null && method.DeclaringType == targetType && method.GetParameters()[0].ParameterType == sourceType)
28142820
{
28152821
il.Emit(OpCodes.Call, method);
2816-
if ((parent & ParentFlags.IgnoreResult) != 0)
2817-
il.Emit(OpCodes.Pop);
2818-
return true;
2822+
return il.EmitPopIfIgnoreResult(parent);
28192823
}
28202824

28212825
var actualSourceType = sourceTypeIsNullable ? underlyingNullableSourceType : sourceType;

test/FastExpressionCompiler.TestsRunner.Net472/Program.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,9 @@ void Run(Func<int> run, string name = null)
201201
Run(new Issue308_Wrong_delegate_type_returned_with_closure().Run);
202202
Run(new FastExpressionCompiler.LightExpression.IssueTests.Issue308_Wrong_delegate_type_returned_with_closure().Run);
203203

204+
Run(new Issue310_InvalidProgramException_ignored_nullable().Run);
205+
Run(new FastExpressionCompiler.LightExpression.IssueTests.Issue310_InvalidProgramException_ignored_nullable().Run);
206+
204207
Console.WriteLine($"============={Environment.NewLine}IssueTests are passing in {sw.ElapsedMilliseconds} ms.");
205208
});
206209

0 commit comments

Comments
 (0)