-
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
Avoid binding lambda body if fully typed #69505
Conversation
src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs
Outdated
Show resolved
Hide resolved
public static void F1(this A a, object x, Func<int, int> f) => Console.Write("B"); | ||
} | ||
"""; | ||
CompileAndVerify(source, expectedOutput: "B").VerifyDiagnostics(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cston wasn't 100% sure this would be the result after he reflected on the proposed change. Wanted to make sure he saw this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this looks correct to me - no change in behavior. (I took a second look at this case and realized my initial thought was incomplete.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the test call the ClassifyConversion API here? Including a case where the lambda body is of the wrong type but explicit return is the expected type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, should we add a new EndToEnd test which shows that the change results in "viable" perf in the relevant scenario?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, should we add a new EndToEnd test which shows that the change results in "viable" perf in the relevant scenario?
Thanks, trying to write such test made me realize this might not be a complete fix (or maybe not easily fixable at all).
For example, when type inference is involved, lambdas are bound later anyway for error recovery
var discarded = unboundArgument.Bind((NamedTypeSymbol)parameterType, isExpressionTree: false); |
or simply when overload resolution binds the arguments:
var boundLambda = unboundLambda.Bind((NamedTypeSymbol)destination, isExpressionTree: destination.IsGenericOrNonGenericExpressionType(out _)).WithInAnonymousFunctionConversion(); |
Hence the change currently in this PR doesn't seem to improve anything in my testing. Will investigate more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, should we add a new EndToEnd test which shows that the change results in "viable" perf in the relevant scenario?
#59733 includes a change to track the number of unbound lambdas and number of times lambda expressions are bound. Would something similar be useful here for measuring the impact?
Co-authored-by: Jared Parsons <[email protected]>
var targetType = comp.GetMember<MethodSymbol>("C.M2").Parameters.Single().Type.GetPublicSymbol(); | ||
Assert.Equal("System.Func<System.Int32>", targetType.ToTestDisplayString()); | ||
var conversion = model.ClassifyConversion(lambdaSyntax, targetType); | ||
Assert.True(conversion.IsValid); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: this would be false
without the change in this PR.
Resolves #69093.