Skip to content

Support lambda expressions and method groups as var initializers#55132

Merged
cston merged 2 commits intodotnet:mainfrom
cston:lambdas-var
Jul 27, 2021
Merged

Support lambda expressions and method groups as var initializers#55132
cston merged 2 commits intodotnet:mainfrom
cston:lambdas-var

Conversation

@cston
Copy link
Copy Markdown
Contributor

@cston cston commented Jul 27, 2021

var d1 = Program.Main;
var d2 = () => { };

Proposal: lambda-improvements.md
Test plan: #52192

@ghost ghost added the Area-Compilers label Jul 27, 2021
@cston cston marked this pull request as ready for review July 27, 2021 05:28
@cston cston requested review from a team as code owners July 27, 2021 05:28
// (7,28): error CS0446: Foreach cannot operate on a 'anonymous method'. Did you intend to invoke the 'anonymous method'?
// foreach (var d3 in delegate () { }) { }
Diagnostic(ErrorCode.ERR_AnonMethGrpInForEach, "delegate () { }").WithArguments("anonymous method").WithLocation(7, 28));
}
Copy link
Copy Markdown
Member

@jcouv jcouv Jul 27, 2021

Choose a reason for hiding this comment

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

nit: consider another similar negative test with deconstruction declaration (var x, var y) = ... #Closed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Also, something like (Action a, var b) = (null, () => {}); (I assume should work per spec, but may not work in current implementation)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please check GetTypeInfo and GetDeclaredSymbol in one of the positive tests

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Consider including a test with a non-simple signature (error)

Copy link
Copy Markdown
Contributor Author

@cston cston Jul 27, 2021

Choose a reason for hiding this comment

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

Added tests. Logged #55139 to investigate support for implicitly-typed variables in tuples and deconstruction.

// var m = Main; // CS0815
Diagnostic(ErrorCode.ERR_ImplicitlyTypedVariableAssignedBadValue, "m = Main").WithArguments("method group"),
// (7,13): error CS0815: Cannot assign lambda expression to an implicitly-typed variable
// (7,17): error CS8917: The delegate type could not be inferred.
Copy link
Copy Markdown
Member

@jcouv jcouv Jul 27, 2021

Choose a reason for hiding this comment

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

Comment in var m = Main; // CS0815 is out-of-date #Closed

Copy link
Copy Markdown
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

Done with review pass (iteration 1)

@jcouv jcouv self-assigned this Jul 27, 2021
Copy link
Copy Markdown
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

LGTM Thanks (iteration 2). How do you want to track the deconstruction issue?

@jcouv
Copy link
Copy Markdown
Member

jcouv commented Jul 27, 2021

@333fred @dotnet/roslyn-compiler for a second review. Thanks

@cston
Copy link
Copy Markdown
Contributor Author

cston commented Jul 27, 2021

How do you want to track the deconstruction issue?

Logged #55139.

@333fred
Copy link
Copy Markdown
Member

333fred commented Jul 27, 2021

Looking.

@333fred
Copy link
Copy Markdown
Member

333fred commented Jul 27, 2021

    public void IAnonymousFunctionExpression_UnboundLambdaAsVar_HasValidLambdaExpressionTree()

Nit: consider renaming to BoundLambda


Refers to: src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IAnonymousFunctionExpression.cs:190 in a884c74. [](commit_id = a884c74, deletion_comment = False)


var variableDeclarationGroupOperation = (IVariableDeclarationGroupOperation)semanticModel.GetOperation(variableDeclaration);
var variableTreeLambdaOperation = (IAnonymousFunctionOperation)variableDeclarationGroupOperation.Declarations.Single().Declarators.Single().Initializer.Value;
var variableTreeLambdaOperation = ((IDelegateCreationOperation)variableDeclarationGroupOperation.Declarations.Single().Declarators.Single().Initializer.Value).Target;
Copy link
Copy Markdown
Member

@333fred 333fred Jul 27, 2021

Choose a reason for hiding this comment

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

IDelegateCreationOperation

I don't think this is keeping the test correct. Please break the test in a different fashion, such as removing the F() definition so the body is still unbound.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will add to the next PR, thanks.

@333fred
Copy link
Copy Markdown
Member

333fred commented Jul 27, 2021

    public void InvalidLambdaBinding_UnboundLambda()

No longer correctly named, and probably not the correct location for this either, since it's no longer invalid. This test can probably just be removed.


Refers to: src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_InvalidExpression.cs:333 in a884c74. [](commit_id = a884c74, deletion_comment = False)

@333fred
Copy link
Copy Markdown
Member

333fred commented Jul 27, 2021

    public void InvalidLambdaBinding_LambdaExpression()

Same comment.


Refers to: src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_InvalidExpression.cs:375 in a884c74. [](commit_id = a884c74, deletion_comment = False)

}

[Fact]
public void ImplicitlyTypedVariables_04()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ImplicitlyTypedVariables_04

Would it be worth making a version of this test where Action inherits from IDisposable?

static void Main()
{
var d1 = F;
var d2 = (ref int x) => x;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Consider expanding these negative tests with ref returns as well.

Copy link
Copy Markdown
Member

@333fred 333fred left a comment

Choose a reason for hiding this comment

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

I'm not going to block on any of my test suggestions, but please make sure they're in the next PR.

@cston
Copy link
Copy Markdown
Contributor Author

cston commented Jul 27, 2021

    public void IAnonymousFunctionExpression_UnboundLambdaAsVar_HasValidLambdaExpressionTree()

Will add to next PR.


In reply to: 887712078


Refers to: src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IAnonymousFunctionExpression.cs:190 in a884c74. [](commit_id = a884c74, deletion_comment = False)

@cston
Copy link
Copy Markdown
Contributor Author

cston commented Jul 27, 2021

    public void InvalidLambdaBinding_UnboundLambda()

Will leave these tests here, to catch any regressions, but I'll rename the tests.


In reply to: 887713598


Refers to: src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_InvalidExpression.cs:333 in a884c74. [](commit_id = a884c74, deletion_comment = False)

@cston cston merged commit 5840335 into dotnet:main Jul 27, 2021
@ghost ghost added this to the Next milestone Jul 27, 2021
@cston cston deleted the lambdas-var branch July 27, 2021 18:26
@cston cston modified the milestones: Next, 17.0.P3 Jul 27, 2021
@davidfowl
Copy link
Copy Markdown
Member

davidfowl commented Jul 29, 2021

Tell me when this is merged 😄 into a VS build.

@oskardudycz
Copy link
Copy Markdown

@cston, a small correction. The link to the proposal should be https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/lambda-improvements.md.
This looks neat! 😄

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.

5 participants