Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed issue with lambdas and System.Action #995

Closed
wants to merge 2 commits into from

Conversation

acizmarik
Copy link
Member

This PR fixes an issue when compiling lambda expressions that need to be assigned to System.Action<...>. It is also necessary for the type inference feature #936.

Current state

If user defines a lambda in a binding whose expected type is Action<...>, current implementation fails for all non-void expressions. DotVVM throws compilation exception because it is unable to find an implicit conversion to convert from Func<...> to Action<...>. This is due to the fact that every expression that has non-void return type gets compiled into a Func<...>.

This is different from C#, where it is possible to have the following:

Action<string> action = (strArg) => MyStringProperty = strArg;

The expression above would be compiled into Func<string, string> in DotVVM because the assignment gets evaluated to a string.

Proposed solution

It is necessary to propagate information about expected types to the BindingExpressionBuilder. This type information can be then used inside ExpressionBuildingVisitor to validate that the body is a valid statement and if so, make sure to generate Action<...> if required.

Breaking change

Interface IBindingExpressionBuilder was altered by adding an optional parameter to its Parse method. Regardless, I do not think that this change could actually break someone.

@acizmarik
Copy link
Member Author

I just realized there is a bigger problem with lambdas and System.Action. I am changing to draft until resolved.

@acizmarik acizmarik marked this pull request as draft April 16, 2021 13:30
private Expression CreateLambdaExpression(Expression body, ParameterExpression[] parameters)
{
// Check if we have type information available
if (expressionDepth == 1 && ExpectedType != null && ReflectionUtils.IsDelegate(ExpectedType))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ExpectedType is the top level expected type. However, the lambda may be used somewhere inside of the expression. ExpectedType might be string, while the expression is MyMethod(x => Prop = x) and it will lead to the same problem with Action and Func

@acizmarik
Copy link
Member Author

Closing in favor of #936. As pointed out by @exyi, this implementation does not fully fix the problem. PR #936 should resolve all mentioned issues together with the introduction of lambdas type inference.

@acizmarik acizmarik closed this Apr 20, 2021
@acizmarik acizmarik deleted the fix/lambdas-body-expression-return-type branch May 10, 2021 08:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants