Skip to content

ArgumentException when converting from object to type with explicit operator #460

@volkmnv

Description

@volkmnv

Hello,

since the update to version 5.0.3 when I call Compile in this code I get the following exception during CompileFast:

private sealed class TestClass()
{
    public void Compile()
    {
        MethodInfo methodInfo = typeof(TestClass).GetProperty(nameof(this.ClassProp))!.SetMethod!;

        ParameterExpression instanceParameterExpression = Expression.Parameter(typeof(object), "instance");
        UnaryExpression instanceConvertParameter = Expression.Convert(instanceParameterExpression, typeof(TestClass));

        ParameterExpression valueParameterExpression = Expression.Parameter(typeof(object), "parameter");
        Expression valueConvertExpression = Expression.Convert(valueParameterExpression, methodInfo.GetParameters()[0].ParameterType);

        Expression call = Expression.Call(instanceConvertParameter, methodInfo, valueConvertExpression);
        Expression<Action<object, object>> lambda = Expression.Lambda<Action<object, object>>(call, [instanceParameterExpression, valueParameterExpression]);

        lambda.CompileFast();
    }

    public TestClass2? ClassProp { get; set; }
}

private sealed class TestClass2()
{
    public static explicit operator TestClass2(int value)
        => new();
}
System.ArgumentException
  HResult=0x80070057
  Message=GenericArguments[0], 'System.Object', on 'System.Nullable`1[T]' violates the constraint of type 'T'.
  Source=System.Private.CoreLib
  StackTrace:
   at System.RuntimeType.ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)
   at System.RuntimeType.MakeGenericType(Type[] instantiation)
   at FastExpressionCompiler.LightExpression.Tools.GetNullable(Type type)
   at FastExpressionCompiler.LightExpression.ExpressionCompiler.EmittingVisitor.TryEmitConvert(UnaryExpression expr, IParameterProvider paramExprs, ILGenerator il, ClosureInfo& closure, CompilerFlags setup, ParentFlags parent)
   at FastExpressionCompiler.LightExpression.ExpressionCompiler.EmittingVisitor.TryEmit(Expression expr, IParameterProvider paramExprs, ILGenerator il, ClosureInfo& closure, CompilerFlags setup, ParentFlags parent, Int32 byRefIndex)
   at FastExpressionCompiler.LightExpression.ExpressionCompiler.EmittingVisitor.TryEmitMethodCall(Expression expr, IParameterProvider paramExprs, ILGenerator il, ClosureInfo& closure, CompilerFlags setup, ParentFlags parent, Int32 byRefIndex)
   at FastExpressionCompiler.LightExpression.ExpressionCompiler.EmittingVisitor.TryEmit(Expression expr, IParameterProvider paramExprs, ILGenerator il, ClosureInfo& closure, CompilerFlags setup, ParentFlags parent, Int32 byRefIndex)
   at FastExpressionCompiler.LightExpression.ExpressionCompiler.TryCompileBoundToFirstClosureParam(Type delegateType, Expression bodyExpr, IParameterProvider paramExprs, Type[] closurePlusParamTypes, Type returnType, CompilerFlags flags)
   at FastExpressionCompiler.LightExpression.ExpressionCompiler.CompileFast[TDelegate](LambdaExpression lambdaExpr, Boolean ifFastFailedReturnNull, CompilerFlags flags)
   at FastExpressionCompiler.LightExpression.ExpressionCompiler.CompileFast[TDelegate](Expression`1 lambdaExpr, Boolean ifFastFailedReturnNull, CompilerFlags flags)
   [user code]

  This exception was originally thrown at this call stack:
    System.RuntimeTypeHandle.Instantiate(System.RuntimeType)
    System.RuntimeType.MakeGenericType(System.Type[])

Inner Exception 1:
TypeLoadException: GenericArguments[0], 'System.Object', on 'System.Nullable`1[T]' violates the constraint of type parameter 'T'.

I tracked this down to the explicit operator in TestClass2. If I remove this the expression compiles without problems.

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions