Skip to content

Commit bc710db

Browse files
committed
fixed: #308
1 parent 715126e commit bc710db

File tree

4 files changed

+28
-8
lines changed

4 files changed

+28
-8
lines changed

src/FastExpressionCompiler/FastExpressionCompiler.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3172,12 +3172,12 @@ internal static void EmitLoadConstantsAndNestedLambdasIntoVars(ILGenerator il, r
31723172
var nestedLambdas = closure.NestedLambdas;
31733173
for (var i = 0; i < nestedLambdas.Length; i++)
31743174
{
3175-
var nestedLambda = nestedLambdas[i];
31763175
il.Emit(OpCodes.Ldloc_0);// SHOULD BE always at 0 locaton; load array field variable on the stack
31773176
EmitLoadConstantInt(il, constCount + i);
31783177
il.Emit(OpCodes.Ldelem_Ref);
31793178

31803179
// store the nested lambda in the local variable
3180+
var nestedLambda = nestedLambdas[i];
31813181
varIndex = il.GetNextLocalVarIndex(nestedLambda.Lambda.GetType());
31823182
nestedLambda.LambdaVarIndex = varIndex; // save the var index
31833183
EmitStoreLocalVariable(il, varIndex);
@@ -4234,11 +4234,20 @@ private static bool TryEmitNestedLambda(LambdaExpression lambdaExpr, IReadOnlyLi
42344234
// - call `Curry` method with nested lambda and array closure to produce a closed lambda with the expected signature
42354235
var lambdaTypeArgs = nestedLambda.GetType().GetTypeInfo().GenericTypeArguments;
42364236

4237-
var closureMethod = nestedLambdaInfo.LambdaExpression.ReturnType == typeof(void)
4237+
var nestedLambdaExpr = nestedLambdaInfo.LambdaExpression;
4238+
var closureMethod = nestedLambdaExpr.ReturnType == typeof(void)
42384239
? CurryClosureActions.Methods[lambdaTypeArgs.Length - 1].MakeGenericMethod(lambdaTypeArgs)
42394240
: CurryClosureFuncs .Methods[lambdaTypeArgs.Length - 2].MakeGenericMethod(lambdaTypeArgs);
42404241

42414242
EmitMethodCall(il, closureMethod);
4243+
4244+
// converting to the original possibly custom delegate type, see #308
4245+
if (closureMethod.ReturnType != nestedLambdaExpr.Type)
4246+
{
4247+
il.Emit(OpCodes.Ldftn, closureMethod.ReturnType.FindDelegateInvokeMethod());
4248+
il.Emit(OpCodes.Newobj, nestedLambdaExpr.Type.GetConstructors()[0]);
4249+
}
4250+
42424251
return true;
42434252
}
42444253

@@ -4663,7 +4672,7 @@ private static bool TryEmitArithmetic(BinaryExpression expr, ExpressionType expr
46634672
EmitLoadLocalVariable(il, InitValueTypeVariable(il, exprType));
46644673
il.Emit(OpCodes.Br_S, endL);
46654674
il.MarkLabel(valueLabel);
4666-
il.Emit(OpCodes.Newobj, exprType.GetTypeInfo().DeclaredConstructors.GetFirst());
4675+
il.Emit(OpCodes.Newobj, exprType.GetConstructors()[0]);
46674676
il.MarkLabel(endL);
46684677
}
46694678
else

test/FastExpressionCompiler.IssueTests/Issue308_Wrong_delegate_type_returned_with_closure.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,26 @@ public int Run()
1919

2020
delegate string Command();
2121

22-
//[Test]
22+
[Test]
2323
public void Test1()
2424
{
2525
var p = Parameter(typeof(string), "vm");
2626
var expr = Lambda<Func<string, Command>>(Lambda<Command>(p), p);
2727

2828
expr.PrintCSharp();
2929

30+
// var x = (Func<string, Issue308_Wrong_delegate_type_returned_with_closure.Command>)((string vm) => //$
31+
// (Issue308_Wrong_delegate_type_returned_with_closure.Command)(() => //$
32+
// vm));
33+
3034
var fSys = expr.CompileSys();
3135
fSys.PrintIL();
32-
36+
3337
Assert.IsInstanceOf<Command>(fSys(null));
34-
38+
3539
var fFast = expr.CompileFast();
3640
fFast.PrintIL();
37-
41+
3842
Assert.IsInstanceOf<Command>(fFast(null));
3943
}
4044
}

test/FastExpressionCompiler.TestsRunner.Net472/Program.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,9 @@ void Run(Func<int> run, string name = null)
198198
Run(new Issue307_Switch_with_fall_through_throws_InvalidProgramException().Run);
199199
Run(new FastExpressionCompiler.LightExpression.IssueTests.Issue307_Switch_with_fall_through_throws_InvalidProgramException().Run);
200200

201+
Run(new Issue308_Wrong_delegate_type_returned_with_closure().Run);
202+
Run(new FastExpressionCompiler.LightExpression.IssueTests.Issue308_Wrong_delegate_type_returned_with_closure().Run);
203+
201204
Console.WriteLine($"============={Environment.NewLine}IssueTests are passing in {sw.ElapsedMilliseconds} ms.");
202205
});
203206

test/FastExpressionCompiler.TestsRunner/Program.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public static void Main()
1111
{
1212
RunAllTests();
1313

14-
//new FastExpressionCompiler.LightExpression.IssueTests.Issue308_Wrong_delegate_type_returned_with_closure().Run();
14+
// new FastExpressionCompiler.LightExpression.IssueTests.Issue308_Wrong_delegate_type_returned_with_closure().Run();
1515

1616
// new FastExpressionCompiler.LightExpression.IssueTests.Issue307_Switch_with_fall_through_throws_InvalidProgramException().Run();
1717
// new FastExpressionCompiler.LightExpression.IssueTests.Issue305_CompileFast_generates_incorrect_code_with_arrays_and_printing().Run();
@@ -219,9 +219,13 @@ void Run(Func<int> run, string name = null)
219219

220220
Run(new Issue305_CompileFast_generates_incorrect_code_with_arrays_and_printing().Run);
221221
Run(new FastExpressionCompiler.LightExpression.IssueTests.Issue305_CompileFast_generates_incorrect_code_with_arrays_and_printing().Run);
222+
222223
Run(new Issue307_Switch_with_fall_through_throws_InvalidProgramException().Run);
223224
Run(new FastExpressionCompiler.LightExpression.IssueTests.Issue307_Switch_with_fall_through_throws_InvalidProgramException().Run);
224225

226+
Run(new Issue308_Wrong_delegate_type_returned_with_closure().Run);
227+
Run(new FastExpressionCompiler.LightExpression.IssueTests.Issue308_Wrong_delegate_type_returned_with_closure().Run);
228+
225229
Console.WriteLine($"============={Environment.NewLine}IssueTests are passing in {sw.ElapsedMilliseconds} ms.");
226230
});
227231

0 commit comments

Comments
 (0)