-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Ensure HasAnonymousFunctionConversion returns without binding lambda body for explicitly-typed lambda #69093
Comments
It looks like the error cases for return type and parameter types are handled here: roslyn/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs Lines 1434 to 1441 in 993fcc8
roslyn/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs Lines 1460 to 1469 in 993fcc8
However, the success case still depends on binding: roslyn/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs Lines 1524 to 1531 in 993fcc8
Is there a reason we need to use |
There may be edge cases where skipping binding the lambda body might lead to a breaking change, with captured variables for instance. For example, the following binds to the extension method rather than the instance method, because binding the lambda body fails for the instance method (see sharplab.io). using System;
class A
{
static void Main()
{
object x = 1;
var a = new A();
a.F1(x, y => F2(int () => y));
}
void F1<T>(T x, Func<T, int> f) { }
static int F2(Func<int> f) => f();
}
static class B
{
public static void F1(this A a, object x, Func<int, int> f) { }
} |
@cston your example though uses an implicitly typed lambda where as the issue is about explicitly typed lambdas. This is how I would explictly type out that lambda a.F1(x, int (int y) => F2(int () => y)); At that point why do we need to look at the lambda body here? The instance method is just going to fail at the generic inference phase. |
For the example above, it looks like there would not be a breaking change if the compiler ignored the lambda body when determining whether the inner lambda expression is convertible to the delegate type. The reason is because the outer lambda is an argument to an overloaded method, and even if we skip binding the body of the inner lambda when determining convertibility to the delegate parameter in |
Discussed this in LDM today and we confirmed that we want to change behavior here. For a lambda with a full explicit signature (return type and parameters) then for purposes of conversion we will only consider that signature. There is no need to bind the lambda body to see if it matches that signature for the purposes of determining if a conversion is legal. |
81.1% of the CPU time spent on the IntelliSense thread in #67926 is calling
HasAnonymousFunctionConversion
.This issue relates to the following code:
roslyn/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs
Lines 1059 to 1064 in ebc2841
This code should return without binding the contents of the lambda if the lambda explicitly declares all types related to its signature. For example, the following lambda declares its parameter types and its return value explicitly, and therefore can be evaluated for having a conversion without further binding.
While this guarantee doesn't automatically fix the problem described in #67926, it provides the user with a viable workaround in nested lambda cases where they can explicitly declare the types and avoid further costs.
The text was updated successfully, but these errors were encountered: